diff --git a/soes/esc_eep.c b/soes/esc_eep.c index c6c4cb1..9837f95 100644 --- a/soes/esc_eep.c +++ b/soes/esc_eep.c @@ -15,6 +15,8 @@ #include 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; +} diff --git a/soes/esc_eep.h b/soes/esc_eep.h index 3c167c9..97c98da 100644 --- a/soes/esc_eep.h +++ b/soes/esc_eep.h @@ -14,15 +14,23 @@ #include #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);