21 Commits

Author SHA1 Message Date
chain40 c846950983 cont. 2025-07-16 01:10:44 +08:00
chain40 e9788b10df Merge branch 'ble_uart' 2025-06-21 11:45:23 +08:00
chain40 c933e15399 feat: Implement the BLE UART service. 2025-06-21 11:45:06 +08:00
chain40 ef19d6b72f bsp update 2025-06-10 22:10:33 +08:00
chain40 089114368e fix: 修正 peripheral 斷線後重連, 不會將資料寫入 sram 的問題 2025-01-13 23:08:07 +08:00
chain40 27560b237d feat: GCC 13.3.1 / GDB 15.1 / r3 2025-01-09 21:35:36 +08:00
Roy_01 fe55899830 feat: GCC 13.3.1 / GDB 15.1 2024-09-12 11:20:49 +08:00
chain40 14a4dec57b feat: 寫入 inst char 以及讀取 data char 會在 rtt 顯示 2024-05-21 19:26:55 +08:00
chain40 d3812a8b72 bugfix: 修正 peer address 的 type 判斷錯誤的問題 2024-05-08 00:29:39 +08:00
chain40 df70d69851 bugfix: 修正 cc2650 相容性實作 2024-05-08 00:04:58 +08:00
chain40 440f443a99 feat: 升級 gcc 版本 12.3.1, 升級 gdb 版本 13.2 2024-01-31 23:14:10 +08:00
chain40 32f5fee764 bugfix: 支援不同的 addree type 連線
1. Public address (cc2650 目前使用, 需向 ieee 註冊)
2. Random static address (bmd380 目前使用)
3. Resolvable random private address (未使用)
4. Non-resolvable random private address (未使用)
2024-01-31 23:14:06 +08:00
chain40 7fc5b54c47 feat: 當接收到 notify 時, 會根據不同的 char handle 執行對應的 callback
1. 目前只有 regular_data_char_handle 有實作
2024-01-31 22:50:01 +08:00
Roy_01 370d6cc80f updated response of disconnection and connection timeout 2023-10-03 16:02:00 +08:00
chain40 d99848592b bugfix: 修正掉資料的問題 (已排除)
原因: 因為連線後的 connection interval 設為 20ms, 造成 EIS 在 100sps 狀況下會掉資料

修正方式: 將連線後的 connection interval 設為 8~10ms, 即可排除 EIS 掉資料的問題

其它: 將程式碼優化調整為 -O0, 利於程式碼除錯
2023-08-15 23:30:50 +08:00
chain40 401c592281 bugfix: 修正掉資料的問題 (未解決, 僅降低發生率)
1. 程式優化為 -O0, 所以效能受限! 將優化改為 -O2 可大幅提升效能

2. 由於 gpiote 中斷有使用到 freertos api, 所以 gpiote 中斷優先權必需低於 configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY, 所以將 gpiote 優先權修改為 _PRIO_APP_MID 可排除掉資料的問題

3. 將 mem_drv_stream 的 buffer size 調整為 4096 bytes (確保 streambuffer 不會被塞爆)
2023-08-14 22:37:10 +08:00
chain40 415f4adfe9 bugfix: 修正自動結束的mode, 有發現沒有收到notify的最後一筆資料的問題
1. 原本是要收到 4 筆以上的資料才上寫入 sram, 現在只要收到 1筆資料就可以寫入 sram, 並切換 sram
2023-08-14 13:07:38 +08:00
chain40 9fc58b51fe Refactoring: 當 on_ins_write_char() 寫入資料如果發生錯誤, 會在 rtt viewer 顯示 2023-08-14 10:48:10 +08:00
chain40 508ac99c0d bugfix: 修正當連線成功之後, 如果重複連線會發生錯誤的問題 2023-08-14 10:45:26 +08:00
chain40 6158961dcf bugfix: NRF_BLE_GQ_QUEUE_SIZE 太小只有 6 bytes, 所以當 characteristic 寫入大於 6 bytes 會寫入失敗
1) NRF_BLE_GQ_QUEUE_SIZE 改為 256
2) NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN 改為 256
3) NRF_BLE_GQ_GATTC_WRITE_MAX_DATA_LEN 改為 256
4) NRF_BLE_GQ_DATAPOOL_ELEMENT_COUNT 改為 32
5) NRF_BLE_GQ_DATAPOOL_ELEMENT_SIZE 改為 256
2023-08-14 10:43:53 +08:00
chain40 be584e2900 cc2650_compitable 2023-08-11 09:15:53 +08:00
53 changed files with 1593 additions and 359 deletions
+1
View File
@@ -2,3 +2,4 @@
/.visualgdb/
/VisualGDB/
*.vgdbsettings.*.user
/build/
+74
View File
@@ -0,0 +1,74 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"name": "(Ubuntu) launch & debug",
"request": "launch",
"type": "cortex-debug",
"servertype": "jlink",
"serverpath": "/opt/SEGGER/JLink/JLinkGDBServerCLExe",
"serverArgs": [
"-halt",
"-ir",
"-vd",
"-strict",
],
"rttConfig": {
"enabled": true,
"address": "auto",
"decoders": [
{
"label": "",
"port": 0,
"type": "console"
}
],
},
"armToolchainPath": "/opt/arm-none-eabi/bin",
"device": "NRF52840_XXAA",
"interface": "swd",
"rtos": "FreeRTOS",
"svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd",
"runToEntryPoint": "main",
"preLaunchTask": "CMake: build"
},
{
"cwd": "${workspaceRoot}",
"executable": "${command:cmake.launchTargetPath}",
"name": "(Windows) launch & debug",
"request": "launch",
"type": "cortex-debug",
"servertype": "jlink",
"serverpath": "C:/Program Files/SEGGER/JLink/JLinkGDBServerCL.exe",
"serverArgs": [
"-halt",
"-ir",
"-vd",
"-strict",
],
"rttConfig": {
"enabled": true,
"address": "auto",
"decoders": [
{
"label": "",
"port": 0,
"type": "console"
}
],
},
"armToolchainPath": "C:/sysgcc/arm-eabi/bin",
"device": "NRF52840_XXAA",
"interface": "swd",
"rtos": "FreeRTOS",
"svdFile": "${workspaceRoot}/../bmd380_sdk/modules/nrfx/mdk/nrf52840.svd",
"runToEntryPoint": "main",
"preLaunchTask": "CMake: build"
},
]
}
+33
View File
@@ -0,0 +1,33 @@
{
"version": "2.0.0",
"tasks": [
{
"type": "cmake",
"label": "CMake: build",
"command": "build",
"targets": [
"all"
],
"preset": "${command:cmake.activeBuildPresetName}",
"group": {
"kind": "build"
},
"problemMatcher": [],
"detail": "CMake template build task"
},
{
"type": "cmake",
"label": "CMake: clean rebuild",
"command": "cleanRebuild",
"targets": [
"all"
],
"group": {
"isDefault": true,
"kind": "build"
},
"problemMatcher": [],
"detail": "CMake template clean rebuild task"
}
]
}
+212
View File
@@ -0,0 +1,212 @@
cmake_minimum_required(VERSION 3.15.3)
# Verbose output (optional)
set(CMAKE_VERBOSE_MAKEFILE ON)
# Toolchain must be set before project()
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/arm-none-eabi-gcc.cmake)
include(${CMAKE_TOOLCHAIN_FILE})
# Project setup
project(bmd380_central
VERSION 1.0.0
LANGUAGES C ASM
)
set(EXECUTABLE ${PROJECT_NAME}.elf)
set(NRF_SDK_DIR ${CMAKE_SOURCE_DIR}/../bmd380_sdk)
#set(LINKER_FILE ${CMAKE_SOURCE_DIR}/linkscripts/nRF52840_XXAA_s140.lds)
set(LINKER_FILE ${CMAKE_SOURCE_DIR}/linkscripts/nRF52840_XXAA_S140_reserve.lds)
set(LINKER_DIR ${CMAKE_SOURCE_DIR}/linkscripts)
set(NRF_SDK_LINKER_DIR ${NRF_SDK_DIR}/modules/nrfx/mdk)
set(SD_LINKER_DIR ${CMAKE_SOURCE_DIR}/SoftdeviceLibraries/hard)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
# Define the build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
endif()
message(STATUS "Using toolchain file: ${CMAKE_TOOLCHAIN_FILE}")
set(COMMON_COMPILE_OPT
-mcpu=cortex-m4
-mfpu=fpv4-sp-d16
-mfloat-abi=hard
-mthumb
-fdata-sections
-ffunction-sections
-Wall
-Os
-g3
-std=gnu99
-Wno-unused-variable
-Wno-pointer-sign
-Wno-array-bounds
)
set(COMMON_COMPILE_DEF
-DDEBUG=1
-DNRF52840_XXAA
-DS140_reserve
-DCONFIG_GPIO_AS_PIN
-DRESETHNRF_DFU_SETTINGS_VERSION=2
-DNRF_SD_BLE_API_VERSION=7
-D__STACK_SIZE=1024
-D__HEAP_SIZE=1024
-DARM_MATH_CM4
-DSOFTDEVICE_PRESENT
-DUSE_APP_CONFIG
)
set(COMMON_COMPILE_INC
${ARM_TOOLCHAIN_DIR}/../arm-none-eabi/include
${CMAKE_SOURCE_DIR}/app
${NRF_SDK_DIR}/components/ble/ble_db_discovery
${NRF_SDK_DIR}/components/ble/ble_services/ble_dis
${NRF_SDK_DIR}/components/ble/ble_services/ble_dis_c
${NRF_SDK_DIR}/components/ble/common/
${NRF_SDK_DIR}/components/ble/nrf_ble_gatt
${NRF_SDK_DIR}/components/ble/nrf_ble_gq
${NRF_SDK_DIR}/components/ble/nrf_ble_scan
${NRF_SDK_DIR}/components/libraries/atomic
${NRF_SDK_DIR}/components/libraries/atomic_flags
${NRF_SDK_DIR}/components/libraries/balloc
${NRF_SDK_DIR}/components/libraries/delay
${NRF_SDK_DIR}/components/libraries/experimental_section_vars
${NRF_SDK_DIR}/components/libraries/log
${NRF_SDK_DIR}/components/libraries/log/src
${NRF_SDK_DIR}/components/libraries/memobj
${NRF_SDK_DIR}/components/libraries/queue
${NRF_SDK_DIR}/components/libraries/ringbuf
${NRF_SDK_DIR}/components/libraries/strerror
${NRF_SDK_DIR}/components/libraries/util
${NRF_SDK_DIR}/components/softdevice/common
${NRF_SDK_DIR}/components/softdevice/mbr/headers
${NRF_SDK_DIR}/components/softdevice/s140/headers
${NRF_SDK_DIR}/components/toolchain/cmsis/include
${NRF_SDK_DIR}/external/fprintf
${NRF_SDK_DIR}/external/freertos/portable/CMSIS/nrf52
${NRF_SDK_DIR}/external/freertos/portable/GCC/nrf52
${NRF_SDK_DIR}/external/freertos/source/include
${NRF_SDK_DIR}/external/segger_rtt
${NRF_SDK_DIR}/integration/nrfx
${NRF_SDK_DIR}/integration/nrfx/legacy
${NRF_SDK_DIR}/modules/nrfx
${NRF_SDK_DIR}/modules/nrfx/drivers/include
${NRF_SDK_DIR}/modules/nrfx/hal
${NRF_SDK_DIR}/modules/nrfx/mdk
)
# ==========================
# Prj Configuration
# ==========================
add_library(prj_config INTERFACE)
target_include_directories(prj_config INTERFACE ${COMMON_COMPILE_INC})
target_compile_definitions(prj_config INTERFACE ${COMMON_COMPILE_DEF})
target_compile_options(prj_config INTERFACE ${COMMON_COMPILE_OPT})
# ====================================================
# Add FreeRTOS kernel and portable layer
# Add application source files as an OBJECT library
# Add board support package (BSP) source files as an OBJECT library
# ====================================================
add_subdirectory(app)
include(cmake/freertos.cmake)
# ==========================
# Executable Target
# ==========================
add_executable(${EXECUTABLE}
$<TARGET_OBJECTS:app>
${NRF_SDK_DIR}/components/ble/ble_db_discovery/ble_db_discovery.c
${NRF_SDK_DIR}/components/ble/ble_services/ble_dis_c/ble_dis_c.c
${NRF_SDK_DIR}/components/ble/common/ble_advdata.c
${NRF_SDK_DIR}/components/ble/common/ble_conn_params.c
${NRF_SDK_DIR}/components/ble/common/ble_conn_state.c
${NRF_SDK_DIR}/components/ble/nrf_ble_gatt/nrf_ble_gatt.c
${NRF_SDK_DIR}/components/ble/nrf_ble_gq/nrf_ble_gq.c
${NRF_SDK_DIR}/components/ble/nrf_ble_scan/nrf_ble_scan.c
${NRF_SDK_DIR}/components/libraries/atomic/nrf_atomic.c
${NRF_SDK_DIR}/components/libraries/atomic_flags/nrf_atflags.c
${NRF_SDK_DIR}/components/libraries/balloc/nrf_balloc.c
${NRF_SDK_DIR}/components/libraries/experimental_section_vars/nrf_section_iter.c
${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_backend_rtt.c
${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_backend_serial.c
${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_default_backends.c
${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_frontend.c
${NRF_SDK_DIR}/components/libraries/log/src/nrf_log_str_formatter.c
${NRF_SDK_DIR}/components/libraries/memobj/nrf_memobj.c
${NRF_SDK_DIR}/components/libraries/queue/nrf_queue.c
${NRF_SDK_DIR}/components/libraries/ringbuf/nrf_ringbuf.c
${NRF_SDK_DIR}/components/libraries/strerror/nrf_strerror.c
${NRF_SDK_DIR}/components/libraries/util/app_error.c
${NRF_SDK_DIR}/components/libraries/util/app_error_handler_gcc.c
${NRF_SDK_DIR}/components/libraries/util/app_error_weak.c
${NRF_SDK_DIR}/components/libraries/util/app_util_platform.c
${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh.c
${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh_ble.c
${NRF_SDK_DIR}/components/softdevice/common/nrf_sdh_freertos.c
${NRF_SDK_DIR}/external/fprintf/nrf_fprintf.c
${NRF_SDK_DIR}/external/fprintf/nrf_fprintf_format.c
${NRF_SDK_DIR}/external/segger_rtt/SEGGER_RTT.c
${NRF_SDK_DIR}/external/segger_rtt/SEGGER_RTT_printf.c
${NRF_SDK_DIR}/integration/nrfx/legacy/nrf_drv_clock.c
${NRF_SDK_DIR}/modules/nrfx/drivers/src/nrfx_clock.c
${NRF_SDK_DIR}/modules/nrfx/mdk/gcc_startup_nrf52840.S
${NRF_SDK_DIR}/modules/nrfx/mdk/system_nrf52.c
)
target_include_directories(${EXECUTABLE} PRIVATE ${COMMON_COMPILE_INC})
target_compile_definitions(${EXECUTABLE} PRIVATE ${COMMON_COMPILE_DEF})
target_compile_options(${EXECUTABLE} PRIVATE ${COMMON_COMPILE_OPT})
# ==========================
# Link configuration
# ==========================
# Linker options (linker script and flags)
target_link_options(${EXECUTABLE} PRIVATE
-T${LINKER_FILE} # Linker script
-L${SD_LINKER_DIR} # Linker library directory (SoftDevice)
-L${NRF_SDK_LINKER_DIR} # Linker library directory (SDK)
-L${LINKER_DIR} # Linker library directory
-mcpu=cortex-m4 # CPU architecture
-mfpu=fpv4-sp-d16 # Floating-point unit
-mfloat-abi=hard
-mthumb
--specs=nano.specs # Use nano C library
--specs=nosys.specs # Minimal syscall stubs
-u _printf_float # Enable float support in printf
-lc # Link C library
-lm # Link math library
-Wl,-Map=${PROJECT_NAME}.map,--cref # Generate memory map file
-Wl,--gc-sections # Remove unused sections
-Xlinker -print-memory-usage -Xlinker # Print memory usage after link
)
# Link with logical (target-based) libraries
target_link_libraries(${EXECUTABLE} PRIVATE
prj_config
app
freertos
)
# ==========================
# Post-build Actions
# ==========================
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_SIZE} ${EXECUTABLE}
COMMENT "Print memory usage"
)
add_custom_command(TARGET ${EXECUTABLE}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O srec --srec-len=64 ${EXECUTABLE} ${PROJECT_NAME}.s19
COMMAND ${CMAKE_OBJCOPY} -O ihex ${EXECUTABLE} ${PROJECT_NAME}.hex
COMMAND ${CMAKE_OBJCOPY} -O binary ${EXECUTABLE} ${PROJECT_NAME}.bin
COMMENT "Generate .s19, .hex, and .bin output files"
)
+59
View File
@@ -0,0 +1,59 @@
{
"version": 3,
"configurePresets": [
{
"name": "default",
"hidden": true,
"generator": "Ninja",
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
}
},
{
"name": "Debug",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
}
},
{
"name": "RelWithDebInfo",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
},
{
"name": "Release",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release"
}
},
{
"name": "MinSizeRel",
"inherits": "default",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "MinSizeRel"
}
}
],
"buildPresets": [
{
"name": "Debug",
"configurePreset": "Debug"
},
{
"name": "RelWithDebInfo",
"configurePreset": "RelWithDebInfo"
},
{
"name": "Release",
"configurePreset": "Release"
},
{
"name": "MinSizeRel",
"configurePreset": "MinSizeRel"
}
]
}
+15
View File
@@ -0,0 +1,15 @@
@echo off
REM Usage: ConvertSoftdevice.bat <Softdevice Name> <Intermediate Hex file name>
set ARM_GCC_PREFIX=arm-none-eabi-
cd /d %~dp0
if not exist soft mkdir soft
if not exist hard mkdir hard
%ARM_GCC_PREFIX%objcopy.exe --gap-fill 0xFF -I ihex -O binary %2 %1_softdevice.bin
%ARM_GCC_PREFIX%gcc empty.c -c -o hard\%1_softdevice.o -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
%ARM_GCC_PREFIX%objcopy.exe --add-section .softdevice=%1_softdevice.bin --set-section-flags .softdevice=CONTENTS,ALLOC,LOAD,READONLY,CODE hard\%1_softdevice.o --remove-section .text --remove-section .data --remove-section .bss
%ARM_GCC_PREFIX%gcc empty.c -c -o soft\%1_softdevice.o -mcpu=cortex-m4 -mthumb -mfloat-abi=soft
%ARM_GCC_PREFIX%objcopy.exe --add-section .softdevice=%1_softdevice.bin --set-section-flags .softdevice=CONTENTS,ALLOC,LOAD,READONLY,CODE soft\%1_softdevice.o --remove-section .text --remove-section .data --remove-section .bss
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+3
View File
@@ -0,0 +1,3 @@
void dummyfunc()
{
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+9
View File
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.15.3)
file(GLOB_RECURSE APP_SOURCES "*.c")
add_library(app OBJECT ${APP_SOURCES})
target_link_libraries(app PRIVATE
prj_config
)
+1 -1
View File
@@ -63,7 +63,7 @@
#define configTICK_RATE_HZ 1024
#define configMAX_PRIORITIES ( 6 )
#define configMINIMAL_STACK_SIZE ( 192 )
#define configTOTAL_HEAP_SIZE ( 32 * 1024 )
#define configTOTAL_HEAP_SIZE ( 64 * 1024 )
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
+15 -15
View File
@@ -15,9 +15,9 @@ extern "C"
#define NRF_LOG_BACKEND_UART_ENABLED 0
#define NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS 1
#define NRF_LOG_BACKEND_RTT_TX_RETRY_CNT 3
#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64
#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 256
#define NRF_LOG_DEFERRED 0
#define NRF_LOG_USES_TIMESTAMP 0
#define NRF_LOG_USES_TIMESTAMP 1
#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 0
// SEGGER-RTT
@@ -160,7 +160,7 @@ extern "C"
// Determines the supervision time-out in units of 10 millisecond.
#define NRF_BLE_SCAN_SUPERVISION_TIMEOUT 4000
// Determines minimum connection interval in milliseconds.
#define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 7.5
#define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 8
// Determines maximum connection interval in milliseconds.
#define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 20
// Determines the slave latency in counts of connection events.
@@ -183,15 +183,15 @@ extern "C"
#define NRF_BLE_GQ_ENABLED 1
// Default size of a single element in the pool of memory objects.
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_SIZE 20
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_SIZE 256
// Default number of elements in the pool of memory objects.
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_COUNT 8
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_COUNT 32
// Maximal size of the data inside GATTC write request (in bytes).
#define NRF_BLE_GQ_GATTC_WRITE_MAX_DATA_LEN 2
#define NRF_BLE_GQ_GATTC_WRITE_MAX_DATA_LEN 256
// Maximal size of the data inside GATTC notification or indication request (in bytes).
#define NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN 16
#define NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN 256
// Queue size for BLE GATT Queue module.
#define NRF_BLE_GQ_QUEUE_SIZE 6
#define NRF_BLE_GQ_QUEUE_SIZE 256
// Priority with which BLE events are dispatched to the GATT Queue module.
#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1
@@ -212,15 +212,15 @@ extern "C"
#define NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED 1
// The maximum number of characteristics present in a service record
#define BLE_GATT_DB_MAX_CHARS 16
#define BLE_GATT_DB_MAX_CHARS 16
// Custom UUID service & char
#define BLE_UUID_CUSTOM_SERVICE 0xFFF0
#define BLE_UUID_REGULAR_DATA_CHAR 0xFFF1
#define BLE_UUID_LOW_FREQ_DATA_CHAR 0xFFF2
#define BLE_UUID_AUXILIARY_DATA_CHAR 0xFFF3
#define BLE_UUID_STATUS_CHAR 0xFFF4
#define BLE_UUID_EVENT_CHAR 0xFFF5
#define BLE_UUID_CUSTOM_SERVICE 0xFFF0
#define BLE_UUID_SIMPLEPROFILECHAR(n) (BLE_UUID_CUSTOM_SERVICE + n)
// Uart UUID service & char
#define BLE_UUID_UART_SERVICE 0xFFF8
#define BLE_UUID_UART_CHAR(n) (BLE_UUID_UART_SERVICE + n)
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
+80 -31
View File
@@ -5,6 +5,8 @@ extern "C"
{
#endif
#include "sdk_config.h"
#include "ble_advdata.h"
#include "nrf_ble_gatt.h"
@@ -125,28 +127,44 @@ static void success_ack(void)
uart_drv_tx(ack, sizeof(ack));
}
static void disconnect_and_timeout_ack(void)
{
uint8_t ack[] = { 0x04, 0x00, 0x01, 0xFF };
uart_drv_tx(ack, sizeof(ack));
}
static void on_ins_scan(ins_scan_t *p_ins)
{
extern void le_scan_start(void);
le_scan_start();
}
bool connect_start = false;
static void on_ins_connect(ins_connect_t *p_ins)
{
ble_gap_addr_t peer_addr;
memset(&peer_addr, 0x00, sizeof(peer_addr));
peer_addr.addr[0] = p_ins->addr[5];
peer_addr.addr[1] = p_ins->addr[4];
peer_addr.addr[2] = p_ins->addr[3];
peer_addr.addr[3] = p_ins->addr[2];
peer_addr.addr[4] = p_ins->addr[1];
peer_addr.addr[5] = p_ins->addr[0];
peer_addr.addr_id_peer = 0;
peer_addr.addr_type = BLE_GAP_ADDR_TYPE_ANONYMOUS;
peer_addr.addr[0] = p_ins->addr[5];
peer_addr.addr[1] = p_ins->addr[4];
peer_addr.addr[2] = p_ins->addr[3];
peer_addr.addr[3] = p_ins->addr[2];
peer_addr.addr[4] = p_ins->addr[1];
peer_addr.addr[5] = p_ins->addr[0];
extern void le_scan_stop(void);
le_scan_stop();
vTaskDelay(pdMS_TO_TICKS(5));
vTaskDelay(pdMS_TO_TICKS(3));
extern void le_scan_get_peer_addr(ble_gap_addr_t * p_peer_addr);
le_scan_get_peer_addr(&peer_addr);
if (peer_addr.addr_type == BLE_GAP_ADDR_TYPE_ANONYMOUS)
{
extern void le_scan_start(void);
le_scan_start();
return;
}
extern void le_gap_connet(ble_gap_addr_t * p_peer_addr);
le_gap_connet(&peer_addr);
@@ -158,14 +176,28 @@ static void on_ins_connect(ins_connect_t *p_ins)
static void on_ins_write_char(ins_write_char_t *p_ins)
{
NRF_LOG_INFO("write handle: 0x%02X", p_ins->handle);
uint16_t write_size = p_ins->len - sizeof(p_ins->handle) - 1;
extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
ret_code_t ret_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
if (ret_code == NRF_SUCCESS)
NRF_LOG_INFO("write handle: 0x%02X", p_ins->handle);
{
success_ack();
uint8_t *p_start = (void *)p_ins->write_data;
uint32_t loop = write_size / 8;
uint32_t remain = write_size % 8;
for (int i = 0; i < loop; i++)
{
NRF_LOG_HEXDUMP_INFO(p_start, 8);
p_start += 8;
}
if (remain)
{
NRF_LOG_HEXDUMP_INFO(p_start, remain);
}
}
extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
ret_code_t err_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
APP_ERROR_CHECK(err_code);
success_ack();
}
static void on_ins_read_char(ins_read_char_t *p_ins)
@@ -186,22 +218,38 @@ static void on_ins_survive(ins_survive_t *p_ins)
success_ack();
}
typedef struct
{
uint16_t rsp_code;
union
{
uint8_t len;
uint8_t payload[256];
};
} __PACKED read_char_rsp_t;
read_char_rsp_t read_char_rsp;
void host_read_char_cb(uint8_t *p_data, uint16_t len)
{
read_char_rsp.rsp_code = 0x0004;
memcpy(&read_char_rsp.len, p_data, len);
uart_drv_tx(&read_char_rsp, offsetof(read_char_rsp_t, payload) + len);
static union
{
struct
{
uint16_t rsp_code;
uint8_t payload[];
};
uint8_t arr[256];
} read_char_rsp = {
.rsp_code = 0x0004
};
memcpy(read_char_rsp.payload, p_data, len);
uart_drv_tx(&read_char_rsp, sizeof(read_char_rsp.rsp_code) + len);
{
uint8_t *p_start = p_data;
uint32_t loop = len / 8;
uint32_t remain = len % 8;
for (int i = 0; i < loop; i++)
{
NRF_LOG_HEXDUMP_INFO(p_start, 8);
p_start += 8;
}
if (remain)
{
NRF_LOG_HEXDUMP_INFO(p_start, remain);
}
}
}
typedef struct
@@ -365,7 +413,8 @@ static void host_tasks_handler(ble_evt_t const *p_ble_evt, void *p_context)
case BLE_GAP_EVT_CONNECTED:
break;
case BLE_GAP_EVT_DISCONNECTED:
success_ack();
case BLE_GAP_EVT_TIMEOUT:
disconnect_and_timeout_ack();
break;
default:
break;
@@ -375,8 +424,8 @@ static void host_tasks_handler(ble_evt_t const *p_ble_evt, void *p_context)
void host_tasks_init(void)
{
host_cmd_msg = xMessageBufferCreate(1024);
xTaskCreate(host_cmd_recv_task, "cmd_recv", 128, NULL, 5, NULL);
xTaskCreate(host_cmd_exec_task, "cmd_exec", 512, NULL, 2, NULL);
xTaskCreate(host_cmd_recv_task, "cmd_recv", 128, NULL, 3, NULL);
xTaskCreate(host_cmd_exec_task, "cmd_exec", 512, NULL, 3, NULL);
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_tasks_observer, 3, host_tasks_handler, NULL);
}
@@ -4,6 +4,8 @@ extern "C"
{
#endif
#include "sdk_config.h"
#include "ble_db_discovery.h"
#include "nrf_ble_gatt.h"
#include "nrf_ble_gq.h"
@@ -28,6 +30,8 @@ static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
le_dis_c_on_db_disc_evt(p_evt);
extern void le_gatt_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
le_gatt_c_on_db_disc_evt(p_evt);
extern void le_uart_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
le_uart_c_on_db_disc_evt(p_evt);
break;
case BLE_DB_DISCOVERY_ERROR:
NRF_LOG_INFO("BLE_DB_DISCOVERY_ERROR");
+2
View File
@@ -1,3 +1,5 @@
#include "sdk_config.h"
#include "ble_dis_c.h"
#include "ble_gattc.h"
+36 -4
View File
@@ -7,7 +7,8 @@ extern "C"
{
#endif
#include "app_config.h"
#include "sdk_config.h"
#include "apply_old_config.h"
#include "sdk_config.h"
@@ -26,13 +27,37 @@ extern "C"
}
#endif
bool is_connected = false;
static void le_gap_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
is_connected = true;
break;
case BLE_GAP_EVT_DISCONNECTED:
is_connected = false;
break;
default:
break;
}
}
void le_gap_init(const char *device_name, uint16_t usAppearance)
{
// TODO...
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_gap_observer, 3, le_gap_handler, NULL);
}
void le_gap_connet(ble_gap_addr_t *p_peer_addr)
{
if (is_connected)
{
return;
}
// If address is correct, stop scanning and initiate connection with peripheral device.
const ble_gap_conn_params_t conn_params = {
.conn_sup_timeout =
@@ -44,11 +69,13 @@ void le_gap_connet(ble_gap_addr_t *p_peer_addr)
.slave_latency =
(uint16_t)NRF_BLE_SCAN_SLAVE_LATENCY,
};
extern ble_gap_scan_params_t *le_scan_params(void);
ret_code_t err_code = sd_ble_gap_connect(p_peer_addr,
le_scan_params(),
&conn_params,
APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
}
@@ -73,10 +100,15 @@ void le_gap_conn_param_update(uint16_t conn_handle)
NRF_LOG_INFO("Central Preferred Connection Parameters.");
// Set GAP Central Preferred Connection Parameters.
ble_gap_conn_params_t const gap_conn_params = {
.min_conn_interval = MSEC_TO_UNITS(8, UNIT_1_25_MS), /**< Minimum connection interval (7.5 ms) */
.max_conn_interval = MSEC_TO_UNITS(20, UNIT_1_25_MS), /**< Maximum connection interval (20 ms). */
.min_conn_interval = MSEC_TO_UNITS(8, UNIT_1_25_MS), /**< Minimum connection interval ( 7.5 ms) */
.max_conn_interval = MSEC_TO_UNITS(10, UNIT_1_25_MS), /**< Maximum connection interval (10.0 ms). */
.slave_latency = 8, /**< Slave latency. */
.conn_sup_timeout = MSEC_TO_UNITS(10000, UNIT_10_MS) /**< Connection supervisory timeout (10s). */
};
sd_ble_gap_conn_param_update(conn_handle, &gap_conn_params);
}
bool le_gap_is_connected(void)
{
return is_connected;
}
+2
View File
@@ -4,6 +4,8 @@ extern "C"
{
#endif
#include "sdk_config.h"
#include "nrf_ble_gq.h"
#ifdef __cplusplus
View File
+36 -57
View File
@@ -3,6 +3,7 @@ extern "C"
{
#endif
#include "app_config.h"
#include "ble_db_discovery.h"
#include "ble_gattc.h"
#include "ble_srv_common.h"
@@ -21,27 +22,18 @@ extern "C"
}
#endif
#define MAX_CHAR_CNT 16
extern nrf_ble_gq_t *le_gap_queue(void);
struct ble_gatt_c_s
{
uint16_t conn_handle;
void (*evt_handler)(ble_evt_t const *p_ble_evt, void *p_context);
union
{
uint16_t char_handles[5];
struct
{
uint16_t regular_data_char_handle;
uint16_t low_freq_data_char_handle;
uint16_t auxiliary_data_char_handle;
uint16_t status_char_handle;
uint16_t event_char_handle;
};
};
uint16_t conn_handle;
uint16_t char_handles[MAX_CHAR_CNT];
};
uint16_t handle_mapping[5];
uint16_t handle_mapping[MAX_CHAR_CNT];
typedef struct ble_gatt_c_s ble_gatt_c_t;
@@ -49,11 +41,11 @@ static ble_gatt_c_t m_gatt_c;
static void on_disconnected(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
{
p_ble_gatt_c->conn_handle = BLE_CONN_HANDLE_INVALID;
p_ble_gatt_c->regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
p_ble_gatt_c->auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
p_ble_gatt_c->status_char_handle = BLE_GATT_HANDLE_INVALID;
p_ble_gatt_c->event_char_handle = BLE_GATT_HANDLE_INVALID;
p_ble_gatt_c->conn_handle = BLE_CONN_HANDLE_INVALID;
for (int i = 0; i < COUNTOF(p_ble_gatt_c->char_handles); i++)
{
p_ble_gatt_c->char_handles[i] = BLE_GATT_HANDLE_INVALID;
}
}
static uint32_t hvx_cnt = 0;
@@ -62,14 +54,17 @@ static void on_connected(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
{
hvx_cnt = 0;
hvx_begin = 0;
extern void mem_board_reset(void);
mem_board_reset();
}
static void on_hvx(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
{
uint32_t len = p_ble_evt->evt.gattc_evt.params.hvx.len;
uint8_t *p = p_ble_evt->evt.gattc_evt.params.hvx.data;
NRF_LOG_INFO("=======================================");
NRF_LOG_HEXDUMP_INFO(p, len);
ble_gattc_evt_hvx_t *hvx = (void *)&p_ble_evt->evt.gattc_evt.params.hvx;
uint32_t len = hvx->len;
uint8_t *p = (uint8_t *)hvx->data;
extern void mem_notify_cb(uint8_t * p, uint32_t len);
mem_notify_cb(p, len);
}
static void on_read_rsp(ble_gatt_c_t *p_le_gatt_c, ble_evt_t const *p_ble_evt)
@@ -226,11 +221,10 @@ static void le_gatt_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
void le_gatt_c_cccd_timer_cb(TimerHandle_t xTimer)
{
xTimerStop(xTimer, pdMS_TO_TICKS(0));
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.regular_data_char_handle, true);
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.low_freq_data_char_handle, true);
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.auxiliary_data_char_handle, true);
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.status_char_handle, true);
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.event_char_handle, true);
for (int i = 0; i < COUNTOF(m_gatt_c.char_handles); i++)
{
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.char_handles[i], true);
}
NRF_LOG_INFO("Enable notifications. ");
}
@@ -238,12 +232,13 @@ static TimerHandle_t le_gatt_c_cccd_timer = NULL;
void le_gatt_c_init(void)
{
m_gatt_c.evt_handler = le_gatt_c_evt_handler;
m_gatt_c.conn_handle = BLE_CONN_HANDLE_INVALID;
m_gatt_c.regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
m_gatt_c.auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
m_gatt_c.status_char_handle = BLE_GATT_HANDLE_INVALID;
m_gatt_c.event_char_handle = BLE_GATT_HANDLE_INVALID;
m_gatt_c.evt_handler = le_gatt_c_evt_handler;
m_gatt_c.conn_handle = BLE_CONN_HANDLE_INVALID;
for (int i = 0; i < COUNTOF(m_gatt_c.char_handles); i++)
{
m_gatt_c.char_handles[i] = BLE_GATT_HANDLE_INVALID;
}
ret_code_t err_code;
uint8_t uuid_type;
ble_uuid_t uuid = {
@@ -275,32 +270,16 @@ void le_gatt_c_on_db_disc_evt(ble_db_discovery_evt_t *p_evt)
{
m_gatt_c.conn_handle = p_evt->conn_handle;
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
for (int i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
switch (p_chars[i].characteristic.uuid.uuid)
for (int j = 0; j < COUNTOF(m_gatt_c.char_handles); j++)
{
case BLE_UUID_REGULAR_DATA_CHAR:
m_gatt_c.regular_data_char_handle = p_chars[i].characteristic.handle_value;
handle_mapping[0] = m_gatt_c.regular_data_char_handle;
break;
case BLE_UUID_LOW_FREQ_DATA_CHAR:
m_gatt_c.low_freq_data_char_handle = p_chars[i].characteristic.handle_value;
handle_mapping[1] = m_gatt_c.low_freq_data_char_handle;
break;
case BLE_UUID_AUXILIARY_DATA_CHAR:
m_gatt_c.auxiliary_data_char_handle = p_chars[i].characteristic.handle_value;
handle_mapping[2] = m_gatt_c.auxiliary_data_char_handle;
break;
case BLE_UUID_STATUS_CHAR:
m_gatt_c.status_char_handle = p_chars[i].characteristic.handle_value;
handle_mapping[3] = m_gatt_c.status_char_handle;
break;
case BLE_UUID_EVENT_CHAR:
m_gatt_c.event_char_handle = p_chars[i].characteristic.handle_value;
handle_mapping[4] = m_gatt_c.event_char_handle;
break;
default:
if (p_chars[i].characteristic.uuid.uuid == BLE_UUID_SIMPLEPROFILECHAR(j + 1))
{
m_gatt_c.char_handles[j] = p_chars[i].characteristic.handle_value;
handle_mapping[j] = m_gatt_c.char_handles[j];
break;
}
}
}
}
+22 -9
View File
@@ -78,14 +78,14 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
p_adv_report->rssi);
}
static uint8_t scan_buffer[BLE_GAP_SCAN_BUFFER_MAX];
static ble_data_t const adv_report_buffer = { .p_data = scan_buffer,
.len = BLE_GAP_SCAN_BUFFER_MAX };
static ble_uuid_t const filter_uuid = { .type = BLE_UUID_TYPE_BLE, .uuid = 0xFFF0 };
static uint64_t mac = 0;
static uint32_t peer_addr_idx = 0;
static ble_gap_addr_t peer_addr_list[16];
static uint64_t mac = 0;
void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
ret_code_t err_code;
@@ -99,14 +99,13 @@ void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
mac = u64_peer_addr;
char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
if (peer_addr)
{
char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
peer_addr_list[peer_addr_idx++ % COUNTOF(peer_addr_list)] = *peer_addr;
sprintf(peer_addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", peer_addr->addr[5], peer_addr->addr[4], peer_addr->addr[3], peer_addr->addr[2], peer_addr->addr[1], peer_addr->addr[0]);
NRF_LOG_INFO("%s", peer_addr_str);
}
NRF_LOG_INFO("%s", peer_addr_str);
}
else if (mac == u64_peer_addr)
{
@@ -116,6 +115,18 @@ void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
sd_ble_gap_scan_start(NULL, &adv_report_buffer);
}
void le_scan_get_peer_addr(ble_gap_addr_t *p_peer_addr)
{
for (uint32_t i = 0; i < COUNTOF(peer_addr_list); i++)
{
if (memcmp(peer_addr_list[i].addr, p_peer_addr->addr, BLE_GAP_ADDR_LEN) == 0)
{
p_peer_addr->addr_type = peer_addr_list[i].addr_type;
break;
}
}
}
static ble_gap_scan_params_t scan_params = {
.active = 1,
.interval = NRF_BLE_SCAN_SCAN_INTERVAL,
@@ -141,7 +152,9 @@ void le_scan_start(void)
{
NRF_LOG_INFO("Start scanning for UUID service 0x%04X.",
BLE_UUID_CUSTOM_SERVICE);
is_scanning = true;
is_scanning = true;
peer_addr_idx = 0;
memset(peer_addr_list, 0x00, sizeof(peer_addr_list));
sd_ble_gap_scan_start(&scan_params, &adv_report_buffer);
}
}
@@ -156,4 +169,4 @@ void le_scan_stop(void)
ble_gap_scan_params_t *le_scan_params(void)
{
return &scan_params;
}
}
+467
View File
@@ -0,0 +1,467 @@
#ifdef __cplusplus
extern "C"
{
#endif
#include "ble_db_discovery.h"
#include "ble_gattc.h"
#include "ble_srv_common.h"
#include "sdk_config.h"
#include "nrf_ble_gq.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "FreeRTOS.h"
#include "message_buffer.h"
#include "semphr.h"
#include "task.h"
#include "timers.h"
#ifdef __cplusplus
}
#endif
#define MAX_CHAR_CNT 4
extern nrf_ble_gq_t *le_gap_queue(void);
struct le_uart_c_s
{
void (*evt_handler)(ble_evt_t const *p_ble_evt, void *p_context);
uint16_t conn_handle;
uint16_t char_handles[MAX_CHAR_CNT];
TimerHandle_t le_uart_c_cccd_timer;
MessageBufferHandle_t rx_msg;
SemaphoreHandle_t baud_sem;
uint32_t baud_rate;
};
#define UART_TX_HAND_IDX 0
#define UART_RX_HAND_IDX 1
#define UART_BAUD_HAND_IDX 2
typedef struct le_uart_c_s le_uart_c_t;
static le_uart_c_t m_le_uart_c;
static void on_disconnected(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
{
p_le_uart_c->conn_handle = BLE_CONN_HANDLE_INVALID;
for (int i = 0; i < COUNTOF(p_le_uart_c->char_handles); i++)
{
p_le_uart_c->char_handles[i] = BLE_GATT_HANDLE_INVALID;
}
}
static void on_connected(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
{
xTimerStart(p_le_uart_c->le_uart_c_cccd_timer, 0);
}
static void on_hvx(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
{
ble_gattc_evt_hvx_t *hvx = (void *)&p_ble_evt->evt.gattc_evt.params.hvx;
if (p_le_uart_c->rx_msg)
{
taskENTER_CRITICAL();
xMessageBufferSend(p_le_uart_c->rx_msg, (void *)hvx->data, hvx->len, 0);
taskEXIT_CRITICAL();
}
}
static void on_read_rsp(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
{
uint16_t handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle;
ble_gattc_evt_read_rsp_t const *p_rsp = &p_ble_evt->evt.gattc_evt.params.read_rsp;
if (handle == p_le_uart_c->char_handles[UART_RX_HAND_IDX])
{
}
else if (handle == p_le_uart_c->char_handles[UART_BAUD_HAND_IDX])
{
xSemaphoreGive(m_le_uart_c.baud_sem);
m_le_uart_c.baud_rate = *(uint32_t *)p_rsp->data;
}
}
ret_code_t le_uart_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bool notification_enable)
{
if (conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_PARAM;
}
if (char_handle == BLE_GATT_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_PARAM;
}
NRF_LOG_INFO("Configuring CCCD Handle = 0x%04X, Connection Handle = 0x%04X",
char_handle + 1,
conn_handle);
nrf_ble_gq_req_t cccd_req;
uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INVALID;
uint8_t cccd[BLE_CCCD_VALUE_LEN];
cccd[0] = LSB_16(cccd_val);
cccd[1] = MSB_16(cccd_val);
memset(&cccd_req, 0, sizeof(nrf_ble_gq_req_t));
cccd_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
cccd_req.params.gattc_write.handle = char_handle + 1;
cccd_req.params.gattc_write.len = BLE_CCCD_VALUE_LEN;
cccd_req.params.gattc_write.offset = 0;
cccd_req.params.gattc_write.p_value = cccd;
cccd_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
return nrf_ble_gq_item_add(le_gap_queue(), &cccd_req, conn_handle);
}
static void le_uart_c_cccd_timer_cb(TimerHandle_t xTimer)
{
xTimerStop(xTimer, pdMS_TO_TICKS(0));
extern ret_code_t le_uart_rx_notify(bool enable);
le_uart_rx_notify(true);
xMessageBufferReset(m_le_uart_c.rx_msg);
}
static void le_uart_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
le_uart_c_t *p_le_uart_c = (le_uart_c_t *)p_context;
if ((p_le_uart_c == NULL) || (p_ble_evt == NULL))
{
return;
}
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_DISCONNECTED:
on_disconnected(p_le_uart_c, p_ble_evt);
break;
case BLE_GAP_EVT_CONNECTED:
on_connected(p_le_uart_c, p_ble_evt);
break;
case BLE_GATTC_EVT_HVX:
/*
Handle Value Notification or Indication event.
Confirm indication with @ref sd_ble_gattc_hv_confirm.
See @ref ble_gattc_evt_hvx_t. */
on_hvx(p_le_uart_c, p_ble_evt);
break;
case BLE_GATTC_EVT_READ_RSP:
/*
Read Response event.
See @ref ble_gattc_evt_read_rsp_t. */
on_read_rsp(p_le_uart_c, p_ble_evt);
break;
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
/*
Primary Service Discovery Response event.
See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
break;
case BLE_GATTC_EVT_REL_DISC_RSP:
/*
Relationship Discovery Response event.
See @ref ble_gattc_evt_rel_disc_rsp_t. */
__BKPT(255);
break;
case BLE_GATTC_EVT_CHAR_DISC_RSP:
/*
Characteristic Discovery Response event.
See @ref ble_gattc_evt_char_disc_rsp_t. */
break;
case BLE_GATTC_EVT_DESC_DISC_RSP:
/*
Descriptor Discovery Response event.
See @ref ble_gattc_evt_desc_disc_rsp_t. */
break;
case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
/*
Attribute Information Response event.
See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
__BKPT(255);
break;
case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
/*
Read By UUID Response event.
See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
__BKPT(255);
break;
case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
/*
Read multiple Response event.
See @ref ble_gattc_evt_char_vals_read_rsp_t. */
__BKPT(255);
break;
case BLE_GATTC_EVT_WRITE_RSP:
/*
Write Response event.
See @ref ble_gattc_evt_write_rsp_t. */
break;
case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
/*
Exchange MTU Response event.
See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
break;
case BLE_GATTC_EVT_TIMEOUT:
/*
Timeout event.
See @ref ble_gattc_evt_timeout_t. */
__BKPT(255);
break;
case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
/*
Write without Response transmission complete. */
__BKPT(255);
break;
default:
// No implementation needed.
break;
}
}
void le_uart_c_on_db_disc_evt(ble_db_discovery_evt_t *p_evt)
{
ble_gatt_db_char_t *p_chars = p_evt->params.discovered_db.charateristics;
// Check if the service discovery is necessary for the link and if the event handler is present.
if (m_le_uart_c.evt_handler == NULL || m_le_uart_c.conn_handle == p_evt->conn_handle)
{
return;
}
// Check if the uart service was discovered.
if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
(p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_UART_SERVICE) &&
(p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
{
m_le_uart_c.conn_handle = p_evt->conn_handle;
for (int i = 0; i < p_evt->params.discovered_db.char_count; i++)
{
for (int j = 0; j < COUNTOF(m_le_uart_c.char_handles); j++)
{
if (p_chars[i].characteristic.uuid.uuid == BLE_UUID_UART_CHAR(j + 1))
{
m_le_uart_c.char_handles[j] = p_chars[i].characteristic.handle_value;
break;
}
}
}
}
}
static void le_uart_c_error_handler(uint32_t nrf_error, void *p_contex, uint16_t conn_handle)
{
UNUSED_PARAMETER(conn_handle);
__BKPT(255);
}
ret_code_t le_uart_tx(uint8_t const *p_data, uint16_t len)
{
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
nrf_ble_gq_req_t gq_req;
memset(&gq_req, 0, sizeof(gq_req));
gq_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
gq_req.error_handler.cb = le_uart_c_error_handler;
gq_req.error_handler.p_ctx = &m_le_uart_c;
gq_req.params.gattc_write.handle = m_le_uart_c.char_handles[UART_TX_HAND_IDX];
gq_req.params.gattc_write.p_value = p_data;
gq_req.params.gattc_write.len = len;
gq_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
return nrf_ble_gq_item_add(le_gap_queue(), &gq_req, m_le_uart_c.conn_handle);
}
ret_code_t le_uart_rx_notify(bool enable)
{
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_PARAM;
}
if (m_le_uart_c.char_handles[UART_RX_HAND_IDX] == BLE_GATT_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_PARAM;
}
ret_code_t ret = le_uart_ccdc_configure(m_le_uart_c.conn_handle, m_le_uart_c.char_handles[UART_RX_HAND_IDX], enable);
if (ret == NRF_SUCCESS)
{
NRF_LOG_INFO(enable == true ? "Enable Rx notifications." : "Disable Rx notifications.");
}
return ret;
}
ret_code_t le_uart_rx(uint8_t *p_data, uint16_t len, uint32_t timeout)
{
size_t recv_size = 0;
if (timeout)
{
recv_size = xMessageBufferReceive(m_le_uart_c.rx_msg, p_data, len, timeout);
}
else
{
taskENTER_CRITICAL();
recv_size = xMessageBufferReceive(m_le_uart_c.rx_msg, p_data, len, 0);
taskEXIT_CRITICAL();
}
if (recv_size)
{
return recv_size;
}
return NRF_ERROR_TIMEOUT;
}
ret_code_t le_uart_baudrate_get(uint32_t *baudrate)
{
ret_code_t ret;
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
nrf_ble_gq_req_t gq_req;
memset(&gq_req, 0, sizeof(gq_req));
gq_req.type = NRF_BLE_GQ_REQ_GATTC_READ;
gq_req.error_handler.cb = le_uart_c_error_handler;
gq_req.error_handler.p_ctx = &m_le_uart_c;
gq_req.params.gattc_read.handle = m_le_uart_c.char_handles[UART_BAUD_HAND_IDX];
ret = nrf_ble_gq_item_add(le_gap_queue(), &gq_req, m_le_uart_c.conn_handle);
if (ret == NRF_SUCCESS)
{
if (xSemaphoreTake(m_le_uart_c.baud_sem, pdMS_TO_TICKS(100)) == pdFALSE)
{
return NRF_ERROR_TIMEOUT;
}
*baudrate = m_le_uart_c.baud_rate;
}
return ret;
}
ret_code_t le_uart_baudrate_set(uint32_t baudrate)
{
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
{
return NRF_ERROR_INVALID_STATE;
}
nrf_ble_gq_req_t gq_req;
memset(&gq_req, 0, sizeof(gq_req));
gq_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
gq_req.error_handler.cb = le_uart_c_error_handler;
gq_req.error_handler.p_ctx = &m_le_uart_c;
gq_req.params.gattc_write.handle = m_le_uart_c.char_handles[UART_BAUD_HAND_IDX];
gq_req.params.gattc_write.p_value = (void *)&baudrate;
gq_req.params.gattc_write.len = sizeof(baudrate);
gq_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
return nrf_ble_gq_item_add(le_gap_queue(), &gq_req, m_le_uart_c.conn_handle);
}
static void ble_uart_echo(void *p_arg)
{
void le_scan_start(void);
le_scan_start();
vTaskDelay(pdMS_TO_TICKS(3000));
void le_scan_stop(void);
le_scan_stop();
vTaskDelay(pdMS_TO_TICKS(10));
ble_gap_addr_t peer_addr;
peer_addr.addr_id_peer = 0;
peer_addr.addr_type = BLE_GAP_ADDR_TYPE_ANONYMOUS;
peer_addr.addr[0] = 0xDA;
peer_addr.addr[1] = 0x71;
peer_addr.addr[2] = 0x1F;
peer_addr.addr[3] = 0x1F;
peer_addr.addr[4] = 0x05;
peer_addr.addr[5] = 0xDC;
extern void le_scan_get_peer_addr(ble_gap_addr_t * p_peer_addr);
le_scan_get_peer_addr(&peer_addr);
vTaskDelay(pdMS_TO_TICKS(10));
extern void le_gap_connet(ble_gap_addr_t * p_peer_addr);
le_gap_connet(&peer_addr);
vTaskDelay(pdMS_TO_TICKS(1000));
uint32_t get_baud = 1000000;
uint32_t set_baud = 115200;
extern ret_code_t le_uart_baudrate_get(uint32_t * baudrate);
le_uart_baudrate_get(&get_baud);
NRF_LOG_INFO("Get Baud rate: %d", get_baud);
extern ret_code_t le_uart_baudrate_set(uint32_t baudrate);
le_uart_baudrate_set(set_baud);
NRF_LOG_INFO("Set Baud rate: %d", set_baud);
le_uart_baudrate_get(&get_baud);
NRF_LOG_INFO("Get Baud rate: %d", get_baud);
extern ret_code_t le_uart_tx(uint8_t const *p_data, uint16_t len);
uint8_t str[] = "ABCDEF";
le_uart_tx(str, strlen(str));
for (;;)
{
uint8_t recv[256];
uint32_t size;
size = le_uart_rx(recv, sizeof(recv), portMAX_DELAY);
le_uart_tx(recv, size);
}
}
void le_uart_c_init(void)
{
m_le_uart_c.rx_msg = xMessageBufferCreate(4096);
m_le_uart_c.baud_sem = xSemaphoreCreateBinary();
m_le_uart_c.evt_handler = le_uart_c_evt_handler;
m_le_uart_c.conn_handle = BLE_CONN_HANDLE_INVALID;
for (int i = 0; i < COUNTOF(m_le_uart_c.char_handles); i++)
{
m_le_uart_c.char_handles[i] = BLE_GATT_HANDLE_INVALID;
}
ret_code_t err_code;
uint8_t uuid_type;
ble_uuid_t uuid = {
.type = BLE_UUID_TYPE_BLE,
.uuid = BLE_UUID_UART_SERVICE,
};
err_code = ble_db_discovery_evt_register(&uuid);
APP_ERROR_CHECK(err_code);
NRF_SDH_BLE_OBSERVER(m_uart_c_observer, 1, le_uart_c_evt_handler, &m_le_uart_c);
m_le_uart_c.le_uart_c_cccd_timer = xTimerCreate("Timer", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, le_uart_c_cccd_timer_cb);
#if 0
xTaskCreate(ble_uart_echo, "ble uart echo", 2048, NULL, 3, NULL);
#endif
}
+4 -78
View File
@@ -102,80 +102,6 @@ static void le_stack_Init(void)
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, le_evt_handler, NULL);
}
#define ROY_MEM_SEL NRF_GPIO_PIN_MAP(1, 9)
#define ROY_MEM_BZY NRF_GPIO_PIN_MAP(0, 8)
#define ROY_MEM_REQ NRF_GPIO_PIN_MAP(0, 6)
#define ROY_RAM_SEL NRF_GPIO_PIN_MAP(0, 5)
#define ROY_MEM_TEST_01 NRF_GPIO_PIN_MAP(0, 26)
#define ROY_MEM_TEST_02 NRF_GPIO_PIN_MAP(0, 17)
#define ROY_MEM_TEST_03 NRF_GPIO_PIN_MAP(0, 21)
#define ROY_MEM_TEST_04 NRF_GPIO_PIN_MAP(0, 19)
#define ROY_MEM_TEST_05 NRF_GPIO_PIN_MAP(0, 22)
#define ROY_LED1 NRF_GPIO_PIN_MAP(1, 10)
static void mem_pin(void *p_arg)
{
nrf_gpio_cfg_output(ROY_MEM_SEL);
nrf_gpio_cfg_output(ROY_MEM_BZY);
nrf_gpio_cfg_output(ROY_MEM_REQ);
nrf_gpio_cfg_output(ROY_RAM_SEL);
static uint8_t time = 0;
for (;;) {
NRF_LOG_INFO("mem_pin %d", time);
time++;
nrf_gpio_pin_set(ROY_MEM_SEL);
nrf_gpio_pin_set(ROY_MEM_BZY);
nrf_gpio_pin_set(ROY_MEM_REQ);
nrf_gpio_pin_set(ROY_RAM_SEL);
NRF_LOG_INFO("mem_pin on");
nrf_delay_ms(2000);
nrf_gpio_pin_clear(ROY_MEM_SEL);
nrf_gpio_pin_clear(ROY_MEM_BZY);
nrf_gpio_pin_clear(ROY_MEM_REQ);
nrf_gpio_pin_clear(ROY_RAM_SEL);
NRF_LOG_INFO("mem_pin off");
nrf_delay_ms(2000);
}
}
static void test_pin(void *p_arg)
{
nrf_gpio_cfg_output(ROY_MEM_TEST_01);
nrf_gpio_cfg_output(ROY_MEM_TEST_02);
nrf_gpio_cfg_output(ROY_MEM_TEST_03);
nrf_gpio_cfg_output(ROY_MEM_TEST_04);
nrf_gpio_cfg_output(ROY_MEM_TEST_05);
nrf_gpio_cfg_output(ROY_LED1);
static uint8_t time = 0;
for (;;) {
NRF_LOG_INFO("test_pin %d", time);
time++;
nrf_gpio_pin_set(ROY_MEM_TEST_01);
nrf_gpio_pin_set(ROY_MEM_TEST_02);
nrf_gpio_pin_set(ROY_MEM_TEST_03);
nrf_gpio_pin_set(ROY_MEM_TEST_04);
nrf_gpio_pin_set(ROY_MEM_TEST_05);
nrf_gpio_pin_set(ROY_LED1);
NRF_LOG_INFO("test_pin on");
nrf_delay_ms(1000);
nrf_gpio_pin_clear(ROY_MEM_TEST_01);
nrf_gpio_pin_clear(ROY_MEM_TEST_02);
nrf_gpio_pin_clear(ROY_MEM_TEST_03);
nrf_gpio_pin_clear(ROY_MEM_TEST_04);
nrf_gpio_pin_clear(ROY_MEM_TEST_05);
nrf_gpio_pin_clear(ROY_LED1);
NRF_LOG_INFO("test_pin off");
nrf_delay_ms(1000);
}
}
static void initialize(void *p_context)
{
extern void uart_drv_init(void);
@@ -193,6 +119,9 @@ static void initialize(void *p_context)
extern void le_gatt_c_init(void);
le_gatt_c_init();
extern void le_uart_c_init(void);
le_uart_c_init();
extern void le_gap_init(void);
le_gap_init();
@@ -208,7 +137,7 @@ static void initialize(void *p_context)
int main(void)
{
NRF_LOG_INIT(NULL, 0);
NRF_LOG_INIT(xTaskGetTickCount, configTICK_RATE_HZ);
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("%s Build: %s %s", LE_DEVICE_NAME, __TIME__, __DATE__);
@@ -216,9 +145,6 @@ int main(void)
nrf_sdh_freertos_init(initialize, NULL);
//xTaskCreate(mem_pin, "mem_pin", 512, NULL, 5, NULL);
//xTaskCreate(test_pin, "test_pin", 512, NULL, 5, NULL);
vTaskStartScheduler();
for (;;)
+283
View File
@@ -0,0 +1,283 @@
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "nrf_spim.h"
#include "FreeRTOS.h"
#include "message_buffer.h"
#include "semphr.h"
#include "stream_buffer.h"
#include "task.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#ifdef __cplusplus
}
#endif
#define MEM_SEL_PIN NRF_GPIO_PIN_MAP(1, 9)
#define MEM_BZY_PIN NRF_GPIO_PIN_MAP(0, 8)
#define MEM_REQ_PIN NRF_GPIO_PIN_MAP(0, 6)
#define RAM_SEL_PIN NRF_GPIO_PIN_MAP(0, 5)
#define MEM_TEST_01_PIN NRF_GPIO_PIN_MAP(0, 26)
#define MEM_TEST_02_PIN NRF_GPIO_PIN_MAP(0, 17)
#define MEM_TEST_03_PIN NRF_GPIO_PIN_MAP(0, 21)
#define MEM_TEST_04_PIN NRF_GPIO_PIN_MAP(0, 19)
#define MEM_TEST_05_PIN NRF_GPIO_PIN_MAP(0, 22)
#define MEM_SEL_GPIOTE_ID 0
#define MEM_REQ_GPIOTE_ID 1
#define MEM_DATA_UNIT 40
#define MEM_DUMP 0
static int ram_sel = 0;
static SemaphoreHandle_t mem_sel_semphr = NULL;
static TaskHandle_t mem_drv_task_handle = NULL;
static StreamBufferHandle_t mem_drv_stream = NULL;
typedef struct
{
struct
{
union
{
uint32_t val;
struct
{
uint16_t len;
uint16_t marker;
} __PACKED;
} header[3];
} green_frame;
uint8_t red_frame[2048];
} mem_data_t;
mem_data_t mem_data;
uint32_t mem_notify_cnt = 0;
uint32_t mem_req;
uint32_t mem_sel;
void mem_ram_select(int select)
{
ram_sel = select;
switch (ram_sel)
{
case 0:
nrf_gpio_pin_clear(RAM_SEL_PIN);
break;
case 1:
nrf_gpio_pin_set(RAM_SEL_PIN);
break;
default:
break;
}
NRF_LOG_INFO("Select SRAM: %d", ram_sel);
}
extern int sram_drv_write(uint32_t addr, void *p_dest, uint32_t len);
extern int sram_drv_read(uint32_t addr, void *p_dest, uint32_t len);
static bool chk_sram_swtich_evt(uint32_t *new_ram_sel)
{
/************************************************
* When the mem_sel is in a low-level state,
* the state of mem_req is considered valid.
************************************************/
while (mem_sel == false)
{
vTaskDelay(pdMS_TO_TICKS(5));
/* sync mem_req status */
mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
if (mem_req != ram_sel)
{
*new_ram_sel = mem_req;
return true;
}
}
return false;
}
static void mem_drv_task(void *p_arg)
{
extern void sram_drv_init(void);
sram_drv_init();
extern void sram_drv_reset(void);
mem_ram_select(0);
sram_drv_reset();
mem_ram_select(1);
sram_drv_reset();
mem_ram_select(0);
for (;;)
{
uint32_t new_ram_sel;
xSemaphoreTake(mem_sel_semphr, portMAX_DELAY);
if (chk_sram_swtich_evt(&new_ram_sel) == false)
{
continue;
}
vTaskDelay(pdMS_TO_TICKS(100));
uint32_t green_frame_size = sizeof(mem_data.green_frame);
uint32_t red_frame_size = 0;
uint32_t total_size = 0;
/* read red frame data from streambuffer */
taskENTER_CRITICAL();
red_frame_size = xStreamBufferReceive(mem_drv_stream, mem_data.red_frame, sizeof(mem_data.red_frame), 0);
taskEXIT_CRITICAL();
/* write green & red frame data to sram */
total_size = green_frame_size + red_frame_size;
mem_data.green_frame.header[0].len = __REVSH(total_size);
mem_data.green_frame.header[0].marker = __REVSH(0xA55A);
mem_data.green_frame.header[1].val = mem_data.green_frame.header[0].val;
mem_data.green_frame.header[2].val = mem_data.green_frame.header[0].val;
sram_drv_write(0x0000, &mem_data, total_size);
/* switch sram */
mem_ram_select(new_ram_sel);
#if MEM_DUMP
for (uint32_t i = 0; i < total_size / 32; i++)
{
uint8_t *p = (uint8_t *)&mem_data;
NRF_LOG_HEXDUMP_INFO(&p[i * 32], 32);
}
if (total_size % 32)
{
uint8_t *p = (uint8_t *)&mem_data;
NRF_LOG_HEXDUMP_INFO(&p[(total_size / 32) * 32], total_size % 32);
}
#endif
NRF_LOG_INFO("Write: %4d bytes, and switch sram done!!!", total_size);
}
}
void mem_board_reset(void)
{
mem_notify_cnt = 0;
xStreamBufferReset(mem_drv_stream);
}
void mem_notify_cb(uint8_t *p, uint32_t len)
{
/* write red frame data to streambuffer */
static struct
{
uint8_t prefix;
uint8_t cnt;
uint8_t len;
uint8_t content[64];
} swap_buf;
swap_buf.prefix = 0xFF;
swap_buf.cnt = mem_notify_cnt++;
swap_buf.len = len;
memcpy(swap_buf.content, p, len);
swap_buf.content[len + 0] = 0;
swap_buf.content[len + 1] = 0;
swap_buf.content[len + 2] = 0;
swap_buf.content[len + 3] = 0;
swap_buf.content[len + 4] = 0;
uint32_t sum = 0;
for (int i = 0; i < len; i++)
{
sum += p[i];
}
sum += swap_buf.prefix;
sum += swap_buf.cnt;
sum += swap_buf.len;
swap_buf.content[len + 5] = sum & 0xFF;
taskENTER_CRITICAL();
xStreamBufferSend(mem_drv_stream, &swap_buf, 3 + len + 6, 0);
taskEXIT_CRITICAL();
}
void mem_board_init(void)
{
// Config RAM test pin
nrf_gpio_cfg_input(MEM_TEST_01_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_02_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_03_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_04_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_05_PIN, NRF_GPIO_PIN_PULLUP);
// Config RAM select pin
nrf_gpio_cfg_output(RAM_SEL_PIN);
nrf_gpio_pin_clear(RAM_SEL_PIN);
// Config PI Ctrl pin
nrf_gpio_cfg_input(MEM_SEL_PIN, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(MEM_REQ_PIN, NRF_GPIO_PIN_NOPULL);
nrf_gpiote_event_configure(MEM_SEL_GPIOTE_ID, MEM_SEL_PIN, NRF_GPIOTE_POLARITY_TOGGLE);
nrf_gpiote_event_enable(MEM_SEL_GPIOTE_ID);
nrf_gpiote_int_enable(0x01 << MEM_SEL_GPIOTE_ID);
nrf_gpiote_event_configure(MEM_REQ_GPIOTE_ID, MEM_REQ_PIN, NRF_GPIOTE_POLARITY_TOGGLE);
nrf_gpiote_event_enable(MEM_REQ_GPIOTE_ID);
nrf_gpiote_int_enable(0x01 << MEM_REQ_GPIOTE_ID);
// Create Semphr & Task
mem_sel_semphr = xSemaphoreCreateBinary();
mem_drv_stream = xStreamBufferCreate(4096, 1);
xTaskCreate(mem_drv_task, "mem_drv", 256, NULL, 5, NULL);
sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_MID);
sd_nvic_EnableIRQ(GPIOTE_IRQn);
}
static void mem_sel_isr(void)
{
mem_sel = nrf_gpio_pin_read(MEM_SEL_PIN);
if (mem_sel == 0)
{
BaseType_t xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(mem_sel_semphr, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
static void mem_req_isr(void)
{
mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
}
void GPIOTE_IRQHandler(void)
{
if (NRF_GPIOTE->EVENTS_IN[MEM_SEL_GPIOTE_ID])
{
NRF_GPIOTE->EVENTS_IN[MEM_SEL_GPIOTE_ID] = 0;
mem_sel_isr();
return;
}
if (NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID])
{
NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID] = 0;
mem_req_isr();
return;
}
}
View File
View File
+1
View File
@@ -4,6 +4,7 @@
extern "C"
{
#endif
#include "app_config.h"
#include "nrf_gpio.h"
#include "nrf_spim.h"
View File
View File
+4 -2
View File
@@ -95,15 +95,17 @@
<EnableAsyncExecutionMode>false</EnableAsyncExecutionMode>
<AsyncModeSupportsBreakpoints>true</AsyncModeSupportsBreakpoints>
<TemporaryBreakConsolidationTimeout>0</TemporaryBreakConsolidationTimeout>
<BacktraceFrameLimit>0</BacktraceFrameLimit>
<EnableNonStopMode>false</EnableNonStopMode>
<MaxBreakpointLimit>0</MaxBreakpointLimit>
<EnableVerboseMode>true</EnableVerboseMode>
<EnablePrettyPrinters>false</EnablePrettyPrinters>
<EnableAbsolutePathReporting>true</EnableAbsolutePathReporting>
</AdditionalGDBSettings>
<DebugMethod>
<ID>jlink-jtag</ID>
<InterfaceID>com.sysprogs.debug.jlink.jlinksw</InterfaceID>
<InterfaceSerialNumber>000682409936</InterfaceSerialNumber>
<InterfaceSerialNumber>000601012352</InterfaceSerialNumber>
<Configuration xsi:type="com.visualgdb.edp.segger.settings">
<CommandLine>-select USB -device $$SYS:MCU_ID$$ -speed auto -if SWD</CommandLine>
<ProgramMode>Enabled</ProgramMode>
@@ -130,7 +132,7 @@
<EndOfStackSymbol>_estack</EndOfStackSymbol>
<TimestampProviderTicksPerSecond>0</TimestampProviderTicksPerSecond>
<KeepConsoleAfterExit>false</KeepConsoleAfterExit>
<UnusedStackFillPattern xsi:nil="true" />
<UnusedStackFillPattern>2779096485</UnusedStackFillPattern>
<CheckInterfaceDrivers>true</CheckInterfaceDrivers>
</Debug>
</VisualGDBProjectSettings2>
+17
View File
@@ -0,0 +1,17 @@
{
"folders": [
{
"path": "."
},
{
"path": "../bmd380_sdk"
}
],
"settings": {
"files.associations": {
"ble_db_discovery.h": "c",
"ble_dis_c.h": "c",
"sdk_config.h": "c"
}
}
}
+8 -2
View File
@@ -32,13 +32,15 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
<GNUConfigurationType>Debug</GNUConfigurationType>
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>12.2.1/12.2/r2</ToolchainVersion>
<ToolchainVersion>14.2.1/15.2/r2</ToolchainVersion>
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
<UseCCache>true</UseCCache>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|VisualGDB'">
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>12.2.1/12.2/r2</ToolchainVersion>
<ToolchainVersion>14.2.1/15.2/r2</ToolchainVersion>
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
<UseCCache>true</UseCCache>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
<ClCompile>
@@ -49,6 +51,8 @@
<SupportRTTI>false</SupportRTTI>
<AdditionalOptions />
<CPPLanguageStandard />
<Optimization>O0</Optimization>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<LinkerScript>nRF52811_XXAA_s140.lds</LinkerScript>
@@ -66,6 +70,7 @@
<CLanguageStandard>GNU99</CLanguageStandard>
<SupportExceptions>false</SupportExceptions>
<SupportRTTI>false</SupportRTTI>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<LinkerScript>nRF52811_XXAA_s140.lds</LinkerScript>
@@ -79,6 +84,7 @@
<ItemGroup>
<ClCompile Include="host_tasks.c" />
<ClCompile Include="le_gatt_c.c" />
<ClCompile Include="le_uart_c.c" />
<ClCompile Include="mem_drv.c" />
<ClCompile Include="sram_drv.c" />
<ClCompile Include="syscalls.c" />
+3
View File
@@ -1685,6 +1685,9 @@
<ClCompile Include="syscalls.c">
<Filter>Source files</Filter>
</ClCompile>
<ClCompile Include="le_uart_c.c">
<Filter>Source files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\bmd380_sdk\components\ble\ble_services\ble_dis_c\ble_dis_c.h">
+47
View File
@@ -0,0 +1,47 @@
# Call Cmake from the 'build' subfolder with the command below.
# For using Make:
# cmake -DCMAKE_MAKE_PROGRAM=make.exe -DCMAKE_TOOLCHAIN_FILE="arm-none-eabi-gcc.cmake" -G "Unix Makefiles" ..
# followed by
# 'make' or 'cmake --build .' to build it
#
# For using Ninja:
# cmake -DCMAKE_MAKE_PROGRAM=ninja.exe -DCMAKE_TOOLCHAIN_FILE="arm-none-eabi-gcc.cmake" -G "Ninja" ..
# followed by
# 'ninja' or 'cmake --build .' to build it
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
if(CMAKE_HOST_WIN32)
set(EXECUTESUFFIX ".exe")
set(ARM_TOOLCHAIN_DIR "C:/SysGCC/arm-eabi/bin")
elseif(CMAKE_HOST_UNIX)
set(EXECUTESUFFIX "")
if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
message(STATUS "Running on macOS")
set(ARM_TOOLCHAIN_DIR "/opt/homebrew/bin")
elseif(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Linux")
message(STATUS "Running on Linux (likely Ubuntu)")
set(ARM_TOOLCHAIN_DIR "/opt/arm-none-eabi/bin")
endif()
else()
message(WARNING "Unknown host OS: ${CMAKE_HOST_SYSTEM_NAME}")
endif()
set(BINUTILS_PATH ${ARM_TOOLCHAIN_DIR})
set(TOOLCHAIN_PREFIX arm-none-eabi-)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(CMAKE_C_COMPILER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}gcc${EXECUTESUFFIX})
set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER})
set(CMAKE_CXX_COMPILER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}g++${EXECUTESUFFIX})
set(CMAKE_LINKER ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}ld${EXECUTESUFFIX})
set(CMAKE_OBJCOPY ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}objcopy${EXECUTESUFFIX} CACHE INTERNAL "objcopy tool")
set(CMAKE_SIZE ${ARM_TOOLCHAIN_DIR}/${TOOLCHAIN_PREFIX}size${EXECUTESUFFIX} CACHE INTERNAL "size tool")
set(CMAKE_FIND_ROOT_PATH ${BINUTILS_PATH})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+21
View File
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.15.3)
file(GLOB FREERTO_KERNEL_SOURCES "${NRF_SDK_DIR}/external/freertos/source/*.c")
add_library(freertos OBJECT
${NRF_SDK_DIR}/external/freertos/portable/GCC/nrf52/port.c
${NRF_SDK_DIR}/external/freertos/portable/CMSIS/nrf52/port_cmsis.c
${NRF_SDK_DIR}/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c
${NRF_SDK_DIR}/external/freertos/source/portable/MemMang/heap_4.c
${FREERTO_KERNEL_SOURCES}
)
target_include_directories(freertos PUBLIC
${NRF_SDK_DIR}/external/freertos/portable/CMSIS/nrf52
${NRF_SDK_DIR}/external/freertos/portable/GCC/nrf52
${NRF_SDK_DIR}/external/freertos/source/include
)
target_link_libraries(freertos PRIVATE
prj_config
)
@@ -1,21 +1,15 @@
/* Linker script for nRF52811_XXAA */
/* Linker script for nRF52840_XXAA */
GROUP(S140_softdevice.o)
MEMORY
{
FLASH_SOFTDEVICE (rx) : ORIGIN = 0x00000000, LENGTH = 0x00027000
FLASH (rx) : ORIGIN = 0x00027000, LENGTH = 0x000d9000
EXTFLASH (rx) : ORIGIN = 0x12000000, LENGTH = 0x8000000
RAM_SOFTDEVICE (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010000
RAM (rwx) : ORIGIN = 0x20010000, LENGTH = 0x0002F000
RTT (rwx) : ORIGIN = 0x2003F000, LENGTH = 0x00001000
CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x6000
}
SECTIONS
{
.segger_rtt (NOLOAD) :
{
} > RTT
CODE_RAM (rwx) : ORIGIN = 0x800000, LENGTH = 0x40000
}
SECTIONS
@@ -23,14 +17,12 @@ SECTIONS
.softdevice :
{
KEEP(*(.softdevice))
FILL(0xFFFFFFFF);
. = 0x00027000;
} > FLASH_SOFTDEVICE
.softdevice_sram :
{
FILL(0xFFFFFFFF);
. = 0x000079e0;
. = 0x00010000;
} > RAM_SOFTDEVICE
}
+128
View File
@@ -0,0 +1,128 @@
SECTIONS
{
}
SECTIONS
{
. = ALIGN(4);
.mem_section_dummy_ram :
{
}
.cli_sorted_cmd_ptrs :
{
PROVIDE(__start_cli_sorted_cmd_ptrs = .);
KEEP(*(.cli_sorted_cmd_ptrs))
PROVIDE(__stop_cli_sorted_cmd_ptrs = .);
} > RAM
.fs_data :
{
PROVIDE(__start_fs_data = .);
KEEP(*(.fs_data))
PROVIDE(__stop_fs_data = .);
} > RAM
.log_dynamic_data :
{
PROVIDE(__start_log_dynamic_data = .);
KEEP(*(SORT(.log_dynamic_data*)))
PROVIDE(__stop_log_dynamic_data = .);
} > RAM
.log_filter_data :
{
PROVIDE(__start_log_filter_data = .);
KEEP(*(SORT(.log_filter_data*)))
PROVIDE(__stop_log_filter_data = .);
} > RAM
} INSERT AFTER .data;
SECTIONS
{
.mem_section_dummy_rom :
{
}
.sdh_soc_observers :
{
PROVIDE(__start_sdh_soc_observers = .);
KEEP(*(SORT(.sdh_soc_observers*)))
PROVIDE(__stop_sdh_soc_observers = .);
} > FLASH
.sdh_ble_observers :
{
PROVIDE(__start_sdh_ble_observers = .);
KEEP(*(SORT(.sdh_ble_observers*)))
PROVIDE(__stop_sdh_ble_observers = .);
} > FLASH
.pwr_mgmt_data :
{
PROVIDE(__start_pwr_mgmt_data = .);
KEEP(*(SORT(.pwr_mgmt_data*)))
PROVIDE(__stop_pwr_mgmt_data = .);
} > FLASH
.sdh_req_observers :
{
PROVIDE(__start_sdh_req_observers = .);
KEEP(*(SORT(.sdh_req_observers*)))
PROVIDE(__stop_sdh_req_observers = .);
} > FLASH
.sdh_state_observers :
{
PROVIDE(__start_sdh_state_observers = .);
KEEP(*(SORT(.sdh_state_observers*)))
PROVIDE(__stop_sdh_state_observers = .);
} > FLASH
.sdh_stack_observers :
{
PROVIDE(__start_sdh_stack_observers = .);
KEEP(*(SORT(.sdh_stack_observers*)))
PROVIDE(__stop_sdh_stack_observers = .);
} > FLASH
.nrf_queue :
{
PROVIDE(__start_nrf_queue = .);
KEEP(*(.nrf_queue))
PROVIDE(__stop_nrf_queue = .);
} > FLASH
.nrf_balloc :
{
PROVIDE(__start_nrf_balloc = .);
KEEP(*(.nrf_balloc))
PROVIDE(__stop_nrf_balloc = .);
} > FLASH
.cli_command :
{
PROVIDE(__start_cli_command = .);
KEEP(*(.cli_command))
PROVIDE(__stop_cli_command = .);
} > FLASH
.crypto_data :
{
PROVIDE(__start_crypto_data = .);
KEEP(*(SORT(.crypto_data*)))
PROVIDE(__stop_crypto_data = .);
} > FLASH
.log_const_data :
{
PROVIDE(__start_log_const_data = .);
KEEP(*(SORT(.log_const_data*)))
PROVIDE(__stop_log_const_data = .);
} > FLASH
.log_backends :
{
PROVIDE(__start_log_backends = .);
KEEP(*(SORT(.log_backends*)))
PROVIDE(__stop_log_backends = .);
} > FLASH
} INSERT AFTER .text
INCLUDE "nrf_common.ld"
PROVIDE(_sbss = __bss_start__);
PROVIDE(_ebss = __bss_end__);
PROVIDE(_sdata = __data_start__);
PROVIDE(_sidata = __etext);
PROVIDE(_estack = __StackTop);
PROVIDE(_edata = __data_end__);
PROVIDE(__isr_vector = __StackTop);
PROVIDE(_etext = __etext);
-146
View File
@@ -1,146 +0,0 @@
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include "nrf_gpio.h"
#include "nrf_gpiote.h"
#include "nrf_spim.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#ifdef __cplusplus
}
#endif
#define MEM_SEL_PIN NRF_GPIO_PIN_MAP(1, 9)
#define MEM_BZY_PIN NRF_GPIO_PIN_MAP(0, 8)
#define MEM_REQ_PIN NRF_GPIO_PIN_MAP(0, 6)
#define RAM_SEL_PIN NRF_GPIO_PIN_MAP(0, 5)
#define MEM_TEST_01_PIN NRF_GPIO_PIN_MAP(0, 26)
#define MEM_TEST_02_PIN NRF_GPIO_PIN_MAP(0, 17)
#define MEM_TEST_03_PIN NRF_GPIO_PIN_MAP(0, 21)
#define MEM_TEST_04_PIN NRF_GPIO_PIN_MAP(0, 19)
#define MEM_TEST_05_PIN NRF_GPIO_PIN_MAP(0, 22)
#define MEM_REQ_GPIOTE_ID 0
static int ram_sel_signal = 0;
static SemaphoreHandle_t mem_drv_semphr = NULL;
static TaskHandle_t mem_drv_task_handle = NULL;
void mem_ram_select(int select)
{
ram_sel_signal = select;
switch (ram_sel_signal)
{
case 0:
nrf_gpio_pin_clear(RAM_SEL_PIN);
break;
case 1:
nrf_gpio_pin_set(RAM_SEL_PIN);
break;
default:
break;
}
}
static void mem_drv_task(void *p_arg)
{
static uint32_t sel = 0;
extern void sram_drv_init(void);
sram_drv_init();
extern void sram_drv_reset(void);
extern int sram_drv_write(uint32_t addr, void *p_dest, uint32_t len);
NRF_LOG_INFO("build----1")
for (int i = 0; i < 2; i++)
{
sel ^= 1;
mem_ram_select(sel);
sram_drv_reset();
if (sel) {
uint8_t buf_1[12] = {1,2,2,6,5,6,7,8,9,0};
sram_drv_write(0x0000, buf_1, sizeof(buf_1));
} else {
uint8_t buf_0[12] = {9,9,8,8,7,7,6,6,5,5,0};
sram_drv_write(0x0000, buf_0, sizeof(buf_0));
}
}
for (;;)
{
extern int sram_drv_read(uint32_t addr, void *p_dest, uint32_t len);
uint8_t buf[4];
xSemaphoreTake(mem_drv_semphr, portMAX_DELAY);
sel ^= 0x01;
mem_ram_select(sel);
sram_drv_read(0x0000, buf, sizeof(buf));
NRF_LOG_INFO("mem_sel[%d]: 0x%02X, 0x%02X, 0x%02X, 0x%02X", sel, buf[0], buf[1], buf[2], buf[3]);
}
}
void mem_board_init(void)
{
// Config RAM test pin
nrf_gpio_cfg_input(MEM_TEST_01_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_02_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_03_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_04_PIN, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_input(MEM_TEST_05_PIN, NRF_GPIO_PIN_PULLUP);
// Config RAM select pin
nrf_gpio_cfg_output(RAM_SEL_PIN);
nrf_gpio_pin_clear(RAM_SEL_PIN);
// Config PI Ctrl pin
nrf_gpio_cfg_input(MEM_SEL_PIN, NRF_GPIO_PIN_NOPULL);
nrf_gpio_cfg_input(MEM_REQ_PIN, NRF_GPIO_PIN_NOPULL);
nrf_gpiote_event_configure(MEM_REQ_GPIOTE_ID, MEM_REQ_PIN, NRF_GPIOTE_POLARITY_TOGGLE);
nrf_gpiote_event_enable(MEM_REQ_GPIOTE_ID);
nrf_gpiote_int_enable(0x01 << MEM_REQ_GPIOTE_ID);
// Create Semphr & Task
mem_drv_semphr = xSemaphoreCreateBinary();
xTaskCreate(mem_drv_task, "mem_drv", 256, NULL, 5, NULL);
sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_HIGH);
sd_nvic_EnableIRQ(GPIOTE_IRQn);
}
static void mem_req_int_callback(void)
{
uint32_t mem_sel = nrf_gpio_pin_read(MEM_SEL_PIN);
uint32_t mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
if (mem_sel != mem_req)
{
BaseType_t xHigherPriorityTaskWoken;
xSemaphoreGiveFromISR(mem_drv_semphr, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
}
void GPIOTE_IRQHandler(void)
{
if (NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID])
{
NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID] = 0;
mem_req_int_callback();
}
}
+2 -2
View File
@@ -2,8 +2,8 @@
<EmbeddedProfile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
<ToolchainVersion>
<GCC>12.2.1</GCC>
<GDB>12.2</GDB>
<GCC>14.2.1</GCC>
<GDB>15.2</GDB>
<Revision>2</Revision>
</ToolchainVersion>
<BspID>com.sysprogs.arm.nordic.nrf5x</BspID>