├── .gitignore ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── armenv.sh ├── bootstrap.sh ├── lib ├── arm-gcc.cmake ├── components │ ├── ant │ │ └── ant.cmake │ ├── ble │ │ └── ble.cmake │ ├── device │ │ └── device.cmake │ ├── drivers_ext │ │ └── drivers-ext.cmake │ ├── drivers_nrf │ │ └── drivers-nrf.cmake │ ├── libraries │ │ └── libraries.cmake │ ├── serialization │ │ └── serialization.cmake │ ├── softdevice │ │ └── softdevice.cmake │ └── toolchain │ │ └── toolchain.cmake ├── erase.jlink ├── flash-softdevice.in ├── flash.in ├── jlink.cmake ├── nrf52-base.cmake ├── post-build.cmake ├── remote.gdbconf └── reset.jlink └── work ├── include ├── boards.h ├── bsp.h ├── bsp_btn_ble.h ├── fstorage_config.h ├── nrf_drv_config.h ├── pca10036.h ├── pstorage_platform.h └── sdk_config.h └── source ├── bsp.c ├── bsp_btn_ble.c ├── bsp_btn_ble.h ├── main.c └── test.ld /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.o 3 | *.hex 4 | *.elf 5 | *.map 6 | *.bin 7 | *.zip 8 | .env 9 | .sdk 10 | lib/components/* 11 | lib/documentation/* 12 | build/ 13 | builds/ 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: c 2 | 3 | addons: 4 | apt: 5 | packages: 6 | - ia32-libs 7 | - ia32-libs-multiarch 8 | - libgd2-xpm 9 | 10 | install: 11 | - ./bootstrap.sh 12 | - source armenv.sh 13 | 14 | script: 15 | - source armenv.sh; make 16 | 17 | notifications: 18 | email: false 19 | 20 | 21 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Base NRF52 CMake file 2 | # 3 | # This can be used as is as a project base, or by adding the nrf52-base 4 | # repository as a submodule to another project, copying this CMakeLists file 5 | # to the top level directory, and updating the BASE_LOCATION variable to reflect this 6 | # change 7 | 8 | ###### Project Environment ##### 9 | 10 | # Set minimum CMake version 11 | cmake_minimum_required(VERSION 2.8.4) 12 | 13 | ##### Project Setup ##### 14 | 15 | # Set our output target 16 | set(TARGET nrf52-test) 17 | 18 | # Configure project and languages 19 | project(${TARGET} C CXX ASM) 20 | 21 | # Set project location 22 | set(BASE_LOCATION ${PROJECT_SOURCE_DIR}) 23 | 24 | # Set the compiler (must be called prior to project setup) 25 | include(${BASE_LOCATION}/lib/arm-gcc.cmake) 26 | 27 | # Set device 28 | if(NOT DEVICE) 29 | set(DEVICE nRF52832) 30 | set(BOARD BOARD_PCA10036) 31 | set(SOFTDEVICE S132) 32 | endif() 33 | 34 | # Set build 35 | if(NOT CMAKE_BUILD_TYPE) 36 | set(CMAKE_BUILD_TYPE DEBUG) 37 | endif() 38 | 39 | set(QUIET_BUILD "") 40 | 41 | ##### Files ##### 42 | 43 | # Add project headers 44 | include_directories(${BASE_LOCATION}/work/include) 45 | 46 | # Add project sources 47 | set(SOURCES 48 | ${BASE_LOCATION}/work/source/main.c 49 | ${BASE_LOCATION}/work/source/bsp.c 50 | ${BASE_LOCATION}/work/source/bsp_btn_ble.c 51 | ) 52 | 53 | ##### Modules ##### 54 | 55 | # Libraries can be added to the LIBS variable 56 | # or manually included here. 57 | # ie. include(${BASE_LOCATION}/my-cool-module/my-cool-module.cmake) 58 | 59 | # nRF components enabled here 60 | # Check out the related component folders for options 61 | set(DRIVERS_NRF hal common delay config gpiote trace pstorage timer ble_flash uart clock) 62 | set(LIBRARIES log util trace timer scheduler button uart fifo fstorage experimental_section_vars) 63 | set(BLE_MODULES ble_advertising) 64 | set(BLE_SERVICES ble_nus) 65 | 66 | # Add nRF52 base support 67 | include(${BASE_LOCATION}/lib/nrf52-base.cmake) 68 | 69 | ##### Outputs ##### 70 | 71 | # Generate executable and link 72 | add_executable(${TARGET} ${SOURCES}) 73 | target_link_libraries(${TARGET} ${LIBS}) 74 | 75 | ##### Post build ##### 76 | 77 | # Add post build commands 78 | include(${BASE_LOCATION}/lib/post-build.cmake) 79 | 80 | # Add JLink commands 81 | include(${BASE_LOCATION}/lib/jlink.cmake) 82 | 83 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Ryan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | #Test compilation makefile 3 | 4 | .PHONY: setup nRF52832_S132 nRF52832_S212 5 | 6 | test: setup nRF52832_S132 7 | 8 | setup: 9 | mkdir -p builds 10 | 11 | nRF52832_NONE: 12 | mkdir -p builds/nRF52832_NONE; cd builds/nRF52832_NONE; cmake -DDEVICE=nRF52832 -DBOARD=BOARD_PCA10036 ../..; make 13 | 14 | nRF52832_S132: 15 | mkdir -p builds/nRF52832_S132; cd builds/nRF52832_S132; cmake -DDEVICE=nRF52832 -DBOARD=BOARD_PCA10036 -DSOFTDEVICE=S132 ../..; make 16 | 17 | nRF52832_S212: 18 | mkdir -p builds/nRF52832_S212; cd builds/nRF52832_S212; cmake -DDEVICE=nRF52832 -DBOARD=BOARD_PCA10036 -DSOFTDEVICE=S212 ../..; make 19 | 20 | clean: 21 | rm -rf builds 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nrf52-base 2 | 3 | STATUS: preliminary support, builds for the nRF52 family and S132 SoftDevice. 4 | Commit 8b1612498a0af3ff86c388b101c0614f3d1ded92 working with old SDK. Current master isn't running correctly, probably a linker / location issue but haven't had time to fix as yet. 5 | 6 | [![Build Status](https://travis-ci.org/ryankurte/nrf52-base.svg)](https://travis-ci.org/ryankurte/nrf52-base) 7 | 8 | ## Getting Started 9 | 10 | ### Quick Start 11 | 12 | 1. Run `./bootstrap.sh` to download the nRF52 SDK and pull the libraries into this project 13 | 2. Run `mkdir build` to create a build directory 14 | 3. In the build directory, run `cmake ..` to initialize cmake 15 | 4. In the build directory, run `make` to build the example project 16 | 17 | ## TODO 18 | - [ ] support for new softdevices 19 | - [ ] better getting started guide 20 | - [ ] integrate nrfjprog to simplify programming etc 21 | 22 | ------ 23 | 24 | This project is MIT licensed to avoid placing limitations on possible uses. Note that Nordic components fetched as part of the `./bootstrap.sh` script are covered under Nordic license terms in `lib\documentation/license.txt` after bootstrapping. 25 | 26 | If you make improvements, please consider opening a pull request and contributing them back. 27 | And if you use this in a project, I would love to hear about it (and you can find my email in any of my git commits). 28 | 29 | If you have any questions, comments, or suggestions, feel free to open an issue or a pull request. 30 | -------------------------------------------------------------------------------- /armenv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Immutable Project-Local Toolchain Setup 3 | # Inspired by Python's virtualenv and npm 4 | # See http://wp.me/pZZvH-an for more 5 | # Run with `source ./armenv.sh` 6 | 7 | # TODOs: 8 | # Add upgrade option 9 | # Cleaner toolchain versioning 10 | # Detect different toolchain versions and warn if installing new? 11 | 12 | # Toolchain base string 13 | # Set this to change toolchain versions (though perhaps this is not the most intuitive method) 14 | TOOLCHAIN_BASE="gcc-arm-none-eabi-4_9-2015q1-20150306" 15 | 16 | # Parse useful information from the toolchain string 17 | 18 | if ! [[ $TOOLCHAIN_BASE =~ gcc-arm-none-eabi-([0-9])_([0-9])-([0-9]{4})q([0-4])-([0-9]{8}) ]]; then 19 | echo "Invalid base toolchain string" 20 | return 21 | fi 22 | 23 | TOOLCHAIN_VERSION_MAJOR=${BASH_REMATCH[1]} 24 | TOOLCHAIN_VERSION_MINOR=${BASH_REMATCH[2]} 25 | TOOLCHAIN_YEAR=${BASH_REMATCH[3]} 26 | TOOLCHAIN_QUARTER=${BASH_REMATCH[4]} 27 | TOOLCHAIN_DATE=${BASH_REMATCH[5]} 28 | 29 | # Toolchain base URL 30 | # example: https://launchpad.net/gcc-arm-embedded/4.9/4.9-2015-q1-update/+download/gcc-arm-none-eabi-4_9-2015q1-20150306-win32.zip 31 | TOOLCHAIN_ADDR="https://launchpad.net/gcc-arm-embedded/${TOOLCHAIN_VERSION_MAJOR}.${TOOLCHAIN_VERSION_MINOR}/${TOOLCHAIN_VERSION_MAJOR}.${TOOLCHAIN_VERSION_MINOR}-${TOOLCHAIN_YEAR}-q${TOOLCHAIN_QUARTER}-update/+download/" 32 | 33 | # Toolchain folder name 34 | # This must match that of the extracted archive 35 | TOOLCHAIN_LOC=gcc-arm-none-eabi-${TOOLCHAIN_VERSION_MAJOR}_${TOOLCHAIN_VERSION_MINOR}-${TOOLCHAIN_YEAR}q${TOOLCHAIN_QUARTER} 36 | 37 | WORKDIR=`pwd` 38 | TOOLDIR="$WORKDIR/.env" 39 | 40 | # Check if tools exist 41 | TOOLTEST="$TOOLDIR/$TOOLCHAIN_LOC/bin/arm-none-eabi-gcc" 42 | 43 | res=$? 44 | if [ -f ${TOOLTEST} ] 45 | then 46 | export PATH=$TOOLDIR/$TOOLCHAIN_LOC/bin:$PATH 47 | echo "Toolchain loaded (already installed)" 48 | return 49 | fi 50 | 51 | # Create tool directory 52 | mkdir .env 53 | 54 | # Determine toolchain file names 55 | 56 | echo "Determining required toolchain" 57 | if [ "$(uname)" == "Darwin" ]; then 58 | # Do something under Mac OS X platform 59 | OS="OSX" 60 | TOOLCHAIN_FILE="$TOOLCHAIN_BASE-mac.tar.bz2" 61 | TOOLCHAIN_DL="$TOOLCHAIN_ADDR$TOOLCHAIN_FILE" 62 | 63 | elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then 64 | # Do something under Linux platform 65 | OS="LINUX" 66 | TOOLCHAIN_FILE="$TOOLCHAIN_BASE-linux.tar.bz2" 67 | TOOLCHAIN_DL="$TOOLCHAIN_ADDR$TOOLCHAIN_FILE" 68 | 69 | elif [ "$(expr substr $(uname -s) 1 10)" == "MINGW32_NT" ]; then 70 | # Do something under Windows NT platform 71 | OS="WIN" 72 | TOOLCHAIN_FILE="$TOOLCHAIN_BASE-win32.zip" 73 | TOOLCHAIN_DL="$TOOLCHAIN_ADDR$TOOLCHAIN_FILE" 74 | fi 75 | 76 | # Check if toolchain is cached 77 | 78 | CACHED="$HOME/.env/$TOOLCHAIN_FILE" 79 | if [ -f $CACHED ]; then 80 | echo "Toolchain found at: $CACHED" 81 | else 82 | echo "Cached toolchain not found, downloading" 83 | wget $TOOLCHAIN_DL -P $HOME/.env 84 | fi 85 | cp $CACHED $TOOLDIR 86 | 87 | #Extract toolchain 88 | 89 | echo "Extracting toolchain" 90 | if [ "$OS" == "OSX" ]; then 91 | tar -xf $TOOLDIR/$TOOLCHAIN_FILE -C $TOOLDIR 92 | elif [ "$OS" == "LINUX" ]; then 93 | tar -xf $TOOLDIR/$TOOLCHAIN_FILE -C $TOOLDIR 94 | elif [ "$OS" == "WIN" ]; then 95 | unzip $TOOLDIR/$TOOLCHAIN_FILE -d $TOOLDIR 96 | fi 97 | 98 | # Setup environment 99 | 100 | if [ "$OS" == "OSX" ]; then 101 | ln -s $TOOLDIR/$TOOLCHAIN_FILE $TOOLDIR/gcc-arm-none-eabo 102 | elif [ "$OS" == "LINUX" ]; then 103 | ln -s $TOOLDIR/$TOOLCHAIN_FILE $TOOLDIR/gcc-arm-none-eabo 104 | elif [ "$OS" == "WIN" ]; then 105 | echo "Unimplemented" 106 | return -1; 107 | fi 108 | 109 | export PATH=$TOOLDIR/$TOOLCHAIN_LOC/bin:$PATH 110 | 111 | echo "Toolchain loaded" 112 | -------------------------------------------------------------------------------- /bootstrap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Get Nordic files, because their SDK license is not permissive. 3 | 4 | SDK_VERSION="12.2.0" 5 | SDK_CHECKSUM="f012efa" 6 | SDK_URL="https://www.nordicsemi.com/eng/nordic/download_resource/54291/51/16000157" 7 | SDK_FILE="nRF52_SDK_${SDK_VERSION}_${SDK_CHECKSUM}.zip" 8 | 9 | WORKING_DIR=".sdk" 10 | 11 | mkdir -p $WORKING_DIR 12 | 13 | if [ -f $WORKING_DIR/$SDK_FILE ] 14 | then 15 | echo "SDK found" 16 | else 17 | echo "Downloading SDK" 18 | curl -o $WORKING_DIR/$SDK_FILE $SDK_URL 19 | fi 20 | 21 | echo "Extracting SDK" 22 | unzip -o -d $WORKING_DIR -q $WORKING_DIR/$SDK_FILE 23 | 24 | echo "Merging into project" 25 | cp -rf $WORKING_DIR/components lib/ 26 | cp -rf $WORKING_DIR/documentation lib/ 27 | 28 | echo "Bootstrapping complete" 29 | -------------------------------------------------------------------------------- /lib/arm-gcc.cmake: -------------------------------------------------------------------------------- 1 | #ARM none eabi gcc toolchain configuration 2 | 3 | # We are cross compiling so we don't want compiler tests to run, as they will fail 4 | include(CMakeForceCompiler) 5 | 6 | # Indicate we aren't compiling for an OS 7 | set(CMAKE_SYSTEM_NAME Generic) 8 | 9 | # Set processor type 10 | set(CMAKE_SYSTEM_PROCESSOR arm) 11 | 12 | # Set compiler paths. We force set so it doesn't run tests 13 | CMAKE_FORCE_C_COMPILER(${COMPILER_PREFIX}arm-none-eabi-gcc GNU) 14 | CMAKE_FORCE_CXX_COMPILER(${COMPILER_PREFIX}arm-none-eabi-g++ GNU) 15 | 16 | set(CMAKE_ASM_COMPILER ${COMPILER_PREFIX}arm-none-eabi-g++) 17 | set(CMAKE_RANLIB ${COMPILER_PREFIX}arm-none-eabi-ranlib) 18 | set(CMAKE_AR ${COMPILER_PREFIX}arm-none-eabi-ar) 19 | 20 | #set(CMAKE_C_LINK_EXECUTABLE ${COMPILER_PREFIX}arm-none-eabi-ld) 21 | #set(CMAKE_CXX_LINK_EXECUTABLE ${COMPILER_PREFIX}arm-none-eabi-ld) 22 | 23 | # Removes invalid (default) flags on OSX 24 | SET(CMAKE_C_LINK_FLAGS "") 25 | SET(CMAKE_CXX_LINK_FLAGS "") 26 | 27 | # Set other tools 28 | set(OBJSIZE ${COMPILER_PREFIX}arm-none-eabi-size) 29 | set(OBJCOPY ${COMPILER_PREFIX}arm-none-eabi-objcopy) 30 | set(OBJDUMP ${COMPILER_PREFIX}arm-none-eabi-objdump) 31 | set(DEBUGGER ${COMPILER_PREFIX}arm-none-eabi-gdb) 32 | 33 | # Remove preset linker flags 34 | set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") 35 | set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "") 36 | set(CMAKE_SHARED_LIBRARY_LINK_ASM_FLAGS "") 37 | 38 | # Set library options 39 | set(SHARED_LIBS OFF) 40 | set(STATIC_LIBS ON) 41 | -------------------------------------------------------------------------------- /lib/components/ant/ant.cmake: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryankurte/nrf52-base/74c84630c8985989292d2d76fdc4c41a073f030a/lib/components/ant/ant.cmake -------------------------------------------------------------------------------- /lib/components/ble/ble.cmake: -------------------------------------------------------------------------------- 1 | # BLE Module 2 | 3 | include_directories( 4 | ${CMAKE_CURRENT_LIST_DIR}/common 5 | ) 6 | 7 | # Add source files 8 | set(BLE_SOURCES 9 | ${CMAKE_CURRENT_LIST_DIR}/common/ble_advdata.c 10 | ${CMAKE_CURRENT_LIST_DIR}/common/ble_conn_params.c 11 | ${CMAKE_CURRENT_LIST_DIR}/common/ble_conn_state.c 12 | ${CMAKE_CURRENT_LIST_DIR}/common/ble_srv_common.c 13 | ) 14 | 15 | # Add modules 16 | foreach(MODULE IN ITEMS ${BLE_MODULES}) 17 | message("Added ble module: ${MODULE} at: ${CMAKE_CURRENT_LIST_DIR}/${MODULE}") 18 | file(GLOB_RECURSE CURRENT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/${MODULE}/*.c) 19 | set(BLE_SOURCES ${BLE_SOURCES} ${CURRENT_SOURCES}) 20 | include_directories(${CMAKE_CURRENT_LIST_DIR}/${MODULE}) 21 | endforeach(MODULE IN ITEMS ${BLE_MODULES}) 22 | 23 | # Add services 24 | foreach(SERVICE IN ITEMS ${BLE_SERVICES}) 25 | message("Added ble service: ${SERVICE} at: ${CMAKE_CURRENT_LIST_DIR}/${SERVICE}") 26 | file(GLOB_RECURSE CURRENT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/ble_services/${SERVICE}/*.c) 27 | set(BLE_SOURCES ${BLE_SOURCES} ${CURRENT_SOURCES}) 28 | include_directories(${CMAKE_CURRENT_LIST_DIR}/ble_services/${SERVICE}) 29 | endforeach(SERVICE IN ITEMS ${BLE_SERVICES}) 30 | 31 | # Create ble library 32 | add_library(ble ${BLE_SOURCES}) 33 | 34 | set(LIBS ${LIBS} ble) -------------------------------------------------------------------------------- /lib/components/device/device.cmake: -------------------------------------------------------------------------------- 1 | # Device Module 2 | 3 | # Add source files 4 | 5 | # Add inclusions 6 | include_directories(${CMAKE_CURRENT_LIST_DIR}) 7 | 8 | # Create ble library 9 | #add_library(device ${DEVICE_SOURCES}) -------------------------------------------------------------------------------- /lib/components/drivers_ext/drivers-ext.cmake: -------------------------------------------------------------------------------- 1 | # External driver Module 2 | 3 | #TODO 4 | 5 | # Add source files 6 | # set(DRIVERS_EXT_SOURCES) 7 | 8 | # Create ble library 9 | #add_library(drivers-ext ${DRIVERS_EXT_SOURCES}) -------------------------------------------------------------------------------- /lib/components/drivers_nrf/drivers-nrf.cmake: -------------------------------------------------------------------------------- 1 | # nRF Driver Module 2 | 3 | # Add source files 4 | set(NRF_DRIVER_SOURCES "") 5 | 6 | # Include nosd driver if no softdevice is used 7 | if(NOT DEFINED SOFTDEVICE) 8 | set(DRIVERS_NRF ${DRIVERS_NRF} nrf_soc_nosd) 9 | endif() 10 | 11 | foreach(DRIVER IN ITEMS ${DRIVERS_NRF}) 12 | if("${DRIVER}" STREQUAL "uart") 13 | # TODO: add other uart components somehow 14 | set(NRF_DRIVER_SOURCES 15 | ${NRF_DRIVER_SOURCES} 16 | ${CMAKE_CURRENT_LIST_DIR}/uart/nrf_drv_uart.c 17 | ) 18 | include_directories(${CMAKE_CURRENT_LIST_DIR}/uart) 19 | elseif("${DRIVER}" STREQUAL "delay") 20 | include_directories(${CMAKE_CURRENT_LIST_DIR}/delay) 21 | else() 22 | message("Added driver: ${DRIVER} at: ${CMAKE_CURRENT_LIST_DIR}/${DRIVER}") 23 | file(GLOB_RECURSE CURRENT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/${DRIVER}/*.c) 24 | set(NRF_DRIVER_SOURCES ${NRF_DRIVER_SOURCES} ${CURRENT_SOURCES}) 25 | include_directories(${CMAKE_CURRENT_LIST_DIR}/${DRIVER}) 26 | endif() 27 | endforeach(DRIVER IN ITEMS ${DRIVERS_NRF}) 28 | 29 | # Create nrf driver library 30 | add_library(drivers-nrf ${NRF_DRIVER_SOURCES}) 31 | 32 | set(LIBS ${LIBS} drivers-nrf) -------------------------------------------------------------------------------- /lib/components/libraries/libraries.cmake: -------------------------------------------------------------------------------- 1 | # Library Module 2 | 3 | # Add source files 4 | 5 | set(NRF_LIB_SOURCES "") 6 | 7 | foreach(LIBRARY IN ITEMS ${LIBRARIES}) 8 | # Hacks for libraries that include things they shouldn't 9 | if("${LIBRARY}" STREQUAL "timer") 10 | # TODO: add other timer components if definitions exist 11 | set(NRF_LIB_SOURCES 12 | ${NRF_LIB_SOURCES} 13 | ${CMAKE_CURRENT_LIST_DIR}/timer/app_timer.c 14 | ) 15 | include_directories(${CMAKE_CURRENT_LIST_DIR}/timer) 16 | else() 17 | message("Added library: ${LIBRARY} at: ${CMAKE_CURRENT_LIST_DIR}/${LIBRARY}") 18 | file(GLOB_RECURSE CURRENT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/${LIBRARY}/*.c) 19 | set(NRF_LIB_SOURCES ${NRF_LIB_SOURCES} ${CURRENT_SOURCES}) 20 | include_directories(${CMAKE_CURRENT_LIST_DIR}/${LIBRARY}) 21 | include_directories(${CMAKE_CURRENT_LIST_DIR}/${LIBRARY}/src) 22 | endif() 23 | endforeach(LIBRARY IN ${LIBRARIES}) 24 | 25 | # Create ble library 26 | add_library(libraries ${NRF_LIB_SOURCES}) 27 | 28 | set(LIBS ${LIBS} libraries) -------------------------------------------------------------------------------- /lib/components/serialization/serialization.cmake: -------------------------------------------------------------------------------- 1 | # Serialization module 2 | 3 | # Add source files 4 | 5 | # Application/codecs 6 | include_directories(${CMAKE_CURRENT_LIST_DIR}/application/codecs/common) 7 | include_directories(${CMAKE_CURRENT_LIST_DIR}/application/codecs/${SOFTDEVICE_L}) 8 | include_directories(${CMAKE_CURRENT_LIST_DIR}/application/codecs/${SOFTDEVICE_L}/serializers) 9 | file(GLOB_RECURSE CODEC_COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/application/codecs/common/*.c) 10 | file(GLOB_RECURSE CODEC_SOFTDEV_SRC ${CMAKE_CURRENT_LIST_DIR}/application/codecs/${SOFTDEVICE_L}/*.c) 11 | 12 | # Application/hal 13 | include_directories(${CMAKE_CURRENT_LIST_DIR}/application/hal) 14 | set(APP_HAL_SRC 15 | ${CMAKE_CURRENT_LIST_DIR}/application/hal/ser_app_power_system_off.c 16 | ${CMAKE_CURRENT_LIST_DIR}/application/hal/ser_app_hal_nrf5x.c) 17 | 18 | # Application/transport 19 | include_directories(${CMAKE_CURRENT_LIST_DIR}/application/transport) 20 | file(GLOB_RECURSE TRANSPORT_SRC ${CMAKE_CURRENT_LIST_DIR}/application/transport/*.c) 21 | 22 | # Common 23 | include_directories(${CMAKE_CURRENT_LIST_DIR}/common/) 24 | include_directories(${CMAKE_CURRENT_LIST_DIR}/common/transport) 25 | file(GLOB COMMON_SRC ${CMAKE_CURRENT_LIST_DIR}/common/*.c) 26 | 27 | include_directories(${CMAKE_CURRENT_LIST_DIR}/common/struct_ser/${SOFTDEVICE_L}) 28 | file(GLOB COMMON_SOFTDEV_SRC ${CMAKE_CURRENT_LIST_DIR}/common/struct_ser/${SOFTDEVICE_L}/*.c) 29 | 30 | # Create nrf driver library 31 | add_library(serialization ${COMMON_SRC} ${COMMON_SOFTDEV_SRC} ${CODEC_COMMON_SRC} ${CODEC_SOFTDEV_SRC} ${TRANSPORT_SRC} ${APP_HAL_SRC}) 32 | 33 | set(LIBS ${LIBS} serialization) -------------------------------------------------------------------------------- /lib/components/softdevice/softdevice.cmake: -------------------------------------------------------------------------------- 1 | # Softdevice inclusion 2 | 3 | if(DEFINED SOFTDEVICE) 4 | 5 | include_directories(${CMAKE_CURRENT_LIST_DIR}/common/softdevice_handler) 6 | 7 | string(TOLOWER ${SOFTDEVICE} SOFTDEVICE_L) 8 | 9 | if(NOT SOFTDEVICE_VERSION) 10 | set(SOFTDEVICE_VERSION "2.0.0") 11 | endif() 12 | 13 | message("Using softdevice: ${SOFTDEVICE} Version: ${SOFTDEVICE_VERSION}") 14 | 15 | if(NOT FLASH_START) 16 | if(SOFTDEVICE STREQUAL "S132") 17 | set(FLASH_START 0x1c000) 18 | elseif(SOFTDEVICE STREQUAL "S212") 19 | set(FLASH_START 0x12000) 20 | endif() 21 | message("Automatically selected flash start address: ${FLASH_START}") 22 | endif(NOT FLASH_START) 23 | 24 | 25 | 26 | set(SOFTDEVICE_SOURCES 27 | ${CMAKE_CURRENT_LIST_DIR}/common/softdevice_handler/softdevice_handler_appsh.c 28 | ${CMAKE_CURRENT_LIST_DIR}/common/softdevice_handler/softdevice_handler.c 29 | ) 30 | 31 | include_directories( 32 | ${CMAKE_CURRENT_LIST_DIR}/${SOFTDEVICE_L}/headers 33 | ${CMAKE_CURRENT_LIST_DIR}/${SOFTDEVICE_L}/headers/nrf52 34 | ) 35 | 36 | if(NOT DEFINED SOFTDEVICE_LD) 37 | set(SOFTDEVICE_LD ${CMAKE_CURRENT_LIST_DIR}/${SOFTDEVICE_L}/toolchain/armgcc/armgcc_${SOFTDEVICE_L}_${DEVICE_L}_xxaa.ld) 38 | endif() 39 | 40 | set(SOFTDEVICE_HEX ${CMAKE_CURRENT_LIST_DIR}/${SOFTDEVICE_L}/hex/${SOFTDEVICE_L}_${CPU_FAMILY_L}_${SOFTDEVICE_VERSION}_softdevice.hex) 41 | set(SOFTDEVICE_BIN ${SOFTDEVICE_L}_${CPU_FAMILY_L}_${SOFTDEVICE_VERSION}_softdevice.bin) 42 | 43 | message("Using softdevice linker script: ${SOFTDEVICE_LD}") 44 | message("Using softdevice binary: ${SOFTDEVICE_HEX}") 45 | 46 | add_custom_target(softdevice-bin ALL COMMAND ${OBJCOPY} -I ihex -O binary ${SOFTDEVICE_HEX} ${SOFTDEVICE_BIN}) 47 | 48 | add_library(softdevice ${SOFTDEVICE_SOURCES}) 49 | 50 | set(LIBS ${LIBS} softdevice) 51 | 52 | endif(DEFINED SOFTDEVICE) -------------------------------------------------------------------------------- /lib/components/toolchain/toolchain.cmake: -------------------------------------------------------------------------------- 1 | # Softdevice inclusion 2 | 3 | include_directories( 4 | ${CMAKE_CURRENT_LIST_DIR} 5 | ${CMAKE_CURRENT_LIST_DIR}/gcc 6 | ${CMAKE_CURRENT_LIST_DIR}/CMSIS/Include 7 | ) 8 | 9 | set(TOOLCHAIN_SOURCES 10 | ${CMAKE_CURRENT_LIST_DIR}/system_${CPU_FAMILY_L}.c 11 | ) 12 | 13 | set(STARTUP_FILE ${CMAKE_CURRENT_LIST_DIR}/gcc/gcc_startup_${CPU_FAMILY_L}.s) 14 | 15 | set(LINKER_TEMPLATE_LOC ${CMAKE_CURRENT_LIST_DIR}/gcc/) 16 | 17 | set(BASE_LD ${CMAKE_CURRENT_LIST_DIR}/gcc/${CPU_FAMILY_L}_xxaa.ld) 18 | 19 | add_library(toolchain ${STARTUP_FILE} ${TOOLCHAIN_SOURCES}) 20 | 21 | set(LIBS ${LIBS} toolchain) 22 | -------------------------------------------------------------------------------- /lib/erase.jlink: -------------------------------------------------------------------------------- 1 | h 2 | r 3 | erase 4 | qc -------------------------------------------------------------------------------- /lib/flash-softdevice.in: -------------------------------------------------------------------------------- 1 | device ${CPU_FAMILY_U} 2 | h 3 | loadbin ${SOFTDEVICE_BIN}, 0x0000 4 | verifybin ${SOFTDEVICE_BIN}, 0x0000 5 | r 6 | g 7 | qc -------------------------------------------------------------------------------- /lib/flash.in: -------------------------------------------------------------------------------- 1 | device ${CPU_FAMILY_U} 2 | h 3 | loadbin ${BINARY}, ${FLASH_START} 4 | verifybin ${BINARY}, ${FLASH_START} 5 | r 6 | g 7 | qc -------------------------------------------------------------------------------- /lib/jlink.cmake: -------------------------------------------------------------------------------- 1 | # JLink functions 2 | # Adds targets for JLink programmers and emulators 3 | 4 | # Configure flasher script for the project 5 | set(BINARY ${TARGET}.bin) 6 | 7 | configure_file(${CMAKE_CURRENT_LIST_DIR}/flash.in ${CMAKE_CURRENT_BINARY_DIR}/flash.jlink) 8 | configure_file(${CMAKE_CURRENT_LIST_DIR}/flash-softdevice.in ${CMAKE_CURRENT_BINARY_DIR}/flash-softdevice.jlink) 9 | 10 | #Add JLink commands 11 | add_custom_target(debug 12 | COMMAND ${DEBUGGER} -tui -command ${CMAKE_CURRENT_LIST_DIR}/remote.gdbconf ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} 13 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET} 14 | ) 15 | 16 | add_custom_target(debug-server 17 | COMMAND JLinkGDBServer -device ${CPU_FAMILY_L} -speed 4000 -if SWD 18 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.bin 19 | ) 20 | 21 | add_custom_target(flash 22 | COMMAND JLinkExe -device ${CPU_FAMILY_L} -speed 4000 -if SWD -CommanderScript ${CMAKE_CURRENT_BINARY_DIR}/flash.jlink 23 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.bin 24 | ) 25 | 26 | add_custom_target(flash-softdevice 27 | COMMAND JLinkExe -device ${CPU_FAMILY_L} -speed 4000 -if SWD -CommanderScript ${CMAKE_CURRENT_BINARY_DIR}/flash-softdevice.jlink 28 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.bin 29 | ) 30 | 31 | add_custom_target(erase 32 | COMMAND JLinkExe -device ${CPU_FAMILY_L} -speed 4000 -if SWD -CommanderScript ${CMAKE_CURRENT_LIST_DIR}/erase.jlink 33 | ) 34 | 35 | add_custom_target(reset 36 | COMMAND JLinkExe -device ${CPU_FAMILY_L} -speed 4000 -if SWD -CommanderScript ${CMAKE_CURRENT_LIST_DIR}/reset.jlink 37 | ) 38 | -------------------------------------------------------------------------------- /lib/nrf52-base.cmake: -------------------------------------------------------------------------------- 1 | # nRF52 Base CMake file 2 | # 3 | # Configures the project files and environment for any nRF52 project 4 | 5 | if(NOT DEFINED DEVICE) 6 | message(FATAL_ERROR "No processor defined") 7 | endif(NOT DEFINED DEVICE) 8 | 9 | # Convert to upper case 10 | string(TOUPPER ${DEVICE} DEVICE_U) 11 | string(TOLOWER ${DEVICE} DEVICE_L) 12 | 13 | # Determine device family 14 | string(REGEX MATCH "^(NRF5[1-2])" CPU_FAMILY_U "${DEVICE_U}") 15 | string(TOLOWER ${CPU_FAMILY_U} CPU_FAMILY_L) 16 | 17 | # Determine core type 18 | set(CPU_TYPE "m4") 19 | 20 | # Include libraries 21 | include(${CMAKE_CURRENT_LIST_DIR}/components/toolchain/toolchain.cmake) 22 | include(${CMAKE_CURRENT_LIST_DIR}/components/softdevice/softdevice.cmake) 23 | include(${CMAKE_CURRENT_LIST_DIR}/components/device/device.cmake) 24 | include(${CMAKE_CURRENT_LIST_DIR}/components/ble/ble.cmake) 25 | include(${CMAKE_CURRENT_LIST_DIR}/components/libraries/libraries.cmake) 26 | include(${CMAKE_CURRENT_LIST_DIR}/components/drivers_nrf/drivers-nrf.cmake) 27 | include(${CMAKE_CURRENT_LIST_DIR}/components/drivers_ext/drivers-ext.cmake) 28 | include(${CMAKE_CURRENT_LIST_DIR}/components/serialization/serialization.cmake) 29 | 30 | message("*******************************************") 31 | message("Device: ${DEVICE_U} Family: ${CPU_FAMILY_U}") 32 | 33 | # Set compiler flags 34 | # Common arguments 35 | # TODO: --specs=nano.specs 36 | set(COMMON_DEFINITIONS "${OPTIONAL_DEBUG_SYMBOLS} -D${CPU_FAMILY_U} -D${DEVICE_U} -D${BOARD}") 37 | set(COMMON_DEFINITIONS "${COMMON_DEFINITIONS} -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16") 38 | set(COMMON_DEFINITIONS "${COMMON_DEFINITIONS} -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin") 39 | set(COMMON_DEFINITIONS "${COMMON_DEFINITIONS} -DSWI_DISABLE0 -DCONFIG_GPIO_AS_PINRESET ") 40 | if(DEFINED SOFTDEVICE) 41 | set(COMMON_DEFINITIONS "${COMMON_DEFINITIONS} -D${SOFTDEVICE} -DSOFTDEVICE_PRESENT -DBLE_STACK_SUPPORT_REQD") 42 | endif() 43 | 44 | set(DEPFLAGS "-MMD -MP") 45 | 46 | if(NOT DEFINED QUIET_BUILD) 47 | set(COMMON_DEFINITIONS "${COMMON_DEFINITIONS} -Wextra -Wall") 48 | endif(NOT DEFINED QUIET_BUILD) 49 | 50 | # Enable FLTO optimization if required 51 | if(USE_FLTO) 52 | set(OPTFLAGS "-Os -flto") 53 | else() 54 | set(OPTFLAGS "-Os") 55 | endif() 56 | 57 | # Select linker script based on soft device selection 58 | # TODO: this could be put into softdevice/toolchain files 59 | if(DEFINED SOFTDEVICE) 60 | set(LINKER_SCRIPT ${SOFTDEVICE_LD}) 61 | else() 62 | set(LINKER_SCRIPT ${BASE_LD}) 63 | endif() 64 | 65 | # Build flags 66 | set(CMAKE_C_FLAGS "-std=gnu11 ${COMMON_DEFINITIONS} ${DEPFLAGS}") 67 | set(CMAKE_CXX_FLAGS "${COMMON_DEFINITIONS} ${DEPFLAGS}") 68 | set(CMAKE_ASM_FLAGS "${COMMON_DEFINITIONS} -x assembler-with-cpp") 69 | set(CMAKE_EXE_LINKER_FLAGS "-Xlinker -L${LINKER_TEMPLATE_LOC} -T${LINKER_SCRIPT} -lc -Wl,-Map=${CMAKE_PROJECT_NAME}.map -Wl,--gc-sections") 70 | 71 | # Set default inclusions 72 | set(LIBS -lc -lnosys ${LIBS}) 73 | 74 | # Debug Flags 75 | #set(COMMON_DEBUG_FLAGS "-O0 -g -gdwarf-2 -DDEBUG=1") 76 | set(CMAKE_C_FLAGS_DEBUG "${COMMON_DEBUG_FLAGS}") 77 | set(CMAKE_CXX_FLAGS_DEBUG "${COMMON_DEBUG_FLAGS}") 78 | set(CMAKE_ASM_FLAGS_DEBUG "${COMMON_DEBUG_FLAGS}") 79 | 80 | # Release Flags 81 | #set(COMMON_RELEASE_FLAGS "${OPTFLAGS} -DNDEBUG=1 -DRELEASE=1") 82 | set(CMAKE_C_FLAGS_RELEASE "${COMMON_RELEASE_FLAGS}") 83 | set(CMAKE_CXX_FLAGS_RELEASE "${COMMON_RELEASE_FLAGS}") 84 | set(CMAKE_ASM_FLAGS_RELEASE "${COMMON_RELEASE_FLAGS}") 85 | 86 | 87 | -------------------------------------------------------------------------------- /lib/post-build.cmake: -------------------------------------------------------------------------------- 1 | 2 | # ARM post build commands 3 | 4 | # Create binary file 5 | add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${OBJCOPY} -O binary ${TARGET} ${TARGET}.bin) 6 | 7 | add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${OBJCOPY} -O ihex ${TARGET} ${TARGET}.hex) 8 | 9 | add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${OBJDUMP} -d -S ${TARGET} > ${TARGET}.dmp) 10 | 11 | add_custom_command(TARGET ${TARGET} POST_BUILD COMMAND ${OBJSIZE} ${TARGET}) -------------------------------------------------------------------------------- /lib/remote.gdbconf: -------------------------------------------------------------------------------- 1 | target remote localhost:2331 -------------------------------------------------------------------------------- /lib/reset.jlink: -------------------------------------------------------------------------------- 1 | h 2 | r 3 | qc -------------------------------------------------------------------------------- /work/include/boards.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | #ifndef BOARDS_H 13 | #define BOARDS_H 14 | 15 | #include "nrf_gpio.h" 16 | 17 | #if defined(BOARD_NRF6310) 18 | #include "nrf6310.h" 19 | #elif defined(BOARD_PCA10000) 20 | #include "pca10000.h" 21 | #elif defined(BOARD_PCA10001) 22 | #include "pca10001.h" 23 | #elif defined(BOARD_PCA10002) 24 | #include "pca10000.h" 25 | #elif defined(BOARD_PCA10003) 26 | #include "pca10003.h" 27 | #elif defined(BOARD_PCA20006) 28 | #include "pca20006.h" 29 | #elif defined(BOARD_PCA10028) 30 | #include "pca10028.h" 31 | #elif defined(BOARD_PCA10031) 32 | #include "pca10031.h" 33 | #elif defined(BOARD_PCA10036) 34 | #include "pca10036.h" 35 | #elif defined(BOARD_PCA10040) 36 | #include "pca10040.h" 37 | #elif defined(BOARD_WT51822) 38 | #include "wt51822.h" 39 | #elif defined(BOARD_N5DK1) 40 | #include "n5_starterkit.h" 41 | #elif defined(BOARD_CUSTOM) 42 | #include "custom_board.h" 43 | #else 44 | #error "Board is not defined" 45 | 46 | #endif 47 | 48 | #define LEDS_OFF(leds_mask) do { NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ 49 | NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) 50 | 51 | #define LEDS_ON(leds_mask) do { NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \ 52 | NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0) 53 | 54 | #define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) ) 55 | 56 | #define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \ 57 | NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \ 58 | NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0) 59 | 60 | #define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \ 61 | for (pin = 0; pin < 32; pin++) \ 62 | if ( (leds_mask) & (1 << pin) ) \ 63 | nrf_gpio_cfg_output(pin); } while (0) 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /work/include/bsp.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | /**@file 14 | * 15 | * @defgroup bsp Board Support Package 16 | * @{ 17 | * @ingroup app_common 18 | * 19 | * @brief BSP module. 20 | * @details This module provides a layer of abstraction from the board. 21 | * It allows the user to indicate certain states on LEDs in a simple way. 22 | * Module functionality can be modified by additional defines: 23 | * - BSP_SIMPLE reduces functionality of this module to enable 24 | * and read state of the buttons 25 | * - BSP_UART_SUPPORT enables support for UART 26 | */ 27 | 28 | #ifndef BSP_H__ 29 | #define BSP_H__ 30 | 31 | #include 32 | #include 33 | #include "boards.h" 34 | 35 | #if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE) 36 | #include "app_button.h" 37 | 38 | #define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */ 39 | #define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */ 40 | #define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */ 41 | #endif 42 | 43 | /* BSP_UART_SUPPORT 44 | * This define enables UART support module. 45 | */ 46 | #ifdef BSP_UART_SUPPORT 47 | #include "app_uart.h" 48 | #endif // BSP_UART_SUPPORT 49 | 50 | #define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK 51 | #define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK 52 | #define BUTTON_ADVERTISE BSP_BUTTON_0_MASK 53 | #define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK 54 | #define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK 55 | #define BSP_BUTTONS_ALL 0xFFFFFFFF 56 | #define BSP_BUTTONS_NONE 0 57 | 58 | /**@brief Types of BSP initialization. 59 | */ 60 | #define BSP_INIT_NONE 0 /**< This define specifies the type of initialization without support for LEDs and buttons (@ref bsp_init).*/ 61 | #define BSP_INIT_LED (1 << 0) /**< This bit enables LEDs during initialization (@ref bsp_init).*/ 62 | #define BSP_INIT_BUTTONS (1 << 1) /**< This bit enables buttons during initialization (@ref bsp_init).*/ 63 | 64 | #define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */ 65 | 66 | typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */ 67 | 68 | #define BSP_INDICATIONS_LIST { \ 69 | "BSP_INDICATE_IDLE\n\r", \ 70 | "BSP_INDICATE_SCANNING\n\r", \ 71 | "BSP_INDICATE_ADVERTISING\n\r", \ 72 | "BSP_INDICATE_ADVERTISING_WHITELIST\n\r", \ 73 | "BSP_INDICATE_ADVERTISING_SLOW\n\r", \ 74 | "BSP_INDICATE_ADVERTISING_DIRECTED\n\r", \ 75 | "BSP_INDICATE_BONDING\n\r", \ 76 | "BSP_INDICATE_CONNECTED\n\r", \ 77 | "BSP_INDICATE_SENT_OK\n\r", \ 78 | "BSP_INDICATE_SEND_ERROR\n\r", \ 79 | "BSP_INDICATE_RCV_OK\n\r", \ 80 | "BSP_INDICATE_RCV_ERROR\n\r", \ 81 | "BSP_INDICATE_FATAL_ERROR\n\r", \ 82 | "BSP_INDICATE_ALERT_0\n\r", \ 83 | "BSP_INDICATE_ALERT_1\n\r", \ 84 | "BSP_INDICATE_ALERT_2\n\r", \ 85 | "BSP_INDICATE_ALERT_3\n\r", \ 86 | "BSP_INDICATE_ALERT_OFF\n\r", \ 87 | "BSP_INDICATE_USER_STATE_OFF\n\r", \ 88 | "BSP_INDICATE_USER_STATE_0\n\r", \ 89 | "BSP_INDICATE_USER_STATE_1\n\r", \ 90 | "BSP_INDICATE_USER_STATE_2\n\r", \ 91 | "BSP_INDICATE_USER_STATE_3\n\r", \ 92 | "BSP_INDICATE_USER_STATE_ON\n\r" \ 93 | } /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/ 94 | 95 | 96 | /**@brief BSP indication states. 97 | * 98 | * @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle. 99 | */ 100 | typedef enum 101 | { 102 | BSP_INDICATE_FIRST = 0, 103 | BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/ 104 | BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/ 105 | BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/ 106 | BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/ 107 | BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/ 108 | BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/ 109 | BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/ 110 | BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/ 111 | BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/ 112 | BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/ 113 | BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/ 114 | BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/ 115 | BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/ 116 | BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/ 117 | BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/ 118 | BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/ 119 | BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/ 120 | BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/ 121 | BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/ 122 | BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/ 123 | BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/ 124 | BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/ 125 | BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/ 126 | BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/ 127 | BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON 128 | } bsp_indication_t; 129 | 130 | /**@brief BSP events. 131 | * 132 | * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons. 133 | */ 134 | typedef enum 135 | { 136 | BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */ 137 | BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */ 138 | BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */ 139 | BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */ 140 | BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */ 141 | BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */ 142 | BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */ 143 | BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */ 144 | BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */ 145 | BSP_EVENT_RESET, /**< The device should reset. */ 146 | BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */ 147 | BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */ 148 | BSP_EVENT_DFU, /**< The device should enter DFU mode. */ 149 | BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */ 150 | BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */ 151 | BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */ 152 | BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */ 153 | BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */ 154 | BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */ 155 | BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */ 156 | BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */ 157 | BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7, 158 | } bsp_event_t; 159 | 160 | 161 | typedef struct 162 | { 163 | bsp_event_t push_event; /**< The event to fire on regular button press. */ 164 | bsp_event_t long_push_event; /**< The event to fire on long button press. */ 165 | bsp_event_t release_event; /**< The event to fire on button release. */ 166 | } bsp_button_event_cfg_t; 167 | 168 | /**@brief BSP module event callback function type. 169 | * 170 | * @details Upon an event in the BSP module, this callback function will be called to notify 171 | * the application about the event. 172 | * 173 | * @param[in] bsp_event_t BSP event type. 174 | */ 175 | typedef void (* bsp_event_callback_t)(bsp_event_t); 176 | 177 | /**@brief Function for initializing BSP. 178 | * 179 | * @details The function initializes the board support package to allow state indication and 180 | * button reaction. Default events are assigned to buttons. 181 | * @note Before calling this function, you must initiate the following required modules: 182 | * - @ref app_timer for LED support 183 | * - @ref app_gpiote for button support 184 | * - @ref app_uart for UART support 185 | * 186 | * @param[in] type Type of peripherals used. 187 | * @param[in] ticks_per_100ms Number of RTC ticks for 100 ms. 188 | * @param[in] callback Function to be called when button press/event is detected. 189 | * 190 | * @retval NRF_SUCCESS If the BSP module was successfully initialized. 191 | * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized. 192 | * @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached. 193 | * @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users. 194 | * @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized. 195 | */ 196 | uint32_t bsp_init(uint32_t type, uint32_t ticks_per_100ms, bsp_event_callback_t callback); 197 | 198 | /**@brief Function for getting buttons states. 199 | * 200 | * @details This function allows to get the state of all buttons. 201 | * 202 | * @param[in] p_buttons_state This variable will store buttons state. Button 0 state is 203 | * represented by bit 0 (1=pressed), Button 1 state by bit 1, 204 | * and so on. 205 | * 206 | * @retval NRF_SUCCESS If buttons state was successfully read. 207 | */ 208 | uint32_t bsp_buttons_state_get(uint32_t * p_buttons_state); 209 | 210 | /**@brief Function for checking buttons states. 211 | * 212 | * @details This function checks if the button is pressed. If the button ID iss out of range, 213 | * the function returns false. 214 | * 215 | * @param[in] button Button ID to check. 216 | * @param[in] p_state This variable will store the information whether the 217 | * specified button is pressed (true) or not. 218 | * 219 | * @retval NRF_SUCCESS If the button state was successfully read. 220 | */ 221 | uint32_t bsp_button_is_pressed(uint32_t button, bool * p_state); 222 | 223 | /**@brief Function for assigning a specific event to a button. 224 | * 225 | * @details This function allows redefinition of standard events assigned to buttons. 226 | * To unassign events, provide the event @ ref BSP_EVENT_NOTHING. 227 | * 228 | * @param[in] button Button ID to be redefined. 229 | * @param[in] action Button action to assign event to. 230 | * @param[in] event Event to be assigned to button. 231 | * 232 | * @retval NRF_SUCCESS If the event was successfully assigned to button. 233 | * @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid. 234 | */ 235 | uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event); 236 | 237 | /**@brief Function for configuring indicators to required state. 238 | * 239 | * @details This function indicates the required state by means of LEDs (if enabled). 240 | * 241 | * @note Alerts are indicated independently. 242 | * 243 | * @param[in] indicate State to be indicated. 244 | * 245 | * @retval NRF_SUCCESS If the state was successfully indicated. 246 | * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full. 247 | * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized, 248 | * or internal timer has not been created. 249 | */ 250 | uint32_t bsp_indication_set(bsp_indication_t indicate); 251 | 252 | /**@brief Function for configuring indicators to required state. 253 | * 254 | * @details This function indicates the required state by means of LEDs (if enabled) 255 | * and UART (if enabled). 256 | * 257 | * @note Alerts are indicated independently. 258 | * 259 | * @param[in] indicate State to be indicated. 260 | * @param[in] p_text Text to be output on UART. 261 | * 262 | * @retval NRF_SUCCESS If the state was successfully indicated. 263 | * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full. 264 | * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized, 265 | * or timer has not been created. 266 | */ 267 | uint32_t bsp_indication_text_set(bsp_indication_t indicate, const char * p_text); 268 | 269 | 270 | /**@brief Function for enabling all buttons. 271 | * 272 | * @details After calling this function, all buttons will generate events when pressed, and 273 | * all buttons will be able to wake the system up from sleep mode. 274 | * 275 | * @retval NRF_SUCCESS If the buttons were successfully enabled. 276 | * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. 277 | * @return A propagated error. 278 | */ 279 | uint32_t bsp_buttons_enable(void); 280 | 281 | 282 | /**@brief Function for disabling all buttons. 283 | * 284 | * @details After calling this function, no buttons will generate events when pressed, and 285 | * no buttons will be able to wake the system up from sleep mode. 286 | * 287 | * @retval NRF_SUCCESS If the buttons were successfully disabled. 288 | * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. 289 | * @return A propagated error. 290 | */ 291 | uint32_t bsp_buttons_disable(void); 292 | 293 | 294 | /**@brief Function for configuring wakeup buttons before going into sleep mode. 295 | * 296 | * @details After calling this function, only the buttons that are set to 1 in wakeup_buttons 297 | * can be used to wake up the chip. If this function is not called before going to, 298 | * sleep either all or no buttons can wake up the chip. 299 | * 300 | * This function should only be called immediately before going into sleep. 301 | * 302 | * @param[in] wakeup_buttons Mask describing which buttons should be able to wake up the chip. 303 | * 304 | * @retval NRF_SUCCESS If the buttons were successfully enabled. 305 | * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined. 306 | */ 307 | uint32_t bsp_wakeup_buttons_set(uint32_t wakeup_buttons); 308 | 309 | 310 | #endif // BSP_H__ 311 | 312 | /** @} */ 313 | -------------------------------------------------------------------------------- /work/include/bsp_btn_ble.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | /**@file 14 | * 15 | * @defgroup bsp_btn_ble BSP: BLE Button Module 16 | * @{ 17 | * @ingroup bsp 18 | * 19 | * @brief Module for controlling BLE behavior through button actions. 20 | * 21 | * @details The application must propagate BLE events to the BLE Button Module. 22 | * Based on these events, the BLE Button Module configures the Board Support Package 23 | * to generate BSP events for certain button actions. These BSP events should then be 24 | * handled by the application's BSP event handler. 25 | * 26 | */ 27 | 28 | #ifndef BSP_BTN_BLE_H__ 29 | #define BSP_BTN_BLE_H__ 30 | 31 | #include 32 | #include "ble.h" 33 | #include "bsp.h" 34 | 35 | /**@brief BLE Button Module error handler type. */ 36 | typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error); 37 | 38 | /**@brief Function for initializing the BLE Button Module. 39 | * 40 | * Before calling this function, the BSP module must be initialized with buttons. 41 | * 42 | * @param[out] error_handler Error handler to call in case of internal errors in BLE Button 43 | * Module. 44 | * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event 45 | * (or BSP_EVENT_NOTHING) derived from the buttons pressed on 46 | * startup. For example, if the bond delete wakeup button was pressed 47 | * to wake up the device, *p_startup_bsp_evt is set to 48 | * @ref BSP_EVENT_CLEAR_BONDING_DATA. 49 | * 50 | * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is 51 | * returned. 52 | */ 53 | uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt); 54 | 55 | /**@brief Function for setting up wakeup buttons before going into sleep mode. 56 | * 57 | * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error 58 | * code is returned. 59 | */ 60 | uint32_t bsp_btn_ble_sleep_mode_prepare(void); 61 | 62 | /**@brief Function for handling the application's BLE stack events. 63 | * 64 | * @details This function handles all events from the BLE stack that are of interest to this module. 65 | * 66 | * @param[in] p_ble_evt BLE stack event. 67 | */ 68 | void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt); 69 | 70 | #endif /* BSP_BTN_BLE_H__ */ 71 | 72 | /** @} */ 73 | -------------------------------------------------------------------------------- /work/include/fstorage_config.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | #ifndef FS_CONFIG_H__ 14 | #define FS_CONFIG_H__ 15 | 16 | /** 17 | * @defgroup fstorage_config fstorage configuration 18 | * @ingroup fstorage 19 | * @{ 20 | * 21 | * @brief fstorage configuration options. 22 | */ 23 | 24 | 25 | /**@brief Configures the size of fstorage internal queue. 26 | * @details Increase this if there are many users, or if it is likely that many operation will be 27 | * queued at once without waiting for the previous operations to complete. In general, 28 | * increase the queue size if you frequently receive @ref FS_ERR_QUEUE_FULL errors when 29 | * calling @ref fs_store or @ref fs_erase. 30 | */ 31 | #define FS_QUEUE_SIZE (4) 32 | 33 | /**@brief Configures how many times should fstorage attempt to execute an operation if 34 | * the SoftDevice fails to schedule flash access due to high BLE activity. 35 | * @details Increase this value if fstorage events return the @ref FS_ERR_OPERATION_TIMEOUT error 36 | * often. 37 | */ 38 | #define FS_OP_MAX_RETRIES (3) 39 | 40 | 41 | /**@brief Configures the maximum number of words to be written to flash in a single operation. 42 | * If data length exceeds this value, the data will be written down in several chunks, 43 | * as necessary. 44 | * 45 | * @details Tweaking this value can increase the chances of the SoftDevice being able to fit 46 | * flash operations in between radio activity. This value is bound by the maximum number 47 | * of words which the SoftDevice can write to flash in a single call to 48 | * @ref sd_flash_write, which is 256 words for nRF51 ICs and 1024 words for nRF52 ICs. 49 | */ 50 | #if defined (NRF51) 51 | #define FS_MAX_WRITE_SIZE_WORDS (256) 52 | #elif defined (NRF52) 53 | #define FS_MAX_WRITE_SIZE_WORDS (1024) 54 | #endif 55 | 56 | /** @} */ 57 | 58 | #endif // FS_CONFIG_H__ 59 | 60 | -------------------------------------------------------------------------------- /work/include/nrf_drv_config.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | #ifndef NRF_DRV_CONFIG_H 14 | #define NRF_DRV_CONFIG_H 15 | 16 | /** 17 | * Provide a non-zero value here in applications that need to use several 18 | * peripherals with the same ID that are sharing certain resources 19 | * (for example, SPI0 and TWI0). Obviously, such peripherals cannot be used 20 | * simultaneously. Therefore, this definition allows to initialize the driver 21 | * for another peripheral from a given group only after the previously used one 22 | * is uninitialized. Normally, this is not possible, because interrupt handlers 23 | * are implemented in individual drivers. 24 | * This functionality requires a more complicated interrupt handling and driver 25 | * initialization, hence it is not always desirable to use it. 26 | */ 27 | #define PERIPHERAL_RESOURCE_SHARING_ENABLED 0 28 | 29 | /* CLOCK */ 30 | #define CLOCK_ENABLED 0 31 | 32 | #if (CLOCK_ENABLED == 1) 33 | #define CLOCK_CONFIG_XTAL_FREQ NRF_CLOCK_XTALFREQ_Default 34 | #define CLOCK_CONFIG_LF_SRC NRF_CLOCK_LFCLK_Xtal 35 | #define CLOCK_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 36 | #endif 37 | 38 | /* GPIOTE */ 39 | #define GPIOTE_ENABLED 1 40 | 41 | #if (GPIOTE_ENABLED == 1) 42 | #define GPIOTE_CONFIG_USE_SWI_EGU false 43 | #define GPIOTE_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 44 | #define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4 45 | #endif 46 | 47 | /* TIMER */ 48 | #define TIMER0_ENABLED 0 49 | 50 | #if (TIMER0_ENABLED == 1) 51 | #define TIMER0_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz 52 | #define TIMER0_CONFIG_MODE TIMER_MODE_MODE_Timer 53 | #define TIMER0_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_32Bit 54 | #define TIMER0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 55 | 56 | #define TIMER0_INSTANCE_INDEX 0 57 | #endif 58 | 59 | #define TIMER1_ENABLED 0 60 | 61 | #if (TIMER1_ENABLED == 1) 62 | #define TIMER1_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz 63 | #define TIMER1_CONFIG_MODE TIMER_MODE_MODE_Timer 64 | #define TIMER1_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit 65 | #define TIMER1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 66 | 67 | #define TIMER1_INSTANCE_INDEX (TIMER0_ENABLED) 68 | #endif 69 | 70 | #define TIMER2_ENABLED 0 71 | 72 | #if (TIMER2_ENABLED == 1) 73 | #define TIMER2_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz 74 | #define TIMER2_CONFIG_MODE TIMER_MODE_MODE_Timer 75 | #define TIMER2_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit 76 | #define TIMER2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 77 | 78 | #define TIMER2_INSTANCE_INDEX (TIMER1_ENABLED+TIMER0_ENABLED) 79 | #endif 80 | 81 | #define TIMER3_ENABLED 0 82 | 83 | #if (TIMER3_ENABLED == 1) 84 | #define TIMER3_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz 85 | #define TIMER3_CONFIG_MODE TIMER_MODE_MODE_Timer 86 | #define TIMER3_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit 87 | #define TIMER3_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 88 | 89 | #define TIMER3_INSTANCE_INDEX (TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) 90 | #endif 91 | 92 | #define TIMER4_ENABLED 0 93 | 94 | #if (TIMER4_ENABLED == 1) 95 | #define TIMER4_CONFIG_FREQUENCY NRF_TIMER_FREQ_16MHz 96 | #define TIMER4_CONFIG_MODE TIMER_MODE_MODE_Timer 97 | #define TIMER4_CONFIG_BIT_WIDTH TIMER_BITMODE_BITMODE_16Bit 98 | #define TIMER4_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 99 | 100 | #define TIMER4_INSTANCE_INDEX (TIMER3_ENABLED+TIMER2_ENABLED+TIMER1_ENABLED+TIMER0_ENABLED) 101 | #endif 102 | 103 | 104 | #define TIMER_COUNT (TIMER0_ENABLED + TIMER1_ENABLED + TIMER2_ENABLED + TIMER3_ENABLED + TIMER4_ENABLED) 105 | 106 | /* RTC */ 107 | #define RTC0_ENABLED 0 108 | 109 | #if (RTC0_ENABLED == 1) 110 | #define RTC0_CONFIG_FREQUENCY 32678 111 | #define RTC0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 112 | #define RTC0_CONFIG_RELIABLE false 113 | 114 | #define RTC0_INSTANCE_INDEX 0 115 | #endif 116 | 117 | #define RTC1_ENABLED 0 118 | 119 | #if (RTC1_ENABLED == 1) 120 | #define RTC1_CONFIG_FREQUENCY 32768 121 | #define RTC1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 122 | #define RTC1_CONFIG_RELIABLE false 123 | 124 | #define RTC1_INSTANCE_INDEX (RTC0_ENABLED) 125 | #endif 126 | 127 | #define RTC2_ENABLED 0 128 | 129 | #if (RTC2_ENABLED == 1) 130 | #define RTC2_CONFIG_FREQUENCY 32768 131 | #define RTC2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 132 | #define RTC2_CONFIG_RELIABLE false 133 | 134 | #define RTC2_INSTANCE_INDEX (RTC0_ENABLED+RTC1_ENABLED) 135 | #endif 136 | 137 | 138 | #define RTC_COUNT (RTC0_ENABLED+RTC1_ENABLED+RTC2_ENABLED) 139 | 140 | #define NRF_MAXIMUM_LATENCY_US 2000 141 | 142 | /* RNG */ 143 | #define RNG_ENABLED 0 144 | 145 | #if (RNG_ENABLED == 1) 146 | #define RNG_CONFIG_ERROR_CORRECTION true 147 | #define RNG_CONFIG_POOL_SIZE 8 148 | #define RNG_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 149 | #endif 150 | 151 | /* PWM */ 152 | 153 | #define PWM0_ENABLED 0 154 | 155 | #if (PWM0_ENABLED == 1) 156 | #define PWM0_CONFIG_OUT0_PIN 2 157 | #define PWM0_CONFIG_OUT1_PIN 3 158 | #define PWM0_CONFIG_OUT2_PIN 4 159 | #define PWM0_CONFIG_OUT3_PIN 5 160 | #define PWM0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 161 | #define PWM0_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz 162 | #define PWM0_CONFIG_COUNT_MODE NRF_PWM_MODE_UP 163 | #define PWM0_CONFIG_TOP_VALUE 1000 164 | #define PWM0_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON 165 | #define PWM0_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO 166 | 167 | #define PWM0_INSTANCE_INDEX 0 168 | #endif 169 | 170 | #define PWM1_ENABLED 0 171 | 172 | #if (PWM1_ENABLED == 1) 173 | #define PWM1_CONFIG_OUT0_PIN 2 174 | #define PWM1_CONFIG_OUT1_PIN 3 175 | #define PWM1_CONFIG_OUT2_PIN 4 176 | #define PWM1_CONFIG_OUT3_PIN 5 177 | #define PWM1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 178 | #define PWM1_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz 179 | #define PWM1_CONFIG_COUNT_MODE NRF_PWM_MODE_UP 180 | #define PWM1_CONFIG_TOP_VALUE 1000 181 | #define PWM1_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON 182 | #define PWM1_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO 183 | 184 | #define PWM1_INSTANCE_INDEX (PWM0_ENABLED) 185 | #endif 186 | 187 | #define PWM2_ENABLED 0 188 | 189 | #if (PWM2_ENABLED == 1) 190 | #define PWM2_CONFIG_OUT0_PIN 2 191 | #define PWM2_CONFIG_OUT1_PIN 3 192 | #define PWM2_CONFIG_OUT2_PIN 4 193 | #define PWM2_CONFIG_OUT3_PIN 5 194 | #define PWM2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 195 | #define PWM2_CONFIG_BASE_CLOCK NRF_PWM_CLK_1MHz 196 | #define PWM2_CONFIG_COUNT_MODE NRF_PWM_MODE_UP 197 | #define PWM2_CONFIG_TOP_VALUE 1000 198 | #define PWM2_CONFIG_LOAD_MODE NRF_PWM_LOAD_COMMON 199 | #define PWM2_CONFIG_STEP_MODE NRF_PWM_STEP_AUTO 200 | 201 | #define PWM2_INSTANCE_INDEX (PWM0_ENABLED + PWM1_ENABLED) 202 | #endif 203 | 204 | #define PWM_COUNT (PWM0_ENABLED + PWM1_ENABLED + PWM2_ENABLED) 205 | 206 | /* SPI */ 207 | #define SPI0_ENABLED 0 208 | 209 | #if (SPI0_ENABLED == 1) 210 | #define SPI0_USE_EASY_DMA 0 211 | 212 | #define SPI0_CONFIG_SCK_PIN 2 213 | #define SPI0_CONFIG_MOSI_PIN 3 214 | #define SPI0_CONFIG_MISO_PIN 4 215 | #define SPI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 216 | 217 | #define SPI0_INSTANCE_INDEX 0 218 | #endif 219 | 220 | #define SPI1_ENABLED 0 221 | 222 | #if (SPI1_ENABLED == 1) 223 | #define SPI1_USE_EASY_DMA 0 224 | 225 | #define SPI1_CONFIG_SCK_PIN 2 226 | #define SPI1_CONFIG_MOSI_PIN 3 227 | #define SPI1_CONFIG_MISO_PIN 4 228 | #define SPI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 229 | 230 | #define SPI1_INSTANCE_INDEX (SPI0_ENABLED) 231 | #endif 232 | 233 | #define SPI2_ENABLED 0 234 | 235 | #if (SPI2_ENABLED == 1) 236 | #define SPI2_USE_EASY_DMA 0 237 | 238 | #define SPI2_CONFIG_SCK_PIN 2 239 | #define SPI2_CONFIG_MOSI_PIN 3 240 | #define SPI2_CONFIG_MISO_PIN 4 241 | #define SPI2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 242 | 243 | #define SPI2_INSTANCE_INDEX (SPI0_ENABLED + SPI1_ENABLED) 244 | #endif 245 | 246 | #define SPI_COUNT (SPI0_ENABLED + SPI1_ENABLED + SPI2_ENABLED) 247 | 248 | /* SPIS */ 249 | #define SPIS0_ENABLED 0 250 | 251 | #if (SPIS0_ENABLED == 1) 252 | #define SPIS0_CONFIG_SCK_PIN 2 253 | #define SPIS0_CONFIG_MOSI_PIN 3 254 | #define SPIS0_CONFIG_MISO_PIN 4 255 | #define SPIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 256 | 257 | #define SPIS0_INSTANCE_INDEX 0 258 | #endif 259 | 260 | #define SPIS1_ENABLED 0 261 | 262 | #if (SPIS1_ENABLED == 1) 263 | #define SPIS1_CONFIG_SCK_PIN 2 264 | #define SPIS1_CONFIG_MOSI_PIN 3 265 | #define SPIS1_CONFIG_MISO_PIN 4 266 | #define SPIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 267 | 268 | #define SPIS1_INSTANCE_INDEX SPIS0_ENABLED 269 | #endif 270 | 271 | #define SPIS2_ENABLED 0 272 | 273 | #if (SPIS2_ENABLED == 1) 274 | #define SPIS2_CONFIG_SCK_PIN 2 275 | #define SPIS2_CONFIG_MOSI_PIN 3 276 | #define SPIS2_CONFIG_MISO_PIN 4 277 | #define SPIS2_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 278 | 279 | #define SPIS2_INSTANCE_INDEX (SPIS0_ENABLED + SPIS1_ENABLED) 280 | #endif 281 | 282 | #define SPIS_COUNT (SPIS0_ENABLED + SPIS1_ENABLED + SPIS2_ENABLED) 283 | 284 | /* UART */ 285 | #define UART0_ENABLED 1 286 | 287 | #if (UART0_ENABLED == 1) 288 | #define UART0_CONFIG_HWFC NRF_UART_HWFC_DISABLED 289 | #define UART0_CONFIG_PARITY NRF_UART_PARITY_EXCLUDED 290 | #define UART0_CONFIG_BAUDRATE NRF_UART_BAUDRATE_115200 291 | #define UART0_CONFIG_PSEL_TXD 6 292 | #define UART0_CONFIG_PSEL_RXD 8 293 | #define UART0_CONFIG_PSEL_CTS 7 294 | #define UART0_CONFIG_PSEL_RTS 5 295 | #define UART0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 296 | #ifdef NRF52 297 | #define UART0_CONFIG_USE_EASY_DMA false 298 | //Compile time flag 299 | #define UART_EASY_DMA_SUPPORT 1 300 | #define UART_LEGACY_SUPPORT 1 301 | #endif //NRF52 302 | #endif 303 | 304 | #define TWI0_ENABLED 0 305 | 306 | #if (TWI0_ENABLED == 1) 307 | #define TWI0_USE_EASY_DMA 0 308 | 309 | #define TWI0_CONFIG_FREQUENCY NRF_TWI_FREQ_100K 310 | #define TWI0_CONFIG_SCL 0 311 | #define TWI0_CONFIG_SDA 1 312 | #define TWI0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 313 | 314 | #define TWI0_INSTANCE_INDEX 0 315 | #endif 316 | 317 | #define TWI1_ENABLED 0 318 | 319 | #if (TWI1_ENABLED == 1) 320 | #define TWI1_USE_EASY_DMA 0 321 | 322 | #define TWI1_CONFIG_FREQUENCY NRF_TWI_FREQ_100K 323 | #define TWI1_CONFIG_SCL 0 324 | #define TWI1_CONFIG_SDA 1 325 | #define TWI1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 326 | 327 | #define TWI1_INSTANCE_INDEX (TWI0_ENABLED) 328 | #endif 329 | 330 | #define TWI_COUNT (TWI0_ENABLED + TWI1_ENABLED) 331 | 332 | /* TWIS */ 333 | #define TWIS0_ENABLED 0 334 | 335 | #if (TWIS0_ENABLED == 1) 336 | #define TWIS0_CONFIG_ADDR0 0 337 | #define TWIS0_CONFIG_ADDR1 0 /* 0: Disabled */ 338 | #define TWIS0_CONFIG_SCL 0 339 | #define TWIS0_CONFIG_SDA 1 340 | #define TWIS0_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 341 | 342 | #define TWIS0_INSTANCE_INDEX 0 343 | #endif 344 | 345 | #define TWIS1_ENABLED 0 346 | 347 | #if (TWIS1_ENABLED == 1) 348 | #define TWIS1_CONFIG_ADDR0 0 349 | #define TWIS1_CONFIG_ADDR1 0 /* 0: Disabled */ 350 | #define TWIS1_CONFIG_SCL 0 351 | #define TWIS1_CONFIG_SDA 1 352 | #define TWIS1_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 353 | 354 | #define TWIS1_INSTANCE_INDEX (TWIS0_ENABLED) 355 | #endif 356 | 357 | #define TWIS_COUNT (TWIS0_ENABLED + TWIS1_ENABLED) 358 | /* For more documentation see nrf_drv_twis.h file */ 359 | #define TWIS_ASSUME_INIT_AFTER_RESET_ONLY 0 360 | /* For more documentation see nrf_drv_twis.h file */ 361 | #define TWIS_NO_SYNC_MODE 0 362 | 363 | /* QDEC */ 364 | #define QDEC_ENABLED 0 365 | 366 | #if (QDEC_ENABLED == 1) 367 | #define QDEC_CONFIG_REPORTPER NRF_QDEC_REPORTPER_10 368 | #define QDEC_CONFIG_SAMPLEPER NRF_QDEC_SAMPLEPER_16384us 369 | #define QDEC_CONFIG_PIO_A 1 370 | #define QDEC_CONFIG_PIO_B 2 371 | #define QDEC_CONFIG_PIO_LED 3 372 | #define QDEC_CONFIG_LEDPRE 511 373 | #define QDEC_CONFIG_LEDPOL NRF_QDEC_LEPOL_ACTIVE_HIGH 374 | #define QDEC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 375 | #define QDEC_CONFIG_DBFEN false 376 | #define QDEC_CONFIG_SAMPLE_INTEN false 377 | #endif 378 | 379 | /* ADC */ 380 | #define ADC_ENABLED 0 381 | 382 | #if (ADC_ENABLED == 1) 383 | #define ADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 384 | #endif 385 | 386 | 387 | /* SAADC */ 388 | #define SAADC_ENABLED 0 389 | 390 | #if (SAADC_ENABLED == 1) 391 | #define SAADC_CONFIG_RESOLUTION NRF_SAADC_RESOLUTION_10BIT 392 | #define SAADC_CONFIG_OVERSAMPLE NRF_SAADC_OVERSAMPLE_DISABLED 393 | #define SAADC_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 394 | #endif 395 | 396 | /* PDM */ 397 | #define PDM_ENABLED 0 398 | 399 | #if (PDM_ENABLED == 1) 400 | #define PDM_CONFIG_MODE NRF_PDM_MODE_MONO 401 | #define PDM_CONFIG_EDGE NRF_PDM_EDGE_LEFTFALLING 402 | #define PDM_CONFIG_CLOCK_FREQ NRF_PDM_FREQ_1032K 403 | #define PDM_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 404 | #endif 405 | 406 | /* COMP */ 407 | #define COMP_ENABLED 0 408 | 409 | #if (COMP_ENABLED == 1) 410 | #define COMP_CONFIG_REF NRF_COMP_REF_Int1V8 411 | #define COMP_CONFIG_MAIN_MODE NRF_COMP_MAIN_MODE_SE 412 | #define COMP_CONFIG_SPEED_MODE NRF_COMP_SP_MODE_High 413 | #define COMP_CONFIG_HYST NRF_COMP_HYST_NoHyst 414 | #define COMP_CONFIG_ISOURCE NRF_COMP_ISOURCE_Off 415 | #define COMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 416 | #define COMP_CONFIG_INPUT NRF_COMP_INPUT_0 417 | #endif 418 | 419 | /* LPCOMP */ 420 | #define LPCOMP_ENABLED 0 421 | 422 | #if (LPCOMP_ENABLED == 1) 423 | #define LPCOMP_CONFIG_REFERENCE NRF_LPCOMP_REF_SUPPLY_4_8 424 | #define LPCOMP_CONFIG_DETECTION NRF_LPCOMP_DETECT_DOWN 425 | #define LPCOMP_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_LOW 426 | #define LPCOMP_CONFIG_INPUT NRF_LPCOMP_INPUT_0 427 | #endif 428 | 429 | /* WDT */ 430 | #define WDT_ENABLED 0 431 | 432 | #if (WDT_ENABLED == 1) 433 | #define WDT_CONFIG_BEHAVIOUR NRF_WDT_BEHAVIOUR_RUN_SLEEP 434 | #define WDT_CONFIG_RELOAD_VALUE 2000 435 | #define WDT_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH 436 | #endif 437 | 438 | /* SWI EGU */ 439 | #ifdef NRF52 440 | #define EGU_ENABLED 0 441 | #endif 442 | 443 | /* I2S */ 444 | #define I2S_ENABLED 0 445 | 446 | #if (I2S_ENABLED == 1) 447 | #define I2S_CONFIG_SCK_PIN 22 448 | #define I2S_CONFIG_LRCK_PIN 23 449 | #define I2S_CONFIG_MCK_PIN NRF_DRV_I2S_PIN_NOT_USED 450 | #define I2S_CONFIG_SDOUT_PIN 24 451 | #define I2S_CONFIG_SDIN_PIN 25 452 | #define I2S_CONFIG_IRQ_PRIORITY APP_IRQ_PRIORITY_HIGH 453 | #define I2S_CONFIG_MASTER NRF_I2S_MODE_MASTER 454 | #define I2S_CONFIG_FORMAT NRF_I2S_FORMAT_I2S 455 | #define I2S_CONFIG_ALIGN NRF_I2S_ALIGN_LEFT 456 | #define I2S_CONFIG_SWIDTH NRF_I2S_SWIDTH_16BIT 457 | #define I2S_CONFIG_CHANNELS NRF_I2S_CHANNELS_STEREO 458 | #define I2S_CONFIG_MCK_SETUP NRF_I2S_MCK_32MDIV8 459 | #define I2S_CONFIG_RATIO NRF_I2S_RATIO_256X 460 | #endif 461 | 462 | #include "nrf_drv_config_validation.h" 463 | 464 | #endif // NRF_DRV_CONFIG_H 465 | -------------------------------------------------------------------------------- /work/include/pca10036.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | #ifndef PCA10036_H 13 | #define PCA10036_H 14 | 15 | // LEDs definitions for PCA10036 16 | #define LEDS_NUMBER 4 17 | 18 | #define LED_START 17 19 | #define LED_1 17 20 | #define LED_2 18 21 | #define LED_3 19 22 | #define LED_4 20 23 | #define LED_STOP 20 24 | 25 | #define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 } 26 | 27 | #define BSP_LED_0 LED_1 28 | #define BSP_LED_1 LED_2 29 | #define BSP_LED_2 LED_3 30 | #define BSP_LED_3 LED_4 31 | 32 | #define BSP_LED_0_MASK (1< 23 | #include "nrf.h" 24 | 25 | static __INLINE uint16_t pstorage_flash_page_size() 26 | { 27 | return (uint16_t)NRF_FICR->CODEPAGESIZE; 28 | } 29 | 30 | #define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */ 31 | #define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */ 32 | 33 | static __INLINE uint32_t pstorage_flash_page_end() 34 | { 35 | uint32_t bootloader_addr = NRF_UICR->NRFFW[0]; 36 | 37 | return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ? 38 | (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE); 39 | } 40 | 41 | #define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end() 42 | 43 | #define PSTORAGE_NUM_OF_PAGES 1 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */ 44 | #define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation is not have this value to be at least size of word. */ 45 | 46 | #define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES - 1) \ 47 | * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */ 48 | #define PSTORAGE_DATA_END_ADDR ((PSTORAGE_FLASH_PAGE_END - 1) * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */ 49 | #define PSTORAGE_SWAP_ADDR PSTORAGE_DATA_END_ADDR /**< Top-most page is used as swap area for clear and update. */ 50 | 51 | #define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. And should be greater than or equal to the minimum size. */ 52 | #define PSTORAGE_CMD_QUEUE_SIZE 10 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */ 53 | 54 | 55 | /** Abstracts persistently memory block identifier. */ 56 | typedef uint32_t pstorage_block_t; 57 | 58 | typedef struct 59 | { 60 | uint32_t module_id; /**< Module ID.*/ 61 | pstorage_block_t block_id; /**< Block ID.*/ 62 | } pstorage_handle_t; 63 | 64 | typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */ 65 | 66 | /**@brief Handles Flash Access Result Events. To be called in the system event dispatcher of the application. */ 67 | void pstorage_sys_event_handler (uint32_t sys_evt); 68 | 69 | #endif // PSTORAGE_PL_H__ 70 | 71 | /** @} */ 72 | /** @endcond */ 73 | -------------------------------------------------------------------------------- /work/source/bsp.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | #include "bsp.h" 14 | #include 15 | #include 16 | #include "nordic_common.h" 17 | #include "nrf.h" 18 | #include "nrf_gpio.h" 19 | #include "nrf_error.h" 20 | 21 | #ifdef BSP_UART_SUPPORT 22 | #include "nrf_log.h" 23 | #endif // BSP_UART_SUPPORT 24 | 25 | #ifndef BSP_SIMPLE 26 | #include "app_timer.h" 27 | #include "app_button.h" 28 | #endif // BSP_SIMPLE 29 | 30 | #define ADVERTISING_LED_ON_INTERVAL 200 31 | #define ADVERTISING_LED_OFF_INTERVAL 1800 32 | 33 | #define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200 34 | #define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200 35 | 36 | #define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200 37 | #define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800 38 | 39 | #define ADVERTISING_SLOW_LED_ON_INTERVAL 400 40 | #define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000 41 | 42 | #define BONDING_INTERVAL 100 43 | 44 | #define SENT_OK_INTERVAL 100 45 | #define SEND_ERROR_INTERVAL 500 46 | 47 | #define RCV_OK_INTERVAL 100 48 | #define RCV_ERROR_INTERVAL 500 49 | 50 | #define ALERT_INTERVAL 200 51 | 52 | #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 53 | static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE; 54 | static uint32_t m_app_ticks_per_100ms = 0; 55 | static uint32_t m_indication_type = 0; 56 | static uint32_t m_alert_mask = 0; 57 | APP_TIMER_DEF(m_leds_timer_id); 58 | APP_TIMER_DEF(m_alert_timer_id); 59 | #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 60 | 61 | #if BUTTONS_NUMBER > 0 62 | #ifndef BSP_SIMPLE 63 | static bsp_event_callback_t m_registered_callback = NULL; 64 | static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}}; 65 | APP_TIMER_DEF(m_button_timer_id); 66 | static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action); 67 | #endif // BSP_SIMPLE 68 | 69 | static const uint32_t m_buttons_list[BUTTONS_NUMBER] = BUTTONS_LIST; 70 | 71 | #ifndef BSP_SIMPLE 72 | static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] = 73 | { 74 | #ifdef BSP_BUTTON_0 75 | {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler}, 76 | #endif // BUTTON_0 77 | 78 | #ifdef BSP_BUTTON_1 79 | {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler}, 80 | #endif // BUTTON_1 81 | 82 | #ifdef BSP_BUTTON_2 83 | {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler}, 84 | #endif // BUTTON_2 85 | 86 | #ifdef BSP_BUTTON_3 87 | {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler}, 88 | #endif // BUTTON_3 89 | 90 | #ifdef BSP_BUTTON_4 91 | {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler}, 92 | #endif // BUTTON_4 93 | 94 | #ifdef BSP_BUTTON_5 95 | {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler}, 96 | #endif // BUTTON_5 97 | 98 | #ifdef BSP_BUTTON_6 99 | {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler}, 100 | #endif // BUTTON_6 101 | 102 | #ifdef BSP_BUTTON_7 103 | {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler}, 104 | #endif // BUTTON_7 105 | }; 106 | #endif // BSP_SIMPLE 107 | #endif // BUTTONS_NUMBER > 0 108 | 109 | #define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100)) 110 | 111 | #ifdef BSP_LED_2_MASK 112 | #define ALERT_LED_MASK BSP_LED_2_MASK 113 | #else 114 | #define ALERT_LED_MASK BSP_LED_1_MASK 115 | #endif // LED_2_MASK 116 | 117 | uint32_t bsp_buttons_state_get(uint32_t * p_buttons_state) 118 | { 119 | uint32_t result = NRF_SUCCESS; 120 | 121 | *p_buttons_state = 0; 122 | #if BUTTONS_NUMBER > 0 123 | uint32_t buttons = ~NRF_GPIO->IN; 124 | uint32_t cnt; 125 | 126 | for (cnt = 0; cnt < BUTTONS_NUMBER; cnt++) 127 | { 128 | if (buttons & (1 << m_buttons_list[cnt])) 129 | { 130 | *p_buttons_state |= 1 << cnt; 131 | } 132 | } 133 | #endif // BUTTONS_NUMBER > 0 134 | 135 | return result; 136 | } 137 | 138 | 139 | uint32_t bsp_button_is_pressed(uint32_t button, bool * p_state) 140 | { 141 | #if BUTTONS_NUMBER > 0 142 | if(button < BUTTONS_NUMBER) 143 | { 144 | uint32_t buttons = ~NRF_GPIO->IN; 145 | *p_state = (buttons & (1 << m_buttons_list[button])) ? true : false; 146 | } 147 | else 148 | { 149 | *p_state = false; 150 | } 151 | #else 152 | *p_state = false; 153 | #endif // BUTTONS_NUMBER > 0 154 | return NRF_SUCCESS; 155 | } 156 | 157 | 158 | #if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) 159 | /**@brief Function for handling button events. 160 | * 161 | * @param[in] pin_no The pin number of the button pressed. 162 | * @param[in] button_action Action button. 163 | */ 164 | static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action) 165 | { 166 | bsp_event_t event = BSP_EVENT_NOTHING; 167 | uint32_t button = 0; 168 | uint32_t err_code; 169 | static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */ 170 | static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */ 171 | 172 | while ((button < BUTTONS_NUMBER) && (m_buttons_list[button] != pin_no)) 173 | { 174 | button++; 175 | } 176 | 177 | if (button < BUTTONS_NUMBER) 178 | { 179 | switch(button_action) 180 | { 181 | case APP_BUTTON_PUSH: 182 | event = m_events_list[button].push_event; 183 | if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING) 184 | { 185 | err_code = app_timer_start(m_button_timer_id, BSP_MS_TO_TICK(BSP_LONG_PUSH_TIMEOUT_MS), (void*)¤t_long_push_pin_no); 186 | if (err_code == NRF_SUCCESS) 187 | { 188 | current_long_push_pin_no = pin_no; 189 | } 190 | } 191 | release_event_at_push[button] = m_events_list[button].release_event; 192 | break; 193 | case APP_BUTTON_RELEASE: 194 | (void)app_timer_stop(m_button_timer_id); 195 | if (release_event_at_push[button] == m_events_list[button].release_event) 196 | { 197 | event = m_events_list[button].release_event; 198 | } 199 | break; 200 | case BSP_BUTTON_ACTION_LONG_PUSH: 201 | event = m_events_list[button].long_push_event; 202 | } 203 | } 204 | 205 | if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL)) 206 | { 207 | m_registered_callback(event); 208 | } 209 | } 210 | 211 | /**@brief Handle events from button timer. 212 | * 213 | * @param[in] p_context parameter registered in timer start function. 214 | */ 215 | static void button_timer_handler(void * p_context) 216 | { 217 | bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH); 218 | } 219 | 220 | 221 | #endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) 222 | 223 | #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 224 | /**@brief Configure leds to indicate required state. 225 | * @param[in] indicate State to be indicated. 226 | */ 227 | static uint32_t bsp_led_indication(bsp_indication_t indicate) 228 | { 229 | uint32_t err_code = NRF_SUCCESS; 230 | uint32_t next_delay = 0; 231 | 232 | switch (indicate) 233 | { 234 | case BSP_INDICATE_IDLE: 235 | LEDS_OFF(LEDS_MASK & ~m_alert_mask); 236 | m_stable_state = indicate; 237 | break; 238 | 239 | case BSP_INDICATE_SCANNING: 240 | case BSP_INDICATE_ADVERTISING: 241 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 242 | 243 | // in advertising blink LED_0 244 | if (LED_IS_ON(BSP_LED_0_MASK)) 245 | { 246 | LEDS_OFF(BSP_LED_0_MASK); 247 | next_delay = indicate == 248 | BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL : 249 | ADVERTISING_SLOW_LED_OFF_INTERVAL; 250 | } 251 | else 252 | { 253 | LEDS_ON(BSP_LED_0_MASK); 254 | next_delay = indicate == 255 | BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL : 256 | ADVERTISING_SLOW_LED_ON_INTERVAL; 257 | } 258 | 259 | m_stable_state = indicate; 260 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); 261 | break; 262 | 263 | case BSP_INDICATE_ADVERTISING_WHITELIST: 264 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 265 | 266 | // in advertising quickly blink LED_0 267 | if (LED_IS_ON(BSP_LED_0_MASK)) 268 | { 269 | LEDS_OFF(BSP_LED_0_MASK); 270 | next_delay = indicate == 271 | BSP_INDICATE_ADVERTISING_WHITELIST ? 272 | ADVERTISING_WHITELIST_LED_OFF_INTERVAL : 273 | ADVERTISING_SLOW_LED_OFF_INTERVAL; 274 | } 275 | else 276 | { 277 | LEDS_ON(BSP_LED_0_MASK); 278 | next_delay = indicate == 279 | BSP_INDICATE_ADVERTISING_WHITELIST ? 280 | ADVERTISING_WHITELIST_LED_ON_INTERVAL : 281 | ADVERTISING_SLOW_LED_ON_INTERVAL; 282 | } 283 | m_stable_state = indicate; 284 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); 285 | break; 286 | 287 | case BSP_INDICATE_ADVERTISING_SLOW: 288 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 289 | 290 | // in advertising slowly blink LED_0 291 | if (LED_IS_ON(BSP_LED_0_MASK)) 292 | { 293 | LEDS_OFF(BSP_LED_0_MASK); 294 | next_delay = indicate == 295 | BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL : 296 | ADVERTISING_SLOW_LED_OFF_INTERVAL; 297 | } 298 | else 299 | { 300 | LEDS_ON(BSP_LED_0_MASK); 301 | next_delay = indicate == 302 | BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL : 303 | ADVERTISING_SLOW_LED_ON_INTERVAL; 304 | } 305 | m_stable_state = indicate; 306 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); 307 | break; 308 | 309 | case BSP_INDICATE_ADVERTISING_DIRECTED: 310 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 311 | 312 | // in advertising very quickly blink LED_0 313 | if (LED_IS_ON(BSP_LED_0_MASK)) 314 | { 315 | LEDS_OFF(BSP_LED_0_MASK); 316 | next_delay = indicate == 317 | BSP_INDICATE_ADVERTISING_DIRECTED ? 318 | ADVERTISING_DIRECTED_LED_OFF_INTERVAL : 319 | ADVERTISING_SLOW_LED_OFF_INTERVAL; 320 | } 321 | else 322 | { 323 | LEDS_ON(BSP_LED_0_MASK); 324 | next_delay = indicate == 325 | BSP_INDICATE_ADVERTISING_DIRECTED ? 326 | ADVERTISING_DIRECTED_LED_ON_INTERVAL : 327 | ADVERTISING_SLOW_LED_ON_INTERVAL; 328 | } 329 | m_stable_state = indicate; 330 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(next_delay), NULL); 331 | break; 332 | 333 | case BSP_INDICATE_BONDING: 334 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 335 | 336 | // in bonding fast blink LED_0 337 | if (LED_IS_ON(BSP_LED_0_MASK)) 338 | { 339 | LEDS_OFF(BSP_LED_0_MASK); 340 | } 341 | else 342 | { 343 | LEDS_ON(BSP_LED_0_MASK); 344 | } 345 | 346 | m_stable_state = indicate; 347 | err_code = 348 | app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(BONDING_INTERVAL), NULL); 349 | break; 350 | 351 | case BSP_INDICATE_CONNECTED: 352 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK & ~m_alert_mask); 353 | LEDS_ON(BSP_LED_0_MASK); 354 | m_stable_state = indicate; 355 | break; 356 | 357 | case BSP_INDICATE_SENT_OK: 358 | // when sending shortly invert LED_1 359 | LEDS_INVERT(BSP_LED_1_MASK); 360 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(SENT_OK_INTERVAL), NULL); 361 | break; 362 | 363 | case BSP_INDICATE_SEND_ERROR: 364 | // on receving error invert LED_1 for long time 365 | LEDS_INVERT(BSP_LED_1_MASK); 366 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(SEND_ERROR_INTERVAL), NULL); 367 | break; 368 | 369 | case BSP_INDICATE_RCV_OK: 370 | // when receving shortly invert LED_1 371 | LEDS_INVERT(BSP_LED_1_MASK); 372 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(RCV_OK_INTERVAL), NULL); 373 | break; 374 | 375 | case BSP_INDICATE_RCV_ERROR: 376 | // on receving error invert LED_1 for long time 377 | LEDS_INVERT(BSP_LED_1_MASK); 378 | err_code = app_timer_start(m_leds_timer_id, BSP_MS_TO_TICK(RCV_ERROR_INTERVAL), NULL); 379 | break; 380 | 381 | case BSP_INDICATE_FATAL_ERROR: 382 | // on fatal error turn on all leds 383 | LEDS_ON(LEDS_MASK); 384 | m_stable_state = indicate; 385 | break; 386 | 387 | case BSP_INDICATE_ALERT_0: 388 | case BSP_INDICATE_ALERT_1: 389 | case BSP_INDICATE_ALERT_2: 390 | case BSP_INDICATE_ALERT_3: 391 | case BSP_INDICATE_ALERT_OFF: 392 | err_code = app_timer_stop(m_alert_timer_id); 393 | next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate; 394 | 395 | // a little trick to find out that if it did not fall through ALERT_OFF 396 | if (next_delay && (err_code == NRF_SUCCESS)) 397 | { 398 | m_alert_mask = ALERT_LED_MASK; 399 | if (next_delay > 1) 400 | { 401 | err_code = app_timer_start(m_alert_timer_id, BSP_MS_TO_TICK( 402 | (next_delay * ALERT_INTERVAL)), NULL); 403 | } 404 | LEDS_ON(m_alert_mask); 405 | } 406 | else 407 | { 408 | LEDS_OFF(m_alert_mask); 409 | m_alert_mask = 0; 410 | } 411 | break; 412 | 413 | case BSP_INDICATE_USER_STATE_OFF: 414 | LEDS_OFF(LEDS_MASK); 415 | m_stable_state = indicate; 416 | break; 417 | 418 | case BSP_INDICATE_USER_STATE_0: 419 | LEDS_OFF(LEDS_MASK & ~BSP_LED_0_MASK); 420 | LEDS_ON(BSP_LED_0_MASK); 421 | m_stable_state = indicate; 422 | break; 423 | 424 | case BSP_INDICATE_USER_STATE_1: 425 | LEDS_OFF(LEDS_MASK & ~BSP_LED_1_MASK); 426 | LEDS_ON(BSP_LED_1_MASK); 427 | m_stable_state = indicate; 428 | break; 429 | 430 | case BSP_INDICATE_USER_STATE_2: 431 | LEDS_OFF(LEDS_MASK & ~(BSP_LED_0_MASK | BSP_LED_1_MASK)); 432 | LEDS_ON(BSP_LED_0_MASK | BSP_LED_1_MASK); 433 | m_stable_state = indicate; 434 | break; 435 | 436 | case BSP_INDICATE_USER_STATE_3: 437 | 438 | case BSP_INDICATE_USER_STATE_ON: 439 | LEDS_ON(LEDS_MASK); 440 | m_stable_state = indicate; 441 | break; 442 | 443 | default: 444 | break; 445 | } 446 | 447 | return err_code; 448 | } 449 | 450 | 451 | /**@brief Handle events from leds timer. 452 | * 453 | * @note Timer handler does not support returning an error code. 454 | * Errors from bsp_led_indication() are not propagated. 455 | * 456 | * @param[in] p_context parameter registered in timer start function. 457 | */ 458 | static void leds_timer_handler(void * p_context) 459 | { 460 | UNUSED_PARAMETER(p_context); 461 | 462 | if (m_indication_type & BSP_INIT_LED) 463 | { 464 | UNUSED_VARIABLE(bsp_led_indication(m_stable_state)); 465 | } 466 | } 467 | 468 | 469 | /**@brief Handle events from alert timer. 470 | * 471 | * @param[in] p_context parameter registered in timer start function. 472 | */ 473 | static void alert_timer_handler(void * p_context) 474 | { 475 | UNUSED_PARAMETER(p_context); 476 | LEDS_INVERT(ALERT_LED_MASK); 477 | } 478 | #endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 479 | 480 | 481 | /**@brief Configure indicators to required state. 482 | */ 483 | uint32_t bsp_indication_set(bsp_indication_t indicate) 484 | { 485 | uint32_t err_code = NRF_SUCCESS; 486 | 487 | #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 488 | 489 | if (m_indication_type & BSP_INIT_LED) 490 | { 491 | err_code = bsp_led_indication(indicate); 492 | } 493 | 494 | #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 495 | return err_code; 496 | } 497 | 498 | 499 | uint32_t bsp_indication_text_set(bsp_indication_t indicate, char const * p_text) 500 | { 501 | uint32_t err_code = bsp_indication_set(indicate); 502 | 503 | #ifdef BSP_UART_SUPPORT 504 | NRF_LOG_PRINTF("%s", p_text); 505 | #endif // BSP_UART_SUPPORT 506 | 507 | return err_code; 508 | } 509 | 510 | 511 | uint32_t bsp_init(uint32_t type, uint32_t ticks_per_100ms, bsp_event_callback_t callback) 512 | { 513 | uint32_t err_code = NRF_SUCCESS; 514 | 515 | #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 516 | m_app_ticks_per_100ms = ticks_per_100ms; 517 | m_indication_type = type; 518 | #else 519 | UNUSED_VARIABLE(ticks_per_100ms); 520 | #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 521 | 522 | #if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) 523 | m_registered_callback = callback; 524 | 525 | // BSP will support buttons and generate events 526 | if (type & BSP_INIT_BUTTONS) 527 | { 528 | uint32_t num; 529 | 530 | for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++) 531 | { 532 | err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT); 533 | } 534 | 535 | if (err_code == NRF_SUCCESS) 536 | { 537 | err_code = app_button_init((app_button_cfg_t *)app_buttons, 538 | BUTTONS_NUMBER, 539 | ticks_per_100ms / 2); 540 | } 541 | 542 | if (err_code == NRF_SUCCESS) 543 | { 544 | err_code = app_button_enable(); 545 | } 546 | 547 | if (err_code == NRF_SUCCESS) 548 | { 549 | err_code = app_timer_create(&m_button_timer_id, 550 | APP_TIMER_MODE_SINGLE_SHOT, 551 | button_timer_handler); 552 | } 553 | } 554 | #elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE) 555 | 556 | if (type & BSP_INIT_BUTTONS) 557 | { 558 | uint32_t cnt; 559 | uint32_t buttons[] = BUTTONS_LIST; 560 | 561 | for (cnt = 0; cnt < BUTTONS_NUMBER; cnt++) 562 | { 563 | nrf_gpio_cfg_input(buttons[cnt], BUTTON_PULL); 564 | } 565 | } 566 | #endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE) 567 | 568 | #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 569 | 570 | if (type & BSP_INIT_LED) 571 | { 572 | LEDS_OFF(LEDS_MASK); 573 | NRF_GPIO->DIRSET = LEDS_MASK; 574 | } 575 | 576 | // timers module must be already initialized! 577 | if (err_code == NRF_SUCCESS) 578 | { 579 | err_code = 580 | app_timer_create(&m_leds_timer_id, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler); 581 | } 582 | 583 | if (err_code == NRF_SUCCESS) 584 | { 585 | err_code = 586 | app_timer_create(&m_alert_timer_id, APP_TIMER_MODE_REPEATED, alert_timer_handler); 587 | } 588 | #endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE) 589 | 590 | return err_code; 591 | } 592 | 593 | 594 | #ifndef BSP_SIMPLE 595 | /**@brief Assign specific event to button. 596 | */ 597 | uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event) 598 | { 599 | uint32_t err_code = NRF_SUCCESS; 600 | 601 | #if BUTTONS_NUMBER > 0 602 | if (button < BUTTONS_NUMBER) 603 | { 604 | if (event == BSP_EVENT_DEFAULT) 605 | { 606 | // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions. 607 | event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING; 608 | } 609 | switch (action) 610 | { 611 | case BSP_BUTTON_ACTION_PUSH: 612 | m_events_list[button].push_event = event; 613 | break; 614 | case BSP_BUTTON_ACTION_LONG_PUSH: 615 | m_events_list[button].long_push_event = event; 616 | break; 617 | case BSP_BUTTON_ACTION_RELEASE: 618 | m_events_list[button].release_event = event; 619 | break; 620 | default: 621 | err_code = NRF_ERROR_INVALID_PARAM; 622 | break; 623 | } 624 | } 625 | else 626 | { 627 | err_code = NRF_ERROR_INVALID_PARAM; 628 | } 629 | #else 630 | err_code = NRF_ERROR_INVALID_PARAM; 631 | #endif // BUTTONS_NUMBER > 0 632 | 633 | return err_code; 634 | } 635 | 636 | #endif // BSP_SIMPLE 637 | 638 | 639 | uint32_t bsp_buttons_enable() 640 | { 641 | #if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) 642 | return app_button_enable(); 643 | #else 644 | return NRF_ERROR_NOT_SUPPORTED; 645 | #endif 646 | } 647 | 648 | uint32_t bsp_buttons_disable() 649 | { 650 | #if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) 651 | return app_button_disable(); 652 | #else 653 | return NRF_ERROR_NOT_SUPPORTED; 654 | #endif 655 | } 656 | 657 | uint32_t bsp_wakeup_buttons_set(uint32_t wakeup_buttons) 658 | { 659 | #if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE) 660 | for (uint32_t i = 0; i < BUTTONS_NUMBER; i++) 661 | { 662 | uint32_t new_cnf = NRF_GPIO->PIN_CNF[m_buttons_list[i]]; 663 | uint32_t new_sense = ((1 << i) & wakeup_buttons) ? GPIO_PIN_CNF_SENSE_Low : GPIO_PIN_CNF_SENSE_Disabled; 664 | new_cnf &= ~GPIO_PIN_CNF_SENSE_Msk; 665 | new_cnf |= (new_sense << GPIO_PIN_CNF_SENSE_Pos); 666 | NRF_GPIO->PIN_CNF[m_buttons_list[i]] = new_cnf; 667 | } 668 | return NRF_SUCCESS; 669 | #else 670 | return NRF_ERROR_NOT_SUPPORTED; 671 | #endif 672 | } 673 | -------------------------------------------------------------------------------- /work/source/bsp_btn_ble.c: -------------------------------------------------------------------------------- 1 | 2 | 3 | #include "bsp_btn_ble.h" 4 | #include 5 | #include 6 | #include 7 | #include "ble.h" 8 | #include "bsp.h" 9 | 10 | 11 | #define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */ 12 | #define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */ 13 | #define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */ 14 | #define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */ 15 | #define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */ 16 | 17 | #define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */ 18 | #define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */ 19 | #define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */ 20 | 21 | 22 | 23 | /**@brief This macro will return from the current function if err_code 24 | * is not NRF_SUCCESS. 25 | */ 26 | #define RETURN_ON_ERROR(err_code) \ 27 | do \ 28 | { \ 29 | if ((err_code) != NRF_SUCCESS) \ 30 | { \ 31 | return err_code; \ 32 | } \ 33 | } \ 34 | while(0) 35 | 36 | 37 | /**@brief This macro will return from the current function if err_code 38 | * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM. 39 | */ 40 | #define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \ 41 | do \ 42 | { \ 43 | if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \ 44 | { \ 45 | return err_code; \ 46 | } \ 47 | } \ 48 | while(0) 49 | 50 | 51 | /**@brief This macro will return from the current function if err_code 52 | * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED. 53 | */ 54 | #define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \ 55 | do \ 56 | { \ 57 | if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \ 58 | { \ 59 | return err_code; \ 60 | } \ 61 | } \ 62 | while(0) 63 | 64 | 65 | /**@brief This macro will call the registered error handler if err_code 66 | * is not NRF_SUCCESS and the error handler is not NULL. 67 | */ 68 | #define CALL_HANDLER_ON_ERROR(err_code) \ 69 | do \ 70 | { \ 71 | if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \ 72 | { \ 73 | m_error_handler(err_code); \ 74 | } \ 75 | } \ 76 | while(0) 77 | 78 | 79 | static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */ 80 | static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */ 81 | 82 | 83 | /**@brief Function for configuring the buttons for connection. 84 | * 85 | * @retval NRF_SUCCESS Configured successfully. 86 | * @return A propagated error code. 87 | */ 88 | static uint32_t connection_buttons_configure() 89 | { 90 | uint32_t err_code; 91 | 92 | err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, 93 | BTN_ACTION_SLEEP, 94 | BSP_EVENT_DEFAULT); 95 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 96 | 97 | err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, 98 | BTN_ACTION_WHITELIST_OFF, 99 | BSP_EVENT_WHITELIST_OFF); 100 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 101 | 102 | err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, 103 | BTN_ACTION_DISCONNECT, 104 | BSP_EVENT_DISCONNECT); 105 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 106 | 107 | return NRF_SUCCESS; 108 | } 109 | 110 | 111 | /**@brief Function for configuring the buttons for advertisement. 112 | * 113 | * @retval NRF_SUCCESS Configured successfully. 114 | * @return A propagated error code. 115 | */ 116 | static uint32_t advertising_buttons_configure() 117 | { 118 | uint32_t err_code; 119 | 120 | err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT, 121 | BTN_ACTION_DISCONNECT, 122 | BSP_EVENT_DEFAULT); 123 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 124 | 125 | err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF, 126 | BTN_ACTION_WHITELIST_OFF, 127 | BSP_EVENT_WHITELIST_OFF); 128 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 129 | 130 | err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP, 131 | BTN_ACTION_SLEEP, 132 | BSP_EVENT_SLEEP); 133 | RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code); 134 | 135 | return NRF_SUCCESS; 136 | } 137 | 138 | 139 | /**@brief Function for extracting the BSP event valid at startup. 140 | * 141 | * @details When a button was used to wake up the device, the button press will not generate an 142 | * interrupt. This function reads which button was pressed at startup, and returns the 143 | * appropriate BSP event. 144 | * 145 | * @param[out] p_startup_event Where to put the extracted BSP event. 146 | * 147 | * @retval NRF_SUCCESS Extraction was successful. 148 | * @return A propagated error code. 149 | */ 150 | static uint32_t startup_event_extract(bsp_event_t * p_startup_event) 151 | { 152 | uint32_t err_code; 153 | bool wakeup_button_is_pressed, bond_erase_button_is_pressed; 154 | 155 | // Read buttons 156 | err_code = bsp_button_is_pressed(BTN_ID_WAKEUP, &wakeup_button_is_pressed); 157 | RETURN_ON_ERROR(err_code); 158 | 159 | err_code = bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE, &bond_erase_button_is_pressed); 160 | RETURN_ON_ERROR(err_code); 161 | 162 | // React to button states 163 | if (bond_erase_button_is_pressed) 164 | { 165 | *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA; 166 | } 167 | else if (wakeup_button_is_pressed) 168 | { 169 | *p_startup_event = BSP_EVENT_WAKEUP; 170 | } 171 | else 172 | { 173 | *p_startup_event = BSP_EVENT_NOTHING; 174 | } 175 | 176 | return NRF_SUCCESS; 177 | } 178 | 179 | 180 | uint32_t bsp_btn_ble_sleep_mode_prepare(void) 181 | { 182 | uint32_t err_code = bsp_wakeup_buttons_set((1 << BTN_ID_WAKEUP) | (1 << BTN_ID_WAKEUP_BOND_DELETE)); 183 | 184 | RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code); 185 | 186 | return NRF_SUCCESS; 187 | } 188 | 189 | 190 | void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt) 191 | { 192 | uint32_t err_code; 193 | 194 | switch (p_ble_evt->header.evt_id) 195 | { 196 | case BLE_GAP_EVT_CONNECTED: 197 | if (m_num_connections == 0) 198 | { 199 | err_code = connection_buttons_configure(); 200 | CALL_HANDLER_ON_ERROR(err_code); 201 | } 202 | 203 | m_num_connections++; 204 | break; 205 | 206 | case BLE_GAP_EVT_DISCONNECTED: 207 | m_num_connections--; 208 | 209 | if (m_num_connections == 0) 210 | { 211 | err_code = advertising_buttons_configure(); 212 | CALL_HANDLER_ON_ERROR(err_code); 213 | } 214 | break; 215 | 216 | default: 217 | break; 218 | } 219 | } 220 | 221 | 222 | uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt) 223 | { 224 | uint32_t err_code = NRF_SUCCESS; 225 | 226 | m_error_handler = error_handler; 227 | 228 | if (p_startup_bsp_evt != NULL) 229 | { 230 | err_code = startup_event_extract(p_startup_bsp_evt); 231 | RETURN_ON_ERROR(err_code); 232 | } 233 | 234 | if (m_num_connections == 0) 235 | { 236 | err_code = advertising_buttons_configure(); 237 | } 238 | 239 | return err_code; 240 | } 241 | -------------------------------------------------------------------------------- /work/source/bsp_btn_ble.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | /**@file 14 | * 15 | * @defgroup bsp_btn_ble BSP: BLE Button Module 16 | * @{ 17 | * @ingroup bsp 18 | * 19 | * @brief Module for controlling BLE behavior through button actions. 20 | * 21 | * @details The application must propagate BLE events to the BLE Button Module. 22 | * Based on these events, the BLE Button Module configures the Board Support Package 23 | * to generate BSP events for certain button actions. These BSP events should then be 24 | * handled by the application's BSP event handler. 25 | * 26 | */ 27 | 28 | #ifndef BSP_BTN_BLE_H__ 29 | #define BSP_BTN_BLE_H__ 30 | 31 | #include 32 | #include "ble.h" 33 | #include "bsp.h" 34 | 35 | /**@brief BLE Button Module error handler type. */ 36 | typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error); 37 | 38 | /**@brief Function for initializing the BLE Button Module. 39 | * 40 | * Before calling this function, the BSP module must be initialized with buttons. 41 | * 42 | * @param[out] error_handler Error handler to call in case of internal errors in BLE Button 43 | * Module. 44 | * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event 45 | * (or BSP_EVENT_NOTHING) derived from the buttons pressed on 46 | * startup. For example, if the bond delete wakeup button was pressed 47 | * to wake up the device, *p_startup_bsp_evt is set to 48 | * @ref BSP_EVENT_CLEAR_BONDING_DATA. 49 | * 50 | * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is 51 | * returned. 52 | */ 53 | uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt); 54 | 55 | /**@brief Function for setting up wakeup buttons before going into sleep mode. 56 | * 57 | * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error 58 | * code is returned. 59 | */ 60 | uint32_t bsp_btn_ble_sleep_mode_prepare(void); 61 | 62 | /**@brief Function for handling the application's BLE stack events. 63 | * 64 | * @details This function handles all events from the BLE stack that are of interest to this module. 65 | * 66 | * @param[in] p_ble_evt BLE stack event. 67 | */ 68 | void bsp_btn_ble_on_ble_evt(ble_evt_t * p_ble_evt); 69 | 70 | #endif /* BSP_BTN_BLE_H__ */ 71 | 72 | /** @} */ 73 | -------------------------------------------------------------------------------- /work/source/main.c: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved. 2 | * 3 | * The information contained herein is property of Nordic Semiconductor ASA. 4 | * Terms and conditions of usage are described in detail in NORDIC 5 | * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT. 6 | * 7 | * Licensees are granted free, non-transferable use of the information. NO 8 | * WARRANTY of ANY KIND is provided. This heading must NOT be removed from 9 | * the file. 10 | * 11 | */ 12 | 13 | /** @file 14 | * 15 | * @defgroup ble_sdk_uart_over_ble_main main.c 16 | * @{ 17 | * @ingroup ble_sdk_app_nus_eval 18 | * @brief UART over BLE application main file. 19 | * 20 | * This file contains the source code for a sample application that uses the Nordic UART service. 21 | * This application uses the @ref srvlib_conn_params module. 22 | */ 23 | 24 | #include 25 | #include 26 | #include "nordic_common.h" 27 | #include "nrf.h" 28 | #include "ble_hci.h" 29 | #include "ble_advdata.h" 30 | #include "ble_advertising.h" 31 | #include "ble_conn_params.h" 32 | #include "softdevice_handler.h" 33 | #include "app_timer.h" 34 | #include "app_button.h" 35 | #include "ble_nus.h" 36 | #include "app_uart.h" 37 | #include "app_util_platform.h" 38 | #include "bsp.h" 39 | #include "bsp_btn_ble.h" 40 | 41 | #define IS_SRVC_CHANGED_CHARACT_PRESENT 0 /**< Include the service_changed characteristic. If not enabled, the server's database cannot be changed for the lifetime of the device. */ 42 | 43 | #if (NRF_SD_BLE_API_VERSION == 3) 44 | #define NRF_BLE_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */ 45 | #endif 46 | 47 | #define APP_FEATURE_NOT_SUPPORTED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< Reply when unsupported features are requested. */ 48 | 49 | #define CENTRAL_LINK_COUNT 0 /**< Number of central links used by the application. When changing this number remember to adjust the RAM settings*/ 50 | #define PERIPHERAL_LINK_COUNT 1 /**< Number of peripheral links used by the application. When changing this number remember to adjust the RAM settings*/ 51 | 52 | #define DEVICE_NAME "Nordic_UART" /**< Name of device. Will be included in the advertising data. */ 53 | #define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */ 54 | 55 | #define APP_ADV_INTERVAL 64 /**< The advertising interval (in units of 0.625 ms. This value corresponds to 40 ms). */ 56 | #define APP_ADV_TIMEOUT_IN_SECONDS 180 /**< The advertising timeout (in units of seconds). */ 57 | 58 | #define APP_TIMER_PRESCALER 0 /**< Value of the RTC1 PRESCALER register. */ 59 | #define APP_TIMER_OP_QUEUE_SIZE 4 /**< Size of timer operation queues. */ 60 | 61 | #define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */ 62 | #define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */ 63 | #define SLAVE_LATENCY 0 /**< Slave latency. */ 64 | #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory timeout (4 seconds), Supervision Timeout uses 10 ms units. */ 65 | #define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */ 66 | #define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(30000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */ 67 | #define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */ 68 | 69 | #define DEAD_BEEF 0xDEADBEEF /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */ 70 | 71 | #define UART_TX_BUF_SIZE 256 /**< UART TX buffer size. */ 72 | #define UART_RX_BUF_SIZE 256 /**< UART RX buffer size. */ 73 | 74 | static ble_nus_t m_nus; /**< Structure to identify the Nordic UART Service. */ 75 | static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */ 76 | 77 | static ble_uuid_t m_adv_uuids[] = {{BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}}; /**< Universally unique service identifier. */ 78 | 79 | 80 | /**@brief Function for assert macro callback. 81 | * 82 | * @details This function will be called in case of an assert in the SoftDevice. 83 | * 84 | * @warning This handler is an example only and does not fit a final product. You need to analyse 85 | * how your product is supposed to react in case of Assert. 86 | * @warning On assert from the SoftDevice, the system can only recover on reset. 87 | * 88 | * @param[in] line_num Line number of the failing ASSERT call. 89 | * @param[in] p_file_name File name of the failing ASSERT call. 90 | */ 91 | void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name) 92 | { 93 | app_error_handler(DEAD_BEEF, line_num, p_file_name); 94 | } 95 | 96 | 97 | /**@brief Function for the GAP initialization. 98 | * 99 | * @details This function will set up all the necessary GAP (Generic Access Profile) parameters of 100 | * the device. It also sets the permissions and appearance. 101 | */ 102 | static void gap_params_init(void) 103 | { 104 | uint32_t err_code; 105 | ble_gap_conn_params_t gap_conn_params; 106 | ble_gap_conn_sec_mode_t sec_mode; 107 | 108 | BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); 109 | 110 | err_code = sd_ble_gap_device_name_set(&sec_mode, 111 | (const uint8_t *) DEVICE_NAME, 112 | strlen(DEVICE_NAME)); 113 | APP_ERROR_CHECK(err_code); 114 | 115 | memset(&gap_conn_params, 0, sizeof(gap_conn_params)); 116 | 117 | gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL; 118 | gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL; 119 | gap_conn_params.slave_latency = SLAVE_LATENCY; 120 | gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT; 121 | 122 | err_code = sd_ble_gap_ppcp_set(&gap_conn_params); 123 | APP_ERROR_CHECK(err_code); 124 | } 125 | 126 | 127 | /**@brief Function for handling the data from the Nordic UART Service. 128 | * 129 | * @details This function will process the data received from the Nordic UART BLE Service and send 130 | * it to the UART module. 131 | * 132 | * @param[in] p_nus Nordic UART Service structure. 133 | * @param[in] p_data Data to be send to UART module. 134 | * @param[in] length Length of the data. 135 | */ 136 | /**@snippet [Handling the data received over BLE] */ 137 | static void nus_data_handler(ble_nus_t * p_nus, uint8_t * p_data, uint16_t length) 138 | { 139 | for (uint32_t i = 0; i < length; i++) 140 | { 141 | while (app_uart_put(p_data[i]) != NRF_SUCCESS); 142 | } 143 | while (app_uart_put('\r') != NRF_SUCCESS); 144 | while (app_uart_put('\n') != NRF_SUCCESS); 145 | } 146 | /**@snippet [Handling the data received over BLE] */ 147 | 148 | 149 | /**@brief Function for initializing services that will be used by the application. 150 | */ 151 | static void services_init(void) 152 | { 153 | uint32_t err_code; 154 | ble_nus_init_t nus_init; 155 | 156 | memset(&nus_init, 0, sizeof(nus_init)); 157 | 158 | nus_init.data_handler = nus_data_handler; 159 | 160 | err_code = ble_nus_init(&m_nus, &nus_init); 161 | APP_ERROR_CHECK(err_code); 162 | } 163 | 164 | 165 | /**@brief Function for handling an event from the Connection Parameters Module. 166 | * 167 | * @details This function will be called for all events in the Connection Parameters Module 168 | * which are passed to the application. 169 | * 170 | * @note All this function does is to disconnect. This could have been done by simply setting 171 | * the disconnect_on_fail config parameter, but instead we use the event handler 172 | * mechanism to demonstrate its use. 173 | * 174 | * @param[in] p_evt Event received from the Connection Parameters Module. 175 | */ 176 | static void on_conn_params_evt(ble_conn_params_evt_t * p_evt) 177 | { 178 | uint32_t err_code; 179 | 180 | if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) 181 | { 182 | err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE); 183 | APP_ERROR_CHECK(err_code); 184 | } 185 | } 186 | 187 | 188 | /**@brief Function for handling errors from the Connection Parameters module. 189 | * 190 | * @param[in] nrf_error Error code containing information about what went wrong. 191 | */ 192 | static void conn_params_error_handler(uint32_t nrf_error) 193 | { 194 | APP_ERROR_HANDLER(nrf_error); 195 | } 196 | 197 | 198 | /**@brief Function for initializing the Connection Parameters module. 199 | */ 200 | static void conn_params_init(void) 201 | { 202 | uint32_t err_code; 203 | ble_conn_params_init_t cp_init; 204 | 205 | memset(&cp_init, 0, sizeof(cp_init)); 206 | 207 | cp_init.p_conn_params = NULL; 208 | cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY; 209 | cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY; 210 | cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT; 211 | cp_init.start_on_notify_cccd_handle = BLE_GATT_HANDLE_INVALID; 212 | cp_init.disconnect_on_fail = false; 213 | cp_init.evt_handler = on_conn_params_evt; 214 | cp_init.error_handler = conn_params_error_handler; 215 | 216 | err_code = ble_conn_params_init(&cp_init); 217 | APP_ERROR_CHECK(err_code); 218 | } 219 | 220 | 221 | /**@brief Function for putting the chip into sleep mode. 222 | * 223 | * @note This function will not return. 224 | */ 225 | static void sleep_mode_enter(void) 226 | { 227 | uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE); 228 | APP_ERROR_CHECK(err_code); 229 | 230 | // Prepare wakeup buttons. 231 | err_code = bsp_btn_ble_sleep_mode_prepare(); 232 | APP_ERROR_CHECK(err_code); 233 | 234 | // Go to system-off mode (this function will not return; wakeup will cause a reset). 235 | err_code = sd_power_system_off(); 236 | APP_ERROR_CHECK(err_code); 237 | } 238 | 239 | 240 | /**@brief Function for handling advertising events. 241 | * 242 | * @details This function will be called for advertising events which are passed to the application. 243 | * 244 | * @param[in] ble_adv_evt Advertising event. 245 | */ 246 | static void on_adv_evt(ble_adv_evt_t ble_adv_evt) 247 | { 248 | uint32_t err_code; 249 | 250 | switch (ble_adv_evt) 251 | { 252 | case BLE_ADV_EVT_FAST: 253 | err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING); 254 | APP_ERROR_CHECK(err_code); 255 | break; 256 | case BLE_ADV_EVT_IDLE: 257 | sleep_mode_enter(); 258 | break; 259 | default: 260 | break; 261 | } 262 | } 263 | 264 | 265 | /**@brief Function for the application's SoftDevice event handler. 266 | * 267 | * @param[in] p_ble_evt SoftDevice event. 268 | */ 269 | static void on_ble_evt(ble_evt_t * p_ble_evt) 270 | { 271 | uint32_t err_code; 272 | 273 | switch (p_ble_evt->header.evt_id) 274 | { 275 | case BLE_GAP_EVT_CONNECTED: 276 | err_code = bsp_indication_set(BSP_INDICATE_CONNECTED); 277 | APP_ERROR_CHECK(err_code); 278 | m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle; 279 | break; // BLE_GAP_EVT_CONNECTED 280 | 281 | case BLE_GAP_EVT_DISCONNECTED: 282 | err_code = bsp_indication_set(BSP_INDICATE_IDLE); 283 | APP_ERROR_CHECK(err_code); 284 | m_conn_handle = BLE_CONN_HANDLE_INVALID; 285 | break; // BLE_GAP_EVT_DISCONNECTED 286 | 287 | case BLE_GAP_EVT_SEC_PARAMS_REQUEST: 288 | // Pairing not supported 289 | err_code = sd_ble_gap_sec_params_reply(m_conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL); 290 | APP_ERROR_CHECK(err_code); 291 | break; // BLE_GAP_EVT_SEC_PARAMS_REQUEST 292 | 293 | case BLE_GATTS_EVT_SYS_ATTR_MISSING: 294 | // No system attributes have been stored. 295 | err_code = sd_ble_gatts_sys_attr_set(m_conn_handle, NULL, 0, 0); 296 | APP_ERROR_CHECK(err_code); 297 | break; // BLE_GATTS_EVT_SYS_ATTR_MISSING 298 | 299 | case BLE_GATTC_EVT_TIMEOUT: 300 | // Disconnect on GATT Client timeout event. 301 | err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle, 302 | BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); 303 | APP_ERROR_CHECK(err_code); 304 | break; // BLE_GATTC_EVT_TIMEOUT 305 | 306 | case BLE_GATTS_EVT_TIMEOUT: 307 | // Disconnect on GATT Server timeout event. 308 | err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle, 309 | BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); 310 | APP_ERROR_CHECK(err_code); 311 | break; // BLE_GATTS_EVT_TIMEOUT 312 | 313 | case BLE_EVT_USER_MEM_REQUEST: 314 | err_code = sd_ble_user_mem_reply(p_ble_evt->evt.gattc_evt.conn_handle, NULL); 315 | APP_ERROR_CHECK(err_code); 316 | break; // BLE_EVT_USER_MEM_REQUEST 317 | 318 | case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: 319 | { 320 | ble_gatts_evt_rw_authorize_request_t req; 321 | ble_gatts_rw_authorize_reply_params_t auth_reply; 322 | 323 | req = p_ble_evt->evt.gatts_evt.params.authorize_request; 324 | 325 | if (req.type != BLE_GATTS_AUTHORIZE_TYPE_INVALID) 326 | { 327 | if ((req.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ) || 328 | (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) || 329 | (req.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)) 330 | { 331 | if (req.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) 332 | { 333 | auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE; 334 | } 335 | else 336 | { 337 | auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ; 338 | } 339 | auth_reply.params.write.gatt_status = APP_FEATURE_NOT_SUPPORTED; 340 | err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, 341 | &auth_reply); 342 | APP_ERROR_CHECK(err_code); 343 | } 344 | } 345 | } break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST 346 | 347 | #if (NRF_SD_BLE_API_VERSION == 3) 348 | case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: 349 | err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle, 350 | NRF_BLE_MAX_MTU_SIZE); 351 | APP_ERROR_CHECK(err_code); 352 | break; // BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST 353 | #endif 354 | 355 | default: 356 | // No implementation needed. 357 | break; 358 | } 359 | } 360 | 361 | 362 | /**@brief Function for dispatching a SoftDevice event to all modules with a SoftDevice 363 | * event handler. 364 | * 365 | * @details This function is called from the SoftDevice event interrupt handler after a 366 | * SoftDevice event has been received. 367 | * 368 | * @param[in] p_ble_evt SoftDevice event. 369 | */ 370 | static void ble_evt_dispatch(ble_evt_t * p_ble_evt) 371 | { 372 | ble_conn_params_on_ble_evt(p_ble_evt); 373 | ble_nus_on_ble_evt(&m_nus, p_ble_evt); 374 | on_ble_evt(p_ble_evt); 375 | ble_advertising_on_ble_evt(p_ble_evt); 376 | bsp_btn_ble_on_ble_evt(p_ble_evt); 377 | 378 | } 379 | 380 | 381 | /**@brief Function for the SoftDevice initialization. 382 | * 383 | * @details This function initializes the SoftDevice and the BLE event interrupt. 384 | */ 385 | static void ble_stack_init(void) 386 | { 387 | uint32_t err_code; 388 | 389 | nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC; 390 | 391 | // Initialize SoftDevice. 392 | SOFTDEVICE_HANDLER_INIT(&clock_lf_cfg, NULL); 393 | 394 | ble_enable_params_t ble_enable_params; 395 | err_code = softdevice_enable_get_default_config(CENTRAL_LINK_COUNT, 396 | PERIPHERAL_LINK_COUNT, 397 | &ble_enable_params); 398 | APP_ERROR_CHECK(err_code); 399 | 400 | //Check the ram settings against the used number of links 401 | CHECK_RAM_START_ADDR(CENTRAL_LINK_COUNT,PERIPHERAL_LINK_COUNT); 402 | 403 | // Enable BLE stack. 404 | #if (NRF_SD_BLE_API_VERSION == 3) 405 | ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE; 406 | #endif 407 | err_code = softdevice_enable(&ble_enable_params); 408 | APP_ERROR_CHECK(err_code); 409 | 410 | // Subscribe for BLE events. 411 | err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch); 412 | APP_ERROR_CHECK(err_code); 413 | } 414 | 415 | 416 | /**@brief Function for handling events from the BSP module. 417 | * 418 | * @param[in] event Event generated by button press. 419 | */ 420 | void bsp_event_handler(bsp_event_t event) 421 | { 422 | uint32_t err_code; 423 | switch (event) 424 | { 425 | case BSP_EVENT_SLEEP: 426 | sleep_mode_enter(); 427 | break; 428 | 429 | case BSP_EVENT_DISCONNECT: 430 | err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); 431 | if (err_code != NRF_ERROR_INVALID_STATE) 432 | { 433 | APP_ERROR_CHECK(err_code); 434 | } 435 | break; 436 | 437 | case BSP_EVENT_WHITELIST_OFF: 438 | if (m_conn_handle == BLE_CONN_HANDLE_INVALID) 439 | { 440 | err_code = ble_advertising_restart_without_whitelist(); 441 | if (err_code != NRF_ERROR_INVALID_STATE) 442 | { 443 | APP_ERROR_CHECK(err_code); 444 | } 445 | } 446 | break; 447 | 448 | default: 449 | break; 450 | } 451 | } 452 | 453 | 454 | /**@brief Function for handling app_uart events. 455 | * 456 | * @details This function will receive a single character from the app_uart module and append it to 457 | * a string. The string will be be sent over BLE when the last character received was a 458 | * 'new line' i.e '\r\n' (hex 0x0D) or if the string has reached a length of 459 | * @ref NUS_MAX_DATA_LENGTH. 460 | */ 461 | /**@snippet [Handling the data received over UART] */ 462 | void uart_event_handle(app_uart_evt_t * p_event) 463 | { 464 | static uint8_t data_array[BLE_NUS_MAX_DATA_LEN]; 465 | static uint8_t index = 0; 466 | uint32_t err_code; 467 | 468 | switch (p_event->evt_type) 469 | { 470 | case APP_UART_DATA_READY: 471 | UNUSED_VARIABLE(app_uart_get(&data_array[index])); 472 | index++; 473 | 474 | if ((data_array[index - 1] == '\n') || (index >= (BLE_NUS_MAX_DATA_LEN))) 475 | { 476 | err_code = ble_nus_string_send(&m_nus, data_array, index); 477 | if (err_code != NRF_ERROR_INVALID_STATE) 478 | { 479 | APP_ERROR_CHECK(err_code); 480 | } 481 | 482 | index = 0; 483 | } 484 | break; 485 | 486 | case APP_UART_COMMUNICATION_ERROR: 487 | APP_ERROR_HANDLER(p_event->data.error_communication); 488 | break; 489 | 490 | case APP_UART_FIFO_ERROR: 491 | APP_ERROR_HANDLER(p_event->data.error_code); 492 | break; 493 | 494 | default: 495 | break; 496 | } 497 | } 498 | /**@snippet [Handling the data received over UART] */ 499 | 500 | 501 | /**@brief Function for initializing the UART module. 502 | */ 503 | /**@snippet [UART Initialization] */ 504 | static void uart_init(void) 505 | { 506 | uint32_t err_code; 507 | const app_uart_comm_params_t comm_params = 508 | { 509 | RX_PIN_NUMBER, 510 | TX_PIN_NUMBER, 511 | RTS_PIN_NUMBER, 512 | CTS_PIN_NUMBER, 513 | APP_UART_FLOW_CONTROL_DISABLED, 514 | false, 515 | UART_BAUDRATE_BAUDRATE_Baud115200 516 | }; 517 | 518 | APP_UART_FIFO_INIT( &comm_params, 519 | UART_RX_BUF_SIZE, 520 | UART_TX_BUF_SIZE, 521 | uart_event_handle, 522 | APP_IRQ_PRIORITY_LOWEST, 523 | err_code); 524 | APP_ERROR_CHECK(err_code); 525 | } 526 | /**@snippet [UART Initialization] */ 527 | 528 | 529 | /**@brief Function for initializing the Advertising functionality. 530 | */ 531 | static void advertising_init(void) 532 | { 533 | uint32_t err_code; 534 | ble_advdata_t advdata; 535 | ble_advdata_t scanrsp; 536 | ble_adv_modes_config_t options; 537 | 538 | // Build advertising data struct to pass into @ref ble_advertising_init. 539 | memset(&advdata, 0, sizeof(advdata)); 540 | advdata.name_type = BLE_ADVDATA_FULL_NAME; 541 | advdata.include_appearance = false; 542 | advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE; 543 | 544 | memset(&scanrsp, 0, sizeof(scanrsp)); 545 | scanrsp.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]); 546 | scanrsp.uuids_complete.p_uuids = m_adv_uuids; 547 | 548 | memset(&options, 0, sizeof(options)); 549 | options.ble_adv_fast_enabled = true; 550 | options.ble_adv_fast_interval = APP_ADV_INTERVAL; 551 | options.ble_adv_fast_timeout = APP_ADV_TIMEOUT_IN_SECONDS; 552 | 553 | err_code = ble_advertising_init(&advdata, &scanrsp, &options, on_adv_evt, NULL); 554 | APP_ERROR_CHECK(err_code); 555 | } 556 | 557 | 558 | /**@brief Function for initializing buttons and leds. 559 | * 560 | * @param[out] p_erase_bonds Will be true if the clear bonding button was pressed to wake the application up. 561 | */ 562 | static void buttons_leds_init(bool * p_erase_bonds) 563 | { 564 | bsp_event_t startup_event; 565 | 566 | uint32_t err_code = bsp_init(BSP_INIT_LED | BSP_INIT_BUTTONS, 567 | APP_TIMER_TICKS(100, APP_TIMER_PRESCALER), 568 | bsp_event_handler); 569 | APP_ERROR_CHECK(err_code); 570 | 571 | err_code = bsp_btn_ble_init(NULL, &startup_event); 572 | APP_ERROR_CHECK(err_code); 573 | 574 | *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA); 575 | } 576 | 577 | 578 | /**@brief Function for placing the application in low power state while waiting for events. 579 | */ 580 | static void power_manage(void) 581 | { 582 | uint32_t err_code = sd_app_evt_wait(); 583 | APP_ERROR_CHECK(err_code); 584 | } 585 | 586 | 587 | /**@brief Application main function. 588 | */ 589 | int main(void) 590 | { 591 | uint32_t err_code; 592 | bool erase_bonds; 593 | 594 | // Initialize. 595 | APP_TIMER_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, false); 596 | uart_init(); 597 | 598 | buttons_leds_init(&erase_bonds); 599 | ble_stack_init(); 600 | gap_params_init(); 601 | services_init(); 602 | advertising_init(); 603 | conn_params_init(); 604 | 605 | printf("\r\nUART Start!\r\n"); 606 | err_code = ble_advertising_start(BLE_ADV_MODE_FAST); 607 | APP_ERROR_CHECK(err_code); 608 | 609 | // Enter main loop. 610 | for (;;) 611 | { 612 | power_manage(); 613 | } 614 | } 615 | 616 | 617 | /** 618 | * @} 619 | */ 620 | -------------------------------------------------------------------------------- /work/source/test.ld: -------------------------------------------------------------------------------- 1 | /* Linker script to configure memory regions. */ 2 | 3 | SEARCH_DIR(.) 4 | GROUP(-lgcc -lc -lnosys) 5 | 6 | MEMORY 7 | { 8 | FLASH (rx) : ORIGIN = 0x1c000, LENGTH = 0x64000 9 | RAM (rwx) : ORIGIN = 0x20002080, LENGTH = 0x5f80 10 | } 11 | 12 | SECTIONS 13 | { 14 | .fs_data : 15 | { 16 | PROVIDE(__start_fs_data = .); 17 | KEEP(*(.fs_data)) 18 | PROVIDE(__stop_fs_data = .); 19 | } > RAM 20 | } INSERT AFTER .data; 21 | 22 | INCLUDE "nrf5x_common.ld" --------------------------------------------------------------------------------