From 4a190d3954682e4122676ad829d40a41aebc5505 Mon Sep 17 00:00:00 2001 From: Yuri D'Elia Date: Mon, 16 Aug 2021 13:28:37 +0200 Subject: [PATCH] Implement an initial Motion ISR for AVR This is a tentative/crude implementation of an Init and ISR for the MMU in order to check the motion API. We remove the "extern void Isr", declaring it "static inline" instead. We need to inline the ISR here in order to avoid the function call. Include the missing speed_table data in the executable. This bumps the code size to ~60% of the flash. Implemement motion::Init to setup the ISR and timers, and replace the call in main from tmc::Init to motion::Init. Motion will init each driver every time the axis is enabled, so there should be no need for a global module initialization (we need SPI, but this is initialized earlier on by it's own module anyway). The timer is currently setup without any HAL or proper TIMER1 wrapper. This is to be improved later. The real MMU unit seems to slow down quite a bit during acceleration. At this point we need to inline some methods in PulseGen to avoid overhead, however this breaks the stubs. --- src/main.cpp | 3 ++- src/modules/CMakeLists.txt | 1 + src/modules/motion.cpp | 53 +++++++++++++++++++++++++++++++++++++- src/modules/motion.h | 4 +-- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ca3a603..f3c2169 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -19,6 +19,7 @@ #include "modules/selector.h" #include "modules/user_input.h" #include "modules/timebase.h" +#include "modules/motion.h" #include "logic/command_base.h" #include "logic/cut_filament.h" @@ -126,7 +127,7 @@ void setup() { ml::leds.SetMode(2, ml::Color::green, ml::Mode::on); ml::leds.Step(); - // tmc::Init() + mm::Init(); ml::leds.SetMode(1, ml::Color::green, ml::Mode::on); ml::leds.Step(); diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 3c5856c..139f1e0 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -12,6 +12,7 @@ target_sources( movable_base.cpp permanent_storage.cpp selector.cpp + speed_table.cpp timebase.cpp user_input.cpp pulse_gen.cpp diff --git a/src/modules/motion.cpp b/src/modules/motion.cpp index 58ffb5e..2ee45fa 100644 --- a/src/modules/motion.cpp +++ b/src/modules/motion.cpp @@ -1,5 +1,12 @@ #include "motion.h" +// TODO: use proper timer abstraction +#ifdef __AVR__ +#include +#else +//#include "../hal/timers.h" +#endif + namespace modules { namespace motion { @@ -89,7 +96,51 @@ st_timer_t Motion::Step() { return next; } -void Isr() {} +static inline void Isr() { + st_timer_t next = motion.Step(); +#ifdef __AVR__ + // TODO: use proper timer abstraction + if (next) + OCR1A = next; + else { + // Idling: plan the next interrupt after 8ms from now. + OCR1A = 0x4000; + } +#endif +} + +void Init() { +#ifdef __AVR__ + // TODO: use proper timer abstraction + + // waveform generation = 0100 = CTC + TCCR1B &= ~(1 << WGM13); + TCCR1B |= (1 << WGM12); + TCCR1A &= ~(1 << WGM11); + TCCR1A &= ~(1 << WGM10); + + // output mode = 00 (disconnected) + TCCR1A &= ~(3 << COM1A0); + TCCR1A &= ~(3 << COM1B0); + + // Set the timer pre-scaler + // We use divider of 8, resulting in a 2MHz timer frequency on a 16MHz MCU + TCCR1B = (TCCR1B & ~(0x07 << CS10)) | (2 << CS10); + + // Plan the first interrupt after 8ms from now. + OCR1A = 0x4000; + TCNT1 = 0; + + // Enable interrupt + TIMSK1 |= (1 << OCIE1A); +#endif +} } // namespace motion } // namespace modules + +#ifdef __AVR__ +ISR(TIMER1_COMPA_vect) { + modules::motion::Isr(); +} +#endif diff --git a/src/modules/motion.h b/src/modules/motion.h index e79636a..1be51bc 100644 --- a/src/modules/motion.h +++ b/src/modules/motion.h @@ -247,8 +247,8 @@ private: }; }; -/// ISR stepping routine -//extern void Isr(); +/// ISR initialization +extern void Init(); extern Motion motion;