Open mipidisaster opened 3 years ago
Further improvement would be to have the overflow interrupt feed into a second timer, which can be used to count the pulses; reducing the load on the CPU to practically nil (although it would take over an extra timer)
New IDEA!! So as to allow the capability to use a single timer for Multiple STEPPERs, the intent now is to use the DMA transfer complete interrupt to check the state of the selected STEPPER motor; so (essentially) giving up on using an extra timer to count in the background, which would utilise an extra counter for a single stepper motor, which is not a good use of resources. The DMA which is used to control the pulse toggle states, will now also be configured to trigger an interrupt at the end of the exchange (so will no longer be circular). This interrupt will be used to count steps (as now even closure to the pulse, then overflow), as well as determine if there is a new position/velocity demand.
From the original problem we are selecting option b), which will now be triggered off the DMA transmit complete interrupt (instead of the overflow, as originally intended), this interrupt is now specific to the specific STEP pulse, and doesn't take full control of the timer. Granting the capability to control multiple Stepper motors in a single timer; as the timer would be configured to count to the maximum position, and each of the "channels", would be individually configured for each specific speed(s). Note, the interrupt would need to determine the number of counts for the NEXT DMA toggle exchange, and there would need to be sufficient time for this calculation to determine this; limiting the maximum RPM of the Stepper motor. It would also need to trigger a DMA update as well, so as to re-update the new timer count for the toggle.
So for example, TIM1 in the STM32F MCU, which has 4 compare channels, will now be able to control upto 4 seperated Stepper motors; noting that the extra GPIOs for direction, reset, microsteps, etc. would need to be controlled via seperate routes; possibly extra GPIOs via SPI, if pin footpin is limited.
Initial version of the DMA interrupt system has been captured within branch 'wip-#5-stepper-improvements' commit b98f644. Analysis underway to determine impact of the new logic has on the processor utilisation (as this is likely to increase due to extra computations needed within the interrupt)
Assessment of the impact of the DMA compared to the TIM method has been captured within the latest commit in the wip branch. Following commit - 15b18a8 README file for assessment
The outcome of this is to update the maximum speed that the STEPPER can support to 200 counts. Additionally, my intent is to create two class types for the STEPPER, one which is the original TIM interupt system, and the other the new DMA interrupt. So as to allow for commonaility, will also introduce a "CORE" Stepper class, which will cover the basis's. Will workt this in the next commit.
Issue has been fixed as of v0.2.1 of repository (e30f82f). Some future improvements could be made, but for now this is acceptable
Issue reopened! As believe that there may be a way to further improve the Stepper class. If can move the calculation of the DMA registers outside of the interrupt, this will improve the speed of the interrupt. The way i am thinking of this is via a buffer of register arrays, which are basically fully populated when a new demand comes through; and all the interrupt needs to then do is link to the next register array in the buffer. Obviously, the main loop will need to update the buffer of registers semi-frequenctly ahead of the DMA, so as to ensure that there is no erroneous steps introduced
At version 0.1.1, the design of the stepper class makes use of two interupts, one which is a "controller" interrupt; the TIMER overflow interrupt, and the other interrupt is used to count the number of pulses, the TIMER Compare interrupt. Both of these interrupts will be triggered for each STEP pulse generated, which essentially doubles the utilisation of the CPU, which can get quite a lot with faster pulses.
The aim of this issue is to reduce the interrupt utilisation, such that either: a) Only the counter interrupt is needed, with the overflow called when a change is needed (i.e. new speed, or position achieved) or b) Only one interrupt is required, which handles everything