This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

sd_flash_write

PLease, could anyone provide me a code exaple on which i can learn how to use sd_flash_write & sd_flash_erease ? 

I tried to use them but keil give me this : 

.\_build\nrf51822_xxac.axf: Error: L6218E: Undefined symbol flash_word_write (referred from main.o).

Thanks 

Parents Reply Children
  • I have done this. 

    in ble_stack_init i add this: 

    // Register with the SoftDevice handler module for BLE events.
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);

    and then i add this function: 

    static void sys_evt_dispatch(uint32_t sys_evt){
    fs_sys_event_handler(sys_evt);
    ble_advertising_on_sys_evt(sys_evt);
    }



    But still the same.. the memory is erased perfectly but when i try to write it doesnt write anything...

    Should i do anything else? 




  • Unless you have switched to using fstorage, you should not use the fstorage handler. You need to create your own handler and use this to set a flag when the write/erase is completed:

    static uint8_t flash_operation_completed = false;
    
    void app_sys_event_handler(uint32_t sys_evt)
    {
    	switch (sys_evt)
    	{
    		case NRF_EVT_FLASH_OPERATION_SUCCESS:
    			flash_operation_completed = true;
    			break;
    
    		case NRF_EVT_FLASH_OPERATION_ERROR:
    			// Handle error
    			break;
    	}
    }

    Then, inside sys_evt_dispatch, you forward the events to this function:

    static void sys_evt_dispatch(uint32_t sys_evt)
    {
        app_sys_event_handler(sys_evt);
        ble_advertising_on_sys_evt(sys_evt);
    }
    

    And when you do sd_flash operations, you should set the clear the flag before and wait for the flag before proceeding with another operation:

    flash_operation_completed = false;
    sd_flash_page_erase();
    while(!flash_operation_completed)
    {
        sd_app_evt_wait();
    }
    
    flash_operation_completed = false;
    sd_flash_write();
    while(!flash_operation_completed)
    {
        sd_app_evt_wait();
    }
    
    //Read back what was written to flash

  • THANKS A LOT !

    This is working. 

    I am now using this: 



    pg_size = NRF_FICR->CODEPAGESIZE;
    pg_num = NRF_FICR->CODESIZE-2; // Use last page in flash
    addr = (uint32_t *)(pg_size * pg_num);
    uint32_t buffer[3]={1,2,3};

    flash_operation_completed = false;
    sd_flash_page_erase(pg_num);
    while(!flash_operation_completed)
    {
    sd_app_evt_wait();
    }

    flash_operation_completed = false;
    devuelve= sd_flash_write(addr,(uint32_t*)buffer,3);
    while(!flash_operation_completed)
    {
    sd_app_evt_wait();
    }




    sprintf((char *)data_UART, "READ %d", (uint32_t)*(addr));
    ble_nus_string_send(&m_nus, data_UART, 6);


    sprintf((char *)data_UART, "READ+1 %d", (uint32_t)*(addr+1));
    ble_nus_string_send(&m_nus, data_UART, 8);



    sprintf((char *)data_UART, "READ+2 %d", (uint32_t)*(addr+2));
    ble_nus_string_send(&m_nus, data_UART, 8);




    And everything works great. So i have two questions

    1) should i use other way to read from memory ? (other than directly acces from (uint32_t)*(addr) ? 

    2) I understand that my system has: 0xFF Pages of 0x400 words, and each word of 32 bits
        so accessing to the addr =pg_size * pg_num is accessing to the last word of the memory right?, then if i want to access to the following words i should increase or decrease addr? ( now i am increasing it as you see in the code bellow, and everything works, but this goes agains my logic )  

    3) With this functions, can i write word by word in the flash memory? 


    Thanks a lot 

  • 1) No, that should work fine.

    2) See the nRF51822 product specifications chapter 3.2.1 for details on flash sizes. Note that the flash size includes the application code size, so the available flash space for writing data will depend on your application size. You can read these sizes out from the FICR registers CODEPAGESIZE and CODESIZE like you do in your code. Since you are subtracting 2 from the FICR value that you assign to pg_num, you are at the start of page two below the end of the flash, you can then increase the address until your reach the end of these two pages. If you assign the FICR value directly, you would have been outside of flash and should not get correct writes.

    3) Yes, you can also write single bits, as long as you set all other bits in the word you want to write to 1. Once a bit has been written to 0, it can only be set high again by erasing the entire flash page. If you plan to do much flash writing and updating of data, I would highly recommend that you look into the FDS library.

  • heard!

    Last question: how many times can i erase a page and then write a word? until the memory start to fail.

    Thanks!

Related