-
-
Notifications
You must be signed in to change notification settings - Fork 19
Description
TL;DR I am not ESP32/Hardware engineer - I am very new to this, but after fiddling with the code, I seem to have found a fix for some ESP32 board not being able run the x40 firmware by declaring and initializing the pwm's globally
Error:
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x400d2a03 PS : 0x00060e30 A0 : 0x800d2a49 A1 : 0x3ffcda50
A2 : 0x3ffc8690 A3 : 0x00000000 A4 : 0x00000000 A5 : 0x00000010
A6 : 0x00000000 A7 : 0x00000000 A8 : 0x0000000f A9 : 0x3ffcdac0
A10 : 0x00000000 A11 : 0x00001800 A12 : 0x00000000 A13 : 0x00001800
A14 : 0x00000000 A15 : 0x00000000 SAR : 0x0000001b EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000000 LBEG : 0x40091410 LEND : 0x40091426 LCOUNT : 0x00000000
Some ESP32 boards crash when running the lastest x40 senseshift firmware. After digging through the x40 and i2cdevlib-contrib code, I found that the pca9685.hpp's setChannelOnOff method appeared to be referencing null/unitialised memory.
return this->_bus.writeReg8(
this->_addr,
PCA9685_REG_LED0_ON_L + (led * 4),
4,
data
);This didn't make sense - and when I googled/queryed claude.ai, i kept finding the suggestion to initialize the pwms globally, which seemed unnecessary and kinda gross. After all, they're only reference in the x40 setup code. After exhausting all other apparent options, I reluctantly grasped at the 'global declaration and initialization' straw, and to my surprise it worked.
Line 37-56 in tactsuit_x40.cpp
+ i2cdev::PCA9685 pwm0(0x40, I2CDev); // Create actual objects, not pointers
+ i2cdev::PCA9685 pwm1(0x41, I2CDev);
void setup()
{
Wire.begin();
// Configure the PCA9685s
- auto pwm0 = i2cdev::PCA9685(0x40, I2CDev);
if (pwm0.setFrequency(PWM_FREQUENCY) != I2CDEV_RESULT_OK) {
LOG_E("pca9685", "Failed to set frequency");
}
if (pwm0.wakeup() != I2CDEV_RESULT_OK) {
LOG_E("pca9685", "Failed to wake up");
}
- auto pwm1 = i2cdev::PCA9685(0x41, I2CDev);
if (pwm1.setFrequency(PWM_FREQUENCY) != I2CDEV_RESULT_OK) {
LOG_E("pca9685", "Failed to set frequency");
}
if (pwm1.wakeup() != I2CDEV_RESULT_OK) {
LOG_E("pca9685", "Failed to wake up");
}
}As previously mentioned, ESP32 is very new to me. I'm a data engineer that dabbles in other fields now and then. I've never seen something like this before (where a local reference works in some deployed environments but not others). Maybe it's because most of the code I write is run on VMs and (from what I've read) ESP32 isn't? Maybe there's a difference between manufactures implementations of the instruction sets/memory allocation/representation?
All I know is that it's working