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.

Parents
  • I now have the flash_dev working. I now use this configuration flags.

    CONFIG_FLASH=y
    CONFIG_SOC_FLASH_NRF=y
    CONFIG_FLASH_HAS_DRIVER_ENABLED=y

    But the configuration is not fully configured. Still get exception error when the driver executes write_op().

  • I fixed the exception error by removing the UNALIGNED_GET() from write_op. Strange why this issue occur, any comments? I also mange to write to the device but only ones. I use flash_write_protection_set(flash_dev, false) but I cannot write to the device anymore. Read and Erase works and I do not get any errors back from the flash_write api.

  • Hi, 

    Thanks for the update. I've started to look into this, but takes time to get familiar with the code base. Please include flash related code snippets in your answer for reference. 

    "I also mange to write to the device but only ones". 

    As you may know, the flash is all ones by default (i.e., after an erase). So are you certain that the flash was actually written to? Also worth noting is that flash writes must be word aligned. Writing to an unaligned address in flash will lead to a  fault exception. 

     

  • 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.

Reply
  • 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.

Children
No Data
Related