From 7b5ffe5f948e127d78c47a44566726ac288c9559 Mon Sep 17 00:00:00 2001 From: Jochen Kiemes Date: Mon, 20 Nov 2023 23:55:43 +0100 Subject: [PATCH] add parameter realtime to getCurrentSpeedIn...() --- CHANGELOG.md | 4 +- examples/Issue208/Issue208.ino | 77 ++++++----- examples/StepperDemo/generic.h | 2 +- extras/doc/FastAccelStepper_API.md | 21 ++- .../simavr_based/test_issue208/expect.txt | 18 ++- .../test_sd_04_timing_2560/expect.txt | 14 +- .../test_sd_04_timing_328p/expect.txt | 10 +- .../test_sd_04_timing_328p_37k/expect.txt | 6 +- src/FastAccelStepper.cpp | 32 +++-- src/FastAccelStepper.h | 23 +++- src/RampGenerator.h | 4 +- src/StepperISR.cpp | 12 +- src/StepperISR.h | 2 +- src/StepperISR_esp32c3_rmt.cpp | 122 +++++++++--------- src/common.h | 2 +- 15 files changed, 189 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5557ee76..99e6d7d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,8 @@ TODO: - merge the two esp32 rmt drivers as soon as esp32c3 works pre-0.30.7: -- Fix for issue #208: close to speed reversal is the sign of current speed incorrect. - Still the speed increase during acceleration/deceleraion is not monotonic +- Fix for issue #208: the sign of current speed may be incorrect close to direction change +- The functions `getCurrentSpeedInMilliHz()` and `getCurrentSpeedInUs()` have been extended to supply a bool parameter about being realtime. 0.30.6: - Support for ESP32C3 diff --git a/examples/Issue208/Issue208.ino b/examples/Issue208/Issue208.ino index 92dc5ad2..0f515634 100644 --- a/examples/Issue208/Issue208.ino +++ b/examples/Issue208/Issue208.ino @@ -19,6 +19,7 @@ FastAccelStepperEngine engine = FastAccelStepperEngine(); FastAccelStepper *stepper; bool test() { + bool verbose = false; int32_t errCnt = 0; Serial.println("Start test: speed up"); int32_t last_v_mHz = 0; @@ -26,52 +27,53 @@ bool test() { stepper->setSpeedInHz(36800); stepper->runForward(); - while(stepper->rampState() != (RAMP_STATE_COAST | RAMP_DIRECTION_COUNT_UP)) { - int32_t v_mHz = stepper->getCurrentSpeedInMilliHz(); - if (v_mHz == last_v_mHz) { - continue; - } - Serial.println(v_mHz); - if (v_mHz < last_v_mHz) { - Serial.print("FAIL: last="); - Serial.print(last_v_mHz); - Serial.print(" new="); - Serial.println(v_mHz); - errCnt++; - // return false; - } - last_v_mHz = v_mHz; + while (stepper->rampState() != (RAMP_STATE_COAST | RAMP_DIRECTION_COUNT_UP)) { + int32_t v_mHz = stepper->getCurrentSpeedInMilliHz(false); + if (v_mHz == last_v_mHz) { + continue; + } + if (verbose) Serial.println(v_mHz); + if (v_mHz < last_v_mHz) { + Serial.print("FAIL: last="); + Serial.print(last_v_mHz); + Serial.print(" new="); + Serial.println(v_mHz); + errCnt++; + // return false; + } + last_v_mHz = v_mHz; } // There can be still speed increases in the queue, even so the ramp generator // is already coasting delay(20); - last_v_mHz = stepper->getCurrentSpeedInMilliHz(); + last_v_mHz = stepper->getCurrentSpeedInMilliHz(false); Serial.println("Reverse"); stepper->runBackward(); - while(stepper->rampState() != (RAMP_STATE_COAST | RAMP_DIRECTION_COUNT_DOWN)) { - int32_t v_mHz = stepper->getCurrentSpeedInMilliHz(); - if (v_mHz == last_v_mHz) { - continue; - } - Serial.println(v_mHz); - if (v_mHz > last_v_mHz) { - Serial.print("FAIL: last="); - Serial.print(last_v_mHz); - Serial.print(" new="); - Serial.println(v_mHz); - errCnt++; - // return false; - } - last_v_mHz = v_mHz; + while (stepper->rampState() != + (RAMP_STATE_COAST | RAMP_DIRECTION_COUNT_DOWN)) { + int32_t v_mHz = stepper->getCurrentSpeedInMilliHz(false); + if (v_mHz == last_v_mHz) { + continue; + } + if (verbose) Serial.println(v_mHz); + if (v_mHz > last_v_mHz) { + Serial.print("FAIL: last="); + Serial.print(last_v_mHz); + Serial.print(" new="); + Serial.println(v_mHz); + errCnt++; + // return false; + } + last_v_mHz = v_mHz; } if (errCnt > 0) { - Serial.print("Errors="); - Serial.println(errCnt); + Serial.print("Errors="); + Serial.println(errCnt); } - return errCnt != 0; + return errCnt == 0; } void setup() { @@ -112,8 +114,7 @@ void setup() { Serial.println("PASS"); digitalWrite(PIN, HIGH); digitalWrite(PIN, LOW); - } - else { + } else { Serial.println("FAIL"); } delay(1000); @@ -122,6 +123,4 @@ void setup() { #endif } - -void loop() { -} +void loop() {} diff --git a/examples/StepperDemo/generic.h b/examples/StepperDemo/generic.h index 241804f8..47404d16 100644 --- a/examples/StepperDemo/generic.h +++ b/examples/StepperDemo/generic.h @@ -13,7 +13,7 @@ #error "Unsupported derivate" #endif -#if defined(CONFIG_IDF_TARGET_ESP32C3) && (ARDUINO_USB_MODE==1) +#if defined(CONFIG_IDF_TARGET_ESP32C3) && (ARDUINO_USB_MODE == 1) #define SerialInterface USBSerial #else #define SerialInterface Serial diff --git a/extras/doc/FastAccelStepper_API.md b/extras/doc/FastAccelStepper_API.md index 498b0808..fa03dd34 100644 --- a/extras/doc/FastAccelStepper_API.md +++ b/extras/doc/FastAccelStepper_API.md @@ -157,8 +157,8 @@ And the two directions of a move #define RAMP_DIRECTION_COUNT_DOWN 64 ``` A ramp state value of 2 is set after any move call on a stopped motor -and until the stepper task. The stepper task will then control the direction -flags +and until the stepper task is serviced. The stepper task will then +control the direction flags ## Timing values - Architecture dependent @@ -326,9 +326,22 @@ retrieves the actual speed. | > 0 | while position counting up  | | < 0 | while position counting down | +If the parameter realtime is true, then the most actual speed +from the stepper queue is derived. This works only, if the queue +does not contain pauses, which is normally the case for slow speeds. +Otherwise the speed from the ramp generator is reported, which is +done always in case of `realtime == false`. That speed is typically +the value of the speed a couple of milliseconds later. + +The drawback of `realtime == true` is, that the reported speed +may either come from the queue or from the ramp generator. +This means the returned speed may have jumps during +acceleration/deceleration. + +For backward compatibility, the default is true. ```cpp - int32_t getCurrentSpeedInUs(); - int32_t getCurrentSpeedInMilliHz(); + int32_t getCurrentSpeedInUs(bool realtime = true); + int32_t getCurrentSpeedInMilliHz(bool realtime = true); ``` ## Acceleration setAcceleration() expects as parameter the change of speed diff --git a/extras/tests/simavr_based/test_issue208/expect.txt b/extras/tests/simavr_based/test_issue208/expect.txt index 8de30f0f..e08e8010 100644 --- a/extras/tests/simavr_based/test_issue208/expect.txt +++ b/extras/tests/simavr_based/test_issue208/expect.txt @@ -1,20 +1,18 @@ DirA: 0*L->H, 1*H->L DirB: 1*L->H, 0*H->L - EnableA: 3*L->H, 2*H->L + EnableA: 0*L->H, 0*H->L EnableB: 0*L->H, 0*H->L - StepA: 1048*L->H, 1048*H->L, Max High=10us Total High=5476us - StepB: 2*L->H, 2*H->L, Max High=4us Total High=9us -Position[A]=0 + StepA: 235909*L->H, 235909*H->L, Max High=11us Total High=1237097us + StepB: 2*L->H, 2*H->L, Max High=13us Total High=17us +Position[A]=37461 Position[B]=2 -Time in EnableA max=4204 us, total=8408 us +Time in FillISR max=769 us, total=1237221 us -Time in FillISR max=1906 us, total=25682 us +Time in StepA max=11 us, total=1237097 us -Time in StepA max=10 us, total=5476 us +Time in StepB max=13 us, total=17 us -Time in StepB max=4 us, total=9 us - -Time in StepISR max=7 us, total=4875 us +Time in StepISR max=7 us, total=1021996 us diff --git a/extras/tests/simavr_based/test_sd_04_timing_2560/expect.txt b/extras/tests/simavr_based/test_sd_04_timing_2560/expect.txt index b570d48b..1240f3bc 100644 --- a/extras/tests/simavr_based/test_sd_04_timing_2560/expect.txt +++ b/extras/tests/simavr_based/test_sd_04_timing_2560/expect.txt @@ -4,9 +4,9 @@ EnableA: 1*L->H, 1*H->L EnableB: 2*L->H, 1*H->L EnableC: 2*L->H, 1*H->L - StepA: 64000*L->H, 64000*H->L, Max High=28us Total High=521699us - StepB: 64000*L->H, 64000*H->L, Max High=35us Total High=393630us - StepC: 64000*L->H, 64000*H->L, Max High=40us Total High=484932us + StepA: 64000*L->H, 64000*H->L, Max High=28us Total High=580688us + StepB: 64000*L->H, 64000*H->L, Max High=31us Total High=392513us + StepC: 64000*L->H, 64000*H->L, Max High=41us Total High=426208us Position[A]=64000 Position[B]=64000 @@ -19,11 +19,11 @@ Time in EnableB max=246080 us, total=246080 us Time in EnableC max=254235 us, total=254235 us -Time in FillISR max=2686 us, total=2092758 us +Time in FillISR max=2686 us, total=2091889 us -Time in StepA max=28 us, total=521699 us +Time in StepA max=28 us, total=580688 us -Time in StepB max=35 us, total=393630 us +Time in StepB max=31 us, total=392513 us -Time in StepC max=40 us, total=484932 us +Time in StepC max=41 us, total=426208 us diff --git a/extras/tests/simavr_based/test_sd_04_timing_328p/expect.txt b/extras/tests/simavr_based/test_sd_04_timing_328p/expect.txt index f976eb62..323d519e 100644 --- a/extras/tests/simavr_based/test_sd_04_timing_328p/expect.txt +++ b/extras/tests/simavr_based/test_sd_04_timing_328p/expect.txt @@ -2,8 +2,8 @@ DirB: 1*L->H, 0*H->L EnableA: 1*L->H, 1*H->L EnableB: 2*L->H, 1*H->L - StepA: 1000*L->H, 1000*H->L, Max High=13us Total High=5539us - StepB: 1000*L->H, 1000*H->L, Max High=15us Total High=5513us + StepA: 1000*L->H, 1000*H->L, Max High=13us Total High=5545us + StepB: 1000*L->H, 1000*H->L, Max High=16us Total High=5520us Position[A]=1000 Position[B]=1000 @@ -12,11 +12,11 @@ Time in EnableA max=225398 us, total=225398 us Time in EnableB max=238116 us, total=238116 us -Time in FillISR max=2644 us, total=47660 us +Time in FillISR max=2644 us, total=47652 us -Time in StepA max=13 us, total=5539 us +Time in StepA max=13 us, total=5545 us -Time in StepB max=15 us, total=5513 us +Time in StepB max=16 us, total=5520 us Time in StepISR max=7 us, total=9224 us diff --git a/extras/tests/simavr_based/test_sd_04_timing_328p_37k/expect.txt b/extras/tests/simavr_based/test_sd_04_timing_328p_37k/expect.txt index 9e754e06..158958c3 100644 --- a/extras/tests/simavr_based/test_sd_04_timing_328p_37k/expect.txt +++ b/extras/tests/simavr_based/test_sd_04_timing_328p_37k/expect.txt @@ -2,15 +2,15 @@ DirB: 1*L->H, 0*H->L EnableA: 1*L->H, 1*H->L EnableB: 1*L->H, 0*H->L - StepA: 1000*L->H, 1000*H->L, Max High=11us Total High=5276us + StepA: 1000*L->H, 1000*H->L, Max High=12us Total High=5274us StepB: 0*L->H, 0*H->L, Max High=0us Total High=0us Position[A]=1000 Time in EnableA max=225399 us, total=225399 us -Time in FillISR max=2015 us, total=27549 us +Time in FillISR max=2015 us, total=27557 us -Time in StepA max=11 us, total=5276 us +Time in StepA max=12 us, total=5274 us Time in StepISR max=7 us, total=4581 us diff --git a/src/FastAccelStepper.cpp b/src/FastAccelStepper.cpp index f0b9a619..cfe422f9 100644 --- a/src/FastAccelStepper.cpp +++ b/src/FastAccelStepper.cpp @@ -775,32 +775,38 @@ uint32_t FastAccelStepper::getPeriodInUsAfterCommandsCompleted() { } return 0; } -void FastAccelStepper::getCurrentSpeedInTicks(struct actual_ticks_s *speed) { - bool valid = fas_queue[_queue_num].getActualTicksWithDirection(speed); +void FastAccelStepper::getCurrentSpeedInTicks(struct actual_ticks_s* speed, + bool realtime) { + bool valid; + if (realtime) { + valid = fas_queue[_queue_num].getActualTicksWithDirection(speed); + } else { + valid = false; + } if (!valid) { if (_rg.isRampGeneratorActive()) { - _rg.getCurrentSpeedInTicks(speed); - } + _rg.getCurrentSpeedInTicks(speed); + } } } -int32_t FastAccelStepper::getCurrentSpeedInUs() { +int32_t FastAccelStepper::getCurrentSpeedInUs(bool realtime) { struct actual_ticks_s speed; - getCurrentSpeedInTicks(&speed); + getCurrentSpeedInTicks(&speed, realtime); int32_t speed_in_us = speed.ticks / (TICKS_PER_S / 1000000); if (speed.count_up) { - return speed_in_us; + return speed_in_us; } return -speed_in_us; } -int32_t FastAccelStepper::getCurrentSpeedInMilliHz() { +int32_t FastAccelStepper::getCurrentSpeedInMilliHz(bool realtime) { struct actual_ticks_s speed; - getCurrentSpeedInTicks(&speed); + getCurrentSpeedInTicks(&speed, realtime); if (speed.ticks > 0) { int32_t speed_in_mhz = ((uint32_t)250 * TICKS_PER_S) / speed.ticks * 4; - if (speed.count_up) { - return speed_in_mhz; - } - return -speed_in_mhz; + if (speed.count_up) { + return speed_in_mhz; + } + return -speed_in_mhz; } return 0; } diff --git a/src/FastAccelStepper.h b/src/FastAccelStepper.h index 9b0cada2..779bad98 100644 --- a/src/FastAccelStepper.h +++ b/src/FastAccelStepper.h @@ -187,8 +187,8 @@ class FastAccelStepperEngine { #define RAMP_DIRECTION_COUNT_DOWN 64 // A ramp state value of 2 is set after any move call on a stopped motor -// and until the stepper task. The stepper task will then control the direction -// flags +// and until the stepper task is serviced. The stepper task will then +// control the direction flags #include "RampGenerator.h" @@ -365,8 +365,21 @@ class FastAccelStepper { // | > 0 | while position counting up  | // | < 0 | while position counting down | // - int32_t getCurrentSpeedInUs(); - int32_t getCurrentSpeedInMilliHz(); + // If the parameter realtime is true, then the most actual speed + // from the stepper queue is derived. This works only, if the queue + // does not contain pauses, which is normally the case for slow speeds. + // Otherwise the speed from the ramp generator is reported, which is + // done always in case of `realtime == false`. That speed is typically + // the value of the speed a couple of milliseconds later. + // + // The drawback of `realtime == true` is, that the reported speed + // may either come from the queue or from the ramp generator. + // This means the returned speed may have jumps during + // acceleration/deceleration. + // + // For backward compatibility, the default is true. + int32_t getCurrentSpeedInUs(bool realtime = true); + int32_t getCurrentSpeedInMilliHz(bool realtime = true); // ## Acceleration // setAcceleration() expects as parameter the change of speed @@ -646,7 +659,7 @@ class FastAccelStepper { bool needAutoDisable(); bool agreeWithAutoDisable(); bool usesAutoEnablePin(uint8_t pin); - void getCurrentSpeedInTicks(struct actual_ticks_s *speed); + void getCurrentSpeedInTicks(struct actual_ticks_s* speed, bool realtime); FastAccelStepperEngine* _engine; RampGenerator _rg; diff --git a/src/RampGenerator.h b/src/RampGenerator.h index a31b5204..b3a25365 100644 --- a/src/RampGenerator.h +++ b/src/RampGenerator.h @@ -92,9 +92,9 @@ class RampGenerator { void getCurrentSpeedInTicks(struct actual_ticks_s *speed) { fasDisableInterrupts(); speed->ticks = _rw.curr_ticks; - uint8_t rs = _rw.rampState(); + uint8_t rs = _rw.rampState(); fasEnableInterrupts(); - speed->count_up = ((rs & RAMP_DIRECTION_COUNT_UP) != 0); + speed->count_up = ((rs & RAMP_DIRECTION_COUNT_UP) != 0); } uint32_t getCurrentPeriodInTicks() { fasDisableInterrupts(); diff --git a/src/StepperISR.cpp b/src/StepperISR.cpp index 9ee7961b..de814e77 100644 --- a/src/StepperISR.cpp +++ b/src/StepperISR.cpp @@ -281,7 +281,7 @@ bool StepperQueue::hasTicksInQueue(uint32_t min_ticks) { return false; } -bool StepperQueue::getActualTicksWithDirection(struct actual_ticks_s *speed) { +bool StepperQueue::getActualTicksWithDirection(struct actual_ticks_s* speed) { // Retrieve current step rate from the current command. // This is valid only, if the command describes more than one step, // or if the next command contains one step, too. @@ -290,19 +290,19 @@ bool StepperQueue::getActualTicksWithDirection(struct actual_ticks_s *speed) { uint8_t wp = next_write_idx; fasEnableInterrupts(); if (wp == rp) { - speed->ticks = 0; + speed->ticks = 0; return true; } struct queue_entry* e = &entry[rp & QUEUE_LEN_MASK]; if (e->hasSteps) { - speed->count_up = e->countUp; - speed->ticks = e->ticks; + speed->count_up = e->countUp; + speed->ticks = e->ticks; if (e->moreThanOneStep) { - return true; + return true; } if (wp != ++rp) { if (entry[rp & QUEUE_LEN_MASK].hasSteps) { - return true; + return true; } } } diff --git a/src/StepperISR.h b/src/StepperISR.h index 5aeca752..b09e1a71 100644 --- a/src/StepperISR.h +++ b/src/StepperISR.h @@ -139,7 +139,7 @@ class StepperQueue { int32_t getCurrentPosition(); uint32_t ticksInQueue(); bool hasTicksInQueue(uint32_t min_ticks); - bool getActualTicksWithDirection(struct actual_ticks_s *speed); + bool getActualTicksWithDirection(struct actual_ticks_s* speed); volatile uint16_t getMaxSpeedInTicks() { return max_speed_in_ticks; } diff --git a/src/StepperISR_esp32c3_rmt.cpp b/src/StepperISR_esp32c3_rmt.cpp index 655db63e..34e6efe4 100644 --- a/src/StepperISR_esp32c3_rmt.cpp +++ b/src/StepperISR_esp32c3_rmt.cpp @@ -24,7 +24,7 @@ // - if the end marker is hit in continuous mode, there is no end interrupt // - there is no tick lost with the end marker // - minimum periods as per relation 1 and 2 to be adhered to -// +// // #ifdef SUPPORT_ESP32C3_RMT #define PART_SIZE 23 @@ -36,16 +36,16 @@ #endif // In order to avoid threshold/end interrupt on end, add one -#define enable_rmt_interrupts(channel) { \ - RMT.tx_lim[channel].RMT_LIMIT = PART_SIZE + 2;\ - RMT.tx_conf[channel].conf_update = 1; \ - RMT.tx_conf[channel].conf_update = 0; \ - RMT.int_clr.val |= 0x101 << channel; \ - RMT.int_ena.val |= 0x101 << channel; \ -} -#define disable_rmt_interrupts(channel) { \ - RMT.int_ena.val &= ~(0x101 << channel); \ -} +#define enable_rmt_interrupts(channel) \ + { \ + RMT.tx_lim[channel].RMT_LIMIT = PART_SIZE + 2; \ + RMT.tx_conf[channel].conf_update = 1; \ + RMT.tx_conf[channel].conf_update = 0; \ + RMT.int_clr.val |= 0x101 << channel; \ + RMT.int_ena.val |= 0x101 << channel; \ + } +#define disable_rmt_interrupts(channel) \ + { RMT.int_ena.val &= ~(0x101 << channel); } void IRAM_ATTR StepperQueue::stop_rmt(bool both) { // We are stopping the rmt by letting it run into the end at high speed. @@ -87,7 +87,7 @@ static void IRAM_ATTR apply_command(StepperQueue *q, bool fill_part_one, // make a pause with approx. 1ms // 258 ticks * 2 * 31 = 15996 @ 16MHz // 347 ticks * 2 * 23 = 15962 @ 16MHz - *data++ = 0x010001 * (16000/2/PART_SIZE); + *data++ = 0x010001 * (16000 / 2 / PART_SIZE); } } else { q->stop_rmt(false); @@ -127,17 +127,17 @@ static void IRAM_ATTR apply_command(StepperQueue *q, bool fill_part_one, if (steps == 0) { q->bufferContainsSteps[fill_part_one ? 0 : 1] = false; // Perhaps the rmt performs look ahead - ticks -= (PART_SIZE-2) * 4 + 8; + ticks -= (PART_SIZE - 2) * 4 + 8; uint16_t ticks_l = ticks >> 1; uint16_t ticks_r = ticks - ticks_l; last_entry = ticks_l; last_entry <<= 16; last_entry |= ticks_r; - *data++ = last_entry; + *data++ = last_entry; for (uint8_t i = 1; i < PART_SIZE - 1; i++) { *data++ = 0x00020002; } - last_entry = 0x00040004; + last_entry = 0x00040004; } else { q->bufferContainsSteps[fill_part_one ? 0 : 1] = true; if (ticks == 0xffff) { @@ -209,13 +209,13 @@ static void IRAM_ATTR apply_command(StepperQueue *q, bool fill_part_one, } // No tick lost mentioned for esp32c3 // if (!fill_part_one) { - // Note: When enabling the continuous transmission mode by setting - // RMT_REG_TX_CONTI_MODE, the transmitter will transmit the data on the - // channel continuously, that is, from the first byte to the last one, - // then from the first to the last again, and so on. In this mode, there - // will be an idle level lasting one clk_div cycle between N and N+1 - // transmissions. - // last_entry -= 1; + // Note: When enabling the continuous transmission mode by setting + // RMT_REG_TX_CONTI_MODE, the transmitter will transmit the data on the + // channel continuously, that is, from the first byte to the last one, + // then from the first to the last again, and so on. In this mode, there + // will be an idle level lasting one clk_div cycle between N and N+1 + // transmissions. + // last_entry -= 1; // } *data = last_entry; @@ -258,7 +258,7 @@ static void IRAM_ATTR apply_command(StepperQueue *q, bool fill_part_one, PROBE_2_TOGGLE; \ /* demonstrate modification of RAM */ \ uint32_t *mem = FAS_RMT_MEM(ch); \ - mem[PART_SIZE] = 0x33ff33ff; \ + mem[PART_SIZE] = 0x33ff33ff; \ RMT.tx_lim[ch].RMT_LIMIT = PART_SIZE; \ } else { \ /* first half of buffer sent */ \ @@ -269,34 +269,34 @@ static void IRAM_ATTR apply_command(StepperQueue *q, bool fill_part_one, RMT.tx_conf[ch].conf_update = 0; \ } #else -#define PROCESS_CHANNEL(ch) \ - if (mask & RMT_CH##ch##_TX_END_INT_ST) { \ - StepperQueue *q = &fas_queue[QUEUES_MCPWM_PCNT + ch]; \ - disable_rmt_interrupts(q->channel); \ - q->_isRunning = false; \ - PROBE_1_TOGGLE; \ - PROBE_2_TOGGLE; \ - PROBE_3_TOGGLE; \ - } \ - if (mask & RMT_CH##ch##_TX_THR_EVENT_INT_ST) { \ - uint8_t old_limit = RMT.tx_lim[ch].RMT_LIMIT; \ - StepperQueue *q = &fas_queue[QUEUES_MCPWM_PCNT + ch]; \ - uint32_t *mem = FAS_RMT_MEM(ch); \ - if (old_limit == PART_SIZE + 1) { \ - /* second half of buffer sent */ \ - PROBE_2_TOGGLE; \ - apply_command(q, false, mem); \ - /* demonstrate modification of RAM */ \ - /*mem[PART_SIZE] = 0x33fff3ff; */ \ - RMT.tx_lim[ch].RMT_LIMIT = PART_SIZE; \ - } else { \ - /* first half of buffer sent */ \ - PROBE_3_TOGGLE; \ - apply_command(q, true, mem); \ - RMT.tx_lim[ch].RMT_LIMIT = PART_SIZE + 1; \ - } \ - RMT.tx_conf[ch].conf_update = 1; \ - RMT.tx_conf[ch].conf_update = 0; \ +#define PROCESS_CHANNEL(ch) \ + if (mask & RMT_CH##ch##_TX_END_INT_ST) { \ + StepperQueue *q = &fas_queue[QUEUES_MCPWM_PCNT + ch]; \ + disable_rmt_interrupts(q->channel); \ + q->_isRunning = false; \ + PROBE_1_TOGGLE; \ + PROBE_2_TOGGLE; \ + PROBE_3_TOGGLE; \ + } \ + if (mask & RMT_CH##ch##_TX_THR_EVENT_INT_ST) { \ + uint8_t old_limit = RMT.tx_lim[ch].RMT_LIMIT; \ + StepperQueue *q = &fas_queue[QUEUES_MCPWM_PCNT + ch]; \ + uint32_t *mem = FAS_RMT_MEM(ch); \ + if (old_limit == PART_SIZE + 1) { \ + /* second half of buffer sent */ \ + PROBE_2_TOGGLE; \ + apply_command(q, false, mem); \ + /* demonstrate modification of RAM */ \ + /*mem[PART_SIZE] = 0x33fff3ff; */ \ + RMT.tx_lim[ch].RMT_LIMIT = PART_SIZE; \ + } else { \ + /* first half of buffer sent */ \ + PROBE_3_TOGGLE; \ + apply_command(q, true, mem); \ + RMT.tx_lim[ch].RMT_LIMIT = PART_SIZE + 1; \ + } \ + RMT.tx_conf[ch].conf_update = 1; \ + RMT.tx_conf[ch].conf_update = 0; \ } #endif @@ -357,14 +357,14 @@ void StepperQueue::init_rmt(uint8_t channel_num, uint8_t step_pin) { // 3 * T_APB + 5 * T_RMT_CLK < period * T_CLK_DIV // => 8 * T_APB < period * T_APB*5 // => period > 8/5 - // => period >= 2 - // + // => period >= 2 + // // Relation 2 in esp32c3 technical reference before end marker: // 6 * T_APB + 12 * T_RMT_CLK < period * T_CLK_DIV // => 18 * T_APB < period * T_APB*5 // => period > 18/5 - // => period >= 4 - // + // => period >= 4 + // disable_rmt_interrupts(channel); rmt_set_source_clk(channel, RMT_BASECLK_APB); rmt_set_clk_div(channel, 5); @@ -409,7 +409,7 @@ void StepperQueue::init_rmt(uint8_t channel_num, uint8_t step_pin) { RMT.tx_conf[channel].mem_tx_wrap_en = 0; RMT.tx_conf[channel].conf_update = 1; RMT.tx_conf[channel].conf_update = 0; - enable_rmt_interrupts(channel); + enable_rmt_interrupts(channel); // tx_start does not need conf_update PROBE_1_TOGGLE; // end interrupt will toggle again PROBE_1 RMT.tx_conf[channel].tx_start = 1; @@ -544,8 +544,8 @@ void StepperQueue::startQueue_rmt() { // Fill the buffer with a significant pattern for debugging // Keep it for now for (uint8_t i = 0; i < 2 * PART_SIZE; i += 2) { -// mem[i] = 0x0fff8fff; -// mem[i + 1] = 0x7fff8fff; + // mem[i] = 0x0fff8fff; + // mem[i + 1] = 0x7fff8fff; } #endif // Write end marker @@ -630,9 +630,9 @@ void StepperQueue::startQueue_rmt() { RMT.tx_conf[channel].tx_conti_mode = 1; RMT.tx_conf[channel].conf_update = 1; RMT.tx_conf[channel].conf_update = 0; - RMT.tx_conf[channel].mem_tx_wrap_en = 0; - RMT.tx_conf[channel].conf_update = 1; - RMT.tx_conf[channel].conf_update = 0; + RMT.tx_conf[channel].mem_tx_wrap_en = 0; + RMT.tx_conf[channel].conf_update = 1; + RMT.tx_conf[channel].conf_update = 0; PROBE_1_TOGGLE; RMT.tx_conf[channel].tx_start = 1; diff --git a/src/common.h b/src/common.h index f76f7a72..31079051 100644 --- a/src/common.h +++ b/src/common.h @@ -17,7 +17,7 @@ struct stepper_command_s { }; struct actual_ticks_s { - uint32_t ticks; // ticks == 0 means standstill + uint32_t ticks; // ticks == 0 means standstill bool count_up; };