Hello,
I am trying to compile a basic Hello World application for a custom PCB with a nRF52832 microcontroller. I am using VS Code and the nRF Connect SDK. I have completed the nRF Connect SDK Fundamentals course and received the certificate, and now I am trying to apply those lessons to my custom hardware.
My goal is to compile a Hello World example and see the message printed on the VS Code console. My custom hardware does not have a UART connection broken out. I am programming my custom hardware over SWD via a nRF52-DK PCA10040 board. I would like to receive logging messages over SWD as well.
When I connect a TagConnect cable to the P19 Debug Out connector and mate it with my custom board, I can see the Connected Devices tab update from NRF52832_xxAA_REV2 to NRF52832_xxAB_REV2, so I am fairly sure that I am programming my custom board and not the DK itself.
Initially, I tried a simple printk statement, which builds and runs, but no messages are received in the terminal. After some digging in the Nordic forums, I realized that I want to use the SWD interface for console output, instead of a UART. So, I enabled logging as explained in the Fundamentals course Lesson 4 Exercise 2. I also tried changing my prj.conf to disable the UART console and enable the RTT_CONSOLE instead.
This builds and flashes without issue, but I am still not getting any of my debug messages.
How can I properly set up the SWD interface for Hello world, printk, and logging messages on a custom PCB?
main.c
/* * Copyright (c) 2012-2014 Wind River Systems, Inc. * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr/device.h> #include <zephyr/devicetree.h> #include <zephyr/kernel.h> #include <zephyr/logging/log.h> LOG_MODULE_REGISTER(NixieLogs,LOG_LEVEL_DBG); int main(void) { while(true){ printk("Hello World! %s\n", CONFIG_BOARD); LOG_INF("nRF Connect SDK Fundamentals"); LOG_DBG("A log message in debug level"); LOG_WRN("A log message in warning level!"); LOG_ERR("A log message in Error level!"); } return 0; }
prj.conf
# nothing here CONFIG_LOG=y CONFIG_USE_SEGGER_RTT=y CONFIG_RTT_CONSOLE=y CONFIG_UART_CONSOLE=n
CMakeLists.txt
# SPDX-License-Identifier: Apache-2.0 cmake_minimum_required(VERSION 3.20.0) list(APPEND BOARD_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(hello_world) target_sources(app PRIVATE src/main.c)
Custom PCB board defconfig
# SPDX-License-Identifier: Apache-2.0 CONFIG_SOC_SERIES_NRF52X=y CONFIG_SOC_NRF52832_QFAA=y CONFIG_BOARD_NIXIE_CLOCK_BOARD=y # Enable MPU CONFIG_ARM_MPU=y # Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y # Enable RTT CONFIG_USE_SEGGER_RTT=y # enable GPIO CONFIG_GPIO=y # enable uart driver CONFIG_SERIAL=y # enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y # additional board options CONFIG_GPIO_AS_PINRESET=y CONFIG_PINCTRL=y
Custom board DTS file
/* * Copyright (c) 2017 Shawn Nock <[email protected]> * Copyright (c) 2017 Linaro Limited * * SPDX-License-Identifier: Apache-2.0 */ /dts-v1/; #include <nordic/nrf52832_qfaa.dtsi> #include "nixie_clock_board-pinctrl.dtsi" / { model = "Chris Fernandez Nixie Clock Board"; compatible = "chrisfernandez,nixie_clock_board"; chosen { zephyr,console = &uart0; zephyr,shell-uart = &uart0; zephyr,uart-mcumgr = &uart0; zephyr,bt-mon-uart = &uart0; zephyr,bt-c2h-uart = &uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,code-partition = &slot0_partition; }; leds { compatible = "gpio-leds"; led0: led_0 { gpios = <&gpio0 17 GPIO_ACTIVE_LOW>; label = "Green LED 0"; }; led1: led_1 { gpios = <&gpio0 18 GPIO_ACTIVE_LOW>; label = "Green LED 1"; }; led2: led_2 { gpios = <&gpio0 19 GPIO_ACTIVE_LOW>; label = "Green LED 2"; }; led3: led_3 { gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; label = "Green LED 3"; }; }; pwmleds { compatible = "pwm-leds"; pwm_led0: pwm_led_0 { pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; buttons { compatible = "gpio-keys"; button0: button_0 { gpios = <&gpio0 13 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button switch 0"; }; button1: button_1 { gpios = <&gpio0 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button switch 1"; }; button2: button_2 { gpios = <&gpio0 15 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button switch 2"; }; button3: button_3 { gpios = <&gpio0 16 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "Push button switch 3"; }; }; arduino_header: connector { compatible = "arduino-header-r3"; #gpio-cells = <2>; gpio-map-mask = <0xffffffff 0xffffffc0>; gpio-map-pass-thru = <0 0x3f>; gpio-map = <0 0 &gpio0 3 0>, /* A0 */ <1 0 &gpio0 4 0>, /* A1 */ <2 0 &gpio0 28 0>, /* A2 */ <3 0 &gpio0 29 0>, /* A3 */ <4 0 &gpio0 30 0>, /* A4 */ <5 0 &gpio0 31 0>, /* A5 */ <6 0 &gpio0 11 0>, /* D0 */ <7 0 &gpio0 12 0>, /* D1 */ <8 0 &gpio0 13 0>, /* D2 */ <9 0 &gpio0 14 0>, /* D3 */ <10 0 &gpio0 15 0>, /* D4 */ <11 0 &gpio0 16 0>, /* D5 */ <12 0 &gpio0 17 0>, /* D6 */ <13 0 &gpio0 18 0>, /* D7 */ <14 0 &gpio0 19 0>, /* D8 */ <15 0 &gpio0 20 0>, /* D9 */ <16 0 &gpio0 22 0>, /* D10 */ <17 0 &gpio0 23 0>, /* D11 */ <18 0 &gpio0 24 0>, /* D12 */ <19 0 &gpio0 25 0>, /* D13 */ <20 0 &gpio0 26 0>, /* D14 */ <21 0 &gpio0 27 0>; /* D15 */ }; arduino_adc: analog-connector { compatible = "arduino,uno-adc"; #io-channel-cells = <1>; io-channel-map = <0 &adc 1>, /* A0 = P0.3 = AIN1 */ <1 &adc 2>, /* A1 = P0.4 = AIN2 */ <2 &adc 4>, /* A2 = P0.28 = AIN4 */ <3 &adc 5>, /* A3 = P0.29 = AIN5 */ <4 &adc 6>, /* A4 = P0.30 = AIN6 */ <5 &adc 7>; /* A5 = P0.31 = AIN7 */ }; /* These aliases are provided for compatibility with samples */ aliases { led0 = &led0; led1 = &led1; led2 = &led2; led3 = &led3; pwm-led0 = &pwm_led0; sw0 = &button0; sw1 = &button1; sw2 = &button2; sw3 = &button3; bootloader-led0 = &led0; mcuboot-button0 = &button0; mcuboot-led0 = &led0; watchdog0 = &wdt0; }; }; &adc { status = "okay"; }; &gpiote { status = "okay"; }; &gpio0 { status = "okay"; }; arduino_serial: &uart0 { status = "okay"; compatible = "nordic,nrf-uarte"; current-speed = <115200>; pinctrl-0 = <&uart0_default>; pinctrl-1 = <&uart0_sleep>; pinctrl-names = "default", "sleep"; }; arduino_i2c: &i2c0 { compatible = "nordic,nrf-twi"; status = "okay"; pinctrl-0 = <&i2c0_default>; pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; }; &i2c1 { compatible = "nordic,nrf-twi"; /* Cannot be used together with spi1. */ /* status = "okay"; */ pinctrl-0 = <&i2c1_default>; pinctrl-1 = <&i2c1_sleep>; pinctrl-names = "default", "sleep"; }; &pwm0 { status = "okay"; pinctrl-0 = <&pwm0_default>; pinctrl-1 = <&pwm0_sleep>; pinctrl-names = "default", "sleep"; }; &spi0 { compatible = "nordic,nrf-spi"; /* Cannot be used together with i2c0. */ /* status = "okay"; */ pinctrl-0 = <&spi0_default>; pinctrl-1 = <&spi0_sleep>; pinctrl-names = "default", "sleep"; }; &spi1 { compatible = "nordic,nrf-spi"; status = "okay"; pinctrl-0 = <&spi1_default>; pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; }; arduino_spi: &spi2 { compatible = "nordic,nrf-spi"; status = "okay"; cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ pinctrl-0 = <&spi2_default>; pinctrl-1 = <&spi2_sleep>; pinctrl-names = "default", "sleep"; }; &flash0 { partitions { compatible = "fixed-partitions"; #address-cells = <1>; #size-cells = <1>; boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 0xc000>; }; slot0_partition: partition@c000 { label = "image-0"; reg = <0x0000C000 0x37000>; }; slot1_partition: partition@43000 { label = "image-1"; reg = <0x00043000 0x37000>; }; storage_partition: partition@7a000 { label = "storage"; reg = <0x0007a000 0x00006000>; }; }; };
Custom PCB board.cmake
# SPDX-License-Identifier: Apache-2.0 board_runner_args(jlink "--device=nRF52832_xxAA" "--speed=4000") board_runner_args(pyocd "--target=nrf52832" "--frequency=4000000") set(OPENOCD_NRF5_SUBFAMILY "nrf52") include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) include(${ZEPHYR_BASE}/boards/common/pyocd.board.cmake) include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake)