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:
2.- New/ C Project
- Configurar proyecto:
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:
--> Practica #12
DEMOSTRACIÓN:
Hola Carlos:
ResponderBorrarLas practicas son increibles. ¿Sería possible tener la contraseña delos ZIps?
oskiman2@gmail.com
Carlos:
ResponderBorrarMuy buena practica. Te felicito
Tendras algun ejemplo con el LR78/L13 or podrias compartir tu projecto?
Muchas gracias