Improve emulated EEPROM reload handling

Add variable to control if ESC support read size 4
or 8 Byte. Depends on ESC.

Add variable and function to set user function
to perform emulated EEPROM reload.

Add EEPROM error codes that can be used to indicatë
crc error on reload.

Include custom reload samples
feature/improve_eeprom_reload_handling
Andreas Karlsson 2024-04-08 09:50:17 +02:00
parent 66111d50fa
commit 4f0704d499
2 changed files with 160 additions and 12 deletions

View File

@ -15,6 +15,8 @@
#include <string.h>
static uint8_t eep_buf[8];
static uint16_t eep_read_size = 8U;
static uint16_t (*eep_reload_ptr)(void) = NULL;
/** EPP periodic task of ESC side EEPROM emulation.
*
@ -51,12 +53,49 @@ void EEP_process (void)
break;
case EEP_CMD_READ:
case EEP_CMD_RELOAD:
/* handle read request */
if (EEP_read (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, EEP_READ_SIZE) != 0) {
if (EEP_read (stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
stat.contstat.bits.ackErr = 1;
} else {
ESC_write (ESCREG_EEDATA, eep_buf, EEP_READ_SIZE);
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
}
break;
case EEP_CMD_RELOAD:
/* user defined reload if set */
if (eep_reload_ptr != NULL) {
uint16_t reload_ret = (*eep_reload_ptr)();
if (reload_ret != 0) {
stat.contstat.bits.ackErr = 1;
if (reload_ret & EEP_ERROR_CSUM) {
stat.contstat.bits.csumErr = 1;
}
}
}
else {
if (eep_read_size == 8U) {
/* handle reload request */
if (EEP_read(stat.addr * 2U /* sizeof(uint16_t) */, eep_buf, eep_read_size) != 0) {
stat.contstat.bits.ackErr = 1;
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, eep_read_size);
}
}
else {
/* Default handler of reload request for 4 Byte read, load config alias.
* To support other ESC behavior, implement user defined reload.
*/
if (EEP_read(EEP_CONFIG_ALIAS_WORD_OFFSET * 2U /* sizeof(uint16_t) */,
eep_buf,
2U /* 2 Bytes config alias*/) != 0) {
stat.contstat.bits.ackErr = 1;
}
else {
ESC_write(ESCREG_EEDATA, eep_buf, 2U /* 2 Bytes config alias*/);
}
}
}
break;
@ -78,3 +117,23 @@ void EEP_process (void)
}
}
/** EPP Set read size, 4 Byte or 8 Byte depending on ESC.
* Default 8 Byte.
*/
void EEP_set_read_size (uint16_t read_size)
{
if ((read_size == 8U) || (read_size == 4U))
{
eep_read_size = read_size;
}
}
/** EPP Set reload fucntion pointer.
* Function shall return 0 on success, else return
* defined error mask eg. EEP_ERROR_CSUM on CRC error
* on reload.
*/
void EEP_set_reload_function_pointer (uint16_t (*reload_ptr)(void))
{
eep_reload_ptr = reload_ptr;
}

View File

@ -14,15 +14,23 @@
#include <cc.h>
#include "esc.h"
/* EEPROM commands */
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x4
/* EEPROM ERRORs */
#define EEP_ERROR_CSUM (1U << 11)
#define EEP_ERROR_LOADING (1U << 12)
#define EEP_ERROR_ACK (1U << 13)
#define EEP_ERROR_WRITE (1U << 14)
/* read/write size */
#define EEP_READ_SIZE 8
#define EEP_WRITE_SIZE 2
/* EEPROM commands */
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x4
/* write size */
#define EEP_WRITE_SIZE 2
/* EEPROm word offset */
#define EEP_CONFIG_ALIAS_WORD_OFFSET 4
/* CONSTAT register content */
typedef struct CC_PACKED
@ -69,6 +77,87 @@ typedef union eep_config
/* periodic task */
void EEP_process (void);
/**
* Application Notes: EEPROM emulation
*
* NOTE: Special handling needed when 4 Byte read is supported.
*
* Ref. ET1100 Datasheet sec2_registers_3i0, chapter 2.45.1,
* "EEPROM emulation with 32 bit EEPROM data register (0x0502[6]=0)".
*
* For a Reload command, fill the EEPROM Data register with the
* values shown in the chapter 2.45.1 before acknowledging
* the command. These values are automatically transferred to the
* designated registers after the Reload command is acknowledged.
*
* NOTE: When 4 Byte read is supported, EEP_process will only load
* config alias on reload.
*
* NOTE: EEP_process support implementing a custom reload function
* for both 4 Byte and 8 Byte read support.
*
* NOTE: Code snippet for custom reload function when 4 Byte read is supported.
*
* uint16_t reload_ptr(void)
* {
* eep_config_t ee_cfg;
*
* // Read configuration area
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
*
* // Check CRC
* if(is_crc_ok(&ee_cfg) == true)
* {
* // Write config alias to EEPROM data registers.
* // Will be loaded to 0x12:13 on command ack.
* ESC_write(ESCREG_EEDATA,
* &ee_cfg.configured_station_alias,
* sizeof(configured_station_alias));
* // Return 0 to indicate success
* return 0;
* }
* else
* {
* // CRC error mask
* return EEP_ERROR_CSUM;
* }
* }
* NOTE: Code snippet for custom reload function when 8 Byte read is supported.
*
* uint16_t reload_ptr(void)
* {
* eep_config_t ee_cfg;
* eep_stat_t stat;
*
* // Read configuration area
* EEP_read(0, &ee_cfg, sizeof(ee_cfg);
*
* // Check CRC
* if(is_crc_ok(&ee_cfg) == true)
* {
* // read requested EEPROM address
* ESC_read (ESCREG_EECONTSTAT, &stat, sizeof (eep_stat_t));
* stat.addr = etohl(stat.addr);
* // Load EEPROM data at requested EEPROM address
* EEP_read (stat.addr * sizeof(uint16_t), eep_buf, 8U);
* // Write loaded data to EEPROM data registers
* ESC_write(ESCREG_EEDATA, eep_buf, 8U);
*
* // Return 0 to indicate success
* return 0;
* }
* else
* {
* // CRC error mask
* return EEP_ERROR_CSUM;
* }
* }
*/
/* Set eep internal variables */
void EEP_set_read_size (uint16_t read_size);
void EEP_set_reload_function_pointer (uint16_t (*reload_ptr)(void));
/* From hardware file */
void EEP_init (void);
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size);