Skip to content

Commit c49da21

Browse files
authored
External target support & automatic target selection for nRF5x-DK boards (#913)
2 parents 00484a4 + 46f388d commit c49da21

File tree

9 files changed

+518
-24
lines changed

9 files changed

+518
-24
lines changed

projects.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,10 @@ projects:
531531
- *module_if
532532
- *module_hic_sam3u2c
533533
- records/board/mkit_dk_dongle_nrf5x.yaml
534+
sam3u2c_nrf5x_dk_ext_if:
535+
- *module_if
536+
- *module_hic_sam3u2c
537+
- records/board/nrf5x_dk_ext.yaml
534538
sam3u2c_ublox_evk_nina_b1_if:
535539
- *module_if
536540
- *module_hic_sam3u2c

records/board/nrf5x_dk_ext.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
common:
2+
macros:
3+
- IO_CONFIG_OVERRIDE
4+
includes:
5+
- source/board/override_nrf5x_dk_ext
6+
sources:
7+
board:
8+
- source/board/nrf5x_dk_ext.c
9+
family:
10+
- source/family/nordic/nrf51822/target_nrf51.c
11+
- source/family/nordic/nrf52/target.c
12+
- source/family/nordic/target_reset_nrf51.c
13+
- source/family/nordic/target_reset_nrf52.c

source/board/nrf5x_dk_ext.c

Lines changed: 258 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,258 @@
1+
/**
2+
* @file mkit_dk_dongle_nrf5x_ext.c
3+
* @brief board ID for the Nordic nRF5x developments boards
4+
*
5+
* DAPLink Interface Firmware
6+
* Copyright (c) 2009-2021, Arm Limited, All Rights Reserved
7+
* SPDX-License-Identifier: Apache-2.0
8+
*
9+
* Licensed under the Apache License, Version 2.0 (the "License"); you may
10+
* not use this file except in compliance with the License.
11+
* You may obtain a copy of the License at
12+
*
13+
* http://www.apache.org/licenses/LICENSE-2.0
14+
*
15+
* Unless required by applicable law or agreed to in writing, software
16+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18+
* See the License for the specific language governing permissions and
19+
* limitations under the License.
20+
*/
21+
22+
#include "sam3u2c.h"
23+
#include "DAP_config.h"
24+
#include "target_config.h"
25+
#include "util.h"
26+
#include "flash_manager.h"
27+
#include "target_family.h"
28+
#include "target_board.h"
29+
30+
// BOARD_ID pointer will be set during run time to point to one of these
31+
const char *board_id_nrf51_dk = "1100";
32+
const char *board_id_nrf52_dk = "1101";
33+
const char *board_id_nrf52840_dk = "1102";
34+
35+
const char *board_name_nrf51_dk = "nRF51-DK";
36+
const char *board_name_nrf52_dk = "nRF52-DK";
37+
const char *board_name_nrf52840_dk = "nRF52840-DK";
38+
static char board_name[24] = "UNKNOWN"; // needs to be >= longest board name + longest suffix + 1
39+
40+
const char *suffix_ext_str = " (ext)";
41+
const char *suffix_shield_str = " (shield)";
42+
43+
extern target_cfg_t target_device_invalid;
44+
extern target_cfg_t target_device_nrf51822_32;
45+
extern target_cfg_t target_device_nrf52_64;
46+
extern target_cfg_t target_device_nrf52840;
47+
48+
target_cfg_t target_device = { // invalid by default
49+
.version = kTargetConfigVersion,
50+
.rt_family_id = kStub_HWReset_FamilyID,
51+
.rt_board_id = "0000",
52+
};
53+
54+
static uint8_t board_supported = 0;
55+
static uint8_t target_ext;
56+
static uint8_t target_shield;
57+
58+
// support for dynamic assignment of SWD signals
59+
Pio *pin_nreset_port = PIN_OB_nRESET_PORT; // GPIO port for nRESET signal
60+
Pio *pin_swclk_port = PIN_OB_SWCLK_PORT; // GPIO port for SWCLK signal
61+
Pio *pin_swdio_port = PIN_OB_SWDIO_PORT; // GPIO port for SWDIO signal
62+
unsigned long pin_nreset_bit = PIN_OB_nRESET_BIT; // GPIO pin for nRESET signal
63+
unsigned long pin_swclk_bit = PIN_OB_SWCLK_BIT; // GPIO pin for SWCLK signal
64+
unsigned long pin_swdio_bit = PIN_OB_SWDIO_BIT; // GPIO pin for SWDIO signal
65+
unsigned long pin_nreset = PIN_OB_nRESET; // GPIO mask for nRESET signal
66+
unsigned long pin_swclk = PIN_OB_SWCLK; // GPIO mask for SWCLK signal
67+
unsigned long pin_swdio = PIN_OB_SWDIO; // GPIO msak for SWDIO signal
68+
69+
static void nrf_prerun_board_config(void)
70+
{
71+
// Work around for setting the correct board id based on GPIOs
72+
uint8_t bit1, bit2, bit3, gpio_id;
73+
74+
PIOB->PIO_PER = (1 << 1); // Enable PIO pin PB1
75+
PIOB->PIO_PER = (1 << 2); // Enable PIO pin PB2
76+
PIOB->PIO_PER = (1 << 3); // Enable PIO pin PB3
77+
PIOB->PIO_ODR = (1 << 1); // Disabe output
78+
PIOB->PIO_ODR = (1 << 2); // Disabe output
79+
PIOB->PIO_ODR = (1 << 3); // Disabe output
80+
PIOB->PIO_PUER = (1 << 1); // Enable pull-up
81+
PIOB->PIO_PUER = (1 << 2); // Enable pull-up
82+
PIOB->PIO_PUER = (1 << 3); // Enable pull-up
83+
84+
bit1 = (PIOB->PIO_PDSR >> 1) & 1; // Read PB1
85+
bit2 = (PIOB->PIO_PDSR >> 2) & 1; // Read PB2
86+
bit3 = (PIOB->PIO_PDSR >> 3) & 1; // Read PB3
87+
88+
PIOB->PIO_PUDR = (1 << 1); // Disable pull-up
89+
PIOB->PIO_PUDR = (1 << 2); // Disable pull-up
90+
PIOB->PIO_PUDR = (1 << 3); // Disable pull-up
91+
92+
gpio_id = (bit3 << 2) | (bit2 << 1) | bit1;
93+
94+
/* Pins translate to board-ids as follow.
95+
* Starred IDs are those supported here.
96+
*
97+
* PB3|PB2|PB1|BOARD ID| BOARD
98+
* ----------------------------------
99+
* 0 | 0 | 0 | 1120 | nRF51-Dongle
100+
* 0 | 0 | 1 | 1100 | nRF51-DK*
101+
* 0 | 1 | 0 | 1101 | nRF52-DK*
102+
* 0 | 1 | 1 | 1102 | nRF52840-DK*
103+
* 1 | 1 | 1 | 1070 | nRF51822-mKIT
104+
* 1 | 0 | 0 | undefined
105+
* 1 | 0 | 1 | undefined
106+
* 1 | 1 | 0 | undefined
107+
*/
108+
109+
// if board is supported, set board name
110+
switch (gpio_id) {
111+
case 0x01: // nRF-51 DK
112+
strcpy(board_name, board_name_nrf51_dk);
113+
board_supported = 1;
114+
break;
115+
116+
case 0x02: // nRF52-DK
117+
strcpy(board_name, board_name_nrf52_dk);
118+
board_supported = 1;
119+
break;
120+
121+
case 0x03: // nRF52840-DK
122+
strcpy(board_name, board_name_nrf52840_dk);
123+
board_supported = 1;
124+
break;
125+
126+
default:
127+
board_supported = 0;
128+
}
129+
130+
// if board is unsupported, we are done.
131+
if (!board_supported)
132+
return;
133+
134+
// External target detection:
135+
// supports nRF51-DK, nRF52-DK, nRF52840-DK
136+
137+
// Configure GPIO for detection
138+
// - EXT_VTG (high if external target is powered)
139+
PIOB->PIO_PUDR = (1 << 6); // pull-up disable
140+
PIOB->PIO_ODR = (1 << 6); // input
141+
PIOB->PIO_PER = (1 << 6); // GPIO control
142+
// - EXT_GND_DETECT (low if external target is connected)
143+
PIOB->PIO_PUER = (1 << 18); // pull-up enable
144+
PIOB->PIO_ODR = (1 << 18); // input
145+
PIOB->PIO_PER = (1 << 18); // GPIO control
146+
// - SH_VTG (high if shield-mounted target is powered)
147+
PIOB->PIO_PUDR = (1 << 5); // pull-up disable
148+
PIOB->PIO_ODR = (1 << 5); // input
149+
PIOB->PIO_PER = (1 << 5); // GPIO control
150+
// - SH_GND_DETECT (low if shield-mounted target is connected)
151+
PIOB->PIO_PUER = (1 << 23); // pull-up enable
152+
PIOB->PIO_ODR = (1 << 23); // input
153+
PIOB->PIO_PER = (1 << 23); // GPIO control
154+
155+
// nonzero if external target is detected
156+
bit1 = (PIOB->PIO_PDSR >> 6) & 1; // Read PB6
157+
bit2 = (PIOB->PIO_PDSR >> 18) & 1; // Read PB18
158+
target_ext = bit1 | !bit2;
159+
160+
// nonzero if shield-mounted target is detected
161+
bit1 = (PIOB->PIO_PDSR >> 5) & 1; // Read PB5
162+
bit2 = (PIOB->PIO_PDSR >> 23) & 1; // Read PB23
163+
target_shield = bit1 | !bit2;
164+
165+
// Disable pull-ups for detection
166+
PIOB->PIO_PUDR = (1 << 18); // pull-up disable
167+
PIOB->PIO_PUDR = (1 << 23); // pull-up disable
168+
169+
// if external/shield target is detected, re-route SWD signals
170+
if (target_ext) {
171+
pin_nreset_port = PIN_EXT_nRESET_PORT;
172+
pin_nreset_bit = PIN_EXT_nRESET_BIT;
173+
pin_nreset = PIN_EXT_nRESET;
174+
175+
pin_swclk_port = PIN_EXT_SWCLK_PORT;
176+
pin_swclk_bit = PIN_EXT_SWCLK_BIT;
177+
pin_swclk = PIN_EXT_SWCLK;
178+
179+
pin_swdio_port = PIN_EXT_SWDIO_PORT;
180+
pin_swdio_bit = PIN_EXT_SWDIO_BIT;
181+
pin_swdio = PIN_EXT_SWDIO;
182+
183+
// append suffix to board name
184+
strcpy(board_name + strlen(board_name), suffix_ext_str);
185+
186+
} else if (target_shield) {
187+
pin_nreset_port = PIN_SH_nRESET_PORT;
188+
pin_nreset_bit = PIN_SH_nRESET_BIT;
189+
pin_nreset = PIN_SH_nRESET;
190+
191+
pin_swclk_port = PIN_SH_SWCLK_PORT;
192+
pin_swclk_bit = PIN_SH_SWCLK_BIT;
193+
pin_swclk = PIN_SH_SWCLK;
194+
195+
pin_swdio_port = PIN_SH_SWDIO_PORT;
196+
pin_swdio_bit = PIN_SH_SWDIO_BIT;
197+
pin_swdio = PIN_SH_SWDIO;
198+
199+
// append suffix to board name
200+
strcpy(board_name + strlen(board_name), suffix_shield_str);
201+
202+
} else { // OB target
203+
switch (gpio_id) {
204+
case 0x01: // nRF-51 DK
205+
target_device = target_device_nrf51822_32;
206+
target_device.rt_family_id = kNordic_Nrf51_FamilyID;
207+
target_device.rt_board_id = board_id_nrf51_dk;
208+
break;
209+
210+
case 0x02: // nRF52-DK
211+
target_device = target_device_nrf52_64;
212+
target_device.rt_family_id = kNordic_Nrf52_FamilyID;
213+
target_device.rt_board_id = board_id_nrf52_dk;
214+
break;
215+
216+
case 0x03: // nRF52840-DK
217+
target_device = target_device_nrf52840;
218+
target_device.rt_family_id = kNordic_Nrf52_FamilyID;
219+
target_device.rt_board_id = board_id_nrf52840_dk;
220+
break;
221+
222+
default: // never reached
223+
;
224+
}
225+
}
226+
227+
// switch on red LED if external/shield target is in use
228+
PIOA->PIO_PUDR = (1 << 28); // pull-up disable
229+
PIOA->PIO_OER = (1 << 28); // output
230+
PIOA->PIO_PER = (1 << 28); // GPIO control
231+
if (target_ext || target_shield)
232+
PIOA->PIO_CODR = (1 << 28); // set low
233+
else
234+
PIOA->PIO_SODR = (1 << 28); // set high
235+
}
236+
237+
// Overrides flash_algo_valid() in source/target/target_board.c .
238+
// Only enables MSD when a supported board is detected and the on-board target is enabled.
239+
uint8_t flash_algo_valid(void)
240+
{
241+
return (board_supported && !target_ext && !target_shield);
242+
}
243+
244+
static void nrf_swd_set_target_reset(uint8_t asserted){
245+
if(!asserted) {
246+
PIOA->PIO_MDER = PIN_SWDIO | PIN_SWCLK | PIN_nRESET;
247+
}
248+
}
249+
250+
const board_info_t g_board_info = {
251+
.info_version = kBoardInfoVersion,
252+
.flags = kEnablePageErase,
253+
.prerun_board_config = nrf_prerun_board_config,
254+
.swd_set_target_reset = nrf_swd_set_target_reset,
255+
.target_cfg = &target_device,
256+
.board_vendor = "Nordic Semiconductor",
257+
.board_name = board_name,
258+
};

source/board/override_mkit_dk_dongle_nrf5x/IO_Config_Override.h

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/**
22
* @file IO_Config_Override.c
3-
* @brief Alternative IO for LPC11U35 based Hardware Interface Circuit
3+
* @brief Alternative IO for Nordic Semiconductor mKit/Dongle/DK
44
*
55
* DAPLink Interface Firmware
66
* Copyright (c) 2009-2016, ARM Limited, All Rights Reserved
@@ -22,6 +22,9 @@
2222
#ifndef __IO_CONFIG_OVERRIDE_H__
2323
#define __IO_CONFIG_OVERRIDE_H__
2424

25+
#include "sam3u2c.h"
26+
#include "daplink.h"
27+
2528
// This GPIO configuration is only valid for the SAM3U2C HIC
2629
COMPILER_ASSERT(DAPLINK_HIC_ID == DAPLINK_HIC_ID_SAM3U2C);
2730

@@ -40,4 +43,30 @@ COMPILER_ASSERT(DAPLINK_HIC_ID == DAPLINK_HIC_ID_SAM3U2C);
4043
#define PIN_CDC_LED_BIT 29
4144
#define PIN_CDC_LED (1UL << PIN_CDC_LED_BIT)
4245

46+
// Non-Forwarded Reset in PIN - Not used
47+
48+
// Forwarded Reset in PIN
49+
#define PIN_RESET_IN_FWRD_PORT PIOA
50+
#define PIN_RESET_IN_FWRD_BIT 25
51+
#define PIN_RESET_IN_FWRD (1UL << PIN_RESET_IN_FWRD_BIT)
52+
53+
// nRESET OUT Pin
54+
#define PIN_nRESET_PORT PIOA
55+
#define PIN_nRESET_BIT 4
56+
#define PIN_nRESET (1UL << PIN_nRESET_BIT)
57+
58+
// SWCLK/TCK Pin
59+
#define PIN_SWCLK_PORT PIOA
60+
#define PIN_SWCLK_BIT 17
61+
#define PIN_SWCLK (1UL << PIN_SWCLK_BIT)
62+
63+
// SWDIO/TMS In/Out Pin
64+
#define PIN_SWDIO_PORT PIOA
65+
#define PIN_SWDIO_BIT 18
66+
#define PIN_SWDIO (1UL << PIN_SWDIO_BIT)
67+
68+
// TDI Pin - Not used
69+
70+
// SWO/TDO Pin - Not used
71+
4372
#endif

0 commit comments

Comments
 (0)