Skip to content

Commit 84ac723

Browse files
committed
Fix: semaphore issue lock with ITR and static power when there is several TMC Class enabled
1 parent 5c28151 commit 84ac723

3 files changed

Lines changed: 33 additions & 18 deletions

File tree

Firmware/FFBoard/Src/Axis.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -512,33 +512,45 @@ void Axis::setDrvType(uint8_t drvtype)
512512
{
513513
return;
514514
}
515-
cpp_freertos::CriticalSection::Enter();
516-
MotorDriver* drv = driverChooser.Create((uint16_t)drvtype);
517-
this->drv.reset(drv);
518-
if (drv == nullptr)
515+
516+
// Create the driver outside of the critical section to avoid FreeRTOS issues (semaphore take with interrupts disabled)
517+
MotorDriver* drv_new = driverChooser.Create((uint16_t)drvtype);
518+
519+
if (drv_new == nullptr)
519520
{
520-
cpp_freertos::CriticalSection::Exit();
521521
return;
522522
}
523+
524+
// Pre-initialization outside of critical section
525+
if(!drv_new->hasIntegratedEncoder()){
526+
drv_new->setEncoder(this->enc);
527+
}
528+
drv_new->setupDriver();
529+
530+
// Use critical section only for atomic replacement of the driver pointer
531+
MotorDriver* old_drv_ptr = nullptr;
532+
cpp_freertos::CriticalSection::Enter();
533+
old_drv_ptr = this->drv.release(); // Detach the old driver safely
534+
this->drv.reset(drv_new); // Attach the new driver
523535
this->conf.drvtype = drvtype;
524-
this->maxTorqueRateMS = drv->getDrvSlewRate();
536+
this->maxTorqueRateMS = drv_new->getDrvSlewRate();
537+
cpp_freertos::CriticalSection::Exit();
525538

526-
// Pass encoder to driver again
527-
if(!this->drv->hasIntegratedEncoder()){
528-
this->drv->setEncoder(this->enc);
539+
// Delete the old driver outside of the critical section to avoid blocking destructors or FreeRTOS issues
540+
if (old_drv_ptr != nullptr) {
541+
delete old_drv_ptr;
529542
}
530543

531-
drv->setupDriver();
544+
// Perform SPI communications (start/suspend) outside of the critical section
532545
if (!tud_connected())
533546
{
534547
control->usb_disabled = false;
535548
this->usbSuspend();
536549
}
537550
else
538551
{
539-
drv->startMotor();
552+
drv_new->startMotor();
540553
}
541-
cpp_freertos::CriticalSection::Exit();
542554
}
543555

544556

Firmware/FFBoard/UserExtensions/Inc/TMC4671.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,7 @@ friend class TMCDebugBridge;
702702
bool encHallRestored = false;
703703
bool canChangeHwType = true; // Allows changing the hardware version by commands
704704
//int32_t phiEOffsetRestored = 0; //-0x8000 to 0x7fff
705+
uint8_t powerCheckCounter = 0;
705706
uint8_t calibrationFailCount = 2;
706707

707708
int16_t externalEncoderPhieOffset = 0; // PhiE offset for external encoders

Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,12 @@ void TMC4671::restoreFlash(){
220220
}
221221

222222
#ifdef COGGING_TABLE_FLASH_START_ADDRESS
223-
uint16_t cogging;
224-
Flash_Read(flashAddrs.coggingEnable, &cogging);
225-
cogging_enabled = cogging & 0x01;
223+
uint16_t cogging = 0; // Initialize to avoid random stack data
224+
if(Flash_Read(flashAddrs.coggingEnable, &cogging)) {
225+
cogging_enabled = cogging & 0x01;
226+
} else {
227+
cogging_enabled = false;
228+
}
226229

227230
Flash_ReadCoggingTable(this->drv_address - 1, this->data_cogging);
228231
#endif
@@ -509,14 +512,13 @@ void TMC4671::Run(){
509512
{
510513
allowStateChange = false;
511514
pulseClipLed(); // blink led
512-
static uint8_t powerCheckCounter = 0;
513515
// if powered check ADCs and go to encoder calibration
514516
if(!hasPower() || emergency){
515-
powerCheckCounter = 0;
517+
this->powerCheckCounter = 0;
516518
Delay(250);
517519
break;
518520
}
519-
if(++powerCheckCounter > 5 && !powerInitialized){
521+
if(++this->powerCheckCounter > 5 && !powerInitialized){
520522
initializeWithPower();
521523
}
522524
if(powerInitialized){

0 commit comments

Comments
 (0)