Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve emulated EEPROM reload handling #180

Merged
merged 1 commit into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 61 additions & 4 deletions soes/esc_eep.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
#include <string.h>

static uint8_t eep_buf[8];
static uint16_t eep_read_size = 8U;
static void (*eep_reload_ptr)(eep_stat_t *stat) = NULL;

/** EPP periodic task of ESC side EEPROM emulation.
*
Expand Down Expand Up @@ -51,12 +53,46 @@ 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) {
/* Reload function is responsible to update
* control status register bits.
*/
(*eep_reload_ptr)(&stat);
}
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;

Expand All @@ -78,3 +114,24 @@ 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 function pointer.
* Function shall update current stat accordingly.
* Eg. on CRC error reload function shall set
* stat.contstat.bits.csumErr = 1
* stat.contstat.bits.ackErr = 1
*
*/
void EEP_set_reload_function_pointer(void (*reload_ptr)(eep_stat_t* stat))
{
eep_reload_ptr = reload_ptr;
}
90 changes: 83 additions & 7 deletions soes/esc_eep.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,16 @@
#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
#define EEP_CMD_IDLE 0x0
#define EEP_CMD_READ 0x1
#define EEP_CMD_WRITE 0x2
#define EEP_CMD_RELOAD 0x4

/* read/write size */
#define EEP_READ_SIZE 8
#define EEP_WRITE_SIZE 2
/* write size */
#define EEP_WRITE_SIZE 2

/* EEPROm word offset */
#define EEP_CONFIG_ALIAS_WORD_OFFSET 4

/* CONSTAT register content */
typedef struct CC_PACKED
Expand Down Expand Up @@ -69,6 +71,80 @@ 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.
*
* void reload_ptr(eep_stat_t *stat)
* {
* 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));
* }
* else
* {
* // Indicate CRC error
* stat->contstat.bits.csumErr = 1;
* stat->contstat.bits.ackErr = 1;
* }
* }
* NOTE: Code snippet for custom reload function when 8 Byte read is supported.
*
* void reload_ptr(eep_stat_t *stat)
* {
* 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)
* {
* // 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);
* }
* else
* {
* // Indicate CRC error
* stat->contstat.bits.csumErr = 1;
* stat->contstat.bits.ackErr = 1;
* }
* }
*/

/* Set eep internal variables */
void EEP_set_read_size (uint16_t read_size);
void EEP_set_reload_function_pointer (void (*reload_ptr)(eep_stat_t *stat));

/* From hardware file */
void EEP_init (void);
int8_t EEP_read (uint32_t addr, uint8_t *data, uint16_t size);
Expand Down
Loading