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 #179

Closed
wants to merge 1 commit into from
Closed
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
67 changes: 63 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 uint16_t (*eep_reload_ptr)(void) = NULL;

/** EPP periodic task of ESC side EEPROM emulation.
*
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}
103 changes: 96 additions & 7 deletions soes/esc_eep.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,23 @@
#include <cc.h>
#include "esc.h"

/* 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)

/* 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

/* write size */
#define EEP_WRITE_SIZE 2

/* read/write size */
#define EEP_READ_SIZE 8
#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 +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);
Expand Down
Loading