Skip to content

Commit b818c20

Browse files
committed
feat: add anti-cogging calibration with heap memory management
1 parent cef7695 commit b818c20

5 files changed

Lines changed: 88 additions & 3 deletions

File tree

Firmware/FFBoard/Inc/flash_helpers.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,11 @@ bool Flash_ReadWriteDefault(uint16_t adr,uint16_t *buf,uint16_t def); // returns
3232
void Flash_Dump(std::vector<std::tuple<uint16_t,uint16_t>> *result,bool includeAll = false);
3333
bool Flash_Format();
3434

35+
#ifdef COGGING_TABLE_FLASH_START_ADDRESS
36+
bool Flash_WriteCoggingTable(uint8_t table_idx, int16_t* data);
37+
bool Flash_ReadCoggingTable(uint8_t table_idx, int16_t* data);
38+
#endif
39+
3540
bool OTP_Write(uint16_t adroffset,uint64_t dat);
3641
bool OTP_Read(uint16_t adroffset,uint64_t* dat);
3742

Firmware/FFBoard/Src/flash_helpers.cpp

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ bool I2C_EEPROM_Write16(uint16_t devAdr,uint16_t adr, uint16_t dat){
153153
/**
154154
* Helper function to read 16b data from i2c eeproms with different block sizes
155155
*/
156-
bool I2C_EEPROM_Read16(uint16_t devAdr,uint16_t adr, uint16_t *buf, bool checkempty){
156+
bool I2C_EEPROM_Read16(uint16_t devAdr,uint16_t adr,uint16_t *buf, bool checkempty){
157157
uint32_t adrAbs = (adr * sizeof(*buf)/I2C_EEPROM_DATA_SIZE);
158158
assert(adrAbs < I2C_EEPROM_SIZE);
159159
while(!i2cport_int.isDeviceReady(&i2cdeveeprom, devAdr, 100, I2C_EEPROM_TIMEOUT,false)){
@@ -245,7 +245,75 @@ __weak bool Flash_Init(){
245245
}
246246

247247
#endif
248+
#if defined(COGGING_TABLE_FLASH_START_ADDRESS)
248249

250+
// Statically allocated buffer to prevent heap allocation errors on memory constrained devices.
251+
static uint8_t cogging_flash_buffer[32 * 1024];
252+
253+
/**
254+
* @brief Writes a single cogging table to flash using a safe read-modify-write procedure.
255+
* @param table_idx Index of the table to write (0 to MAX_COGGING_TABLES-1).
256+
* @param data Pointer to the table data to be written.
257+
* @return true on success, false on failure.
258+
*/
259+
bool Flash_WriteCoggingTable(uint8_t table_idx, int16_t* data) {
260+
if (table_idx >= MAX_COGGING_TABLES) {
261+
return false;
262+
}
263+
264+
// Use a statically allocated buffer to avoid stack overflow and heap allocation errors.
265+
const uint32_t region_size = sizeof(cogging_flash_buffer);
266+
uint8_t* temp_buffer = cogging_flash_buffer;
267+
268+
// 1. Read the entire existing region from flash into the buffer
269+
memcpy(temp_buffer, (void*)COGGING_TABLE_FLASH_START_ADDRESS, region_size);
270+
271+
// 2. Copy the new table data into the buffer at the correct offset
272+
uint32_t offset = table_idx * COGGING_TABLE_SIZE;
273+
memcpy(temp_buffer + offset, data, COGGING_TABLE_SIZE);
274+
275+
// 3. Erase the flash sector
276+
HAL_FLASH_Unlock();
277+
FLASH_EraseInitTypeDef pEraseInit;
278+
pEraseInit.TypeErase = FLASH_TYPEERASE_SECTORS;
279+
pEraseInit.Sector = FLASH_SECTOR_11; // The reserved 32k region is within this sector
280+
pEraseInit.NbSectors = 1;
281+
pEraseInit.VoltageRange = VOLTAGE_RANGE_3;
282+
uint32_t SectorError = 0;
283+
if (HAL_FLASHEx_Erase(&pEraseInit, &SectorError) != HAL_OK) {
284+
HAL_FLASH_Lock();
285+
return false;
286+
}
287+
288+
// 4. Write the entire modified buffer back to flash, word by word for efficiency
289+
for (uint32_t i = 0; i < region_size / sizeof(uint32_t); ++i) {
290+
uint32_t write_address = COGGING_TABLE_FLASH_START_ADDRESS + i * sizeof(uint32_t);
291+
uint32_t word_to_write = ((uint32_t*)temp_buffer)[i];
292+
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, write_address, word_to_write) != HAL_OK) {
293+
HAL_FLASH_Lock();
294+
return false;
295+
}
296+
}
297+
298+
HAL_FLASH_Lock();
299+
return true;
300+
}
301+
302+
/**
303+
* @brief Reads a single cogging table from its dedicated flash area.
304+
* @param table_idx Index of the table to read (0 to MAX_COGGING_TABLES-1).
305+
* @param data Pointer to a buffer where the table data will be stored.
306+
* @return true on success, false on failure.
307+
*/
308+
bool Flash_ReadCoggingTable(uint8_t table_idx, int16_t* data) {
309+
if (table_idx >= MAX_COGGING_TABLES) {
310+
return false;
311+
}
312+
uint32_t address = COGGING_TABLE_FLASH_START_ADDRESS + (table_idx * COGGING_TABLE_SIZE);
313+
memcpy(data, (void*)address, COGGING_TABLE_SIZE);
314+
return true;
315+
}
316+
#endif
249317
/*
250318
* Dumps all set variables from flash to a vector
251319
* does by default not include certain calibration constants that could break something if imported on a different board

Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@
1313

1414
#include "main.h"
1515
// Change this to the amount of currently registered variables
16-
#define NB_OF_VAR 183
16+
#define NB_OF_VAR 186
1717
extern const uint16_t VirtAddVarTab[NB_OF_VAR];
1818

1919
// Amount of variables in exportable list
20-
#define NB_EXPORTABLE_ADR 168
20+
#define NB_EXPORTABLE_ADR 171
2121
extern const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR];
2222

2323

@@ -125,6 +125,7 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if
125125
#define ADR_TMC1_FLUX_I 0x32A
126126
#define ADR_TMC1_PHIE_OFS 0x32B
127127
#define ADR_TMC1_TRQ_FILT 0x32C
128+
#define ADR_TMC1_COGGING_CAL 0x32D
128129
// AXIS2
129130
#define ADR_AXIS2_CONFIG 0x341 // 0-2 ENC, 3-5 DRV
130131
#define ADR_AXIS2_POWER 0x342
@@ -157,6 +158,7 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if
157158
#define ADR_TMC2_FLUX_I 0x36A
158159
#define ADR_TMC2_PHIE_OFS 0x36B
159160
#define ADR_TMC2_TRQ_FILT 0x36C
161+
#define ADR_TMC2_COGGING_CAL 0x36D
160162
// AXIS3
161163
#define ADR_AXIS3_CONFIG 0x381 // 0-2 ENC, 3-5 DRV
162164
#define ADR_AXIS3_POWER 0x382
@@ -189,6 +191,7 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if
189191
#define ADR_TMC3_FLUX_I 0x3AA
190192
#define ADR_TMC3_PHIE_OFS 0x3AB
191193
#define ADR_TMC3_TRQ_FILT 0x3AC
194+
#define ADR_TMC3_COGGING_CAL 0x3AD
192195
// RMD CAN Motor
193196
#define ADR_RMD1_DATA1 0x3C0 //0-4 CAN ID
194197
#define ADR_RMD1_TORQUE 0x3C1 //Maximum current

Firmware/FFBoard/UserExtensions/Src/eeprom_addresses.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ const uint16_t VirtAddVarTab[NB_OF_VAR] =
107107
ADR_TMC1_FLUX_I,
108108
ADR_TMC1_PHIE_OFS,
109109
ADR_TMC1_TRQ_FILT,
110+
ADR_TMC1_COGGING_CAL,
110111
// AXIS2
111112
ADR_AXIS2_CONFIG, // 0-2 ENC, 3-5 DRV
112113
ADR_AXIS2_POWER,
@@ -139,6 +140,7 @@ const uint16_t VirtAddVarTab[NB_OF_VAR] =
139140
ADR_TMC2_FLUX_I,
140141
ADR_TMC2_PHIE_OFS,
141142
ADR_TMC2_TRQ_FILT,
143+
ADR_TMC2_COGGING_CAL,
142144
// AXIS3
143145
ADR_AXIS3_CONFIG, // 0-2 ENC, 3-5 DRV
144146
ADR_AXIS3_POWER,
@@ -171,6 +173,7 @@ const uint16_t VirtAddVarTab[NB_OF_VAR] =
171173
ADR_TMC3_FLUX_I,
172174
ADR_TMC3_PHIE_OFS,
173175
ADR_TMC3_TRQ_FILT,
176+
ADR_TMC3_COGGING_CAL,
174177
// RMD CAN Motor
175178
ADR_RMD1_DATA1, //0-4 CAN ID
176179
ADR_RMD1_TORQUE, //Maximum current
@@ -326,6 +329,7 @@ const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR] =
326329
ADR_TMC1_FLUX_I,
327330
// ADR_TMC1_PHIE_OFS,
328331
ADR_TMC1_TRQ_FILT,
332+
ADR_TMC1_COGGING_CAL,
329333
// AXIS2
330334
ADR_AXIS2_CONFIG, // 0-2 ENC, 3-5 DRV
331335
ADR_AXIS2_POWER,
@@ -358,6 +362,7 @@ const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR] =
358362
ADR_TMC2_FLUX_I,
359363
// ADR_TMC2_PHIE_OFS,
360364
ADR_TMC2_TRQ_FILT,
365+
ADR_TMC2_COGGING_CAL,
361366
// AXIS3
362367
ADR_AXIS3_CONFIG, // 0-2 ENC, 3-5 DRV
363368
ADR_AXIS3_POWER,
@@ -390,6 +395,7 @@ const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR] =
390395
ADR_TMC3_FLUX_I,
391396
// ADR_TMC3_PHIE_OFS,
392397
ADR_TMC3_TRQ_FILT,
398+
ADR_TMC3_COGGING_CAL,
393399
// RMD CAN Motor
394400
ADR_RMD1_DATA1, //0-4 CAN ID
395401
ADR_RMD1_TORQUE, //Maximum current

Firmware/scripts/memory_map.csv

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ Section comment,Name,Value,Comment on key,VirtAddVarTab,exportableFlashAddresses
8989
,ADR_TMC1_FLUX_I,0x32A,,1,1
9090
,ADR_TMC1_PHIE_OFS,0x32B,,1,
9191
,ADR_TMC1_TRQ_FILT,0x32C,,1,1
92+
,ADR_TMC1_COGGING_CAL,0x32D,,1,1
9293
// AXIS2,,,,,
9394
,ADR_AXIS2_CONFIG,0x341,"// 0-2 ENC, 3-5 DRV",1,1
9495
,ADR_AXIS2_POWER,0x342,,1,1
@@ -121,6 +122,7 @@ Section comment,Name,Value,Comment on key,VirtAddVarTab,exportableFlashAddresses
121122
,ADR_TMC2_FLUX_I,0x36A,,1,1
122123
,ADR_TMC2_PHIE_OFS,0x36B,,1,
123124
,ADR_TMC2_TRQ_FILT,0x36C,,1,1
125+
,ADR_TMC2_COGGING_CAL,0x36D,,1,1
124126
// AXIS3,,,,,
125127
,ADR_AXIS3_CONFIG,0x381,"// 0-2 ENC, 3-5 DRV",1,1
126128
,ADR_AXIS3_POWER,0x382,,1,1
@@ -153,6 +155,7 @@ Section comment,Name,Value,Comment on key,VirtAddVarTab,exportableFlashAddresses
153155
,ADR_TMC3_FLUX_I,0x3AA,,1,1
154156
,ADR_TMC3_PHIE_OFS,0x3AB,,1,
155157
,ADR_TMC3_TRQ_FILT,0x3AC,,1,1
158+
,ADR_TMC3_COGGING_CAL,0x3AD,,1,1
156159
// RMD CAN Motor,,,,,
157160
,ADR_RMD1_DATA1,0x3C0,//0-4 CAN ID,1,1
158161
,ADR_RMD1_TORQUE,0x3C1,//Maximum current,1,1

0 commit comments

Comments
 (0)