This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

save scan data in flash memory

Hi!

There are many questions about flash memory already.

But I could not find the question I wanted.

I want to save scan data to flash memory.

However, when you try to save the scan data, a system reset occurs.

Below is my code.


uint32_t * addr;
uint8_t    patwr;
uint8_t    patrd;
uint8_t    patold=0xFF;
uint32_t   i=0;
uint32_t   pg_size;
uint32_t   pg_num;

static void flash_word_write(uint32_t * address, uint32_t value) {

// Turn on flash write enable and wait until the NVMC is ready:
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos);

while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
    // Do nothing.
}

*address = value;

while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
    // Do nothing.
}

// Turn off flash write enable and wait until the NVMC is ready:
NRF_NVMC->CONFIG = (NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos);

while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
{
    // Do nothing.
}

}

static void on_ble_evt(ble_evt_t * p_ble_evt) {

const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt;

switch (p_ble_evt->header.evt_id)
{
    case BLE_GAP_EVT_ADV_REPORT:
    {
        const ble_gap_evt_adv_report_t * p_adv_report = &p_gap_evt->params.adv_report;
        const ble_gap_evt_scan_req_report_t * p_scan_report = &p_gap_evt->params.scan_req_report;
        

        for(int8_t i=0;i<BLE_GAP_ADV_MAX_SIZE;i++)
    {
	app_uart_put(p_adv_report->data[i]);

        }

        sd_ble_gap_scan_stop();
        patwr = p_adv_report->data[0];
        flash_word_write(addr,(uint32_t)patwr);


    }
    break; // BLE_GAP_EVT_ADV_REPORT
   default:
        break;
}   

}

int main(void) {

pg_size = NRF_FICR->CODEPAGESIZE;
pg_num  = NRF_FICR->CODESIZE - 1;  // Use last page in flash  

// Start address:
addr = (uint32_t *)(pg_size * pg_num);
  ble_scan_stack_init();
  sd_ble_gap_scan_start(&m_scan_params);

}


What's the problem? Please help me.

Thank you for your help all the time.

Parents
  • I modified it like below, but it returns NRF_ERROR_INVALID_ADDR error.


    uint32_t * addr;
    uint8_t    patwr;
    uint8_t    patrd;
    uint8_t    patold=0xFF;
    uint32_t   i=0;
    uint32_t   pg_size;
    uint32_t   pg_num;
    

    static void on_ble_evt(ble_evt_t * p_ble_evt) {

    const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt;
    uint32_t err_code;  
    
    pg_size = NRF_FICR->CODEPAGESIZE;
    pg_num  = NRF_FICR->CODESIZE - 1;  // Use last page in flash  
    
    // Start address:
    addr = (uint32_t *)(pg_size * pg_num-BLE_GAP_ADV_MAX_SIZE);     
    
    uint32_t test2=0x00;
    uint32_t* test = &test2;
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_ADV_REPORT:
        {
            const ble_gap_evt_adv_report_t * p_adv_report = &p_gap_evt->params.adv_report;
            
          
            for(int8_t i=0;i<BLE_GAP_ADV_MAX_SIZE;i++)
       {
    	app_uart_put(p_adv_report->data[i]);
            }
    
            sd_ble_gap_scan_stop();
            
            *test = p_adv_report->data[0];
            
            err_code = sd_flash_write(addr,test,1);
            app_uart_put(err_code);
            
            patrd = (uint8_t)*(addr);
            app_uart_put(patrd);
        }
        break; // BLE_GAP_EVT_ADV_REPORT
       default:
            break;
    }
    

    }


    Why? Also, Is my reading method correct? (About patrd)

Reply
  • I modified it like below, but it returns NRF_ERROR_INVALID_ADDR error.


    uint32_t * addr;
    uint8_t    patwr;
    uint8_t    patrd;
    uint8_t    patold=0xFF;
    uint32_t   i=0;
    uint32_t   pg_size;
    uint32_t   pg_num;
    

    static void on_ble_evt(ble_evt_t * p_ble_evt) {

    const ble_gap_evt_t * p_gap_evt = &p_ble_evt->evt.gap_evt;
    uint32_t err_code;  
    
    pg_size = NRF_FICR->CODEPAGESIZE;
    pg_num  = NRF_FICR->CODESIZE - 1;  // Use last page in flash  
    
    // Start address:
    addr = (uint32_t *)(pg_size * pg_num-BLE_GAP_ADV_MAX_SIZE);     
    
    uint32_t test2=0x00;
    uint32_t* test = &test2;
    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GAP_EVT_ADV_REPORT:
        {
            const ble_gap_evt_adv_report_t * p_adv_report = &p_gap_evt->params.adv_report;
            
          
            for(int8_t i=0;i<BLE_GAP_ADV_MAX_SIZE;i++)
       {
    	app_uart_put(p_adv_report->data[i]);
            }
    
            sd_ble_gap_scan_stop();
            
            *test = p_adv_report->data[0];
            
            err_code = sd_flash_write(addr,test,1);
            app_uart_put(err_code);
            
            patrd = (uint8_t)*(addr);
            app_uart_put(patrd);
        }
        break; // BLE_GAP_EVT_ADV_REPORT
       default:
            break;
    }
    

    }


    Why? Also, Is my reading method correct? (About patrd)

Children
  • I believe your computation of addr pointer is incorrect. Never play with FICR address (even if it should be just to write below it), you should compute your address from the memory layout. If you want to write to the last 32-bit word of the flash then first make sure the page is erased (should be at the first run after programming) and then write to the address. Note that you need to always write whole 4 bytes (your example with single byte written should fail).

  • Thank you very much for your advice. I succeeded in writing and reading in flash memory. I will study and utilize this part more. Thank you!

Related