Today I decided to test the Nordic Uart Service (NUS) to enable a serial communication (emulated) between a Bluetooh Low Energy device (nRF51822) and an Android device.
The Nordic SDK comes with an example (nordic/examples/ble_peripheral/ble_app_uart) used for serial communication over BLE. For more info:
https://devzone.nordicsemi.com/documentation/nrf51/6.0.0/s110/html/a00066.html
I download the SDK modified to compile with open-source toolchains:
https://github.com/relayr/nrf51-sdk.git
For more info read me previous post:
https://acassis.wordpress.com/2016/02/25/using-openocd-to-program-a-homebrew-nrf51822-board/
The compilation was not so easy as it is supposed to do. I got some undefined references, like this one:
.../newlib/libc/reent/sbrkr.c:58: undefined reference to `_sbrk'
I fixed it editting “relayr/ld/libc-nano.ld” file and adding:
EXTERN(_sbrk_r) EXTERN(_write_r) EXTERN(_close_r) EXTERN(_lseek_r) EXTERN(_read_r) EXTERN(_fstat_r) EXTERN(_isatty_r)
Also I created a custom board definition based on wunderbar-master-nrf.h
$ cp relayr/include/wunderbar-master-nrf.h relayr/include/custom_board.h
And finally created a build.mk with all files needed to compile the example:
DEVICE_VARIANT?= xxaa DEFINES+= NRF51 NRF51822_QFAA_CA BOARD_CUSTOM SDKINCDIRS+= toolchain toolchain/gcc drivers_nrf/hal device libraries/scheduler SDKINCDIRS+= softdevice/common/softdevice_handler libraries/timer SDKINCDIRS+= ble/ble_advertising libraries/button ble/ble_services/ble_nus SDKINCDIRS+= drivers_nrf/uart drivers_nrf/gpiote drivers_nrf/config drivers_nrf/common SDKINCDITS+= drivers_nrf/hal libraries/fifo EXPINCDIR+= bsp EXPINCDIR+= ble_peripheral/ble_app_uart/config SDKSRCS+= toolchain/gcc/gcc_startup_nrf51.s toolchain/system_nrf51.c SDKSRCS+= libraries/timer/app_timer.c SDKSRCS+= ble/common/ble_advdata.c SDKSRCS+= ble/common/ble_conn_params.c SDKSRCS+= softdevice/common/softdevice_handler/softdevice_handler.c SDKSRCS+= libraries/scheduler/app_scheduler.c SDKSRCS+= libraries/timer/app_timer_appsh.c SDKSRCS+= drivers_nrf/uart/app_uart_fifo.c SDKSRCS+= ble/ble_services/ble_nus/ble_nus.c SDKSRCS+= ble/ble_advertising/ble_advertising.c SDKSRCS+= libraries/button/app_button.c SDKSRCS+= drivers_nrf/gpiote/nrf_drv_gpiote.c SDKSRCS+= drivers_nrf/common/nrf_drv_common.c SDKSRCS+= libraries/fifo/app_fifo.c EXPSRCS+= bsp/bsp.c EXPSRCS+= bsp/bsp_btn_ble.c USE_SOFTDEVICE?= s110 SDKDIR:= $(abspath $(dir $(lastword ${MAKEFILE_LIST}))) ifndef SDDIR SDKINCDIRS+= softdevice/${USE_SOFTDEVICE}/headers else CFLAGS+= -I${SDDIR}/include endif SOFTDEV_HEX?= $(lastword $(wildcard ${SDKDIR}/nordic/components/softdevice/${USE_SOFTDEVICE}/hex/${USE_SOFTDEVICE}*softdevice.hex)) SDKINCDIRS+= $(sort $(dir ${SDKSRCS}) ) SRCS+= $(patsubst %,${SDKDIR}/nordic/examples/%,${EXPSRCS}) ifdef USE_RTX DEFINES+= RTX __HEAP_SIZE=0 __STACK_SIZE=1024 SRCS+= ${SDKDIR}/nordic/external/rtx/port/RTX_Conf_CM.c CFLAGS+= -I${SDKDIR}/nordic/external/rtx/include LDLIBS+= ${SDKDIR}/nordic/external/rtx/source/GCC/libRTX_CM0.a endif ifeq ($(filter FALSE false NO no 0,${USE_SIMBLE}),) include ${SDKDIR}/relayr/src/build.mk endif CPPFLAGS+= $(patsubst %,-D%,${DEFINES}) CFLAGS+= -I${SDKDIR}/relayr/include CFLAGS+= $(patsubst %,-I${SDKDIR}/nordic/examples/%,${EXPINCDIR}) CFLAGS+= $(patsubst %,-I${SDKDIR}/nordic/components/%,${SDKINCDIRS}) CFLAGS+= -mcpu=cortex-m0 -mfloat-abi=soft -mthumb -mabi=aapcs \ -ffunction-sections -fdata-sections -fno-builtin \ -fplan9-extensions CFLAGS+= -std=gnu11 CFLAGS+= -fshort-wchar -Wl,--no-wchar-size-warning CFLAGS+= -Wall -Wno-main -Werror CFLAGS+= -g LINKERSCRIPT?= gcc_nrf51_${USE_SOFTDEVICE}_${DEVICE_VARIANT}.ld LDFLAGS+= -Wl,--gc-sections -fwhole-program --specs=nano.specs LDFLAGS+= -Wl,-Map=${PROG}.map LDFLAGS+= -Wl,-T,${SDKDIR}/relayr/ld/libc-nano.ld LDFLAGS+= -Wl,-L${SDKDIR}/relayr/ld LDFLAGS+= -Wl,-L${SDKDIR}/nordic/components/toolchain/gcc LDFLAGS+= -Wl,-T,${LINKERSCRIPT} LDFLAGS+= -lgcc -lc -lm -lg -lrdimon -lnosys ASFLAGS+= -x assembler-with-cpp SRCS+= $(patsubst %,${SDKDIR}/nordic/components/%,${SDKSRCS}) CC= arm-none-eabi-gcc OBJCOPY= arm-none-eabi-objcopy OBJDUMP= arm-none-eabi-objdump GDB= arm-none-eabi-gdb GENERATE.d= $(CC) -MM ${CFLAGS} ${CPPFLAGS} -MT $@ -MT ${@:.d=.o} -MP -MF $@ $< COMPILE.s= ${COMPILE.S} all: ${PROG}.hex ${PROG}.bin define compile_source ifneq ($(filter %.c %.S %.s,${1}),) $(addsuffix .o,$(notdir $(basename ${1}))): ${1} $${COMPILE$(suffix ${1})} $${OUTPUT_OPTION} $$< endif ifneq ($(filter %.c,${1}),) $(addsuffix .d,$(notdir $(basename ${1}))): ${1} $$(GENERATE.d) endif OBJS+= $$(addsuffix .o,$(notdir $(basename ${1}))) endef $(foreach f,${SRCS},$(eval $(call compile_source,$f))) ifneq (${MAKECMDGOALS},clean) -include $(patsubst %.o,%.d,${OBJS}) endif CLEANFILES+= ${OBJS} ${OBJS:.o=.d} ${PROG}.hex ${PROG}.elf ${PROG}.bin ${PROG}.map ${PROG}.jlink ${PROG}-all.jlink ${PROG}.elf: ${OBJS} ${CC} -o $@ ${CFLAGS} ${LDFLAGS} ${OBJS} ${LDLIBS} %.hex: %.elf ${OBJCOPY} -O ihex $< $@ %.bin: %.elf ${OBJCOPY} -O binary $< $@ %.jlink: %.hex ${OBJDUMP} -h $< | \ awk '$$1 ~ /^[0-9]+$$/ {addr="0x"$$5; if (!min || addr < min) min = addr} END { printf "\ loadbin %s,%s\n\ r\n\ g\n\ exit\n", f, min}' f="$ $@ %-all.jlink: %.jlink ${SOFTDEV_HEX} FORCE @[ -e "${SOFTDEV_HEX}" ] || echo "cannot find softdevice hex image '${SOFTDEV_HEX}'" >&2 # w4 0x4001e504, 0x2 -> enable erase: CONFIG.WEN = EEN # w4 0x4001e50c, 0x1 -> erase all: ERASEALL = 1 printf "\ device NRF51822_XXAA\n\ halt\n\ w4 0x4001e504, 0x2\n\ w4 0x4001e50c, 0x1\n\ sleep 1\n\ loadbin %s,0\n" ${SOFTDEV_HEX} > $@ cat $> $@ flash: ${PROG}.hex ${PROG}.jlink JLinkExe -device nRF51822_xxAA -if SWD ${PROG}.jlink flash-all: ${PROG}.hex ${SOFTDEV_HEX} ${PROG}-all.jlink JLinkExe -device nRF51822_xxAA -if SWD ${PROG}-all.jlink gdbserver: ${PROG}.elf JLinkGDBServer -device nRF51822_xxAA -if SWD gdb: ${PROG}.elf ${GDB} ${PROG}.elf -ex 'target extended-remote :2331' GITREV= $(shell git describe --always) MAILFILE= ${PROG}-${GITREV}.hex CLEANFILES+= ${PROG}-*.hex mailfile: ${MAILFILE} -$(foreach f,$(filter-out $<,$(wildcard ${PROG}-*.hex)),rm $f;) -@md5sum $< -@sha256sum $< ${PROG}-${GITREV}.hex: ${PROG}.hex cp $< $@ clean: -rm -f ${CLEANFILES} .PHONY: all flash flash-all gdbserver gdb clean FORCE