domingo, 25 de diciembre de 2016

PRACTICA # 12 DATA FLASH

OBJETIVO:

Haremos uso de la memoria flash interna del MCU R5F104PJAFB de la tarjeta de evaluación YRDKRL78G14. Escribiremos 8 bytes dentro de la data flash y posteriormente los leeremos para visualizarlos en el debug en forma de array. Se mostrará que los datos son guardados con éxito a partir de la dirección de memoria 0XF1000.
  •  Reservaremos espacio de memoria RAM para la librería pfdl
  •  Se crearán rutinas de inicialización, verificación, borrado, escritura y lectura de la flash
  •  Se agregará la librería pfdl.lib en las propiedades del proyecto.

DESARROLLO:
  •  Del manual Renesas RL78G14 User's Manual Hardware pagina 130 vemos la dirección y tamaño de la memoria de datos flash y RAM:
  • Y en la página 982 vemos la memoria que se reserva en la RAM para las rutinas de la flash data:


Nota: Es necesario preservar la memoria de datos a partir de la dirección 0x000FA3A0

PASOS:
  • Creación de un proyecto:
1.- Abrir el software e2studio
2.- New/ C Project


  •  Configurar proyecto:
1.- Clic derecho en el proyecto generado y seleccionar Properties

2.- Seleccionar C/C++ Build / Settings / Linker / Device y establecer los siguientes parámetros:
OCD = 85
Option Byte = efffe8
Palomear: Use range of debug monitor area. Nota: No establecer ningún valor solo dejarlo en blanco.
Apply y después OK.


3.- Seleccionar C/C++ Build / Settings / Linker / Section y establecer los siguientes parámetros:
0x000FA3A0 .bss
.dataR



4.- Bajar la librería Data Flash Library Type04 Ver.1.05 for the CC-RL Compiler for the RL78 Family y agregar los archivos al Proyecto.
https://www.renesas.com/en-us/software/D3016256.html

5.- Seleccionar C/C++ Build / Settings / Linker / Input y agregar la librería pdfl.lib

6.- Las rutinas para el control completo de la data flash se encuentran en el archivo FlashData.c

void SR_Init_Flash_Data(void)
{
            pfdl_descriptor_t descriptor;

            // this depends on the system settings!
            // fast mode @ 32 MHz in this case
            descriptor.fx_MHz_u08 = 32;
            descriptor.wide_voltage_mode_u08 = 0;
            dataFlashStatus =  PFDL_Open(&descriptor);
}

void SR_Erase_Flash_Data(void)
{
            // NOTA1: Siempre para escribir se necesita borrar. Tambien puedes hacer una verificacion antes y tomar desicion de borrar primero
            // NOTA2: Se borra bloques de memoria de 1K
            // erase block 0
            __DI();                  // Deshabilita interrupciones para las funciones de flash
            dataFlashRequest.index_u16 = BLOCK;
            dataFlashRequest.data_pu08 = 0;
            dataFlashRequest.bytecount_u16 = 0;
            dataFlashRequest.command_enu = PFDL_CMD_ERASE_BLOCK;
            dataFlashStatus = PFDL_Execute(&dataFlashRequest);
            while(PFDL_BUSY == dataFlashStatus)
            {
                         dataFlashStatus = PFDL_Handler();
            };
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

void SR_Check_Erase_Flash_Data(void)
{
            // check block is erased
            __DI();                  // Deshabilita interrupciones para las funciones de flash
    dataFlashRequest.index_u16 = BLOCK;
            dataFlashRequest.data_pu08 = 0;
            dataFlashRequest.bytecount_u16 = SIZEMEM;
            dataFlashRequest.command_enu = PFDL_CMD_BLANKCHECK_BYTES;
            dataFlashStatus = PFDL_Execute(&dataFlashRequest);
            while(PFDL_BUSY == dataFlashStatus)
            {
              dataFlashStatus = PFDL_Handler();
            };
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

void SR_Verify_Cell_Flash_Data(void)
{
            // verify cells
            __DI();                  // Deshabilita interrupciones para las funciones de flash
            dataFlashRequest.index_u16 = Address;
            dataFlashRequest.data_pu08 = 0;
            dataFlashRequest.bytecount_u16 = SIZEMEM;
            dataFlashRequest.command_enu = PFDL_CMD_IVERIFY_BYTES;
            dataFlashStatus =  PFDL_Execute(&dataFlashRequest);
            while(PFDL_BUSY == dataFlashStatus)
            {
              dataFlashStatus = PFDL_Handler();
            }
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

void SR_Write_Flash_Data(void)
{
            // write bytes
            __DI();                  // Deshabilita interrupciones para las funciones de flash
            dataFlashRequest.index_u16 = Address;
            dataFlashRequest.data_pu08 = &flashData[0];
            dataFlashRequest.bytecount_u16 = SIZEMEM;
            dataFlashRequest.command_enu = PFDL_CMD_WRITE_BYTES;
            dataFlashStatus = PFDL_Execute(&dataFlashRequest);
            while(PFDL_BUSY == dataFlashStatus)
            {
                        dataFlashStatus = PFDL_Handler();
            };
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

void SR_Read_Flash_Data(void)
{
            // read back from data flash
            __DI();                  // Deshabilita interrupciones para las funciones de flash
            dataFlashRequest.index_u16 = Address;
            dataFlashRequest.data_pu08 = &flashData[0];
            dataFlashRequest.bytecount_u16 = SIZEMEM;
            dataFlashRequest.command_enu = PFDL_CMD_READ_BYTES;
            // this execute immediately returns OK, as it does not use the sequencer
            dataFlashStatus = PFDL_Execute(&dataFlashRequest);
            // a call to the Handler will return "idle" status
            while(PFDL_BUSY == dataFlashStatus)
            {
              dataFlashStatus = PFDL_Handler();
            };
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

void SR_Close_Flash_Data(void)
{
            __DI();                  // Deshabilita interrupciones para las funciones de flash
            PFDL_Close();
            __EI();                   // Es necesario para que las interrupciones funcionen (interrupt enable)
}

  •  Agregar código, compilar y debug:
1.- Bajar el código de:

2.- Compilar con el icono del martillo, debug con el icono del insecto y correr software:



DEMOSTRACIÓN:

2 comentarios:

  1. Hola Carlos:
    Las practicas son increibles. ¿Sería possible tener la contraseña delos ZIps?
    oskiman2@gmail.com

    ResponderBorrar
  2. Carlos:
    Muy buena practica. Te felicito

    Tendras algun ejemplo con el LR78/L13 or podrias compartir tu projecto?

    Muchas gracias



    ResponderBorrar