From eb5a3c2a8d83c0e1762157fef34ee10acb63601c Mon Sep 17 00:00:00 2001 From: Embedded_Projects <> Date: Thu, 26 Oct 2023 13:18:36 +0000 Subject: [PATCH] Initial commit --- .clang-format | 12 + .gitignore | 5 + .gitmodules | 6 + CMakeLists.txt | 179 ++++++++++ arm-none-eabi.cmake | 17 + board/board.c | 57 ++++ board/board.h | 11 + board/n32wb03x_it.c | 72 ++++ board/n32wb03x_it.h | 65 ++++ board/system_n32wb03x.c | 344 ++++++++++++++++++++ include/FreeRTOSConfig.h | 113 +++++++ include/ble/app_ble_profiles/app_ble_diss.h | 63 ++++ include/ble/app_user_config.h | 114 +++++++ include/ble/rwapp_config.h | 110 +++++++ pyocd_user.py | 31 ++ src/app_ble_profiles/app_ble_diss.c | 109 +++++++ src/app_ble_support.c | 173 ++++++++++ src/app_freertos_support.c | 230 +++++++++++++ src/main.c | 39 +++ 19 files changed, 1750 insertions(+) create mode 100644 .clang-format create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 CMakeLists.txt create mode 100644 arm-none-eabi.cmake create mode 100644 board/board.c create mode 100644 board/board.h create mode 100644 board/n32wb03x_it.c create mode 100644 board/n32wb03x_it.h create mode 100644 board/system_n32wb03x.c create mode 100644 include/FreeRTOSConfig.h create mode 100644 include/ble/app_ble_profiles/app_ble_diss.h create mode 100644 include/ble/app_user_config.h create mode 100644 include/ble/rwapp_config.h create mode 100644 pyocd_user.py create mode 100644 src/app_ble_profiles/app_ble_diss.c create mode 100644 src/app_ble_support.c create mode 100644 src/app_freertos_support.c create mode 100644 src/main.c diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..214adf0 --- /dev/null +++ b/.clang-format @@ -0,0 +1,12 @@ +BasedOnStyle: Google +IndentWidth: 4 +AlignConsecutiveMacros: Consecutive +AlignConsecutiveDeclarations: Consecutive +AlignConsecutiveAssignments: Consecutive +AllowShortFunctionsOnASingleLine: None +BreakBeforeBraces: Custom +BraceWrapping: + AfterEnum: false + AfterStruct: false + SplitEmptyFunction: false +ColumnLimit: 120 \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2da6168 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/cmake-build-* +/build +/board/*.bak +/.vscode + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..cbcbf9c --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "SDK"] + path = SDK + url = https://git.minori.work/Embedded_SDK/N32WB031_SDK.git +[submodule "lib/freertos"] + path = lib/freertos + url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f072f1e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,179 @@ +cmake_minimum_required(VERSION 3.10) + +project(n32wb03x_template) + +enable_language(CXX) +enable_language(ASM) + +# Different linker scripts +set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/gcc/n32wb03x_FLASH.ld") + +# ROM API Symbols +set(TARGET_SYMBOL_LIST "${CMAKE_CURRENT_SOURCE_DIR}/SDK/middlewares/Nationstech/ble_library/ns_ble_stack/symdef/symbol_g15.txt") + +set(TARGET_SOURCES + "SDK/firmware/n32wb03x_std_periph_driver/src/misc.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_adc.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_crc.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_dma.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_exti.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_gpio.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_i2c.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_iwdg.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_keyscan.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_lpuart.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_pwr.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_qflash.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_rcc.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_rtc.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_spi.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_tim.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_usart.c" + "SDK/firmware/n32wb03x_std_periph_driver/src/n32wb03x_wwdg.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_profile/dis/diss/src/diss.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_profile/dis/diss/src/diss_task.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_profile/prf.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/src/att/lib_att.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/stack_common/rwip.c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/stack_common/rwip_driver.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/ble/ns_ble.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/ble/ns_ble_task.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/ecc/ns_ecc.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/ecc/sha256.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/ecc/uECC.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/error/ns_error.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/log/ns_log_lpuart.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/log/ns_log_usart.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/scheduler/ns_scheduler.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/sec/ns_sec.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/sleep/ns_sleep.c" + "SDK/middlewares/Nationstech/ble_library/ns_library/timer/ns_timer.c" + "board/board.c" + "board/n32wb03x_it.c" + "board/system_n32wb03x.c" + "SDK/gcc/startup_n32wb03x.S" + "src/app_ble_support.c" + "src/app_ble_profiles/app_ble_diss.c" + "src/app_freertos_support.c" + "src/main.c" +) + +set(TARGET_C_DEFINES + "N32WB03X" + "USE_STDPERIPH_DRIVER" +) + +set(TARGET_C_INCLUDES + "SDK/firmware/CMSIS/core" + "SDK/firmware/CMSIS/device" + "SDK/firmware/n32wb03x_std_periph_driver/inc" + "SDK/middlewares/Nationstech/ble_library/ns_ble_profile/dis/diss/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/arch" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/arch" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ahi/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/inc" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/src/gap" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/src/gatt" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/hl/src/l2c" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/ll/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/ll/src" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/ll/src/llc" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/ll/src/lld" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/ble/ll/src/llm" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/em/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/hci/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/ip/sch/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/aes/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/common/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/common/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/common/src" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/dbg/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/ecc_p256/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/h4tl/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/ke/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/modules/rwip/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/rfinit/api" + "SDK/middlewares/Nationstech/ble_library/ns_ble_stack/stack_common" + "SDK/middlewares/Nationstech/ble_library/ns_library/adv" + "SDK/middlewares/Nationstech/ble_library/ns_library/ble" + "SDK/middlewares/Nationstech/ble_library/ns_library/delay" + "SDK/middlewares/Nationstech/ble_library/ns_library/log" + "SDK/middlewares/Nationstech/ble_library/ns_library/sec" + "SDK/middlewares/Nationstech/ble_library/ns_library/sleep" + "SDK/middlewares/Nationstech/ble_library/ns_library/timer" + "board" + "include" + "include/ble" +) + +# Shared libraries linked with application +set(TARGET_LIBS + "c" + "m" + "nosys" + "freertos_kernel" +) + +# Shared library and linker script search paths +set(TARGET_LIB_DIRECTORIES +) + +# Conditional flags +# DEBUG +set(CMAKE_C_FLAGS_DEBUG "-DDEBUG -O0 -g") +set(CMAKE_CXX_FLAGS_DEBUG "-DDEBUG -O0 -g") +set(CMAKE_ASM_FLAGS_DEBUG "-DDEBUG -O0 -g") + +# RELEASE +set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_ASM_FLAGS_RELEASE "-DNDEBUG -O2 -flto") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "-flto") + +# Final compiler flags +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-common -fno-builtin -ffreestanding -fdata-sections -ffunction-sections") +set(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS} -x assembler-with-cpp") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--just-symbols=${TARGET_SYMBOL_LIST} -Wl,--gc-sections") + +# FreeRTOS +set(FREERTOS_PORT "GCC_ARM_CM0" CACHE STRING "") +set(FREERTOS_HEAP "4" CACHE STRING "") + +add_library(freertos_config INTERFACE) +target_include_directories(freertos_config SYSTEM INTERFACE include) + +add_subdirectory(lib/freertos) + + +# Shared sources, includes and definitions +add_compile_definitions(${TARGET_C_DEFINES}) +include_directories(${TARGET_C_INCLUDES}) +link_directories(${TARGET_LIB_DIRECTORIES}) +link_libraries(${TARGET_LIBS}) + +# Main targets are added here + +# Create ELF +add_executable("${CMAKE_PROJECT_NAME}_FLASH.elf" ${TARGET_SOURCES}) +target_compile_definitions("${CMAKE_PROJECT_NAME}_FLASH.elf" + PRIVATE ${TARGET_C_DEFINES_XIP} +) +target_link_options("${CMAKE_PROJECT_NAME}_FLASH.elf" + PRIVATE "-T${TARGET_LDSCRIPT_FLASH}" + PRIVATE "-Wl,--Map=${CMAKE_PROJECT_NAME}_FLASH.map" +) +set_property(TARGET "${CMAKE_PROJECT_NAME}_FLASH.elf" APPEND + PROPERTY ADDITIONAL_CLEAN_FILES "${CMAKE_PROJECT_NAME}_FLASH.map" +) +add_custom_command(OUTPUT "${CMAKE_PROJECT_NAME}_FLASH.hex" + COMMAND ${CMAKE_OBJCOPY} "-O" "ihex" "${CMAKE_PROJECT_NAME}_FLASH.elf" "${CMAKE_PROJECT_NAME}_FLASH.hex" + DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.elf" +) +add_custom_target("${CMAKE_PROJECT_NAME}_FLASH_HEX" DEPENDS "${CMAKE_PROJECT_NAME}_FLASH.hex") +if (DEFINED TARGET_TOOLCHAIN_SIZE) + add_custom_command(TARGET "${CMAKE_PROJECT_NAME}_FLASH.elf" POST_BUILD + COMMAND ${TARGET_TOOLCHAIN_SIZE} "${CMAKE_PROJECT_NAME}_FLASH.elf" + ) +endif () diff --git a/arm-none-eabi.cmake b/arm-none-eabi.cmake new file mode 100644 index 0000000..c7fba17 --- /dev/null +++ b/arm-none-eabi.cmake @@ -0,0 +1,17 @@ +# Poor old Windows... +if(WIN32) + set(CMAKE_SYSTEM_NAME "Generic") +endif() + +set(CMAKE_C_COMPILER arm-none-eabi-gcc) +set(CMAKE_CXX_COMPILER arm-none-eabi-g++) + +# Optionally set size binary name, for elf section size reporting. +set(TARGET_TOOLCHAIN_SIZE arm-none-eabi-size) + +set(CMAKE_C_FLAGS_INIT "-mcpu=cortex-m0 -mthumb -mfloat-abi=soft") +set(CMAKE_CXX_FLAGS_INIT "-mcpu=cortex-m0 -mthumb -mfloat-abi=soft") +set(CMAKE_EXE_LINKER_FLAGS_INIT "-specs=nano.specs -specs=nosys.specs -Wl,--print-memory-usage -Wl,--no-warn-rwx-segments") + +# Make CMake happy about those compilers +set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY") diff --git a/board/board.c b/board/board.c new file mode 100644 index 0000000..ec812f6 --- /dev/null +++ b/board/board.c @@ -0,0 +1,57 @@ +/* Device */ +#include "n32wb03x.h" + +/* Board */ +#include "board.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) + +typedef struct { + GPIO_Module *port; + uint32_t port_rcc; + uint8_t pin; + bool active_high; +} board_led_table_t; + +static const board_led_table_t s_led_table[] = { + {.port = GPIOB, .port_rcc = RCC_APB2_PERIPH_GPIOB, .pin = 0, .active_high = true}, + {.port = GPIOA, .port_rcc = RCC_APB2_PERIPH_GPIOA, .pin = 6, .active_high = true}, +}; + +void board_led_init(uint8_t led) { + GPIO_InitType led_init; + GPIO_InitStruct(&led_init); + + if (led >= ARRAY_SIZE(s_led_table)) { + return; + } + + led_init.Pin = (1U << s_led_table[led].pin); + led_init.GPIO_Mode = GPIO_MODE_OUTPUT_PP; + + RCC_EnableAPB2PeriphClk(s_led_table[led].port_rcc, ENABLE); + GPIO_InitPeripheral(s_led_table[led].port, &led_init); + + board_led_set(led, false); +} + +void board_led_set(uint8_t led, bool on) { + if (led >= ARRAY_SIZE(s_led_table)) { + return; + } + + Bit_OperateType val = on ? Bit_SET : Bit_RESET; + + if (!s_led_table[led].active_high) { + val = on ? Bit_RESET : Bit_SET; + } + + GPIO_WriteBit(s_led_table[led].port, (1U << s_led_table[led].pin), val); +} + +void board_led_toggle(uint8_t led) { + if (led >= ARRAY_SIZE(s_led_table)) { + return; + } + GPIO_TogglePin(s_led_table[led].port, (1U << s_led_table[led].pin)); +} \ No newline at end of file diff --git a/board/board.h b/board/board.h new file mode 100644 index 0000000..f156f91 --- /dev/null +++ b/board/board.h @@ -0,0 +1,11 @@ +#ifndef BOARD_H +#define BOARD_H + +#include +#include + +void board_led_init(uint8_t led); +void board_led_set(uint8_t led, bool on); +void board_led_toggle(uint8_t led); + +#endif // BOARD_H diff --git a/board/n32wb03x_it.c b/board/n32wb03x_it.c new file mode 100644 index 0000000..bf1790a --- /dev/null +++ b/board/n32wb03x_it.c @@ -0,0 +1,72 @@ +/***************************************************************************** + * Copyright (c) 2019, Nations Technologies 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: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Nations' name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 n32wb03x_it.c + * @author Nations Firmware Team + * @version v1.0.0 + * + * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. + */ +#include "n32wb03x_it.h" + +/** @addtogroup N32WB03X_StdPeriph_Template + * @{ + */ + +/******************************************************************************/ +/* Cortex-M0 Processor Exceptions Handlers */ +/******************************************************************************/ + +/** + * @brief This function handles NMI exception. + */ +void NMI_Handler(void) +{ +} + +/** + * @brief This function handles Hard Fault exception. + */ +void HardFault_Handler(void) +{ + /* Go to infinite loop when Hard Fault exception occurs */ + while (1) + { + } +} + +/*******************************************************************************/ +/* N32WB03X Peripherals Interrupt Handlers */ +/* Add here the Interrupt Handler for the used peripheral(s) (PPP), for the */ +/* available peripheral interrupt handler's name please refer to the startup */ +/* file (startup_n32wb03x.S). */ +/*******************************************************************************/ + +/** + * @} + */ diff --git a/board/n32wb03x_it.h b/board/n32wb03x_it.h new file mode 100644 index 0000000..a790f71 --- /dev/null +++ b/board/n32wb03x_it.h @@ -0,0 +1,65 @@ +/***************************************************************************** + * Copyright (c) 2019, Nations Technologies 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: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Nations' name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 n32wb03x_it.h + * @author Nations Firmware Team + * @version v1.0.0 + * + * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. + */ +#ifndef __N32WB03X_IT_H__ +#define __N32WB03X_IT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "n32wb03x.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void SVC_Handler(void); +void PendSV_Handler(void); +void SysTick_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __N32WB03X_IT_H__ */ +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ diff --git a/board/system_n32wb03x.c b/board/system_n32wb03x.c new file mode 100644 index 0000000..512fc57 --- /dev/null +++ b/board/system_n32wb03x.c @@ -0,0 +1,344 @@ +/***************************************************************************** + * Copyright (c) 2019, Nations Technologies 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: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the disclaimer below. + * + * Nations' name may not be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 system_n32wb03x.c + * @author Nations Firmware Team + * @version v1.0.2 + * + * @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. + */ +#include "n32wb03x.h" +#include "string.h" +/* Uncomment the line corresponding to the desired System clock (SYSCLK) + frequency (after reset the HSI is used as SYSCLK source) + + IMPORTANT NOTE: + ============== + 1. After each device reset the HSI is used as System clock source. + + 2. Please make sure that the selected System clock doesn't exceed your + device's maximum frequency. + + 3. If none of the define below is enabled, the HSI is used as System clock + source. + + 4. The System clock configuration functions provided within this file assume + that: + - HSI is configer as 64M and used to driverd the system clock. + - External 32MHz crystal use for Bluetooth RF system only. + - If Bluetooth stack is enable, we should select the LSI or LSE when configer + the Bluetooth stack only. +*/ + +#define SYSCLK_USE_HSI 1 +#define SYSCLK_USE_HSE 0 + +#ifndef SYSCLK_FREQ +#define SYSCLK_FREQ HSI_VALUE +#endif + +/* +* SYSCLK_SRC * +** SYSCLK_USE_HSI ** +** SYSCLK_USE_HSE ** +*/ +#ifndef SYSCLK_SRC +#define SYSCLK_SRC SYSCLK_USE_HSI +#endif + + + +#define TRIM_STORE_ADDR 0x1000 +#define TRIM_READ_CMD_CODE_LEN 0x140 +#define TRIM_READ_CMD_CODE_CRC 0x3aa0 +const unsigned char TRIM_READ_CMD_CODE[] ={ +0x40,0xba,0x70,0x47,0xc0,0xba,0x70,0x47,0x01,0x38,0xfd,0xd1,0x70,0x47,0x00,0x00, +0xf7,0xb5,0x03,0x25,0xad,0x06,0x28,0x6a,0x82,0xb0,0x16,0x46,0x0c,0x46,0x40,0x08, +0x40,0x00,0x28,0x62,0x28,0x6a,0x02,0x21,0x08,0x43,0x28,0x62,0x28,0x6a,0x80,0x07, +0xfc,0xd4,0x66,0x20,0x68,0x60,0x01,0x27,0x2f,0x61,0xa8,0x6a,0xc0,0x05,0xfc,0xd5, +0x99,0x20,0x68,0x60,0x2f,0x61,0xa8,0x6a,0xc0,0x05,0xfc,0xd5,0xff,0x20,0x91,0x30, +0xff,0xf7,0xda,0xff,0xff,0x23,0x01,0x33,0xab,0x62,0x68,0x46,0xef,0x60,0x35,0x21, +0x69,0x60,0x2f,0x61,0xa9,0x6a,0xc9,0x05,0xfc,0xd5,0xab,0x62,0xa9,0x69,0xef,0x60, +0xc9,0xb2,0x05,0x22,0x6a,0x60,0x2f,0x61,0xaa,0x6a,0xd2,0x05,0xfc,0xd5,0xab,0x62, +0xaa,0x69,0x09,0x02,0xd2,0xb2,0x11,0x43,0x01,0x80,0xc8,0x07,0x02,0xd0,0x03,0x20, +0x05,0xb0,0xf0,0xbd,0xab,0x62,0x68,0x69,0xff,0x21,0x08,0x31,0x88,0x43,0x68,0x61, +0x68,0x69,0xc9,0x1e,0x08,0x43,0x68,0x61,0x02,0x98,0x00,0x02,0x48,0x30,0x68,0x60, +0x08,0x20,0xa8,0x60,0xee,0x60,0x2f,0x61,0xa8,0x6a,0xc0,0x05,0xfc,0xd5,0xff,0x20, +0x01,0x30,0xa8,0x62,0x00,0x23,0xf6,0x1c,0xb0,0x08,0x0e,0xd0,0xb2,0x08,0x11,0x48, +0x00,0x68,0x99,0x00,0x60,0x54,0x06,0x0a,0x09,0x19,0x4e,0x70,0x06,0x0c,0x00,0x0e, +0x8e,0x70,0x5b,0x1c,0xc8,0x70,0x9a,0x42,0xf1,0xd8,0xff,0x20,0x01,0x30,0xa8,0x62, +0x68,0x69,0xff,0x21,0x08,0x31,0x88,0x43,0x68,0x61,0x68,0x69,0x38,0x43,0x68,0x61, +0x28,0x6a,0x80,0x08,0x80,0x00,0x28,0x62,0x28,0x6a,0x38,0x43,0x28,0x62,0x00,0x20, +0x05,0xb0,0xf0,0xbd,0x80,0x00,0x00,0x0c,0x03,0x20,0x80,0x06,0x41,0x69,0xff,0x22, +0x08,0x32,0x91,0x43,0x41,0x61,0x42,0x69,0x01,0x21,0x0a,0x43,0x42,0x61,0x02,0x6a, +0x92,0x08,0x92,0x00,0x02,0x62,0x02,0x6a,0x0a,0x43,0x02,0x62,0x70,0x47,0x00,0x00, +}; +typedef uint32_t (*trim_read_cmd_func_t)(uint32_t,uint8_t*,uint32_t); +trim_stored_t trim_stored; + +/******************************************************************************* + * Clock Definitions + *******************************************************************************/ +uint32_t SystemCoreClock = SYSCLK_FREQ; /*!< System Clock Frequency (Core Clock) */ +static void RCC_HsiCalib(uint32_t systemfreq); + +void SystemTrimValueRead(uint8_t* p_data,uint32_t byte_length) +{ + uint32_t ramcode[TRIM_READ_CMD_CODE_LEN/4 +1 ]; + trim_read_cmd_func_t trim_read_cmd_func = (trim_read_cmd_func_t)((uint8_t*)&ramcode[0] + 0x11); + memcpy((void*)ramcode,(const void*)TRIM_READ_CMD_CODE,TRIM_READ_CMD_CODE_LEN); + (*trim_read_cmd_func)(TRIM_STORE_ADDR, p_data, byte_length); +} + +trim_stored_t* SystemTrimValueGet(void) +{ + //read the trim value if not in RAM yet + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + SystemTrimValueRead((uint8_t*)&trim_stored,sizeof(trim_stored)); + } + //check again if read trim value sucessful + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + return NULL; + }else{ + return &trim_stored; + } +} + +uint8_t* SystemGetUUID(void) +{ + //read the trim value if not in RAM yet + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + SystemTrimValueRead((uint8_t*)&trim_stored,sizeof(trim_stored)); + } + //check again if read trim value sucessful + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + return NULL; + }else{ + return trim_stored.flash_uuid; + } + +} + +uint8_t* SystemGetMacAddr(void) +{ + //read the trim value if not in RAM yet + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + SystemTrimValueRead((uint8_t*)&trim_stored,sizeof(trim_stored)); + } + //check again if read trim value sucessful + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + return NULL; + }else{ + return &trim_stored.flash_uuid[5]; + } + +} + + +/** + * @brief Setup the microcontroller system + * Initialize the Embedded Flash Interface, the PLL and update the + * SystemCoreClock variable. + * @note This function should be used only after reset. + */ +void SystemInit(void) +{ + uint32_t tmp; + RCC->APB1PCLKEN |= RCC_APB1_PERIPH_PWR; // PWR enable + PWR->VTOR_REG = 0x81000000; //set irq vtor to flash address + + *(uint32_t*)0x40007014 = 0x0000080F; + *(uint32_t*)0x40007020 = 0x00020018; + *(uint32_t*)0x40011000 &= ~0xC000; + + SystemTrimValueRead((uint8_t*)&trim_stored,sizeof(trim_stored)); + /* check otp has been write */ + if(trim_stored.stote_rc64m_trim_value == 0xFFFFFFFF || trim_stored.stote_rc64m_trim_value == 0) + { + RCC->CFG |= RCC_CFG_HSISRC_DIV1; // USE HSI as system clock + RCC->CFG &= ~RCC_CFG_APB1PRES; + RCC->CFG |= RCC_HCLK_DIV2; //APB1 = HCLK/2, APB1 max is 32M + /* Calib from HSE */ + RCC_HsiCalib(SYSCLK_FREQ); + } + else + { + tmp = (PWR->reserved4)&(~0X1F); + tmp |= (trim_stored.stote_bg_vtrim_value)&0X1F; + PWR->reserved4 = tmp; + if(SYSCLK_FREQ == 64000000) + { + RCC->CTRL &= ~0x8000;// Set HSI as 64M + /* Configures LSI trim */ + tmp = RCC->CTRL & ~(0x7F << 8); // TRIM 8-14 bit + RCC->CTRL = tmp|(trim_stored.stote_rc64m_trim_value << 8);// clear and set TRIM value + + RCC->CFG |= RCC_CFG_HSISRC_DIV1; // USE HSI as system clock + + RCC->CFG &= ~RCC_CFG_APB1PRES; + RCC->CFG |= RCC_HCLK_DIV2; //APB1 = HCLK/2, APB1 max is 32M + } +// else if(SYSCLK_FREQ == 96000000) +// { +// RCC->CTRL |= 0x8000; // Set HSI as 96M +// /* Configures LSI trim */ +// tmp = RCC->CTRL & ~(0x7F << 8); // TRIM 8-14 bit +// RCC->CTRL = tmp|(trim_stored.stote_rc96m_trim_value << 8);// clear and set TRIM value +// +// RCC->CFG |= RCC_CFG_HSISRC_DIV1; // USE HSI as system clock +// tmp = RCC->CFG & ~RCC_CFG_APB1PRES; +// RCC->CFG |= RCC_HCLK_DIV4; //APB1 = HCLK/4, APB1 max is 32M +// +// tmp = RCC->CFG & ~RCC_CFG_APB2PRES; +// RCC->CFG |= RCC_HCLK_DIV4<<3; //APB2 = HCLK/2, APB1 max is 64M +// } + /* Configures LSI trim */ + RCC->LSCTRL &= ~RCC_LSCTRL_LSTTRIM; + RCC->LSCTRL |= trim_stored.stote_rc32768_trim_value << 8; + + } + +} + +/** + * @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: + */ +void SystemCoreClockUpdate(void) +{ + SystemCoreClock = HSI_VALUE; +} + +/** + * @brief dealy cycles. + */ +void system_delay_cycles(uint32_t i) { + for (volatile uint32_t j = i; j > 0; j--) { + j = j; + } +} + +/** + * @brief Dealy 10 us + */ +void system_delay_n_10us(uint32_t value) +{ + system_delay_cycles(107*value); +} + +/** + * @brief Enable the HSI and calibration it. + */ +static void RCC_HsiCalib(uint32_t systemfreq) +{ + + uint32_t g_hsi_accuracy = 0; + uint32_t g_timeoutcnt = 1000; + uint32_t g_cal_hsi_cnt_value = 1024; + + uint32_t delta =0; + uint32_t min = 0; + uint32_t max = 127; //32M TRIM 8-14 bit + uint32_t mid = (RCC->CTRL >> 8) & 0x7F; + uint16_t count_value = 0; + uint32_t hsi_timeoutcnt = 0; + uint8_t tmp_trim; + + if(systemfreq == 64000000) + { + RCC->CTRL &= ~0x8000; + g_cal_hsi_cnt_value = 2048; //for 64M + } + else + { + RCC->CTRL |= 0x8000; + g_cal_hsi_cnt_value = 3072; //for 96M + } + + do{ + uint32_t tmp = RCC->CTRL & ~(0x7F << 8); //32M TRIM 8-14 bit + RCC->CTRL = tmp| (mid << 8); // clear and set TRIM value //and start to cnt + system_delay_cycles(5); // delay scape + while(1) + { + system_delay_cycles(1); + if((RCC->OSCFCSR & 0x02)) + { + break; + } + if(hsi_timeoutcnt++ > g_timeoutcnt) + { + break; + } + } + count_value = RCC->OSCFCHSICNT; //ready cnt value + if(count_value > g_cal_hsi_cnt_value) + { + delta = count_value - g_cal_hsi_cnt_value; + } + else + { + delta = g_cal_hsi_cnt_value - count_value; + } + + if(count_value >= g_cal_hsi_cnt_value) + { + max = mid; + } + else + { + min = mid; + } + + tmp_trim = (min + max)/2; + if(tmp_trim == mid ) //0 and 127 if not used + { + break; + } + mid = tmp_trim; + }while(delta > g_hsi_accuracy); + RCC->CFG &= ~1; + while((RCC->CFG & (1<<2))); +} + diff --git a/include/FreeRTOSConfig.h b/include/FreeRTOSConfig.h new file mode 100644 index 0000000..df518cc --- /dev/null +++ b/include/FreeRTOSConfig.h @@ -0,0 +1,113 @@ +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* Ensure stdint is only used by the compiler, and not the assembler. */ +#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__) +#include +extern uint32_t SystemCoreClock; +#endif + +/* General configuration */ +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ (SystemCoreClock) +#define configTICK_RATE_HZ 1000 +#define configMAX_PRIORITIES 8 +#define configMINIMAL_STACK_SIZE 128 +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 3 +#define configUSE_MUTEXES 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configUSE_COUNTING_SEMAPHORES 0 +#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */ +#define configQUEUE_REGISTRY_SIZE 10 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 1 +#define configENABLE_BACKWARD_COMPATIBILITY 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 +#define configSTACK_DEPTH_TYPE uint16_t +#define configMESSAGE_BUFFER_LENGTH_TYPE size_t + +#ifdef NDEBUG +#define configUSE_TICKLESS_IDLE 1 +#else +#define configUSE_TICKLESS_IDLE 0 +#endif + +/* Memory allocation related definitions. */ +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configTOTAL_HEAP_SIZE (16 * 1024) +#define configAPPLICATION_ALLOCATED_HEAP 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 0 +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine related definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 1 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY 3 +#define configTIMER_QUEUE_LENGTH 10 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Define to trap errors during development. */ +#define configASSERT( x ) if( ( x ) == 0 ) for(;;) { } + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_xResumeFromISR 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 0 +#define INCLUDE_xTaskAbortDelay 0 +#define INCLUDE_xTaskGetHandle 0 +#define INCLUDE_xTaskResumeFromISR 1 + + +/* Port-specific settings */ + +#ifdef __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS +#else +#define configPRIO_BITS 2 /* 3 priority levels */ +#endif + +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 3 +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 3 +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +#define vPortSVCHandler SVC_Handler +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler + +/* A header file that defines trace macro can be included here. */ + +#endif /* FREERTOS_CONFIG_H */ diff --git a/include/ble/app_ble_profiles/app_ble_diss.h b/include/ble/app_ble_profiles/app_ble_diss.h new file mode 100644 index 0000000..57a002c --- /dev/null +++ b/include/ble/app_ble_profiles/app_ble_diss.h @@ -0,0 +1,63 @@ +#ifndef APP_BLE_DISS_H +#define APP_BLE_DISS_H + +#include + +#include "rwip_config.h" // SW Configuration + +/* Define ------------------------------------------------------------*/ + +/// Manufacturer Name Value +#define APP_DISS_MANUFACTURER_NAME ("Nations") +#define APP_DISS_MANUFACTURER_NAME_LEN (7) + +/// Model Number String Value +#define APP_DISS_MODEL_NB_STR ("NS-BLE-1.0") +#define APP_DISS_MODEL_NB_STR_LEN (10) + +/// Serial Number +#define APP_DISS_SERIAL_NB_STR ("1.0.0.0-LE") +#define APP_DISS_SERIAL_NB_STR_LEN (10) + +/// Firmware Revision +#define APP_DISS_FIRM_REV_STR ("1.0.0") +#define APP_DISS_FIRM_REV_STR_LEN (5) + +/// System ID Value - LSB -> MSB +#define APP_DISS_SYSTEM_ID ("\x12\x34\x56\xFF\xFE\x9A\xBC\xDE") +#define APP_DISS_SYSTEM_ID_LEN (8) + +/// Hardware Revision String +#define APP_DISS_HARD_REV_STR ("1.0.0") +#define APP_DISS_HARD_REV_STR_LEN (5) + +/// Software Revision String +#define APP_DISS_SW_REV_STR ("1.0.0") +#define APP_DISS_SW_REV_STR_LEN (5) + +/// IEEE +#define APP_DISS_IEEE ("\xFF\xEE\xDD\xCC\xBB\xAA") +#define APP_DISS_IEEE_LEN (6) + +/** + * PNP ID Value - LSB -> MSB + * Vendor ID Source : 0x02 (USB Implementer’s Forum assigned Vendor ID value) + * Vendor ID : 0x045E (Microsoft Corp) + * Product ID : 0x0040 + * Product Version : 0x0300 + */ +#define APP_DISS_PNP_ID ("\x02\x5E\x04\x40\x00\x00\x03") +#define APP_DISS_PNP_ID_LEN (7) + +#if (BLE_APP_HID) +#define APP_DISS_FEATURES \ + (DIS_MANUFACTURER_NAME_CHAR_SUP_BIT | DIS_MODEL_NB_STR_CHAR_SUP_BIT | DIS_SYSTEM_ID_CHAR_SUP_BIT | \ + DIS_PNP_ID_CHAR_SUP_BIT) + +#else +#define APP_DISS_FEATURES (DIS_ALL_FEAT_SUP) +#endif //(BLE_APP_HID) + +void app_ble_diss_init(void); + +#endif // APP_BLE_DISS_H diff --git a/include/ble/app_user_config.h b/include/ble/app_user_config.h new file mode 100644 index 0000000..f3aeff1 --- /dev/null +++ b/include/ble/app_user_config.h @@ -0,0 +1,114 @@ +/***************************************************************************** +* Copyright (c) 2019, Nations Technologies 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: +* +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the disclaimer below. +* +* Nations' name may not be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +* DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 app_user_config.h +* @author Nations Firmware Team +* @version v1.0.1 +* +* @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. +*/ + +#ifndef _APP_USER_CONFIG_H_ +#define _APP_USER_CONFIG_H_ + +#include "ns_adv_data_def.h" + +/* Super secret hidden feature */ +#define _PATCH_KE_MSG_SET_ 1 + +/* Device name */ +#define CUSTOM_DEVICE_NAME "Nations RTOS!" + +/* adv configer*/ +#define CUSTOM_ADV_FAST_INTERVAL 160 /**< Fast advertising interval (in units of 0.625 ms. This value corresponds to 100 ms.). */ +#define CUSTOM_ADV_SLOW_INTERVAL 3200 /**< Slow advertising interval (in units of 0.625 ms. This value corresponds to 2 seconds). */ + +#define CUSTOM_ADV_FAST_DURATION 0 /**< The advertising duration of fast advertising in units of 1 seconds. maximum is 655 seconds */ +#define CUSTOM_ADV_SLOW_DURATION 180 /**< The advertising duration of slow advertising in units of 1 seconds. maximum is 655 seconds */ + +// Advertise data +#define CUSTOM_USER_ADVERTISE_DATA "\x00" + + +#define CUSTOM_USER_ADVERTISE_DATA_LEN (sizeof(CUSTOM_USER_ADVERTISE_DATA) - 1) + +// Scan response data +#define CUSTOM_USER_ADV_SCAN_RESP_DATA \ + "\x06"\ + ADV_TYPE_MANUFACTURER_SPECIFIC_DATA\ + "\x25\x00NXP" + +// Scan response data length- maximum 31 bytes +#define CUSTOM_USER_ADV_SCAN_RESP_DATA_LEN (sizeof(CUSTOM_USER_ADV_SCAN_RESP_DATA) - 1) + + +/* connection config */ +#define MIN_CONN_INTERVAL 15 /**< Minimum connection interval (15 ms) */ +#define MAX_CONN_INTERVAL 30 /**< Maximum connection interval (30 ms). */ +#define SLAVE_LATENCY 0 /**< Slave latency. */ +#define CONN_SUP_TIMEOUT 5000 /**< Connection supervisory timeout (5000ms). */ + +#define FIRST_CONN_PARAMS_UPDATE_DELAY (5000) /**< Time of initiating event to update connection params (5 seconds). */ + +//sec config +#define SEC_PARAM_IO_CAPABILITIES GAP_IO_CAP_NO_INPUT_NO_OUTPUT /**< No I/O capabilities. (@enum gap_io_cap) */ +#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */ +#define SEC_PARAM_KEY_SIZE 16 /**< Minimum encryption key size. 7 to 16 */ +#define SEC_PARAM_BOND 1 /**< Perform bonding. */ +#define SEC_PARAM_MITM 1 /**< Man In The Middle protection not required. */ +#define SEC_PARAM_LESC 0 /**< LE Secure Connections not enabled. */ +#define SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */ +#define SEC_PARAM_IKEY GAP_KDIST_NONE /**< Initiator Key Distribution. (@enum gap_kdist) */ +#define SEC_PARAM_RKEY GAP_KDIST_ENCKEY /**< Responder Key Distribution. (@enum gap_kdist) */ +#define SEC_PARAM_SEC_MODE_LEVEL GAP_NO_SEC /**< Device security requirements (minimum security level). (@enum see gap_sec_req) */ + +//bond conifg +#define MAX_BOND_PEER 5 +#define BOND_STORE_ENABLE 0 +#define BOND_DATA_BASE_ADDR 0x0103B000 + +/* profiles config */ +#define CFG_APP_DIS 1 +#define CFG_PRF_DISS 1 + +/* User config */ + +#define NS_LOG_ERROR_ENABLE 1 +#define NS_LOG_WARNING_ENABLE 1 +#define NS_LOG_INFO_ENABLE 1 +#define NS_LOG_DEBUG_ENABLE 0 + +#define NS_LOG_LPUART_ENABLE 1 + +#define NS_TIMER_ENABLE 1 + +#define FIRMWARE_VERSION "1.0.0" +#define HARDWARE_VERSION "1.0.0" + +#endif // _APP_USER_CONFIG_H_ + diff --git a/include/ble/rwapp_config.h b/include/ble/rwapp_config.h new file mode 100644 index 0000000..cafc6c6 --- /dev/null +++ b/include/ble/rwapp_config.h @@ -0,0 +1,110 @@ +/***************************************************************************** +* Copyright (c) 2019, Nations Technologies 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: +* +* - Redistributions of source code must retain the above copyright notice, +* this list of conditions and the disclaimer below. +* +* Nations' name may not be used to endorse or promote products derived from +* this software without specific prior written permission. +* +* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY NATIONS "AS IS" AND ANY EXPRESS OR +* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE +* DISCLAIMED. IN NO EVENT SHALL NATIONS BE LIABLE FOR ANY DIRECT, INDIRECT, +* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (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 rwapp_config.h +* @author Nations Firmware Team +* @version v1.0.0 +* +* @copyright Copyright (c) 2019, Nations Technologies Inc. All rights reserved. +*/ + + +#ifndef _RWAPP_CONFIG_H_ +#define _RWAPP_CONFIG_H_ + +/** +* @addtogroup app +* @brief Application configuration definition +* +* @{ +**/ + +#include "app_user_config.h" +#include "rwip_config.h" +/* Includes ------------------------------------------------------------------*/ + +/* Define ------------------------------------------------------------*/ + + +/// Application Profile +#if defined(CFG_APP_PRF) +#define BLE_APP_PRF 1 +#else // defined(CFG_APP_PRF) +#define BLE_APP_PRF 0 +#endif // defined(CFG_APP_PRF) + + +/// Health Thermometer Application +#if defined(CFG_APP_HT) +#define BLE_APP_HT 1 +#else // defined(CFG_APP_HT) +#define BLE_APP_HT 0 +#endif // defined(CFG_APP_HT) + +/// HID Application +#if defined(CFG_APP_HID) +#define BLE_APP_HID 1 +#else // defined(CFG_APP_HID) +#define BLE_APP_HID 0 +#endif // defined(CFG_APP_HID) + +/// DIS Application +#if defined(CFG_APP_DIS) +#define BLE_APP_DIS 1 +#else // defined(CFG_APP_DIS) +#define BLE_APP_DIS 0 +#endif // defined(CFG_APP_DIS) + + + +/// Battery Service Application +#if (CFG_APP_BATT) +#define BLE_APP_BATT 1 +#else +#define BLE_APP_BATT 0 +#endif //(CFG_APP_BATT) + +/// Security Application +#if (defined(CFG_APP_SEC) || BLE_APP_HID) +#define BLE_APP_SEC 1 +#else //(defined(CFG_APP_SEC) || BLE_APP_HID) +#define BLE_APP_SEC 0 +#endif //(defined(CFG_APP_SEC) || BLE_APP_HID) + + +#define AM0_APP_OPTIONAL_CHARACTERISTICS 0 + +#if defined(CFG_APP_NS_IUS) +#define BLE_APP_NS_IUS 1 +#else // defined(CFG_APP_NS_IUS) +#define BLE_APP_NS_IUS 0 +#endif // defined(CFG_APP_NS_IUS) + +/// @} rwapp_config + +#endif /* _RWAPP_CONFIG_H_ */ diff --git a/pyocd_user.py b/pyocd_user.py new file mode 100644 index 0000000..b7544da --- /dev/null +++ b/pyocd_user.py @@ -0,0 +1,31 @@ +def will_connect(board): + # Use "cortex_m" as target, remove the following default regions: + + old_region = target.memory_map.get_first_matching_region(name="Code") + target.memory_map.remove_region(old_region) + + old_region = target.memory_map.get_first_matching_region(name="SRAM") + target.memory_map.remove_region(old_region) + + old_region = target.memory_map.get_first_matching_region(name="RAM1") + target.memory_map.remove_region(old_region) + + old_region = target.memory_map.get_first_matching_region(name="RAM2") + target.memory_map.remove_region(old_region) + + flash = FlashRegion( + name="FLASH", + start=0x01000000, + length=0x00040000, + are_erased_sectors_readable=False, # Never seen that usage for something other than LPC5500 ... + flm="SDK/utilities/N32WB03x.FLM" + ) + + ram = RamRegion( + name="SRAM", + start=0x20000000, + length=0x0000C000 + ) + + target.memory_map.add_region(ram) + target.memory_map.add_region(flash) diff --git a/src/app_ble_profiles/app_ble_diss.c b/src/app_ble_profiles/app_ble_diss.c new file mode 100644 index 0000000..4a45d0a --- /dev/null +++ b/src/app_ble_profiles/app_ble_diss.c @@ -0,0 +1,109 @@ +#include "app_ble_profiles/app_ble_diss.h" + +/* Stack configuration */ +#include "rwip_config.h" + +/* BLE Stack */ +#include "ns_ble.h" + +/* Profile */ +#include "diss.h" +#include "diss_task.h" + +static int app_ble_diss_handler(ke_msg_id_t const msgid, struct diss_value_req_ind const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id); + +static const struct ke_msg_handler app_diss_msg_handler_list[] = { + {DISS_VALUE_REQ_IND, (ke_msg_func_t)app_ble_diss_handler}, +}; + +static const struct app_subtask_handlers app_diss_handlers = APP_HANDLERS(app_diss); + +void app_ble_diss_init(void) { + struct diss_db_cfg *db_cfg; + struct gapm_profile_task_add_cmd *req = KE_MSG_ALLOC_DYN(GAPM_PROFILE_TASK_ADD_CMD, TASK_GAPM, TASK_APP, + gapm_profile_task_add_cmd, sizeof(struct diss_db_cfg)); + req->operation = GAPM_PROFILE_TASK_ADD; + req->sec_lvl = PERM(SVC_AUTH, NO_AUTH); + req->prf_task_id = TASK_ID_DISS; + req->app_task = TASK_APP; + req->start_hdl = 0; + + db_cfg = (struct diss_db_cfg *)req->param; + db_cfg->features = APP_DISS_FEATURES; + + ke_msg_send(req); + + struct prf_task_t prf; + prf.prf_task_id = TASK_ID_DISS; + prf.prf_task_handler = &app_diss_handlers; + ns_ble_prf_task_register(&prf); + + struct prf_get_func_t get_func; + get_func.task_id = TASK_ID_DISS; + get_func.prf_itf_get_func = diss_prf_itf_get; + prf_get_itf_func_register(&get_func); +} + +static int app_ble_diss_handler(ke_msg_id_t const msgid, struct diss_value_req_ind const *param, + ke_task_id_t const dest_id, ke_task_id_t const src_id) { + // Initialize length + uint8_t len = 0; + // Pointer to the data + uint8_t *data = NULL; + + // Check requested value + switch (param->value) { + case DIS_MANUFACTURER_NAME_CHAR: + len = APP_DISS_MANUFACTURER_NAME_LEN; + data = (uint8_t *)APP_DISS_MANUFACTURER_NAME; + break; + case DIS_MODEL_NB_STR_CHAR: + len = APP_DISS_MODEL_NB_STR_LEN; + data = (uint8_t *)APP_DISS_MODEL_NB_STR; + break; + case DIS_SYSTEM_ID_CHAR: + len = APP_DISS_SYSTEM_ID_LEN; + data = (uint8_t *)APP_DISS_SYSTEM_ID; + break; + case DIS_PNP_ID_CHAR: + len = APP_DISS_PNP_ID_LEN; + data = (uint8_t *)APP_DISS_PNP_ID; + break; + case DIS_SERIAL_NB_STR_CHAR: + len = APP_DISS_SERIAL_NB_STR_LEN; + data = (uint8_t *)APP_DISS_SERIAL_NB_STR; + break; + case DIS_HARD_REV_STR_CHAR: + len = APP_DISS_HARD_REV_STR_LEN; + data = (uint8_t *)APP_DISS_HARD_REV_STR; + break; + case DIS_FIRM_REV_STR_CHAR: + len = APP_DISS_FIRM_REV_STR_LEN; + data = (uint8_t *)APP_DISS_FIRM_REV_STR; + break; + case DIS_SW_REV_STR_CHAR: + len = APP_DISS_SW_REV_STR_LEN; + data = (uint8_t *)APP_DISS_SW_REV_STR; + break; + case DIS_IEEE_CHAR: + len = APP_DISS_IEEE_LEN; + data = (uint8_t *)APP_DISS_IEEE; + break; + + default: + break; + } + + struct diss_value_cfm *cfm_value = KE_MSG_ALLOC_DYN(DISS_VALUE_CFM, src_id, dest_id, diss_value_cfm, len); + + cfm_value->value = param->value; + cfm_value->length = len; + + if (len) { + memcpy(&cfm_value->data[0], data, len); + } + ke_msg_send(cfm_value); + + return (KE_MSG_CONSUMED); +} diff --git a/src/app_ble_support.c b/src/app_ble_support.c new file mode 100644 index 0000000..b8dc96f --- /dev/null +++ b/src/app_ble_support.c @@ -0,0 +1,173 @@ +/* FreeRTOS */ +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +/* BLE Stack */ +#include "ns_ble.h" +#include "ns_ble_task.h" +#include "ns_sec.h" + +/* Profiles */ +#include "app_ble_profiles/app_ble_diss.h" + +/* Board */ +#include "board.h" + +static TaskHandle_t s_ble_task_handle; + +static void app_ble_task(void *parameters); +static void app_ble_msg_handler(struct ble_msg_t const *p_ble_msg); +static void app_user_msg_handler(ke_msg_id_t msgid, void const *p_param); +static void app_ble_gap_params_init(void); +static void app_ble_adv_init(void); +static void app_ble_sec_init(void); +static void app_ble_prf_init(void); + +void app_ble_init(void) { + struct ns_stack_cfg_t app_handler = {0}; + app_handler.ble_msg_handler = app_ble_msg_handler; + app_handler.user_msg_handler = app_user_msg_handler; + app_handler.lsc_cfg = BLE_LSC_LSE_32768HZ; + + ns_ble_stack_init(&app_handler); + + app_ble_gap_params_init(); + app_ble_sec_init(); + app_ble_adv_init(); + app_ble_prf_init(); + + // start advertising + ns_ble_adv_start(); + + if (xTaskCreate(app_ble_task, "BLE", 1536, NULL, 5, &s_ble_task_handle) != pdPASS) { + for (;;) { + /* -- */ + } + } + + NVIC_SetPriority(RESERVED_IRQn, 2); + NVIC_EnableIRQ(RESERVED_IRQn); +} + +void RESERVED_IRQHandler(void) { + BaseType_t hp_woken = pdFALSE; + xTaskNotifyFromISR(s_ble_task_handle, 0, eNoAction, &hp_woken); + portYIELD_FROM_ISR(hp_woken); +} + +static void app_ble_task(void *parameters) { + uint32_t notification_value; + + for (;;) { + rwip_schedule(); + xTaskNotifyWait(0, 0, ¬ification_value, portMAX_DELAY); + } +} + +static void app_ble_msg_handler(struct ble_msg_t const *p_ble_msg) { + switch (p_ble_msg->msg_id) { + case APP_BLE_OS_READY: + break; + case APP_BLE_GAP_CONNECTED: + board_led_set(1, true); + break; + case APP_BLE_GAP_DISCONNECTED: + ns_ble_adv_start(); + board_led_set(1, false); + break; + + default: + break; + } +} + +static void app_ble_adv_msg_handler(enum app_adv_mode adv_mode) { +} + +static void app_user_msg_handler(ke_msg_id_t const msgid, void const *p_param) { +} + +static void app_ble_gap_params_init(void) { + struct ns_gap_params_t dev_info = {0}; + uint8_t *p_mac = SystemGetMacAddr(); + if (p_mac != NULL) { + memcpy(dev_info.mac_addr.addr, p_mac, BD_ADDR_LEN); + } else { + memcpy(dev_info.mac_addr.addr, "\x01\x02\x03\x04\x05\x06", BD_ADDR_LEN); + } + + dev_info.mac_addr_type = GAPM_STATIC_ADDR; + dev_info.appearance = 0; + dev_info.dev_role = GAP_ROLE_PERIPHERAL; + dev_info.dev_name_len = sizeof(CUSTOM_DEVICE_NAME) - 1; + + memcpy(dev_info.dev_name, CUSTOM_DEVICE_NAME, dev_info.dev_name_len); + + dev_info.dev_conn_param.intv_min = MSECS_TO_UNIT(MIN_CONN_INTERVAL, MSECS_UNIT_1_25_MS); + dev_info.dev_conn_param.intv_max = MSECS_TO_UNIT(MAX_CONN_INTERVAL, MSECS_UNIT_1_25_MS); + dev_info.dev_conn_param.latency = SLAVE_LATENCY; + dev_info.dev_conn_param.time_out = MSECS_TO_UNIT(CONN_SUP_TIMEOUT, MSECS_UNIT_10_MS); + dev_info.conn_param_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; + + ns_ble_gap_init(&dev_info); +} + +static void app_ble_adv_init(void) { + struct ns_adv_params_t user_adv = {0}; + + // init advertising data + user_adv.adv_data_len = CUSTOM_USER_ADVERTISE_DATA_LEN; + memcpy(user_adv.adv_data, CUSTOM_USER_ADVERTISE_DATA, CUSTOM_USER_ADVERTISE_DATA_LEN); + user_adv.scan_rsp_data_len = CUSTOM_USER_ADV_SCAN_RESP_DATA_LEN; + memcpy(user_adv.scan_rsp_data, CUSTOM_USER_ADV_SCAN_RESP_DATA, CUSTOM_USER_ADV_SCAN_RESP_DATA_LEN); + + user_adv.attach_appearance = false; + user_adv.attach_name = true; + user_adv.ex_adv_enable = false; + user_adv.adv_phy = PHY_1MBPS_VALUE; + + // init advertising params + user_adv.directed_adv.enable = false; + + user_adv.fast_adv.enable = true; + user_adv.fast_adv.duration = CUSTOM_ADV_FAST_DURATION; + user_adv.fast_adv.adv_intv = CUSTOM_ADV_FAST_INTERVAL; + + user_adv.slow_adv.enable = true; + user_adv.slow_adv.duration = CUSTOM_ADV_SLOW_DURATION; + user_adv.slow_adv.adv_intv = CUSTOM_ADV_SLOW_INTERVAL; + + user_adv.ble_adv_msg_handler = app_ble_adv_msg_handler; + + ns_ble_adv_init(&user_adv); +} + +static void app_ble_sec_init(void) { + struct ns_sec_init_t sec_init = {0}; + + sec_init.rand_pin_enable = false; + sec_init.pin_code = 123456; + + sec_init.pairing_feat.auth = + (SEC_PARAM_BOND | (SEC_PARAM_MITM << 2) | (SEC_PARAM_LESC << 3) | (SEC_PARAM_KEYPRESS << 4)); + sec_init.pairing_feat.iocap = SEC_PARAM_IO_CAPABILITIES; + sec_init.pairing_feat.key_size = SEC_PARAM_KEY_SIZE; + sec_init.pairing_feat.oob = SEC_PARAM_OOB; + sec_init.pairing_feat.ikey_dist = SEC_PARAM_IKEY; + sec_init.pairing_feat.rkey_dist = SEC_PARAM_RKEY; + sec_init.pairing_feat.sec_req = SEC_PARAM_SEC_MODE_LEVEL; + + sec_init.bond_enable = BOND_STORE_ENABLE; + sec_init.bond_db_addr = BOND_DATA_BASE_ADDR; + sec_init.bond_max_peer = MAX_BOND_PEER; + sec_init.bond_sync_delay = 2000; + + sec_init.ns_sec_msg_handler = NULL; + + ns_sec_init(&sec_init); +} + +static void app_ble_prf_init(void) { + ns_ble_add_prf_func_register(app_ble_diss_init); +} \ No newline at end of file diff --git a/src/app_freertos_support.c b/src/app_freertos_support.c new file mode 100644 index 0000000..22eff4d --- /dev/null +++ b/src/app_freertos_support.c @@ -0,0 +1,230 @@ +#include "FreeRTOS.h" +#include "task.h" + +/* SDK */ +#include "n32wb03x.h" + +/* BLE */ +#include "ns_ble.h" +#include "ns_ble_task.h" +#include "ns_sleep.h" +#include "rwip.h" +#include "rwip_int.h" + +#define MAX_SLEEP_DURATION_PERIODIC_WAKEUP 0x0640 +#define MAX_SLEEP_DURATION_EXTERNAL_WAKEUP 0x7D00 + +extern uint32_t ns_sleep_lock; + +extern void entry_sleep(void); + +static uint8_t app_check_stack_status(uint32_t msec); + +void vPortSuppressTicksAndSleep(TickType_t xExpectedIdleTime) { + rwip_time_t sleep_start, sleep_end; + + /* Stop SysTick timer */ + SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk); + + /* Disable global interrupts */ + vPortEnterCritical(); + + sleep_start = rwip_time_get(); + + /* User supplied routine before low-power state entry */ + app_sleep_prepare_proc(); + + /* Check whether BLE stack allows SLEEP */ + if (app_check_stack_status(xExpectedIdleTime) == RWIP_DEEP_SLEEP) { + entry_sleep(); + } + + vPortExitCritical(); + + /* User supplied routine after low-power state entry */ + app_sleep_resume_proc(); + + /* Check whether BLE stack wake up completed */ + while ((rwip_env.prevent_sleep & (RW_WAKE_UP_ONGOING | RW_DEEP_SLEEP))) { + /* -- */ + } + + sleep_end = rwip_time_get(); + + if (rwip_env.timer_1ms_target.hs != RWIP_INVALID_TARGET_TIME) { + if (CLK_DIFF(sleep_end.hs, rwip_env.timer_1ms_target.hs) < 0) { + ke_event_set(KE_EVENT_KE_TIMER); + } + } + + /* Fix-up actual sleep time */ + uint32_t elapsed_ms; + if (sleep_end.hs == 0) { + elapsed_ms = xExpectedIdleTime; + goto step_tick_exit; + } + + /* Elapsed time in half-slots */ + int32_t elapsed_hs = CLK_DIFF(sleep_start.hs, sleep_end.hs); + if (elapsed_hs <= 0) { + elapsed_ms = xExpectedIdleTime; + goto step_tick_exit; + } + + elapsed_ms = (uint32_t)(elapsed_hs + 1) * HALF_SLOT_SIZE / 2000; + if (elapsed_ms > xExpectedIdleTime) { + elapsed_ms = xExpectedIdleTime; + } + +step_tick_exit: + vTaskStepTick(elapsed_ms); + + /* Re-enable SysTick */ + SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk | SysTick_CTRL_TICKINT_Msk; +} + +void vApplicationMallocFailedHook(void) { + for (;;) { + __WFI(); + } +} + +void vApplicationStackOverflowHook(TaskHandle_t xTask, char *pcTaskName) { + for (;;) { + __WFI(); + } +} + +/** + * Supplied by Nations, See LICENSE headers in SDK files. + * @param msec + * @return + */ +static uint8_t app_check_stack_status(uint32_t msec) { + uint8_t sleep_res = RWIP_ACTIVE; + + do { + if (g_sleep_sleep_enable == 0) // sleep condition param 0: not sleep 1: allow to sleep + { + break; + } + +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) + int32_t sleep_duration; + rwip_time_t current_time; +#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT) + + /************************************************************************ + ************** CHECK KERNEL EVENTS ************** + ************************************************************************/ + + // Check if some kernel processing is ongoing (during wakeup, kernel events are not processed) + if (((rwip_env.prevent_sleep & RW_WAKE_UP_ONGOING) == 0) && !ke_sleep_check()) { + break; + } + + // Processor sleep can be enabled + sleep_res = RWIP_CPU_SLEEP; + + /************************************************************************ + ************** CHECK RW FLAGS ************** + ************************************************************************/ + // First check if no pending procedure prevent from going to sleep + if (rwip_env.prevent_sleep != 0) { + break; + } + +#if (BLE_EMB_PRESENT || BT_EMB_PRESENT) + /************************************************************************ + ************** Retrieve Current time ************** + ************************************************************************/ + current_time = rwip_time_get(); + // Consider 2 half-slots for clock correction (worst case: 1 half-slot before correction, 1 half-slot after + // correction) + current_time.hs += 2; + + // Remove 1 more slot because next slot will be started at end of function + // if((HALF_SLOT_INV(current_time.hus)) < rwip_env.sleep_algo_dur) + { current_time.hs += 1; } + // Be sure that we don't exceed the clock wrapping time + current_time.hs &= RWIP_MAX_CLOCK_TIME; + + /************************************************************************ + ******* COMPUTE SLEEP TIME ACCORDING TO 1 MS AND HALF SLOT TIMER ****** + ************************************************************************/ + + // put sleep duration to maximum value + sleep_duration = + (rwip_env.ext_wakeup_enable) ? MAX_SLEEP_DURATION_EXTERNAL_WAKEUP : MAX_SLEEP_DURATION_PERIODIC_WAKEUP; + + // check if 1ms timer is active + if (rwip_env.timer_1ms_target.hs != RWIP_INVALID_TARGET_TIME) { + int32_t duration = CLK_DIFF(current_time.hs, rwip_env.timer_1ms_target.hs); + // update sleep duration to minimum value + sleep_duration = co_min_s(sleep_duration, duration); + } + + // check if Half slot timer is active + if (rwip_env.timer_hs_target != RWIP_INVALID_TARGET_TIME) { + int32_t duration = CLK_DIFF(current_time.hs, rwip_env.timer_hs_target); + // update sleep duration to minimum value + sleep_duration = co_min_s(sleep_duration, duration); + } + + // check if Half us timer is active + if (rwip_env.timer_hus_target != RWIP_INVALID_TARGET_TIME) { + int32_t duration = CLK_DIFF(current_time.hs, rwip_env.timer_hus_target); + // update sleep duration to minimum value + sleep_duration = co_min_s(sleep_duration, duration); + } + + // for rtos sleep time + uint32_t rtos_slp_slot = msec * 10000 / 3125; + sleep_duration = co_min_s(sleep_duration, (int32_t)rtos_slp_slot); + + // A timer ISR is not yet handled or will be raised soon + // note the sleep duration could be negative, that's why it's useful to check if a minimum requirement is ok + // at least one half slot. + if (sleep_duration <= RWIP_MINIMUM_SLEEP_TIME) { + break; + } + + if (app_env.lsc_cfg != BLE_LSC_LSE_32768HZ) { + if ((RCC->OSCFCSR & 0x01)) { + uint32_t count_value = 0; + count_value = RCC->OSCFCLSICNT; + g_lsi_1_syscle_cnt_value = (count_value / g_lsi_count_n_syscle) + + (count_value % g_lsi_count_n_syscle) / (g_lsi_count_n_syscle / 2); + } + } + /************************************************************************ + ************** CHECK SLEEP TIME ************** + ************************************************************************/ + + sleep_duration = (int32_t)(sleep_duration * 10000 / g_lsi_1_syscle_cnt_value) - 1; + // check if sleep duration is sufficient according to wake-up delay + + if (sleep_duration < rwip_env.lp_cycle_wakeup_delay + 1) { + break; + } + + sleep_res = RWIP_DEEP_SLEEP; + + /************************************************************************ + ************** PROGRAM CORE DEEP SLEEP ************** + ************************************************************************/ + // Program wake-up time + ip_deepslwkup_set(sleep_duration); + + // Prevent re-entering sleep, until it effectively sleeps and wakes up + rwip_prevent_sleep_set(RW_DEEP_SLEEP); + + /************************************************************************ + ************** SWITCH OFF RF ************** + ************************************************************************/ + rwip_rf.sleep(); +#endif // (BLE_EMB_PRESENT || BT_EMB_PRESENT) + } while (0); + + return sleep_res; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..5b7889c --- /dev/null +++ b/src/main.c @@ -0,0 +1,39 @@ +/* FreeRTOS */ +#include "FreeRTOS.h" +#include "task.h" + +/* Device */ +#include "n32wb03x.h" + +/* Board */ +#include "board.h" + +void app_ble_init(void); + +static void task_initialize(void *parameters); + +int main(void) { + board_led_init(0); + board_led_init(1); + + app_ble_init(); + + if (xTaskCreate(task_initialize, "INIT", 256, NULL, 4, NULL) != pdTRUE) { + goto dead_loop; + } + + vTaskStartScheduler(); + +dead_loop: + for (;;) { + /* -- */ + __WFI(); + } +} + +static void task_initialize(void *parameters) { + for (;;) { + board_led_toggle(0); + vTaskDelay(pdMS_TO_TICKS(100)); + } +} \ No newline at end of file