Skip to content

stm32g0xx_fdcan example project updated with eeprom storage routines#109

Open
TheCitrusMan wants to merge 7 commits into
CANopenNode:masterfrom
TheCitrusMan:storage/eeprom
Open

stm32g0xx_fdcan example project updated with eeprom storage routines#109
TheCitrusMan wants to merge 7 commits into
CANopenNode:masterfrom
TheCitrusMan:storage/eeprom

Conversation

@TheCitrusMan

Copy link
Copy Markdown

Modified Canopen files:

CO_app_STM32.c :

updated include references
CO_storageBlank_init replaced by CO_storageEeprom_init
uint32_t storageInitError moved to global scope

CO_driver_target.h :

#undef CO_CONFIG_STORAGE_ENABLE commented out
CO_storage_entry_t added extra parameters

CO_eeprom_STM32.c and CO_eeprom_STM32.h added to project. These files contain the main eeprom storage routines and are based on the PIC32 example.

CO_storageBlank.c and CO_storageBlank.h removed from project.

eeprom.c and eeprom.h files added to project. These files contain the low level eeprom routines.

i2c.h in core project:

added a couple of defines

Modified Canopen files:

CO_app_STM32.c :
> updated include references
> CO_storageBlank_init replaced by CO_storageEeprom_init
> uint32_t storageInitError moved to global scope

CO_driver_target.h :
> #undef CO_CONFIG_STORAGE_ENABLE commented out
> CO_storage_entry_t added extra parameters

CO_eeprom_STM32.c and CO_eeprom_STM32.h added to project.
These files contain the main eeprom storage routines and are based on the PIC32 example.

CO_storageBlank.c and CO_storageBlank.h removed from project.

eeprom.c and eeprom.h files added to project. These files contain the low level eeprom routines.

i2c.h in core project:
> added a couple of defines
@MaJerle

MaJerle commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

@CANopenNode @HamedJafarzadeh is this OK to merge?

@TheCitrusMan

Copy link
Copy Markdown
Author

A little comment on function CO_eeprom_init() in CO_eeprom_STM32.c :

This funcion initializes the EEPROM storage. The chosen EEPROM types contain a fixed serial number. This number is placed in OD_PERSIST_COMM.x1018_identity.serialNumber.

What it also does is to check the status of a predefined I/O pin of the microcontroller. When this pin is active high (in this case), (part of) the eeprom storage is erased, invalidating the contents of PERSIST_COMM. I have found that such functionality can be very handy when a project is still under development and the number of parameters in PERSIST_COMM changes. It seems that, when parameters are added to or removed from PERSIST_COMM after parameters were successfully written to eeprom, the old eeprom storage is still considered valid by canopennode. I haven't put any time in figuring this out yet, I opted for a simple "config mode" option instead.

In this demo project I have connected this "config mode" to the "joystick down" button. The idea is to press this button during power up of the device.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the stm32g0xx_fdcan example integration to use EEPROM-backed CANopen Object Dictionary storage (via CO_storageEeprom) instead of the previous blank storage stub, adding STM32-specific EEPROM access routines.

Changes:

  • Switch CANopen app initialization from CO_storageBlank_* to CO_storageEeprom_* and enable storage configuration.
  • Add STM32 EEPROM discovery + low-level I2C EEPROM access (eeprom.c/.h) and a CANopen storage EEPROM adapter (CO_eeprom_STM32.c/.h).
  • Add example-level I2C helper defines used by the new EEPROM code.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
examples/stm32g0xx_fdcan/Core/Inc/i2c.h Adds I2C timeout + handle macro used by EEPROM routines
CANopenNode_STM32/eeprom.h Adds EEPROM public API + exported device/layout globals
CANopenNode_STM32/eeprom.c Adds EEPROM device detection (ST/Microchip) and layout setup
CANopenNode_STM32/CO_storageBlank.h Removes blank storage stub (header)
CANopenNode_STM32/CO_storageBlank.c Removes blank storage stub (implementation)
CANopenNode_STM32/CO_eeprom_STM32.h Adds STM32 EEPROM adapter header (currently minimal)
CANopenNode_STM32/CO_eeprom_STM32.c Adds CO_storageEeprom ↔ STM32 EEPROM adapter implementation
CANopenNode_STM32/CO_driver_target.h Enables storage config and extends CO_storage_entry_t with EEPROM fields
CANopenNode_STM32/CO_app_STM32.c Switches to CO_storageEeprom_init and adjusts storage init handling

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +125 to +148
while (len > 0)
{
size_t len_x = len;
if (len_x > page_size)
len_x = page_size;

if (HAL_I2C_Mem_Write(HI2C, device_i2c_address << 1, eepromAddr, 2, (uint8_t *) data + idx, len_x,
I2C_TIMEOUT_MS) != HAL_OK)
{
// write command error
return false;
}

eepromAddr += page_size;
idx += page_size;

if (len > page_size)
len -= page_size;
else
len = 0;

/* wait for completion of the write operation */
while (HAL_I2C_IsDeviceReady(HI2C, device_i2c_address << 1, 3, I2C_TIMEOUT_MS) != HAL_OK);
}
Comment on lines +168 to +173
/* update crc from data part */
HAL_I2C_Mem_Read(HI2C, device_i2c_address << 1, eepromAddr, 2, buf, subLen, I2C_TIMEOUT_MS);
crc = crc16_ccitt(buf, subLen, crc);
eepromAddr += BUF_SIZE;
len -= subLen;
}
Comment on lines +25 to +33
#include "storage/CO_storage.h"
#include "storage/CO_eeprom.h"
#include "301/crc16-ccitt.h"
#include "CO_app_STM32.h"
#include "OD.h"

#include "i2c.h"
#include "eeprom.h"
#include "CO_eeprom_STM32.h"
Comment on lines +47 to +53
bool_t CO_eeprom_init(void *storageModule)
{
// initialize canopen eeprom storage
if (!Eeprom_Init_CO())
{
return false;
}
Comment thread CANopenNode_STM32/eeprom.c Outdated
Comment on lines +54 to +66
bool eeprom_initialized = false;

uint16_t device_size = 0;
size_t page_size = 0;
uint16_t device_i2c_address = EEP_MEM_I2C_ADDR;
uint32_t device_serial_number = 0;

uint16_t data_storage_start = 0;
uint16_t data_storage_size = 0;

size_t device_start_co_auto = 0;
size_t device_start_co_prot = 0;
size_t device_size_co = 0;
Comment thread CANopenNode_STM32/eeprom.h Outdated
Comment on lines +18 to +35
/* USER CODE BEGIN Includes */
#include "main.h"

bool Eeprom_Init();
bool Eeprom_Init_CO();

extern uint16_t device_size;
extern size_t page_size;
extern uint16_t device_i2c_address;
extern uint32_t device_serial_number;

extern uint16_t data_storage_start;
extern uint16_t data_storage_size;

extern size_t device_start_co_auto;
extern size_t device_start_co_prot;
extern size_t device_size_co;

Comment on lines +105 to 108
if (err != CO_ERROR_NO && err != CO_ERROR_DATA_CORRUPT)
{
log_printf("Error: Storage %ld\n", storageInitError);
return 2;
@CANopenNode

CANopenNode commented Jun 26, 2026

Copy link
Copy Markdown
Owner

After a quick look it seems OK to me. I can't test the code.

I ran copilot AI review and it showed some suggestions. @TheCitrusMan, please check, if they make sense.

Then I suggest to merge.

the Github Copilot code review :

CO_eeprom_STM32.c :
> #include <string.h> added
> HAL_I2C_IsDeviceReady() timeout

eeprom.c :
> replaced size_t by uint32_t / uint16_t specifiers
> removed support for m24m01e-u and m24m02e-u eeprom types
>  as they cannot be fully adressed by 16-bit adresses

eeprom.h :
> adjusted type specifiers for external variables
> #include <stdbool.h> added

main.c :
> #include "eeprom.h" added
> Added missing Eeprom_Init()
@TheCitrusMan

Copy link
Copy Markdown
Author

After a quick look it seems OK to me. I can't test the code.

I ran copilot AI review and it showed some suggestions. @TheCitrusMan, please check, if they make sense.

Then I suggest to merge.

Made some changes. Eeprom initialisation in main() was still missing. Removed the support for the largest eeprom types as they cannot be simply addressed with 2-byte addresses and I don't plan adding code for that as 32Kbytes or 64KBytes eeproms are already plenty large.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants