mirror of
https://github.com/bluekitchen/btstack.git
synced 2025-03-13 04:13:54 +00:00
port: new nrf5 port with Cinnamon Controller/Link Layer
This commit is contained in:
parent
aff7b6f1f5
commit
0138fcae13
48
port/nrf5-cinnamon/CMakeLists.txt
Normal file
48
port/nrf5-cinnamon/CMakeLists.txt
Normal file
@ -0,0 +1,48 @@
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(n5rf-ll)
|
||||
|
||||
# nrf5 sdk root with nrfx
|
||||
set(NRF5_SDK_ROOT /Users/mringwal/Projects/Nordic/nRF5_SDK_17.0.2_d674dde)
|
||||
|
||||
# list all sources
|
||||
file(GLOB_RECURSE btstack_src_src ../../src/*.c)
|
||||
file(GLOB_RECURSE btstack_src_hdr ../../src/*.h)
|
||||
file(GLOB_RECURSE btstack_embedded_src ../../platform/embedded/src/*.c)
|
||||
file(GLOB_RECURSE btstack_embedded_hdr ../../platform/embedded/src/*.h)
|
||||
file(GLOB_RECURSE btstack_port_src *.c)
|
||||
file(GLOB_RECURSE btstack_port_hdr *.h)
|
||||
file(GLOB_RECURSE nrfx_src ${NRF5_SDK_ROOT}/modules/*.c)
|
||||
file(GLOB_RECURSE nrfx_hdr ${NRF5_SDK_ROOT}/modules/*.h)
|
||||
|
||||
# Compile pca10040 port using Make
|
||||
find_program(MAKE make)
|
||||
add_custom_target(pca10040
|
||||
ALL
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/pca10040/armgcc
|
||||
COMMAND ${MAKE}
|
||||
SOURCES ${btstack_src_src} ${btstack_embedded_src} ${btstack_port_src} ${nrfx_src})
|
||||
|
||||
# fake executable for navigation in IDE
|
||||
add_executable(port EXCLUDE_FROM_ALL
|
||||
${btstack_src_src}
|
||||
${btstack_src_hdr}
|
||||
${btstack_embedded_src}
|
||||
${btstack_embedded_hdr}
|
||||
${btstack_port_src}
|
||||
${btstack_port_hdr}
|
||||
${nrfx_src}
|
||||
${nrfx_hdr}
|
||||
)
|
||||
target_include_directories(port SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/port
|
||||
../../3rd-party/segger-rtt
|
||||
../../platform/embedded
|
||||
../../chipset/controller
|
||||
../../src
|
||||
${NRF5_SDK_ROOT}/components/boards
|
||||
${NRF5_SDK_ROOT}/components/libraries/delay
|
||||
${NRF5_SDK_ROOT}/modules/nrfx/drivers/include
|
||||
${NRF5_SDK_ROOT}/modules/nrfx/mdk
|
||||
${NRF5_SDK_ROOT}/modules/nrfx/hal
|
||||
${NRF5_SDK_ROOT}/modules/nrfx
|
||||
)
|
25
port/nrf5-cinnamon/README.md
Normal file
25
port/nrf5-cinnamon/README.md
Normal file
@ -0,0 +1,25 @@
|
||||
# BTstack port with Cinnamon for Nordic nRF5 Series
|
||||
|
||||
*Cinnamon* is BlueKitchen's minimal, yet robust Controller/Link Layer implementation for use with BTstack.
|
||||
|
||||
In contrast to common Link Layer implementations, our focus is on a robust and compact implementation for production use,
|
||||
where code size matters (e.g. current code size about 8 kB).
|
||||
|
||||
## Status
|
||||
The current implementation supports a single Peripheral role, or, passive scanning in Observer role. In the Peripheral role,
|
||||
channel map updates, as well as connection param updates are supported.
|
||||
|
||||
Support for LE Central Role as well as Encryption is planned but not supported yet.
|
||||
|
||||
## Requirements
|
||||
- arm-none-eabi toolchain
|
||||
- Nordic's nRF5-SDK
|
||||
|
||||
## Supported Hardware
|
||||
All nNRF5x SOCs. Built files are provided for PCA10040 (52832 DK), but others can be supported with minimal changes.
|
||||
|
||||
## Use
|
||||
- Provide path to nRF5-SDK either in `NRF5_SDK_ROOT` environment variable or directly in `pca10040/armgcc/Makefile`.
|
||||
- run make
|
||||
- All supported examples are built in the `build` folder.
|
||||
- You can use Segger's OZONE with the provided `EXAMPLE.jdebug` project file to flash and run the examples.
|
174
port/nrf5-cinnamon/main.c
Normal file
174
port/nrf5-cinnamon/main.c
Normal file
@ -0,0 +1,174 @@
|
||||
/**
|
||||
* Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form, except as embedded into a Nordic
|
||||
* Semiconductor ASA integrated circuit in a product or a software update for
|
||||
* such product, must reproduce the above copyright notice, this list of
|
||||
* conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of Nordic Semiconductor ASA nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from this
|
||||
* software without specific prior written permission.
|
||||
*
|
||||
* 4. This software, with or without modification, must only be used with a
|
||||
* Nordic Semiconductor ASA integrated circuit.
|
||||
*
|
||||
* 5. Any software provided in binary form under this license must not be reverse
|
||||
* engineered, decompiled, modified and/or disassembled.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
|
||||
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
/** @file
|
||||
*
|
||||
* @defgroup blinky_example_main main.c
|
||||
* @{
|
||||
* @ingroup blinky_example
|
||||
* @brief Blinky Example Application main file.
|
||||
*
|
||||
* This file contains the source code for a sample application to blink LEDs.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "boards.h"
|
||||
#include "SEGGER_RTT.h"
|
||||
|
||||
#include "nrf.h"
|
||||
#include "nrf52.h"
|
||||
#include "nrf_delay.h"
|
||||
#include "nrfx_clock.h"
|
||||
#include "hal_timer.h"
|
||||
#include "radio.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#include "btstack_memory.h"
|
||||
#include "btstack_run_loop_embedded.h"
|
||||
#include "controller.h"
|
||||
#include "btstack_tlv.h"
|
||||
#include "btstack_tlv_none.h"
|
||||
#include "ble/le_device_db_tlv.h"
|
||||
#include "hci_dump.h"
|
||||
#include "hci_dump_segger_rtt_stdout.h"
|
||||
#include "hci_dump_segger_rtt_binary.h"
|
||||
#include "hci_dump_embedded_stdout.h"
|
||||
|
||||
void btstack_assert_failed(const char * file, uint16_t line_nr){
|
||||
printf("Assert: file %s, line %u\n", file, line_nr);
|
||||
while (1);
|
||||
}
|
||||
|
||||
/** hal_time_ms.h */
|
||||
#include "hal_time_ms.h"
|
||||
extern uint32_t hal_timer_get_ticks(void);
|
||||
uint32_t hal_time_ms(void){
|
||||
uint32_t ticks = hal_timer_get_ticks();
|
||||
uint32_t seconds = ticks >> 15; // / 32768
|
||||
uint32_t remaining_ms = (ticks & 0x7fff) * 1000 / 32768;
|
||||
return seconds * 1000 + remaining_ms;
|
||||
}
|
||||
|
||||
/** hal_cpu.h */
|
||||
|
||||
// TODO: implement
|
||||
void hal_cpu_disable_irqs(void){
|
||||
__disable_irq();
|
||||
}
|
||||
|
||||
void hal_cpu_enable_irqs(void){
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void hal_cpu_enable_irqs_and_sleep(void){
|
||||
__enable_irq();
|
||||
// __asm__("wfe"); // go to sleep if event flag isn't set. if set, just clear it. IRQs set event flag
|
||||
}
|
||||
|
||||
static void lf_clock_init(void) {
|
||||
// select 32.768 kHz XTAL as LF Clock source and start
|
||||
NRF_CLOCK->LFCLKSRC = NRF_CLOCK_LFCLK_Xtal;
|
||||
NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_LFCLKSTART = 1;
|
||||
while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0);
|
||||
}
|
||||
|
||||
void btstack_main(void);
|
||||
int main(void){
|
||||
|
||||
// system init
|
||||
lf_clock_init();
|
||||
hal_timer_init();
|
||||
|
||||
#if 0
|
||||
// get startup time, around 9 ticks and verify that we don't need to wait until it's disabled
|
||||
uint32_t t0 = hal_timer_get_ticks();
|
||||
radio_hf_clock_enable(true);
|
||||
uint32_t t1 = hal_timer_get_ticks();
|
||||
radio_hf_clock_disable();
|
||||
radio_hf_clock_enable(true);
|
||||
radio_hf_clock_disable();
|
||||
printf("HF Startup time: %lu ticks\n", t1-t0);
|
||||
#endif
|
||||
|
||||
|
||||
btstack_memory_init();
|
||||
btstack_run_loop_init(btstack_run_loop_embedded_get_instance());
|
||||
|
||||
// initialize controller
|
||||
controller_init();
|
||||
|
||||
// get virtual HCI transpoft
|
||||
const hci_transport_t * hci_transport = controller_get_hci_transport();
|
||||
|
||||
// TODO: use flash storage
|
||||
|
||||
const btstack_tlv_t * btstack_tlv_impl = btstack_tlv_none_init_instance();
|
||||
// setup global tlv
|
||||
btstack_tlv_set_instance(btstack_tlv_impl, NULL);
|
||||
|
||||
// setup LE Device DB using TLV
|
||||
le_device_db_tlv_configure(btstack_tlv_impl, NULL);
|
||||
|
||||
// init HCI
|
||||
hci_init(hci_transport, NULL);
|
||||
|
||||
// uncomment to enable packet logger
|
||||
#ifdef ENABLE_SEGGER_RTT
|
||||
// hci_dump_init(hci_dump_segger_rtt_stdout_get_instance());
|
||||
|
||||
// hci_dump_segger_rtt_binary_open(HCI_DUMP_PACKETLOGGER);
|
||||
// hci_dump_init(hci_dump_segger_rtt_binary_get_instance());
|
||||
#else
|
||||
// hci_dump_init(hci_dump_embedded_stdout_get_instance());
|
||||
#endif
|
||||
|
||||
// hand over to btstack embedded code
|
||||
btstack_main();
|
||||
|
||||
// go
|
||||
btstack_run_loop_execute();
|
||||
|
||||
while (1){};}
|
||||
|
||||
/**
|
||||
*@}
|
||||
**/
|
213
port/nrf5-cinnamon/pca10040/armgcc/Makefile
Normal file
213
port/nrf5-cinnamon/pca10040/armgcc/Makefile
Normal file
@ -0,0 +1,213 @@
|
||||
|
||||
NRF5_SDK_ROOT ?= /Users/mringwal/Projects/Nordic/nRF5_SDK_17.0.2_d674dde
|
||||
|
||||
# unset GNU_INSTALL_ROOT will select arm-none-eabi-gcc from your PATH
|
||||
export GNU_INSTALL_ROOT ?=
|
||||
|
||||
OUTPUT_DIRECTORY := build
|
||||
|
||||
SDK_ROOT := $(NRF5_SDK_ROOT)
|
||||
PROJ_DIR := ../..
|
||||
|
||||
BTSTACK_ROOT = ../../../..
|
||||
|
||||
LINKER_SCRIPT := nrf52832_xxaa.ld
|
||||
|
||||
# Source files common to all targets
|
||||
C_SOURCES = \
|
||||
$(SDK_ROOT)/modules/nrfx/mdk/system_nrf52.c \
|
||||
$(SDK_ROOT)/components/boards/boards.c \
|
||||
$(PROJ_DIR)/main.c \
|
||||
$(PROJ_DIR)/port/hal_timer_nrf5.c \
|
||||
$(PROJ_DIR)/port/ll_nrf5.c \
|
||||
$(PROJ_DIR)/port/radio_nrf5.c \
|
||||
${BTSTACK_ROOT}/3rd-party/micro-ecc/uECC.c \
|
||||
${BTSTACK_ROOT}/3rd-party/rijndael/rijndael.c \
|
||||
${BTSTACK_ROOT}/3rd-party/segger-rtt/SEGGER_RTT.c \
|
||||
${BTSTACK_ROOT}/3rd-party/segger-rtt/SEGGER_RTT_printf.c \
|
||||
${BTSTACK_ROOT}/3rd-party/segger-rtt/SEGGER_RTT_Syscalls_GCC.c \
|
||||
${BTSTACK_ROOT}/chipset/controller/controller.c \
|
||||
${BTSTACK_ROOT}/chipset/controller/hci_event.c \
|
||||
${BTSTACK_ROOT}/chipset/controller/hopping.c \
|
||||
${BTSTACK_ROOT}/platform/embedded/btstack_run_loop_embedded.c \
|
||||
${BTSTACK_ROOT}/platform/embedded/hci_dump_embedded_stdout.c \
|
||||
${BTSTACK_ROOT}/platform/embedded/hci_dump_segger_rtt_stdout.c \
|
||||
${BTSTACK_ROOT}/platform/embedded/hci_dump_segger_rtt_binary.c \
|
||||
${BTSTACK_ROOT}/src/ad_parser.c \
|
||||
${BTSTACK_ROOT}/src/ble/att_db.c \
|
||||
${BTSTACK_ROOT}/src/ble/att_dispatch.c \
|
||||
${BTSTACK_ROOT}/src/ble/att_server.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/ancs_client.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/battery_service_client.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/battery_service_server.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/device_information_service_client.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/device_information_service_server.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt-service/hids_device.c \
|
||||
${BTSTACK_ROOT}/src/ble/gatt_client.c \
|
||||
${BTSTACK_ROOT}/src/ble/le_device_db_memory.c \
|
||||
${BTSTACK_ROOT}/src/ble/le_device_db_tlv.c \
|
||||
${BTSTACK_ROOT}/src/ble/sm.c \
|
||||
${BTSTACK_ROOT}/src/btstack_audio.c \
|
||||
${BTSTACK_ROOT}/src/btstack_crypto.c \
|
||||
${BTSTACK_ROOT}/src/btstack_hid_parser.c \
|
||||
${BTSTACK_ROOT}/src/btstack_linked_list.c \
|
||||
${BTSTACK_ROOT}/src/btstack_linked_queue.c \
|
||||
${BTSTACK_ROOT}/src/btstack_memory.c \
|
||||
${BTSTACK_ROOT}/src/btstack_memory_pool.c \
|
||||
${BTSTACK_ROOT}/src/btstack_resample.c \
|
||||
${BTSTACK_ROOT}/src/btstack_ring_buffer.c \
|
||||
${BTSTACK_ROOT}/src/btstack_run_loop.c \
|
||||
${BTSTACK_ROOT}/src/btstack_tlv.c \
|
||||
${BTSTACK_ROOT}/src/btstack_tlv_none.c \
|
||||
${BTSTACK_ROOT}/src/btstack_util.c \
|
||||
${BTSTACK_ROOT}/src/hci.c \
|
||||
${BTSTACK_ROOT}/src/hci_cmd.c \
|
||||
${BTSTACK_ROOT}/src/hci_dump.c \
|
||||
${BTSTACK_ROOT}/src/hci_transport_h4.c \
|
||||
${BTSTACK_ROOT}/src/l2cap.c \
|
||||
${BTSTACK_ROOT}/src/l2cap_signaling.c \
|
||||
|
||||
ASM_SOURCES= \
|
||||
$(SDK_ROOT)/modules/nrfx/mdk/gcc_startup_nrf52.S \
|
||||
|
||||
# Include folders common to all targets
|
||||
INC_FOLDERS += \
|
||||
$(PROJ_DIR) \
|
||||
$(SDK_ROOT)/integration/nrfx \
|
||||
$(SDK_ROOT)/integration/nrfx/legacy \
|
||||
$(SDK_ROOT)/modules/nrfx \
|
||||
$(SDK_ROOT)/modules/nrfx/hal \
|
||||
$(SDK_ROOT)/modules/nrfx/mdk \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/include/ \
|
||||
$(SDK_ROOT)/components/boards \
|
||||
$(SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
|
||||
$(SDK_ROOT)/components/libraries/bsp \
|
||||
$(SDK_ROOT)/components/toolchain/cmsis/include \
|
||||
$(SDK_ROOT)/components/libraries/util \
|
||||
$(SDK_ROOT)/components/libraries/delay \
|
||||
$(SDK_ROOT)/components/libraries/log/ \
|
||||
$(SDK_ROOT)//components/libraries/log/src \
|
||||
$(SDK_ROOT)/components/libraries/experimental_section_vars/ \
|
||||
$(BTSTACK_ROOT)/3rd-party/segger-rtt \
|
||||
$(BTSTACK_ROOT)/chipset/controller \
|
||||
$(BTSTACK_ROOT)/src/ \
|
||||
$(BTSTACK_ROOT)/platform/embedded \
|
||||
../config \
|
||||
../../port \
|
||||
$(OUTPUT_DIRECTORY)\
|
||||
|
||||
# Libraries common to all targets
|
||||
LIB_FILES += \
|
||||
|
||||
# Optimization flags
|
||||
# OPT = -O3 -g3
|
||||
# Uncomment the line below to enable link time optimization
|
||||
#OPT += -flto
|
||||
OPT = -Os -g
|
||||
|
||||
# C flags common to all targets
|
||||
CFLAGS += $(OPT)
|
||||
CFLAGS += -DBOARD_PCA10040
|
||||
CFLAGS += -DBSP_DEFINES_ONLY
|
||||
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
|
||||
CFLAGS += -DFLOAT_ABI_HARD
|
||||
CFLAGS += -DNRF52
|
||||
CFLAGS += -DNRF52832_XXAA
|
||||
CFLAGS += -DNRF52_PAN_74
|
||||
CFLAGS += -mcpu=cortex-m4
|
||||
CFLAGS += -mthumb -mabi=aapcs
|
||||
CFLAGS += -Wall -Werror
|
||||
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
# keep every function in a separate section, this allows linker to discard unused ones
|
||||
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
|
||||
CFLAGS += -fno-builtin -fshort-enums
|
||||
|
||||
# C++ flags common to all targets
|
||||
CXXFLAGS += $(OPT)
|
||||
# Assembler flags common to all targets
|
||||
ASMFLAGS += -g3
|
||||
ASMFLAGS += -mcpu=cortex-m4
|
||||
ASMFLAGS += -mthumb -mabi=aapcs
|
||||
ASMFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
ASMFLAGS += -DBOARD_PCA10040
|
||||
ASMFLAGS += -DBSP_DEFINES_ONLY
|
||||
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
|
||||
ASMFLAGS += -DFLOAT_ABI_HARD
|
||||
ASMFLAGS += -DNRF52
|
||||
ASMFLAGS += -DNRF52832_XXAA
|
||||
ASMFLAGS += -DNRF52_PAN_74
|
||||
|
||||
# Linker flags
|
||||
LDFLAGS += $(OPT)
|
||||
LDFLAGS += -mthumb -mabi=aapcs -L$(SDK_ROOT)/modules/nrfx/mdk -T$(LINKER_SCRIPT)
|
||||
LDFLAGS += -mcpu=cortex-m4
|
||||
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
# let linker dump unused sections
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
# use newlib in nano version
|
||||
LDFLAGS += --specs=nano.specs
|
||||
|
||||
# Add standard libraries at the very end of the linker input, after all objects
|
||||
# that may need symbols provided by these libraries.
|
||||
LIB_FILES += -lc -lnosys -lm
|
||||
|
||||
# default action: build all
|
||||
EXAMPLES = \
|
||||
gap_le_advertisements \
|
||||
gatt_counter \
|
||||
gatt_streamer_server \
|
||||
# require encryption:
|
||||
# hog_keyboard_demo \
|
||||
# hog_mouse_demo \
|
||||
# sm_pairing_peripheral \
|
||||
|
||||
GATT_FILES = \
|
||||
gatt_counter.gatt \
|
||||
gatt_streamer_server.gatt \
|
||||
# require encryption:
|
||||
# hog_keyboard_demo.gatt \
|
||||
# hog_mouse_demo.gatt \
|
||||
# sm_pairing_peripheral.gatt \
|
||||
|
||||
# list of objects
|
||||
OBJECTS = $(addprefix $(OUTPUT_DIRECTORY)/,$(notdir $(C_SOURCES:.c=.o)))
|
||||
vpath %.c $(sort $(dir $(C_SOURCES)))
|
||||
# list of ASM program objects
|
||||
OBJECTS += $(addprefix $(OUTPUT_DIRECTORY)/,$(notdir $(ASM_SOURCES:.S=.o)))
|
||||
vpath %.S $(sort $(dir $(ASM_SOURCES)))
|
||||
|
||||
.PHONY: default help
|
||||
|
||||
# VPATH to find .gatt files
|
||||
VPATH += ${BTSTACK_ROOT}/example
|
||||
|
||||
# Default target - first one defined
|
||||
default: \
|
||||
$(OBJECTS) \
|
||||
$(addprefix $(OUTPUT_DIRECTORY)/,$(GATT_FILES:.gatt=.h)) \
|
||||
$(addprefix $(OUTPUT_DIRECTORY)/,$(EXAMPLES:=.elf)) \
|
||||
$(addprefix $(OUTPUT_DIRECTORY)/,$(EXAMPLES:=.jdebug)) \
|
||||
|
||||
$(OUTPUT_DIRECTORY)/%.h: %.gatt | $(OUTPUT_DIRECTORY)
|
||||
python3 ${BTSTACK_ROOT}/tool/compile_gatt.py $< $@
|
||||
|
||||
$(OUTPUT_DIRECTORY)/%.o: %.S Makefile | $(OUTPUT_DIRECTORY)
|
||||
$(CC) -c $(ASMFLAGS) $< -o $@
|
||||
|
||||
$(OUTPUT_DIRECTORY)/%.o: %.c Makefile | $(OUTPUT_DIRECTORY)
|
||||
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(OUTPUT_DIRECTORY)/$(notdir $(<:.c=.lst)) $< -o $@
|
||||
|
||||
$(OUTPUT_DIRECTORY)/%.elf: Makefile $(OBJECTS) $(OUTPUT_DIRECTORY)/%.o
|
||||
$(CC) $(filter-out Makefile,$^) $(LDFLAGS) -o $@
|
||||
$(SIZE) $@
|
||||
|
||||
$(OUTPUT_DIRECTORY)/%.jdebug: ozone.jdebug | $(OUTPUT_DIRECTORY)
|
||||
sed -e "s|EXAMPLE|$(basename $(notdir $@))|" $< > $@
|
||||
|
||||
TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc
|
||||
|
||||
include $(TEMPLATE_PATH)/Makefile.common
|
||||
|
||||
# Convert INC_FOLDERS into CFLAGS
|
||||
$(eval INC_PATHS := $(call get_inc_paths, $(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1))))
|
||||
CFLAGS += ${INC_PATHS}
|
64
port/nrf5-cinnamon/pca10040/armgcc/nrf52832_xxaa.ld
Normal file
64
port/nrf5-cinnamon/pca10040/armgcc/nrf52832_xxaa.ld
Normal file
@ -0,0 +1,64 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
. = ALIGN(4);
|
||||
.mem_section_dummy_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 :
|
||||
{
|
||||
}
|
||||
.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
|
||||
.nrf_balloc :
|
||||
{
|
||||
PROVIDE(__start_nrf_balloc = .);
|
||||
KEEP(*(.nrf_balloc))
|
||||
PROVIDE(__stop_nrf_balloc = .);
|
||||
} > FLASH
|
||||
|
||||
} INSERT AFTER .text
|
||||
|
||||
|
||||
INCLUDE "nrf_common.ld"
|
3320
port/nrf5-cinnamon/pca10040/config/sdk_config.h
Normal file
3320
port/nrf5-cinnamon/pca10040/config/sdk_config.h
Normal file
File diff suppressed because it is too large
Load Diff
42
port/nrf5-cinnamon/port/btstack_config.h
Normal file
42
port/nrf5-cinnamon/port/btstack_config.h
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// btstack_config.h for nRF5x LL
|
||||
//
|
||||
|
||||
#ifndef BTSTACK_CONFIG_H
|
||||
#define BTSTACK_CONFIG_H
|
||||
|
||||
// Port related features
|
||||
#define HAVE_EM9304_PATCH_CONTAINER
|
||||
#define HAVE_EMBEDDED_TIME_MS
|
||||
|
||||
// BTstack features that can be enabled
|
||||
#define ENABLE_BLE
|
||||
#define ENABLE_LE_CENTRAL
|
||||
#define ENABLE_LE_DATA_LENGTH_EXTENSION
|
||||
#define ENABLE_LE_PERIPHERAL
|
||||
#define ENABLE_LOG_ERROR
|
||||
#define ENABLE_LOG_INFO
|
||||
#define ENABLE_PRINTF_HEXDUMP
|
||||
#define ENABLE_SEGGER_RTT
|
||||
#define ENABLE_BTSTACK_ASSERT
|
||||
|
||||
// BTstack configuration. buffers, sizes, ...
|
||||
#define HCI_ACL_PAYLOAD_SIZE 100
|
||||
#define MAX_NR_GATT_CLIENTS 1
|
||||
#define MAX_NR_HCI_CONNECTIONS 1
|
||||
#define MAX_NR_L2CAP_CHANNELS 1
|
||||
#define MAX_NR_L2CAP_SERVICES 1
|
||||
#define MAX_NR_SM_LOOKUP_ENTRIES 3
|
||||
#define MAX_NR_WHITELIST_ENTRIES 1
|
||||
|
||||
// LE Device DB using TLV on top of Flash Sector interface
|
||||
#define NVM_NUM_DEVICE_DB_ENTRIES 16
|
||||
|
||||
// GPIO debugging
|
||||
#define DEBUG_PIN_HF_CLOCK 19
|
||||
#define DEBUG_PIN_ADDRESS 20
|
||||
#define DEBUG_PIN_RX 22
|
||||
#define DEBUG_PIN_TX 23
|
||||
#define DEBUG_PIN_RADIO_IRQ 24
|
||||
|
||||
#endif
|
51
port/nrf5-cinnamon/port/debug.h
Normal file
51
port/nrf5-cinnamon/port/debug.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*******************************************************************************
|
||||
*
|
||||
* Copyright (c) 2018, Raccon BLE Sniffer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following disclaimer
|
||||
* in the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of "btlejack2" nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _DEBUG_H_
|
||||
#define _DEBUG_H_
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#include "SEGGER_RTT.h"
|
||||
#define printf(...) SEGGER_RTT_printf( 0, __VA_ARGS__ )
|
||||
#define LOG_DBG(...) SEGGER_RTT_printf( 0, __VA_ARGS__ )
|
||||
#define log(format, ...) SEGGER_RTT_printf(0, "[%010u] " format, __HAL_TIM_GET_COUNTER(&htim2), ## __VA_ARGS__)
|
||||
|
||||
#else
|
||||
|
||||
#define printf(...)
|
||||
#define LOG_DBG(...)
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _DEBUG_H_
|
85
port/nrf5-cinnamon/port/hal_timer.h
Normal file
85
port/nrf5-cinnamon/port/hal_timer.h
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2020 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. Any redistribution, use, or modification is done solely for
|
||||
* personal benefit and not for any commercial purpose or for
|
||||
* monetary gain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at
|
||||
* contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* hci_event.h
|
||||
*/
|
||||
|
||||
#ifndef HAL_TIMER_H
|
||||
#define HCI_TIMER_H
|
||||
|
||||
#include "bluetooth.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* @brief Initialize 32.768 kHz timer, usually low power and used by RTC and in deep sleep
|
||||
*/
|
||||
void hal_timer_init(void);
|
||||
|
||||
/*
|
||||
* @brief Set Timer Callback
|
||||
* @param callback
|
||||
*/
|
||||
void hal_timer_set_callback(void (*callback)(void));
|
||||
|
||||
/**
|
||||
* @brief Get current ticks
|
||||
* @return num_ticks
|
||||
*/
|
||||
uint32_t hal_timer_get_ticks(void);
|
||||
|
||||
/**
|
||||
* @brief Stop Timer
|
||||
*/
|
||||
void hal_timer_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Start Timer and fire at given timeout
|
||||
* @param timeout_ticks timeout in ticks
|
||||
*/
|
||||
void hal_timer_start(uint32_t timeout_ticks);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // HAL_TIMER_H
|
96
port/nrf5-cinnamon/port/hal_timer_nrf5.c
Normal file
96
port/nrf5-cinnamon/port/hal_timer_nrf5.c
Normal file
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2020 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. Any redistribution, use, or modification is done solely for
|
||||
* personal benefit and not for any commercial purpose or for
|
||||
* monetary gain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at
|
||||
* contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
#define BTSTACK_FILE__ "hal_timer_nrf5.c"
|
||||
|
||||
/*
|
||||
* hal_timer.c
|
||||
* HAL for 32.768 kHz low power timer with 16 bit resolution
|
||||
* @note Only uses one of multiple RTCs and only a single Capture-Compare unit
|
||||
*/
|
||||
|
||||
#include "hal_timer.h"
|
||||
#include "btstack_debug.h"
|
||||
|
||||
#include "nrf.h"
|
||||
|
||||
static void (*hal_timer_callback)(void);
|
||||
|
||||
void RTC0_IRQHandler(void){
|
||||
if (NRF_RTC0->EVENTS_COMPARE[0]){
|
||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
||||
btstack_assert(hal_timer_callback != NULL);
|
||||
(*hal_timer_callback)();
|
||||
}
|
||||
}
|
||||
|
||||
void hal_timer_init(void) {
|
||||
/* Stop the timer first */
|
||||
NRF_RTC0->TASKS_STOP = 1;
|
||||
NRF_RTC0->TASKS_CLEAR = 1;
|
||||
|
||||
/* Always no prescaler */
|
||||
NRF_RTC0->PRESCALER = 0;
|
||||
|
||||
/* Clear overflow events and set overflow interrupt */
|
||||
NRF_RTC0->EVENTS_OVRFLW = 0;
|
||||
NRF_RTC0->INTENSET = RTC_INTENSET_OVRFLW_Msk;
|
||||
|
||||
/* Start the timer */
|
||||
NRF_RTC0->TASKS_START = 1;
|
||||
|
||||
/* Set isr in vector table and enable interrupt */
|
||||
NVIC_EnableIRQ( RTC0_IRQn );
|
||||
}
|
||||
|
||||
void hal_timer_set_callback(void (*callback)(void)){
|
||||
hal_timer_callback = callback;
|
||||
}
|
||||
|
||||
uint32_t hal_timer_get_ticks(void){
|
||||
return NRF_RTC0->COUNTER;
|
||||
}
|
||||
|
||||
void hal_timer_stop(void){
|
||||
NRF_RTC0->INTENCLR =RTC_INTENCLR_COMPARE0_Msk;
|
||||
}
|
||||
|
||||
void hal_timer_start(uint32_t timeout_ticks){
|
||||
NRF_RTC0->CC[0] = timeout_ticks & 0x00ffffff;
|
||||
NRF_RTC0->EVENTS_COMPARE[0] = 0;
|
||||
NRF_RTC0->INTENSET =RTC_INTENSET_COMPARE0_Msk;
|
||||
}
|
1408
port/nrf5-cinnamon/port/ll_nrf5.c
Normal file
1408
port/nrf5-cinnamon/port/ll_nrf5.c
Normal file
File diff suppressed because it is too large
Load Diff
138
port/nrf5-cinnamon/port/radio.h
Normal file
138
port/nrf5-cinnamon/port/radio.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2020 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. Any redistribution, use, or modification is done solely for
|
||||
* personal benefit and not for any commercial purpose or for
|
||||
* monetary gain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at
|
||||
* contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* radio.h
|
||||
*/
|
||||
|
||||
#ifndef RADIO_H
|
||||
#define RADIO_H
|
||||
|
||||
#include "btstack_bool.h"
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* API_START */
|
||||
|
||||
typedef struct {
|
||||
void (*tx_done)(void);
|
||||
void (*rx_done)(void);
|
||||
} radio_callbacks_t;
|
||||
|
||||
typedef enum {
|
||||
RADIO_TRANSITION_TX_ONLY,
|
||||
RADIO_TRANSITION_TX_TO_RX,
|
||||
} radio_transition_t;
|
||||
|
||||
typedef enum {
|
||||
RADIO_RESULT_OK,
|
||||
RADIO_RESULT_CRC_ERROR,
|
||||
RADIO_RESULT_TIMEOUT,
|
||||
} radio_result_t;
|
||||
|
||||
typedef void (*radio_callback_t)(radio_result_t result);
|
||||
|
||||
/**
|
||||
* Init radio
|
||||
*/
|
||||
void radio_init(void);
|
||||
|
||||
/**
|
||||
* Set Access Address
|
||||
* @param access_address
|
||||
*/
|
||||
void radio_set_access_address(uint32_t access_address);
|
||||
|
||||
/**
|
||||
* Enable RF CLock
|
||||
* @param wait_until_ready if true, waits until HF clock is ready
|
||||
*/
|
||||
void radio_hf_clock_enable(bool wait_until_ready);
|
||||
|
||||
/**
|
||||
* Disable RF CLock
|
||||
*/
|
||||
void radio_hf_clock_disable(void);
|
||||
|
||||
/**
|
||||
* Set CRC Init value
|
||||
* @param crc 24-bit init value
|
||||
*/
|
||||
void radio_set_crc_init(uint32_t crc);
|
||||
|
||||
/**
|
||||
* Set Channel: frequency and whitening
|
||||
* @param channel 0..39
|
||||
*/
|
||||
void radio_set_channel(uint8_t channel);
|
||||
|
||||
/**
|
||||
* Transmit packet.
|
||||
* @param callback
|
||||
* @param transition - on RADIO_TRANSITION_TX_TO_RX, radio transitions to RX
|
||||
* @param packet
|
||||
* @param len
|
||||
*/
|
||||
void radio_transmit(radio_callback_t callback, radio_transition_t transition, const uint8_t * packet, uint16_t len);
|
||||
|
||||
/**
|
||||
* Receive packet
|
||||
* @note automatic transition to TX
|
||||
* @param callback
|
||||
* @param timeout_us if radio was disabled before (i.e. not in tx -> rx transition)
|
||||
* @param buffer
|
||||
* @param len
|
||||
* @param rssi (out)
|
||||
*/
|
||||
void radio_receive(radio_callback_t callback, uint32_t timeout_us, uint8_t * buffer, uint16_t len, int8_t * rssi);
|
||||
|
||||
/**
|
||||
* Stop active transmission, e.g. tx after rx
|
||||
* @param callback
|
||||
*/
|
||||
void radio_stop(radio_callback_t callback);
|
||||
|
||||
/* API_END */
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // LL_H
|
546
port/nrf5-cinnamon/port/radio_nrf5.c
Normal file
546
port/nrf5-cinnamon/port/radio_nrf5.c
Normal file
@ -0,0 +1,546 @@
|
||||
/*
|
||||
* Copyright (C) 2021 BlueKitchen GmbH
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
* 4. Any redistribution, use, or modification is done solely for
|
||||
* personal benefit and not for any commercial purpose or for
|
||||
* monetary gain.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
|
||||
* RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Please inquire about commercial licensing options at
|
||||
* contact@bluekitchen-gmbh.com
|
||||
*
|
||||
*/
|
||||
|
||||
#define BTSTACK_FILE__ "radio_nrf5.c"
|
||||
|
||||
#include "radio.h"
|
||||
#include "btstack_debug.h"
|
||||
#include <inttypes.h>
|
||||
#include "nrf.h"
|
||||
#include "nrf52.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_gpiote.h"
|
||||
|
||||
#define MAXLEN 37
|
||||
|
||||
static enum {
|
||||
RADIO_OFF,
|
||||
RADIO_DISABLED,
|
||||
RADIO_W2_TX,
|
||||
RADIO_W4_TX_DONE,
|
||||
RADIO_W4_TX_TO_RX,
|
||||
RADIO_W2_RX,
|
||||
RADIO_W4_RX_DONE,
|
||||
RADIO_W4_RX_TIMEOUT,
|
||||
RADIO_W4_DISABLED,
|
||||
} volatile radio_state;
|
||||
|
||||
static radio_callback_t radio_callback;
|
||||
static int8_t * rssi_buffer;
|
||||
|
||||
// channel table: freq in hertz and whitening seed
|
||||
static const struct {
|
||||
uint8_t freq_index;
|
||||
uint8_t whitening;
|
||||
} channel_table[] = {
|
||||
{ 4, 0x01 /* 00000001 */ },
|
||||
{ 6, 0x41 /* 01000001 */ },
|
||||
{ 8, 0x21 /* 00100001 */ },
|
||||
{ 10, 0x61 /* 01100001 */ },
|
||||
{ 12, 0x11 /* 00010001 */ },
|
||||
{ 14, 0x51 /* 01010001 */ },
|
||||
{ 16, 0x31 /* 00110001 */ },
|
||||
{ 18, 0x71 /* 01110001 */ },
|
||||
{ 20, 0x09 /* 00001001 */ },
|
||||
{ 22, 0x49 /* 01001001 */ },
|
||||
{ 24, 0x29 /* 00101001 */ },
|
||||
{ 28, 0x69 /* 01101001 */ },
|
||||
{ 30, 0x19 /* 00011001 */ },
|
||||
{ 32, 0x59 /* 01011001 */ },
|
||||
{ 34, 0x39 /* 00111001 */ },
|
||||
{ 36, 0x79 /* 01111001 */ },
|
||||
{ 38, 0x05 /* 00000101 */ },
|
||||
{ 40, 0x45 /* 01000101 */ },
|
||||
{ 42, 0x25 /* 00100101 */ },
|
||||
{ 44, 0x65 /* 01100101 */ },
|
||||
{ 46, 0x15 /* 00010101 */ },
|
||||
{ 48, 0x55 /* 01010101 */ },
|
||||
{ 50, 0x35 /* 00110101 */ },
|
||||
{ 52, 0x75 /* 01110101 */ },
|
||||
{ 54, 0x0d /* 00001101 */ },
|
||||
{ 56, 0x4d /* 01001101 */ },
|
||||
{ 58, 0x2d /* 00101101 */ },
|
||||
{ 60, 0x6d /* 01101101 */ },
|
||||
{ 62, 0x1d /* 00011101 */ },
|
||||
{ 64, 0x5d /* 01011101 */ },
|
||||
{ 66, 0x3d /* 00111101 */ },
|
||||
{ 68, 0x7d /* 01111101 */ },
|
||||
{ 70, 0x03 /* 00000011 */ },
|
||||
{ 72, 0x43 /* 01000011 */ },
|
||||
{ 74, 0x23 /* 00100011 */ },
|
||||
{ 76, 0x63 /* 01100011 */ },
|
||||
{ 78, 0x13 /* 00010011 */ },
|
||||
{ 2, 0x53 /* 01010011 */ },
|
||||
{ 26, 0x33 /* 00110011 */ },
|
||||
{ 80, 0x73 /* 01110011 */ },
|
||||
};
|
||||
|
||||
void radio_init(void){
|
||||
|
||||
radio_state = RADIO_OFF;
|
||||
|
||||
/* TIMER0 setup */
|
||||
NRF_TIMER0->TASKS_STOP = 1;
|
||||
NRF_TIMER0->TASKS_SHUTDOWN = 1;
|
||||
NRF_TIMER0->BITMODE = 3; /* 32-bit timer */
|
||||
NRF_TIMER0->MODE = 0; /* Timer mode */
|
||||
NRF_TIMER0->PRESCALER = 4; /* gives us 1 MHz */
|
||||
|
||||
// PPI setup
|
||||
// Channel 0: RADIO END -> TIMER0 Start
|
||||
NRF_PPI->CH[0].EEP = (uint32_t)&(NRF_RADIO->EVENTS_END);
|
||||
NRF_PPI->CH[0].TEP = (uint32_t)&(NRF_TIMER0->TASKS_START);
|
||||
// Channel 1: RADIO ADDRESS -> TIMER0 Stop
|
||||
NRF_PPI->CH[1].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
|
||||
NRF_PPI->CH[1].TEP = (uint32_t)&(NRF_TIMER0->TASKS_STOP);
|
||||
|
||||
#ifdef NRF51
|
||||
// Handle BLE Radio tuning parameters from production if required.
|
||||
// Does not exist on NRF52
|
||||
// See PCN-083.
|
||||
if (NRF_FICR->OVERRIDEEN & FICR_OVERRIDEEN_BLE_1MBIT_Msk){
|
||||
NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0];
|
||||
NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1];
|
||||
NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2];
|
||||
NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3];
|
||||
NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4] | 0x80000000;
|
||||
}
|
||||
#endif // NRF51
|
||||
|
||||
// Mode: BLE 1 Mbps
|
||||
NRF_RADIO->MODE = RADIO_MODE_MODE_Ble_1Mbit << RADIO_MODE_MODE_Pos;
|
||||
|
||||
// PacketConfig 0:
|
||||
// ---
|
||||
// LENGTH field in bits = 8
|
||||
// S0 field in bytes = 1
|
||||
// S1 field not used
|
||||
// 8 bit preamble
|
||||
NRF_RADIO->PCNF0 =
|
||||
( 8 << RADIO_PCNF0_LFLEN_Pos ) |
|
||||
( 1 << RADIO_PCNF0_S0LEN_Pos ) |
|
||||
( 0 << RADIO_PCNF0_S1LEN_Pos );
|
||||
|
||||
// PacketConfig 1:
|
||||
// ---
|
||||
// Payload MAXLEN = MAXLEN
|
||||
// No additional bytes
|
||||
// 4 address bytes (1 + 3)
|
||||
// S0, LENGTH, S1, PAYLOAD in little endian
|
||||
// Packet whitening enabled
|
||||
NRF_RADIO->PCNF1 =
|
||||
( MAXLEN << RADIO_PCNF1_MAXLEN_Pos) |
|
||||
( 0 << RADIO_PCNF1_STATLEN_Pos ) |
|
||||
( 3 << RADIO_PCNF1_BALEN_Pos ) |
|
||||
( RADIO_PCNF1_ENDIAN_Little << RADIO_PCNF1_ENDIAN_Pos ) |
|
||||
( RADIO_PCNF1_WHITEEN_Enabled << RADIO_PCNF1_WHITEEN_Pos );
|
||||
|
||||
// Use logical address 0 for sending and receiving
|
||||
NRF_RADIO->TXADDRESS = 0;
|
||||
NRF_RADIO->RXADDRESSES = 1 << 0;
|
||||
|
||||
// 24 bit CRC, skip address field
|
||||
NRF_RADIO->CRCCNF =
|
||||
( RADIO_CRCCNF_SKIPADDR_Skip << RADIO_CRCCNF_SKIPADDR_Pos ) |
|
||||
( RADIO_CRCCNF_LEN_Three << RADIO_CRCCNF_LEN_Pos );
|
||||
|
||||
// The polynomial has the form of x^24 +x^10 +x^9 +x^6 +x^4 +x^3 +x+1
|
||||
NRF_RADIO->CRCPOLY = 0x100065B;
|
||||
|
||||
// Inter frame spacing 150 us
|
||||
NRF_RADIO->TIFS = 150;
|
||||
|
||||
// Transmit with max power
|
||||
NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_Pos4dBm << RADIO_TXPOWER_TXPOWER_Pos);
|
||||
|
||||
// Disable all interrupts
|
||||
NRF_RADIO->INTENCLR = 0xffffffff;
|
||||
|
||||
// enable Radio IRQs
|
||||
NVIC_SetPriority( RADIO_IRQn, 0 );
|
||||
NVIC_ClearPendingIRQ( RADIO_IRQn );
|
||||
NVIC_EnableIRQ( RADIO_IRQn );
|
||||
|
||||
#ifdef DEBUG_PIN_HF_CLOCK
|
||||
// debug pins
|
||||
nrf_gpio_cfg_output(DEBUG_PIN_HF_CLOCK);
|
||||
nrf_gpio_cfg_output(DEBUG_PIN_ADDRESS);
|
||||
nrf_gpio_cfg_output(DEBUG_PIN_RX);
|
||||
nrf_gpio_cfg_output(DEBUG_PIN_TX);
|
||||
nrf_gpio_cfg_output(DEBUG_PIN_RADIO_IRQ);
|
||||
// toggle DEBUG_PIN_ADDRESS on RADIO ADDRESS event. Use PPI Channel 19 and GPIOT[0]
|
||||
// NOTE: unclear how pin could be cleared after set on address.
|
||||
nrf_gpiote_task_configure(0, DEBUG_PIN_ADDRESS, GPIOTE_CONFIG_POLARITY_Toggle, NRF_GPIOTE_INITIAL_VALUE_LOW);
|
||||
nrf_gpiote_task_enable(0);
|
||||
NRF_PPI->CH[19].EEP = (uint32_t)&(NRF_RADIO->EVENTS_ADDRESS);
|
||||
NRF_PPI->CH[19].TEP = nrf_gpiote_task_addr_get(0);
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH19_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Enable the High Frequency clock on the processor.
|
||||
static void radio_hf_clock_enable_reset(radio_result_t result){
|
||||
UNUSED(result);
|
||||
}
|
||||
void radio_hf_clock_enable(bool wait_until_ready){
|
||||
|
||||
// Work around for incomplete RX
|
||||
if (radio_state == RADIO_W4_RX_DONE){
|
||||
#ifdef DEBUG_PIN_HF_CLOCK
|
||||
nrf_gpio_pin_clear(DEBUG_PIN_HF_CLOCK);
|
||||
nrf_gpio_pin_set(DEBUG_PIN_HF_CLOCK);
|
||||
#endif
|
||||
#if 0
|
||||
// state = RX, PAYLOAD = 1, END = 0, DISABLED = 0
|
||||
printf("Enable: STATE %u\n", (int) NRF_RADIO->STATE);
|
||||
printf("Enable: PAYLOAD %u\n", (int) NRF_RADIO->EVENTS_PAYLOAD);
|
||||
printf("Enable: END %u\n", (int) NRF_RADIO->EVENTS_END);
|
||||
printf("Enable: DISABLED %u\n", (int) NRF_RADIO->EVENTS_DISABLED);
|
||||
btstack_assert(false);
|
||||
#else
|
||||
printf("\n\nRADIO_W4_RX_DONE hang\n\n\n");
|
||||
radio_stop(&radio_hf_clock_enable_reset);
|
||||
radio_state = RADIO_DISABLED;
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG_PIN_HF_CLOCK
|
||||
nrf_gpio_pin_set(DEBUG_PIN_HF_CLOCK);
|
||||
#endif
|
||||
|
||||
|
||||
// the RADIO module. Without this clock, no communication is possible.
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_HFCLKSTART = 1;
|
||||
if (wait_until_ready){
|
||||
while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
|
||||
}
|
||||
|
||||
radio_state = RADIO_DISABLED;
|
||||
}
|
||||
|
||||
void radio_hf_clock_disable(void) {
|
||||
#ifdef DEBUG_PIN_HF_CLOCK
|
||||
nrf_gpio_pin_clear(DEBUG_PIN_HF_CLOCK);
|
||||
#endif
|
||||
|
||||
NRF_CLOCK->TASKS_HFCLKSTOP = 1;
|
||||
radio_state = RADIO_OFF;
|
||||
}
|
||||
|
||||
void radio_set_access_address(uint32_t access_address) {
|
||||
NRF_RADIO->BASE0 = ( access_address << 8 ) & 0xFFFFFF00;
|
||||
NRF_RADIO->PREFIX0 = ( access_address >> 24 ) & RADIO_PREFIX0_AP0_Msk;
|
||||
}
|
||||
|
||||
void radio_set_crc_init(uint32_t crc_init){
|
||||
NRF_RADIO->CRCINIT = crc_init;
|
||||
}
|
||||
|
||||
void radio_set_channel(uint8_t channel){
|
||||
// set frequency based on channel
|
||||
NRF_RADIO->FREQUENCY = channel_table[channel].freq_index;
|
||||
|
||||
// initializes data whitening with channel index
|
||||
NRF_RADIO->DATAWHITEIV = channel & 0x3F;
|
||||
}
|
||||
|
||||
void radio_transmit(radio_callback_t callback, radio_transition_t transition, const uint8_t * packet, uint16_t len){
|
||||
|
||||
#ifdef DEBUG_PIN_TX
|
||||
nrf_gpio_pin_set(DEBUG_PIN_TX);
|
||||
#endif
|
||||
|
||||
uint16_t state = (uint16_t) NRF_RADIO->STATE;
|
||||
|
||||
switch (radio_state){
|
||||
case RADIO_W2_TX:
|
||||
// already in transition to tx
|
||||
if (state != RADIO_STATE_STATE_TxRu){
|
||||
log_info("TX Start after RX, transition %u, state 0x%04x", (int) transition, state);
|
||||
btstack_assert(false);
|
||||
}
|
||||
break;
|
||||
case RADIO_DISABLED:
|
||||
if (state != RADIO_STATE_STATE_Disabled){
|
||||
log_info("TX Start after Disabled, transition %u, state 0x%04x", (int) transition, state);
|
||||
btstack_assert(false);
|
||||
}
|
||||
// start tx
|
||||
NRF_RADIO->TASKS_TXEN = 1;
|
||||
break;
|
||||
default:
|
||||
log_info("TX Start unexpected state: our state %u, transition %u, state 0x%04x", radio_state, (int) transition, state);
|
||||
btstack_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
radio_callback = callback;
|
||||
|
||||
// set data to send (assume it's valid until tx done)
|
||||
NRF_RADIO->PACKETPTR = (uint32_t) packet;
|
||||
|
||||
switch (transition){
|
||||
case RADIO_TRANSITION_TX_ONLY:
|
||||
radio_state = RADIO_W4_TX_DONE;
|
||||
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk;
|
||||
break;
|
||||
case RADIO_TRANSITION_TX_TO_RX:
|
||||
radio_state = RADIO_W4_TX_TO_RX;
|
||||
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_RXEN_Msk;
|
||||
// - Clear Timer0
|
||||
NRF_TIMER0->TASKS_CLEAR = 1;
|
||||
// - Set CC for receive (ca. 300 us)
|
||||
NRF_TIMER0->CC[1] = 300; // 300 us
|
||||
NRF_TIMER0->EVENTS_COMPARE[1] = 0;
|
||||
// - END -> Start Timer0
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH0_Msk;
|
||||
// - Timer0 CC[1] -> Radio END
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH22_Msk;
|
||||
// - Disable address->stop
|
||||
NRF_PPI->CHENCLR = PPI_CHEN_CH1_Msk;
|
||||
break;
|
||||
default:
|
||||
btstack_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_RADIO->INTENCLR = 0xffffffff;
|
||||
NRF_RADIO->EVENTS_END = 0;
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
|
||||
NVIC_ClearPendingIRQ(RADIO_IRQn);
|
||||
NVIC_EnableIRQ(RADIO_IRQn);
|
||||
|
||||
// Interrupt on DISABLED
|
||||
NRF_RADIO->INTENSET = 0x00000010;
|
||||
}
|
||||
|
||||
static void radio_setup_rx(void){
|
||||
NRF_RADIO->EVENTS_ADDRESS = 0;
|
||||
NRF_RADIO->EVENTS_END = 0;
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
// PPI0: END -> Start Timer0
|
||||
NRF_PPI->CHENCLR = PPI_CHEN_CH0_Msk;
|
||||
// PPI1: Radio Address -> Stop Timer
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH1_Msk;
|
||||
// Update Shortcuts
|
||||
NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_END_DISABLE_Msk | RADIO_SHORTS_DISABLED_TXEN_Msk;
|
||||
}
|
||||
|
||||
void radio_receive(radio_callback_t callback, uint32_t timeout_us, uint8_t * buffer, uint16_t len, int8_t * rssi){
|
||||
|
||||
#ifdef DEBUG_PIN_RX
|
||||
nrf_gpio_pin_set(DEBUG_PIN_RX);
|
||||
#endif
|
||||
|
||||
uint16_t state = (uint16_t) NRF_RADIO->STATE;
|
||||
|
||||
// log_info("RX Start: our state = 0x%0x, radio_state 0x%04x", radio_state, state);
|
||||
|
||||
radio_callback = callback;
|
||||
rssi_buffer = rssi;
|
||||
|
||||
NRF_RADIO->PACKETPTR = (uint32_t) buffer;
|
||||
buffer[0] = 0;
|
||||
buffer[1] = 0;
|
||||
|
||||
switch (radio_state){
|
||||
case RADIO_W2_RX:
|
||||
// radio setup as part of TX->RX transition
|
||||
switch (state){
|
||||
case RADIO_STATE_STATE_RxRu:
|
||||
case RADIO_STATE_STATE_RxIdle:
|
||||
case RADIO_STATE_STATE_Rx:
|
||||
break;
|
||||
default:
|
||||
btstack_assert(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case RADIO_DISABLED:
|
||||
btstack_assert(state == RADIO_STATE_STATE_Disabled);
|
||||
// - Stop Timer0
|
||||
NRF_TIMER0->TASKS_STOP = 1;
|
||||
// - Clear Timer0
|
||||
NRF_TIMER0->TASKS_CLEAR = 1;
|
||||
// - Set CC for receive
|
||||
NRF_TIMER0->CC[1] = timeout_us;
|
||||
NRF_TIMER0->EVENTS_COMPARE[1] = 0;
|
||||
// - Timer0 CC[1] -> Radio Disable
|
||||
NRF_PPI->CHENSET = PPI_CHEN_CH22_Msk;
|
||||
// - Start Timer0
|
||||
NRF_TIMER0->TASKS_START = 1;
|
||||
// Start Receive
|
||||
radio_setup_rx();
|
||||
NRF_RADIO->TASKS_RXEN = 1;
|
||||
break;
|
||||
default:
|
||||
log_info("RX unexpected radio_state: state 0x%04x / phy state state 0x%04x", radio_state, state);
|
||||
log_info("cc[1] %" PRIu32 "events_compare[1] %u", NRF_TIMER0->CC[1], (int) NRF_TIMER0->EVENTS_COMPARE[1]);
|
||||
btstack_assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable all interrupts
|
||||
NRF_RADIO->INTENCLR = 0xffffffff;
|
||||
|
||||
NVIC_ClearPendingIRQ(RADIO_IRQn);
|
||||
NVIC_EnableIRQ(RADIO_IRQn);
|
||||
|
||||
// Interrupt on DISABLED
|
||||
NRF_RADIO->INTENSET = 0x00000010;
|
||||
|
||||
radio_state = RADIO_W4_RX_DONE;
|
||||
}
|
||||
|
||||
void radio_stop(radio_callback_t callback){
|
||||
|
||||
// log_info("Disable, state 0x%04x", (uint16_t) NRF_RADIO->STATE);
|
||||
|
||||
radio_callback = callback;
|
||||
|
||||
NRF_RADIO->SHORTS = 0;
|
||||
|
||||
uint16_t state = (uint16_t) NRF_RADIO->STATE;
|
||||
switch (state){
|
||||
case RADIO_STATE_STATE_Disabled:
|
||||
(*callback)(RADIO_RESULT_OK);
|
||||
break;
|
||||
default:
|
||||
radio_state = RADIO_W4_DISABLED;
|
||||
NRF_RADIO->TASKS_DISABLE = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void RADIO_IRQHandler(void){
|
||||
uint16_t state = (uint16_t) NRF_RADIO->STATE;
|
||||
|
||||
#ifdef DEBUG_PIN_RADIO_IRQ
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RADIO_IRQ);
|
||||
#endif
|
||||
#ifdef DEBUG_PIN_RX
|
||||
nrf_gpio_pin_clear(DEBUG_PIN_RX);
|
||||
#endif
|
||||
#ifdef DEBUG_PIN_TX
|
||||
nrf_gpio_pin_clear(DEBUG_PIN_TX);
|
||||
#endif
|
||||
|
||||
switch (radio_state){
|
||||
case RADIO_W4_TX_DONE:
|
||||
// TX Done, no transition to rx requested
|
||||
btstack_assert(state == RADIO_STATE_STATE_Disabled);
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
radio_state = RADIO_DISABLED;
|
||||
(*radio_callback)(RADIO_RESULT_OK);
|
||||
break;
|
||||
case RADIO_W4_TX_TO_RX:
|
||||
// TX Done, transition to rx
|
||||
btstack_assert(state == RADIO_STATE_STATE_RxRu);
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
radio_state = RADIO_W2_RX;
|
||||
radio_setup_rx();
|
||||
(*radio_callback)(RADIO_RESULT_OK);
|
||||
break;
|
||||
case RADIO_W4_RX_DONE:
|
||||
// RX Done
|
||||
btstack_assert(state == RADIO_STATE_STATE_TxRu);
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
NRF_TIMER0->TASKS_STOP = 1;
|
||||
// check EVENTS_COMPARE[1]
|
||||
if (NRF_TIMER0->EVENTS_COMPARE[1]){
|
||||
// compare event -> timeout
|
||||
radio_state = RADIO_W4_RX_TIMEOUT;
|
||||
NRF_RADIO->SHORTS = 0;
|
||||
NRF_RADIO->TASKS_DISABLE = 1;
|
||||
#ifdef DEBUG_PIN_RX
|
||||
// toggle twice for timeout
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
#endif
|
||||
} else {
|
||||
// no compare event -> packet with address received
|
||||
radio_state = RADIO_W2_TX;
|
||||
// RSSI is stored without sign but is negative (range: 0..127)
|
||||
if (rssi_buffer != NULL){
|
||||
uint32_t rssi_sample = NRF_RADIO->RSSISAMPLE;
|
||||
int8_t rssi;
|
||||
if (rssi_sample < 128){
|
||||
rssi = -rssi_sample;
|
||||
} else {
|
||||
rssi = -128;
|
||||
}
|
||||
*rssi_buffer = rssi;
|
||||
}
|
||||
// check CRC
|
||||
radio_result_t result = ((NRF_RADIO->CRCSTATUS & RADIO_CRCSTATUS_CRCSTATUS_Msk) != 0) ? RADIO_RESULT_OK : RADIO_RESULT_CRC_ERROR;
|
||||
#ifdef DEBUG_PIN_RX
|
||||
// toggle once for crc error
|
||||
if (result == RADIO_RESULT_CRC_ERROR){
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RX);
|
||||
}
|
||||
#endif
|
||||
(*radio_callback)(result);
|
||||
}
|
||||
break;
|
||||
case RADIO_W4_RX_TIMEOUT:
|
||||
// after RX Timeout, RX was started and stopped again
|
||||
btstack_assert(state == RADIO_STATE_STATE_Disabled);
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
radio_state = RADIO_DISABLED;
|
||||
(*radio_callback)(RADIO_RESULT_TIMEOUT);
|
||||
break;
|
||||
case RADIO_W4_DISABLED:
|
||||
NRF_RADIO->EVENTS_DISABLED = 0;
|
||||
NRF_RADIO->INTENCLR = 0xffffffff;
|
||||
radio_state = RADIO_DISABLED;
|
||||
(*radio_callback)(RADIO_RESULT_OK);
|
||||
break;
|
||||
default:
|
||||
log_info("IRQ: our state = 0x%0x, radio_state 0x%04x", radio_state, state);
|
||||
btstack_assert(false);
|
||||
break;
|
||||
}
|
||||
#ifdef DEBUG_PIN_RADIO_IRQ
|
||||
nrf_gpio_pin_toggle(DEBUG_PIN_RADIO_IRQ);
|
||||
#endif
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user