[SOLVED] MCPWM works in app_main but not in a FreeRTOS task
Posted: Tue Dec 19, 2023 9:51 pm
Hello,
I am experiencing an issue with MCPWM when inside a FreeRTOS task. My code is adapted from the esp-idf BLDC MCPWM example:https://github.com/espressif/esp-idf/tr ... dc_control.
When executed in app_main as a standalone function, motor control works as expected. When I use the same function implemented as a task, I get an error in either mcpwm_comparator_set_compare_value or mcpwm_generator_set_force_level.
I've been chasing this for a while; does anyone have a clue as to what may be causing this? Any help would be appreciated.
Example of error:
Here is my code (some sections removed for brevity). There are other tasks as well that are running properly when the vCommutateMotor is run outside of a task.
I am experiencing an issue with MCPWM when inside a FreeRTOS task. My code is adapted from the esp-idf BLDC MCPWM example:https://github.com/espressif/esp-idf/tr ... dc_control.
When executed in app_main as a standalone function, motor control works as expected. When I use the same function implemented as a task, I get an error in either mcpwm_comparator_set_compare_value or mcpwm_generator_set_force_level.
I've been chasing this for a while; does anyone have a clue as to what may be causing this? Any help would be appreciated.
Example of error:
- Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
- Core 0 register dump:
- PC : 0x4200ba9e PS : 0x00060030 A0 : 0x82008635 A1 : 0x3fc9da60
- 0x4200ba9e: mcpwm_comparator_set_compare_value at C:/Espressif/frameworks/esp-idf-v5.0.4-2/components/driver/mcpwm/mcpwm_cmpr.c:128 (discriminator 2)
- A2 : 0xb33fffff A3 : 0x00000000 A4 : 0x3fc99948 A5 : 0x00000000
- A6 : 0x00000000 A7 : 0x3fc93d8c A8 : 0x8037b0b5 A9 : 0x3fc9da30
- A10 : 0x3fc93d8c A11 : 0x3fc942b4 A12 : 0x00060020 A13 : 0x00060023
- A14 : 0x00060223 A15 : 0x0000cdcd SAR : 0x00000000 EXCCAUSE: 0x0000001c
- EXCVADDR: 0xb3400003 LBEG : 0x40056f5c LEND : 0x40056f72 LCOUNT : 0xffffffff
- ClearCommError failed (PermissionError(13, 'The device does not recognize the command.', None, 22))
- Waiting for the device to reconnect
- Backtrace: 0x4200ba9b:0x3fc9da60 0x42008632:0x3fc9da90 0x4037a049:0x3fc9dab0
- 0x4200ba9b: mcpwm_comparator_set_compare_value at C:/Espressif/frameworks/esp-idf-v5.0.4-2/components/driver/mcpwm/mcpwm_cmpr.c:127 (discriminator 5)
- 0x42008632: vChangeSpeedFromQueue at C:/Espressif/esp_applications_working/motor_commutation/main/main.c:115
- 0x4037a049: vPortTaskWrapper at C:/Espressif/frameworks/esp-idf-v5.0.4-2/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:149
- ELF file SHA256: f039a8f7c9e5c080
- Rebooting...
- ESP-ROM:esp32s3-20210327
- Build:Mar 27 2021
- rst:0x3 (RTC_SW_SYS_RST),boot:0xa (SPI_FAST_FLASH_BOOT)
- Saved PC:0x4037576d
- 0x4037576d: esp_restart_noos_dig at C:/Espressif/frameworks/esp-idf-v5.0.4-2/components/esp_system/esp_system.c:64 (discriminator 1)
- SPIWP:0xee
- mode:DIO, clock div:1
- load:0x3fce3810,len:0x168c
- load:0x403c9700,len:0xbf4
- load:0x403cc700,len:0x2da8
- entry 0x403c9904
- static portMUX_TYPE xSpinLock = portMUX_INITIALIZER_UNLOCKED;
- const bldc_hall_phase_action_t xHallStates[] = {
- [6] = vSetState1,
- [4] = vSetState2,
- [5] = vSetState3,
- [1] = vSetState4,
- [3] = vSetState5,
- [2] = vSetState6,
- };
- // Representative function, vSetState2-vSetState6 are not shown.
- void vSetState1(mcpwm_gen_handle_t (*pxGenerators)[2])
- {
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_1][PWM_GEN_INDEX_EN], 0, true);
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_1][PWM_GEN_INDEX_MOTOR], 0, true);
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_3][PWM_GEN_INDEX_EN], 1, true);
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_3][PWM_GEN_INDEX_MOTOR], 0, true);
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_2][PWM_GEN_INDEX_EN], 1, true);
- mcpwm_generator_set_force_level(pxGenerators[PWM_OP_INDEX_2][PWM_GEN_INDEX_MOTOR], -1, true);
- }
- uint32_t ulGetHallSensorValue(bool xMotorDirectionCounterClockwise)
- {
- uint32_t ulHallValue = gpio_get_level(DIN_HALL_1) * 4 + gpio_get_level(DIN_HALL_2) * 2 + gpio_get_level(DIN_HALL_3) * 1;
- return xMotorDirectionCounterClockwise ? ulHallValue ^ (0x07) : ulHallValue;
- }
- void vChangeSpeedFromQueue(void *pvParameters)
- {
- static uint32_t ulCurrentSpeedValue;
- mcpwm_cmpr_handle_t *xComparators = (mcpwm_cmpr_handle_t *)pvParameters;
- while (1) {
- if (xQueueReceive(xSpeedControlQueue, &ulCurrentSpeedValue, 0)) {
- for (int i = 0; i < 3; i++) {
- if (ulCurrentSpeedValue < PWM_PERIOD) {
- ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(xComparators[i], ulCurrentSpeedValue));
- } else {
- ESP_ERROR_CHECK(mcpwm_comparator_set_compare_value(xComparators[i], PWM_PERIOD));
- }
- }
- }
- }
- }
- void vCommutateMotor(void *pvParameters) {
- mcpwm_gen_handle_t (*xGenerators)[3][2] = pvParameters;
- uint32_t ulHallSensorValue = 0;
- while (1) {
- ulHallSensorValue = ulGetHallSensorValue(SPIN_DIRECTION_CCW);
- if (ulHallSensorValue >= 1 && ulHallSensorValue <= 6) {
- taskENTER_CRITICAL(&xSpinLock);
- xHallStates[ulHallSensorValue](xGenerators);
- taskEXIT_CRITICAL(&xSpinLock);
- } else {
- ESP_LOGE(TAG, "invalid bldc phase, wrong hall sensor value:%"PRIu32, ulHallSensorValue);
- }
- ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
- }
- }
- void app_main(void) {
- mcpwm_cmpr_handle_t xComparators[3];
- mcpwm_gen_handle_t xGenerators[3][2] = {};
- xTaskCreate(vChangeSpeedFromQueue, "vChangeSpeedFromQueue", 8192, &xComparators, tskIDLE_PRIORITY, NULL);
- // Throws error, core panics and restarts.
- xTaskCreate(vCommutateMotor, "vCommutateMotor", 8192, xGenerators, tskIDLE_PRIORITY + 1, NULL);
- // Controls BLDC motor as expected.
- vCommutateMotor(xGenerators);
- }