Compare commits

Invalid templates have been ignored

1 invalid template(s) found .github/PULL_REQUEST_TEMPLATE.md: 'about' is required

...

4 Commits

Author SHA1 Message Date
QiayuanLiao 998be09313
Merge b3e17ffe50 into 8f3841e3ce 2024-04-10 09:46:21 +02:00
nakarlsson 8f3841e3ce
Merge pull request #180 from OpenEtherCATsociety/feature/improve_eeprom_reload_handling_al2
Improve emulated EEPROM reload handling
2024-04-09 16:15:44 +02:00
Andreas Karlsson fcd43fb2e6 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.

Include custom reload sample snippets.
2024-04-09 14:03:31 +02:00
qiayuanl b3e17ffe50 Move fbuffer and buffer_size from foe_file_cfg to foe_cfg 2024-03-25 12:22:10 -07:00
4 changed files with 154 additions and 21 deletions

View File

@ -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.
*
@ -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;
@ -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;
}

View File

@ -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
@ -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);

View File

@ -125,7 +125,7 @@ static uint32_t FOE_fread (uint8_t * data, uint32_t maxlength)
while (maxlength && (FOEvar.fend - FOEvar.fposition))
{
maxlength--;
*(data++) = foe_cfg->fbuffer[FOEvar.fposition++];
*(data++) = foe_file->fbuffer[FOEvar.fposition++];
ncopied++;
}
@ -154,12 +154,12 @@ static uint32_t FOE_fwrite (uint8_t *data, uint32_t length)
while (length && (FOEvar.fend - FOEvar.fposition) && !failed)
{
length--;
foe_cfg->fbuffer[FOEvar.fbufposition++] = *(data++);
if(FOEvar.fbufposition >= foe_cfg->buffer_size)
foe_file->fbuffer[FOEvar.fbufposition++] = *(data++);
if(FOEvar.fbufposition >= foe_file->buffer_size)
{
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
failed = foe_file->write_function (foe_file, foe_file->fbuffer, FOEvar.fbufposition);
FOEvar.fbufposition = 0;
foe_file->address_offset += foe_cfg->buffer_size;
foe_file->address_offset += foe_file->buffer_size;
}
FOEvar.fposition++;
if(failed)
@ -190,7 +190,7 @@ static uint32_t FOE_fclose (void)
DPRINT("FOE_fclose\n");
failed = foe_file->write_function (foe_file, foe_cfg->fbuffer, FOEvar.fbufposition);
failed = foe_file->write_function (foe_file, foe_file->fbuffer, FOEvar.fbufposition);
foe_file->address_offset += FOEvar.fbufposition;
FOEvar.fbufposition = 0;

View File

@ -23,6 +23,10 @@ struct foe_file_cfg
const char * name;
/** Size of file,sizeof data we can recv */
uint32_t max_data;
/** Allocate static in caller func to fit buffer_size */
uint8_t * fbuffer;
/** Buffer size before we flush to destination */
uint32_t buffer_size;
/** Where to store the data initially */
uint32_t dest_start_address;
/** Current address during write of file */
@ -41,10 +45,6 @@ struct foe_file_cfg
typedef struct foe_cfg
{
/** Allocate static in caller func to fit buffer_size */
uint8_t * fbuffer;
/** Buffer size before we flush to destination */
uint32_t buffer_size;
/** Number of files used in firmware update */
uint32_t n_files;
/** Pointer to files configured to be used by FoE */