Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Zephyr nRF52 flash driver

I plan to use the flash device driver from Nordic (52840) in a Zephyr system. My plan is to use the <flash.h> api but it seams that this api is not available in a default configuration.

I have experimented with this parameters from the project::

CONFIG_FLASH_NRF=y
CONFIG_FLASH_HAS_DRIVER_ENABLED=y

And it's obviously not working because ->

flash_dev = device_get_binding(FLASH_DEV_NAME);

returns NULL.

  • Yes I know it must be 32-bit aligned so this i not the issue, the driver also check for this so you would get an error. Write can only lower bits so this is super clear and this goes for all NOR and NAND devices. I follow the write operation so I see that its writing to the erase block want and the data is not 0xFF.

    This is a test code and this is the what parameters are provided:

    -000|write_op(
        |    context = 0x20003D38)
        |  w_ctx = 0x20003D38
        |  tmp_word = 0x19AB
        |  ticks_begin = 0x0
        |  i = 0x1
        |
    -001|write(
        |  ?,
        |  ?,
        |  ?)
        |  context = (
        |    data_addr = 0x20003D60,
        |    flash_addr = 0x00040000,
        |    len = 0x18,
        |    enable_time_limit = 0x0)

    And the code exit on -> return FLASH_OP_DONE;

  • this is the exception:

    ______addr/line|code___________|label____|mnemonic________________|comment
        ST:00012D40|BDF0                      pop     {r4-r7,pc}
                499|                nvmc_wait_ready();
        ST:00012D42|F7FFFE37                  bl      0x129B4          ; nvmc_wait_ready
                501|                                UNALIGNED_GET((u32_t *)w_ctx->data_addr);
        ST:00012D46|6823                      ldr     r3,[r4]
        ST:00012D48|681A                      ldr     r2,[r3]
                500|                *(u32_t *)w_ctx->flash_addr =
        ST:00012D4A|6863                      ldr     r3,[r4,#0x4]
        ST:00012D4C|601A______________________str_____r2,[r3]
                   |
                   |static void shift_write_context(u32_t shift, struct write_context *w_ctx)
                   |{
                441|        w_ctx->flash_addr += shift;

    and the register:

    N _  R0          0  R8          0  ^
    Z _  R1   FFFFFFFF  R9          0
    C C  R2   01020304  R10         0
    V _  R3   00040000  R11         0
    Q _  R4   20003D48  R12         3
         R5          0  R13  20003D18
    0 _  R6          1  R14  00012D47
    1 _  R7       0B7B  PC   00012D4C
    2 _                 XPSR 21000000
    3 _  CONTROL     2  MSP  200046E0
    4 _  FAULTMASK   0  PSP  20003D18
         BASEPRI     0
         PRIMASK     0

    Looks ok, writing 0x01020304 to 0x40000. But I get exception. If I write t manually it works so no ASIC or NOR issue.

  • You could try to run zephyr/samples/drivers/soc_flash_nrf to see if that is working and confirm whether it's a problem with the driver or its use in your application. As Vidar suggested though, you should try to ask on the Zephyr mailing list or IRC. The file you are debugging is indeed 100% part of Zephyr and not of the "Nordic device driver implementation" (I guess you meant nrfx).

  • I solved the issue with this hidden flag:

    CONFIG_MPU_ALLOW_FLASH_WRITE=y

Related