Flash HAL Module Application Project

 Hello,

I'm implementing the Flash Module in our recent project. To get into this topic I downloaded the FLASH_HP_MG_AP an looked over it.

By reading the User Manuel I learned, that the Data Flash memory as well as the Code Flash memory has one set of address for reading and another one for programming/erasing. So far so good.

Back in the application project I tried to get familiar with the data_flash_operations() function. Unfortunately im getting confused because there is alwas the same Address regardless of wich access is performed. (For read access the same as for programming/earasing access).

What kind of conclusion do i have to draw here?

I would be verry grateful if someone could help me out here.

  • Marvin,

    Yes the same address blocks are used.  For example for the S3A3 the Data Flash block are:

    /* Data Flash Blocks */
    const uint32_t D_Flash_Blk0 = 0x40100000;
    const uint32_t D_Flash_Blk1 = 0x40100400;
    const uint32_t D_Flash_Blk2 = 0x40100800;
    const uint32_t D_Flash_Blk3 = 0x40100C00;
    const uint32_t D_Flash_Blk4 = 0x40101000;
    const uint32_t D_Flash_Blk5 = 0x40101400;
    const uint32_t D_Flash_Blk6 = 0x40101800;
    const uint32_t D_Flash_Blk7 = 0x40101C00;

     

    As an example some code snippets that were used for the Pet Monitor project: https://www.renesas.com/us/en/products/software-tools/boards-and-kits/reference-kits/pet-monitor.html

     

    void user_data_init()
    {
    volatile ssp_err_t status;

    status = g_flash0.p_api->read(g_flash0.p_ctrl,&flashdata.valid, D_Flash_Blk0,(uint32_t)(sizeof(flashdata)));
    APP_ERR_TRAP(status)

    if (flashdata.valid == 69){
    user.height = flashdata.height;
    user.weight = flashdata.weight;
    user.step = flashdata.step;
    user.bark = flashdata.bark;
    user.adc_upper = flashdata.adc_upper;
    current_time.tm_hour = flashdata.hour;
    current_time.tm_min = flashdata.min;
    current_time.tm_sec = flashdata.sec;
    user.NextLogEntry = flashdata.NextLogEntry;
    user.LogWrapped = flashdata.LogWrapped;
    current_time.tm_mon = flashdata.tm_mon;
    current_time.tm_mday = flashdata.tm_mday;
    current_time.tm_year = flashdata.tm_year;
    /* check Current time can be corrupted if Low Battery occurs prior to log write */
    if ( current_time.tm_min == -1){ // we have corruption so reset
    flashdata.hour = 8;
    flashdata.min = 0;
    flashdata.sec = 0;
    flashdata.tm_mon = 10;
    flashdata.tm_mday = 1;
    flashdata.tm_year = 118;
    user.NextLogEntry = flashdata.NextLogEntry;
    user.LogWrapped = flashdata.LogWrapped;
    current_time.tm_hour = flashdata.hour;
    current_time.tm_min = flashdata.min;
    current_time.tm_sec = flashdata.sec;
    current_time.tm_mon = flashdata.tm_mon;
    current_time.tm_mday = flashdata.tm_mday;
    current_time.tm_year = flashdata.tm_year;
    }
    } else { // new setup create the defaults
    user.height = 0x4; // inches
    user.weight = 0x1; // pounds
    user.step = 0;
    user.bark = 0;
    user.LogWrapped = false;
    user.NextLogEntry = D_Flash_Blk1;
    strcpy(user.date, "11/01/2018");
    flashdata.height = user.height;
    flashdata.weight = user.weight;
    flashdata.valid = 69;
    flashdata.step = user.step; // steps
    flashdata.bark = user.bark;
    flashdata.adc_upper = 7200;
    user.adc_upper = flashdata.adc_upper;
    flashdata.hour = 8;
    flashdata.min = 0;
    flashdata.sec = 0;
    flashdata.tm_mon = 10;
    flashdata.tm_mday = 1;
    flashdata.tm_year = 118;
    flashdata.NextLogEntry = user.NextLogEntry;
    flashdata.LogWrapped = user.LogWrapped;
    flashdata.FlashValid = 0xA5;
    // Erase block 0 of the data flash
    FLASH_READY = false;
    status = g_flash0.p_api->erase(g_flash0.p_ctrl, D_Flash_Blk0, 7); // erase all of D_Flash memory
    APP_ERR_TRAP(status)
    while(FLASH_READY == false){
    }
    // store our data in flash
    FLASH_READY = false;
    status = g_flash0.p_api->write(g_flash0.p_ctrl,(uint32_t)&flashdata.valid, D_Flash_Blk0,(uint32_t)(sizeof(flashdata)));
    APP_ERR_TRAP(status)
    while(FLASH_READY == false){
    }

    /* setup initial clock calendar settings */
    /* November 1, 2018 @ 8:00:00 am */
    /* Time based on 24hr clock */
    /* hours, range 0 to 23 */
    current_time.tm_hour = 8;
    /* minutes, range 0 to 59 */
    current_time.tm_min = 0;
    /* seconds, range 0 to 59 */
    current_time.tm_sec = 0;
    /* week days start Sunday = 0 through Saturday = 6 */
    /* day of the week, range 0 to 6 */
    current_time.tm_wday = 2;
    /* day of the month, range 1 to 31 */
    current_time.tm_mday = 1;
    /* months start in January = 0 through December = 11 */
    /* month, range 0 to 11 */
    current_time.tm_mon = 10;
    /* daylight saving time */
    current_time.tm_isdst = 1;
    /* The number of years since 1900 */
    current_time.tm_year = 118;
    /* day in the year, range 0 to 365 */
    current_time.tm_yday = 304;
    }

    STEP_LENGTH_RATIO = (float)(user.height * 0.04233);

    user.status = USER_STATUS_IDLE;
    user.step_length = (float)(user.height * STEP_LENGTH_RATIO);
    user.distance = 0;
    user.calories = 0;
    EventRecordData = user.NextLogEntry;
    }

     

    void flash0_callback(flash_callback_args_t * p_args)
    {
    switch(p_args->event){
    case FLASH_EVENT_NOT_BLANK:
    case FLASH_EVENT_ERR_DF_ACCESS:
    case FLASH_EVENT_ERR_CF_ACCESS:
    case FLASH_EVENT_ERR_CMD_LOCKED:
    case FLASH_EVENT_ERR_FAILURE:
    FLASH_READY = false;
    break;
    case FLASH_EVENT_ERASE_COMPLETE:
    case FLASH_EVENT_WRITE_COMPLETE:
    case FLASH_EVENT_BLANK:
    FLASH_READY = true;
    break;
    }
    }

    void UpdateFlash(UINT value)
    {
    volatile ssp_err_t err;
    bool EraseFlag;

    g_ioport.p_api->pinWrite(IOPORT_PORT_00_PIN_02, ON);

    switch(value){
    case 0: // include erase log then continue to update block 0
    FLASH_READY = false;
    err = g_flash0.p_api->erase(g_flash0.p_ctrl, D_Flash_Blk1, 6);
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    EventRecordData = D_Flash_Blk1;
    case 1:
    flashdata.height = user.height;
    flashdata.weight = user.weight;
    flashdata.step = user.step;
    flashdata.bark = user.bark;
    flashdata.adc_upper = user.adc_upper;
    flashdata.hour = current_time.tm_hour;
    flashdata.min = current_time.tm_min;
    flashdata.sec = current_time.tm_sec;
    flashdata.NextLogEntry = EventRecordData;
    user.NextLogEntry = flashdata.NextLogEntry;
    flashdata.LogWrapped = user.LogWrapped;
    flashdata.tm_mday = current_time.tm_mday;
    flashdata.tm_mon = current_time.tm_mon;
    flashdata.tm_year = current_time.tm_year;

    // Erase block 0 of the data flash
    FLASH_READY = false;
    err = g_flash0.p_api->erase(g_flash0.p_ctrl, D_Flash_Blk0, 1);
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    // store our data in flash
    FLASH_READY = false;
    err = g_flash0.p_api->write(g_flash0.p_ctrl,(uint32_t)&flashdata.valid, D_Flash_Blk0,(uint32_t)(sizeof(flashdata)));
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    break;
    case 2:
    EventRecord.tm_hour = (int8_t)(current_time.tm_hour);
    EventRecord.tm_min = (int8_t)(current_time.tm_min);
    EventRecord.tm_sec = (int8_t)(current_time.tm_sec);
    EventRecord.tm_mon = (int8_t)(current_time.tm_mon);
    EventRecord.tm_mday = (int8_t)(current_time.tm_mday);
    EventRecord.tm_wday = (int8_t)(current_time.tm_wday);
    EventRecord.tm_yday = (int8_t)(current_time.tm_yday);
    EventRecord.tm_year = (int8_t)(current_time.tm_year);
    user.NextLogEntry = EventRecordData;
    if(EventRecordData == D_Flash_Blk1){ // start of memory and may not be erased so erase it.
    FLASH_READY = false;
    err = g_flash0.p_api->erase(g_flash0.p_ctrl, EventRecordData, 1);
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    }
    FLASH_READY = false;
    EraseFlag = false;
    err = g_flash0.p_api->write(g_flash0.p_ctrl,(uint32_t)&EventRecord.step, EventRecordData,(uint32_t)(sizeof(EventRecord)));
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    EventRecordData = EventRecordData + ((uint32_t)(sizeof(EventRecord)));
    switch(EventRecordData){
    case 0x40100800:
    case 0x40100C00:
    case 0x40101000:
    case 0x40101400:
    case 0x40101800:
    case 0x40101C00:
    EraseFlag = true;
    break;
    case 0x40102000:
    EventRecordData = D_Flash_Blk1;
    user.LogWrapped = true;
    flashdata.LogWrapped = user.LogWrapped;
    EraseFlag = true;
    // need to save the state of LogWrapped quickly just in case
    // Erase block 0 of the data flash
    FLASH_READY = false;
    err = g_flash0.p_api->erase(g_flash0.p_ctrl, D_Flash_Blk0, 1);
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    // store our data in flash
    FLASH_READY = false;
    err = g_flash0.p_api->write(g_flash0.p_ctrl,(uint32_t)&flashdata.valid, D_Flash_Blk0,(uint32_t)(sizeof(flashdata)));
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    break;
    }
    if(EraseFlag == true){
    FLASH_READY = false;
    err = g_flash0.p_api->erase(g_flash0.p_ctrl, EventRecordData, 1);
    APP_ERR_TRAP(err)
    while(FLASH_READY == false){
    }
    }
    EventRecord.bark = 0; // reset counters as log will only be written every minute
    EventRecord.step = 0;
    EventFlag = false;
    user.NextLogEntry = EventRecordData;
    break;
    }
    value = 0;
    g_ioport.p_api->pinWrite(IOPORT_PORT_00_PIN_02, OFF);
    }

  • Hello Marvin,

    Has Michael answered your question or do you need any further assistance?

    Kind regards,