OpenOCD
nrf54.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 #ifdef HAVE_CONFIG_H
4 #include "config.h"
5 #endif
6 
7 #include "imp.h"
8 #include <helper/binarybuffer.h>
9 #include <target/algorithm.h>
10 #include <target/armv7m.h>
11 #include <helper/types.h>
12 #include <helper/time_support.h>
13 #include <helper/bits.h>
14 
15 /*
16  * Related documents
17  *
18  * nRF54L15, nRF54L10, and nRF54L05 Wireless SoCs
19  * https://docs-be.nordicsemi.com/bundle/ps_nrf54L15/page/pdf/nRF54L15_nRF54L10_nRF54L05_Datasheet_v0.8.pdf
20  *
21  * nRF54L Series Production Programming
22  * https://docs-be.nordicsemi.com/bundle/nan_047/attach/nan_047.pdf
23  */
24 
25 #define NRF54_FICR_BASE_ADDR 0x00FFC000
26 
27 #define NRF54_FICR_INFO_PART_REG 0x31c
28 #define NRF54_FICR_INFO_VARIANT_REG 0x320
29 #define NRF54_FICR_INFO_PACKAGE_REG 0x324
30 #define NRF54_FICR_INFO_RAM_REG 0x328
31 #define NRF54_FICR_INFO_RRAM_REG 0x32C
32 
33 #define NRF54_RRAM_BASE_ADDR 0x00000000
34 
35 #define NRF54_RRAMC_BASE_ADDR 0x5004B000
36 
37 #define NRF54_RRAMC_REG_CONFIG 0x500
38 #define NRF54_RRAMC_REG_READY 0x400
39 
40 #define NRF54_RRAMC_CONFIG_WEN BIT(0)
41 
42 struct {
43  uint32_t id;
44  const char *name;
45 } nrf54_part_names[] = {
46  { 0x00054B15, "nRF54L15" },
47  { 0x00054B10, "nRF54L10" },
48  { 0x00054B05, "nRF54L05" },
49 };
50 
52  // Part identification number.
53  uint32_t part;
54  /*
55  * Part variant (V), hardware version (H) and production
56  * configuration (P) encoded as ASCII: <VV><H><P>.
57  */
58  uint32_t variant;
59  /*
60  * Package variant (P) encoded as ASCII: <__><PP>, where (_) indicates
61  * the null character.
62  */
63  uint32_t package;
64  // SRAM size in KiB.
65  uint32_t sram_size;
66  // RRAM size in KiB.
67  uint32_t rram_size;
68 };
69 
70 struct nrf54_info {
71  bool probed;
72  const char *part_name;
73 
75 };
76 
77 static int nrf54_read_ficr_info(struct target *target,
78  struct nrf54_ficr_info *info)
79 {
80  int retval = target_read_u32(target,
82  if (retval != ERROR_OK)
83  return retval;
84 
85  retval = target_read_u32(target,
87  if (retval != ERROR_OK)
88  return retval;
89 
90  retval = target_read_u32(target,
92  if (retval != ERROR_OK)
93  return retval;
94 
95  retval = target_read_u32(target,
97  if (retval != ERROR_OK)
98  return retval;
99 
100  retval = target_read_u32(target,
102  if (retval != ERROR_OK)
103  return retval;
104 
105  return ERROR_OK;
106 }
107 
108 static const char *nrf54_get_part_name(uint32_t id)
109 {
110  for (size_t i = 0; i < ARRAY_SIZE(nrf54_part_names); i++) {
111  if (id == nrf54_part_names[i].id)
112  return nrf54_part_names[i].name;
113  }
114 
115  return NULL;
116 }
117 
118 static void nrf54_u32_to_str(uint32_t data, char *str)
119 {
120  uint8_t tmp[4];
121 
122  h_u32_to_be(tmp, data);
123  memcpy(str, tmp, 4);
124  str[4] = '\0';
125 }
126 
127 static bool nrf54_get_chip_type_str(const struct nrf54_info *info,
128  char *buf, size_t size)
129 {
130  char variant[5];
131  nrf54_u32_to_str(info->ficr_info.variant, variant);
132 
133  char package[5];
134  // Note that the first two characters are always null characters.
135  nrf54_u32_to_str(info->ficr_info.package, package);
136 
137  int res = snprintf(buf, size, "%s-%c%c%c%c",
138  info->part_name, package[2], package[3], variant[0], variant[1]);
139 
140  if (res < 0)
141  return false;
142 
143  if ((size_t)res >= size)
144  return false;
145 
146  return true;
147 }
148 
149 static int nrf54_info(struct flash_bank *bank, struct command_invocation *cmd)
150 {
151  struct nrf54_info *info = bank->driver_priv;
152 
153  char chip_type[128];
154  if (!nrf54_get_chip_type_str(info, chip_type, sizeof(chip_type))) {
155  LOG_ERROR("Failed to build chip type string");
156  return ERROR_FAIL;
157  }
158 
159  command_print_sameline(cmd, "%s %" PRIu32 " KiB RRAM, %" PRIu32 " KiB SRAM",
160  chip_type, info->ficr_info.rram_size, info->ficr_info.sram_size);
161 
162  return ERROR_OK;
163 }
164 
165 static int nrf54_probe(struct flash_bank *bank)
166 {
167  struct target *target = bank->target;
168  struct nrf54_info *nrf54_info = bank->driver_priv;
169  struct nrf54_ficr_info *ficr_info = &nrf54_info->ficr_info;
170 
171  int retval = nrf54_read_ficr_info(target, ficr_info);
172  if (retval != ERROR_OK) {
173  LOG_ERROR("Failed to load FICR from device");
174  return retval;
175  }
176 
177  const char *part_name = nrf54_get_part_name(ficr_info->part);
178 
179  if (!part_name) {
180  LOG_ERROR("Unknown device with part number 0x%08" PRIx32,
182  return ERROR_FAIL;
183  }
184 
185  nrf54_info->part_name = part_name;
186  bank->size = ficr_info->rram_size * 1024;
187 
188  nrf54_info->probed = true;
189 
190  // RRAM has no alignment constraints, see section 4.2.6.2 in the datasheet.
191  bank->write_start_alignment = 0;
192  bank->write_end_alignment = 0;
193 
194  return ERROR_OK;
195 }
196 
197 static int nrf54_auto_probe(struct flash_bank *bank)
198 {
199  struct nrf54_info *info = bank->driver_priv;
200 
201  if (!info->probed)
202  return nrf54_probe(bank);
203 
204  return ERROR_OK;
205 }
206 
207 static int nrf54_wait_until_ready(struct target *target, uint32_t timeout)
208 {
209  const int64_t start_time = timeval_ms();
210 
211  while (true) {
212  uint32_t ready;
213  int retval = target_read_u32(target,
215 
216  if (retval != ERROR_OK)
217  return retval;
218 
219  /*
220  * Send a 'keep-alive' signal before checking if the target is ready.
221  * The target is usually ready immediately, so without this 'keep-alive'
222  * it would process consecutive write calls without any keep-alive and
223  * eventually trigger a timeout.
224  */
225  keep_alive();
226 
227  if (ready)
228  break;
229 
230  if ((timeval_ms() - start_time) > timeout) {
231  LOG_ERROR("Timed out waiting for RRAM");
232  return ERROR_FAIL;
233  }
234  }
235 
236  return ERROR_OK;
237 }
238 
239 static int nrf54_write(struct flash_bank *bank, const uint8_t *buffer,
240  uint32_t offset, uint32_t count)
241 {
242  struct target *target = bank->target;
243 
244  if (target->state != TARGET_HALTED) {
245  LOG_ERROR("Target not halted");
247  }
248 
249  // Write buffer size in 128-bit words, we always use the maximum.
250  const uint32_t write_buffer_size = 32;
251 
252  // Unlock RRAM to enables writes and configure the write buffer size.
253  int retval = target_write_u32(target,
255  (write_buffer_size << 8) | NRF54_RRAMC_CONFIG_WEN);
256 
257  if (retval != ERROR_OK) {
258  LOG_ERROR("Failed to unlock RRAM");
259  return retval;
260  }
261 
262  retval = nrf54_wait_until_ready(target, 1000);
263  if (retval != ERROR_OK)
264  goto error;
265 
266  // See section (4.2.6.2) in the datasheet about writing to RRAM.
267  const uint32_t buffer_size = (write_buffer_size == 0) ?
268  4 : write_buffer_size * 16;
269 
270  while (count > 0) {
271  const uint32_t write_size = MIN(buffer_size, count);
272  retval = target_write_buffer(target, bank->base + offset, write_size,
273  buffer);
274 
275  if (retval != ERROR_OK)
276  goto error;
277 
278  retval = nrf54_wait_until_ready(target, 1000);
279  if (retval != ERROR_OK)
280  goto error;
281 
282  offset += write_size;
283  buffer += write_size;
284  count -= write_size;
285  }
286 
287  // Check if there is data in the write-buffer that needs to be committed.
288  uint32_t buf_status;
289  retval = target_read_u32(target, NRF54_RRAMC_BASE_ADDR + 0x418, &buf_status);
290  if (retval != ERROR_OK) {
291  LOG_ERROR("Failed to read write-buffer status");
292  goto error;
293  }
294 
295  if (!buf_status) {
296  LOG_DEBUG("Commit data from write-buffer to RRAM");
297 
298  retval = target_write_u32(target, NRF54_RRAMC_BASE_ADDR + 0x8, 0x1);
299  if (retval != ERROR_OK) {
300  LOG_ERROR("Failed to start write-buffer commit task");
301  goto error;
302  }
303 
304  retval = nrf54_wait_until_ready(target, 1000);
305  if (retval != ERROR_OK) {
306  LOG_ERROR("Timed out during write-buffer commit task");
307  goto error;
308  }
309  }
310 
311  int retval_lock;
312 error:
313  // Lock RRAMC and disable writes.
314  retval_lock = target_write_u32(target,
316 
317  if (retval != ERROR_OK)
318  return retval;
319 
320  if (retval_lock != ERROR_OK) {
321  LOG_ERROR("Failed to lock RRAMC");
322  return retval_lock;
323  }
324 
325  return ERROR_OK;
326 }
327 
328 FLASH_BANK_COMMAND_HANDLER(nrf54_flash_bank_command)
329 {
330  if (bank->base != NRF54_RRAM_BASE_ADDR) {
331  LOG_ERROR("Bank base address must be %" PRIx32, NRF54_RRAM_BASE_ADDR);
332  return ERROR_FAIL;
333  }
334 
335  struct nrf54_info *nrf54_info = calloc(1, sizeof(struct nrf54_info));
336 
337  if (!nrf54_info) {
338  LOG_ERROR("Failed to allocate memory");
339  return ERROR_FAIL;
340  }
341 
342  nrf54_info->probed = false;
343  bank->driver_priv = nrf54_info;
344 
345  return ERROR_OK;
346 }
347 
348 static const struct command_registration nrf54_command_handlers[] = {
349  {
350  .name = "nrf54",
351  .mode = COMMAND_ANY,
352  .help = "nrf54 flash command group",
353  .usage = "",
354  },
356 };
357 
358 const struct flash_driver nrf54_flash = {
359  .name = "nrf54",
360  .commands = nrf54_command_handlers,
361  .flash_bank_command = nrf54_flash_bank_command,
362  .info = nrf54_info,
363  .write = nrf54_write,
364  .read = default_flash_read,
365  .probe = nrf54_probe,
366  .auto_probe = nrf54_auto_probe,
367  .erase_check = default_flash_blank_check,
368  .free_driver_priv = default_flash_free_driver_priv,
369 };
Support functions to access arbitrary bits in a byte array.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:378
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:256
@ COMMAND_ANY
Definition: command.h:42
uint64_t buffer
Pointer to data buffer to send over SPI.
Definition: dw-spi-helper.h:0
uint32_t size
Size of dw_spi_transaction::buffer.
Definition: dw-spi-helper.h:4
uint32_t buffer_size
Size of dw_spi_program::buffer.
Definition: dw-spi-helper.h:5
uint8_t bank
Definition: esirisc.c:135
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void keep_alive(void)
Definition: log.c:437
#define ERROR_FAIL
Definition: log.h:188
#define LOG_ERROR(expr ...)
Definition: log.h:147
#define LOG_DEBUG(expr ...)
Definition: log.h:124
#define ERROR_OK
Definition: log.h:182
static int nrf54_read_ficr_info(struct target *target, struct nrf54_ficr_info *info)
Definition: nrf54.c:77
#define NRF54_FICR_INFO_VARIANT_REG
Definition: nrf54.c:28
static int nrf54_auto_probe(struct flash_bank *bank)
Definition: nrf54.c:197
#define NRF54_FICR_INFO_RAM_REG
Definition: nrf54.c:30
const struct flash_driver nrf54_flash
Definition: nrf54.c:358
#define NRF54_RRAMC_BASE_ADDR
Definition: nrf54.c:35
static const struct command_registration nrf54_command_handlers[]
Definition: nrf54.c:348
#define NRF54_RRAMC_CONFIG_WEN
Definition: nrf54.c:40
static bool nrf54_get_chip_type_str(const struct nrf54_info *info, char *buf, size_t size)
Definition: nrf54.c:127
static int nrf54_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: nrf54.c:149
struct @15 nrf54_part_names[]
#define NRF54_FICR_INFO_PART_REG
Definition: nrf54.c:27
#define NRF54_FICR_INFO_RRAM_REG
Definition: nrf54.c:31
const char * name
Definition: nrf54.c:44
#define NRF54_FICR_INFO_PACKAGE_REG
Definition: nrf54.c:29
static int nrf54_probe(struct flash_bank *bank)
Definition: nrf54.c:165
#define NRF54_RRAMC_REG_CONFIG
Definition: nrf54.c:37
static int nrf54_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: nrf54.c:239
static int nrf54_wait_until_ready(struct target *target, uint32_t timeout)
Definition: nrf54.c:207
#define NRF54_RRAMC_REG_READY
Definition: nrf54.c:38
uint32_t id
Definition: nrf54.c:43
#define NRF54_RRAM_BASE_ADDR
Definition: nrf54.c:33
FLASH_BANK_COMMAND_HANDLER(nrf54_flash_bank_command)
Definition: nrf54.c:328
static const char * nrf54_get_part_name(uint32_t id)
Definition: nrf54.c:108
#define NRF54_FICR_BASE_ADDR
Definition: nrf54.c:25
static void nrf54_u32_to_str(uint32_t data, char *str)
Definition: nrf54.c:118
#define MIN(a, b)
Definition: replacements.h:22
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:239
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:75
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
Definition: nor/driver.h:39
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Definition: nor/driver.h:44
uint32_t variant
Definition: nrf54.c:58
uint32_t part
Definition: nrf54.c:53
uint32_t package
Definition: nrf54.c:63
uint32_t sram_size
Definition: nrf54.c:65
uint32_t rram_size
Definition: nrf54.c:67
struct nrf54_ficr_info ficr_info
Definition: nrf54.c:74
bool probed
Definition: nrf54.c:71
const char * part_name
Definition: nrf54.c:72
Definition: target.h:119
enum target_state state
Definition: target.h:167
Definition: psoc6.c:83
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2410
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2676
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2602
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:818
@ TARGET_HALTED
Definition: target.h:58
int64_t timeval_ms(void)
static void h_u32_to_be(uint8_t *buf, uint32_t val)
Definition: types.h:186
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
static struct ublast_lowlevel_priv info
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t count[4]
Definition: vdebug.c:22