aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorSelene ToyKeeper2021-08-23 03:05:32 -0600
committerSelene ToyKeeper2021-08-23 03:05:32 -0600
commit07877b6a549b0e7bad7f6e1db4e0f280410f4be6 (patch)
tree4b03a370e17de439282899277d7507db4c3029d2 /spaghetti-monster
parentmerged digitalcircuit's branch to make autolock timer configurable at build time (diff)
downloadanduril-07877b6a549b0e7bad7f6e1db4e0f280410f4be6.tar.gz
anduril-07877b6a549b0e7bad7f6e1db4e0f280410f4be6.tar.bz2
anduril-07877b6a549b0e7bad7f6e1db4e0f280410f4be6.zip
force reset PWM phase when turning on from zero
(to make initial response consistent) (otherwise, it can randomly take up to ~16ms to turn on)
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/fsm-ramping.c30
1 files changed, 27 insertions, 3 deletions
diff --git a/spaghetti-monster/fsm-ramping.c b/spaghetti-monster/fsm-ramping.c
index 1a08149..017a5b8 100644
--- a/spaghetti-monster/fsm-ramping.c
+++ b/spaghetti-monster/fsm-ramping.c
@@ -58,6 +58,11 @@ void set_level(uint8_t level) {
set_level_override(level);
#else
+ #ifdef PWM1_CNT
+ static uint8_t prev_level = 0;
+ uint8_t api_level = level;
+ #endif
+
//TCCR0A = PHASE;
if (level == 0) {
#if PWM_CHANNELS >= 1
@@ -97,6 +102,7 @@ void set_level(uint8_t level) {
LED2_ENABLE_PORT |= (1 << LED2_ENABLE_PIN);
#endif
+ // PWM array index = level - 1
level --;
#ifdef USE_TINT_RAMPING
@@ -160,8 +166,10 @@ void set_level(uint8_t level) {
// goes all the way to 65535 before returning)
// (see attiny1634 reference manual page 103 for a warning about
// the timing of changing the TOP value (section 12.8.4))
+ // (but don't wait when turning on from zero, because
+ // it'll reset the phase below anyway)
// to be safe, allow at least 64 cycles to update TOP
- while(PWM1_CNT > (top - 64)) {}
+ while(prev_level && (PWM1_CNT > (top - 64))) {}
#endif
// pulse frequency modulation, a.k.a. dynamic PWM
PWM1_TOP = top;
@@ -169,18 +177,34 @@ void set_level(uint8_t level) {
// repeat for other channels if necessary
#ifdef PMW2_TOP
#ifdef PWM2_CNT
- while(PWM2_CNT > (top - 64)) {}
+ while(prev_level && (PWM2_CNT > (top - 64))) {}
#endif
PWM2_TOP = top;
#endif
#ifdef PMW3_TOP
#ifdef PWM3_CNT
- while(PWM3_CNT > (top - 64)) {}
+ while(prev_level && (PWM3_CNT > (top - 64))) {}
#endif
PWM3_TOP = top;
#endif
#endif // ifdef USE_DYN_PWM
+ #ifdef PWM1_CNT
+ // force reset phase when turning on from zero
+ // (because otherwise the initial response is inconsistent)
+ if (! prev_level) {
+ PWM1_CNT = 0;
+ #ifdef PWM2_CNT
+ PWM2_CNT = 0;
+ #endif
+ #ifdef PWM3_CNT
+ PWM3_CNT = 0;
+ #endif
+ }
+ #endif
}
+ #ifdef PWM1_CNT
+ prev_level = api_level;
+ #endif
#endif // ifdef OVERRIDE_SET_LEVEL
#ifdef USE_DYNAMIC_UNDERCLOCKING
auto_clock_speed();