Forum Rule: Always post complete source code & details to reproduce any issue!
Page 1 of 2 1 2 LastLast
Results 1 to 25 of 29

Thread: Marlin on Teensy 4.0 / 4.1

  1. #1
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9

    Marlin on Teensy 4.0 / 4.1

    Hi all,

    I've been running a custom version of the Marlin firmware ( https://github.com/MarlinFirmware/Marlin ) on Teensy 3.5 for a while now and it runs great.
    I would like to see I could run in it on Teensy 4.0 but there's one piece I can't seem to figure out how to change for Teensy 4.0.
    One thing I find particularly difficult is moving the timer code ( https://github.com/MarlinFirmware/Ma..._36/timers.cpp ) from Teensy 3.5 to 4.0.

    Does anyone have any idea how to get started on this or should I just read the documentation of IMXRT1062 ?

    Thanks for any pointers!

  2. #2
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,196
    didn't look .... but Sounds like the timers are being used low level and not through PJRC interfaces?

    This github.com/luni64/TeensyTimerTool is a set of code that may show needed example or details or offer needed usage for various timers ...

    The CORES for Teensy4 will have PJRC's solution for timer access as well.

    Both of those might be easier to read than the manual?

  3. #3
    Senior Member
    Join Date
    Mar 2016
    Posts
    198
    Take a look at the iMXRT 1062 version of grblHAL (32-bit port of GRBL). Look in the drivers/IMXRT1062/main - all the iMXRT 1062 changes are in driver.c and driver.h.

    I suggest you use the Teensy 4.1 - same processor and no backside pins to fuss with. Plus, it has ethernet phy and Host mode USB.

    There is also a grblHAL BoB for Teensy 4.1 available on tindie

  4. #4
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    Thank you both defragster and PhilB! Those look like very interesting things to look at!
    I have no experience using hardware timers, so this is all still quite dense to go through..
    Code:
    TMR4_CSCTRL0 &= ~(TMR_CSCTRL_TCF1|TMR_CSCTRL_TCF2);
    ... yummy

    I'm sorry if I'm asking too much, but this for example is already difficult to understand:
    Code:
    TMR4_COMP10 = F_BUS_MHZ * settings->steppers.pulse_delay_microseconds;
    TMR4_COMP20 = F_BUS_MHZ * settings->steppers.pulse_microseconds;
    TMR4_CSCTRL0 |= TMR_CSCTRL_TCF2EN;
    TMR4_CTRL0 |= TMR_CTRL_OUTMODE(0b100);
    What exactly do TMR4_COMP10 and TMR4_COMP20 do?

    Any recommendations on how to get started with using / understanding the hardware timers?

  5. #5
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,432
    First thing I would suggest, is if you have not already done so, you should download the reference manuals for the processors you are interested in. In this case T3.5 and T4.

    You can get these from PJRC website: https://www.pjrc.com/teensy/datasheets.html

    So in this case T4.. In this case also good place to look is in the sources: imxrt.h will give you the definitions of TMR4_... values

    In this case you are talking about the Quad timers. So that is chapter 53 of the IMXRT1060RM pdf file.

    TMR4_COMP10 - is the Quad Timer 4 Sub Timer 0 Compare register 1 (53.6.1) the 16 bit value:
    Code:
    This read/write register stores the value used for comparison with the counter value in count up mode.
    Similar for TMR4_COMP20

    TMR4_CSCTRL0 |= TMR_CSCTRL_TCF2EN;
    Timer Compare 2 interrupt enable - generate an interrupt when TCF2 are set


    TMR4_CTRL0 |= TMR_CTRL_OUTMODE(0b100);
    Sets the Output mode - 100 Toggle OFLAG output using alternating compare registers

    To actually understand this you probably need to read parts of that chapter in the reference manual

  6. #6
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    I was kind of hoping there would a more general introduction to hardware timers somewhere...
    But all good, I will try going through the timer code for Teensy3.5 in Marlin (and the other code you both have suggested) and look at the manual to explain the names of the registers. Should be interesting!

    A little of topic: I'm getting help from a dog and a soaring eagle, should I also change my profile pic to an animal to better fit in on this forum?

  7. #7
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    oh wow 3437 pages... I'll see you guys in a few weeks!

  8. #8
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,196
    Not knowing - or even having looked - how the timers are used - is it possible they could be replaced with the higher level code in TeensyTimerTool or the intervalTimer where those low level details are already handled?

    As for images: eagles are here - that one overhead on July 4th seemed good for here - with his feet under the translucent sunlit white tail.

  9. #9
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,432
    Yes it is sort of a chicken and egg issue.

    That is in your previous post you asked:
    What exactly do TMR4_COMP10 and TMR4_COMP20 do?
    So I pointed you to location in the manual the explains these registers.

    And yes I do spend a bit of time looking through these reference manuals. Especially any time I see or want to do something at the register level.

    Sorry probably might answer differently if the question was, I need a timer to do X... than maybe can give a bett question.

    As Defragster mentioned, it might help if we knew the usage.

    That is do you need it for doing something like PWM output? If so maybe you can directly use PWM.

    If you need timer interrupts of some specific timing, maybe IntervalTimer might work or maybe @Luni's timer tool:
    There is some write up about different timers up in his WIKI for that tool: https://github.com/luni64/TeensyTimerTool/wiki

    Else I often look at datasheet and searching through the Teensy install. To see other places that maybe use TMR4, or maybe IMXRT_TMR4.
    And find it is used in the core file pwm.c, also used in the ADC Library, also in FreqCount, PulsePosition and maybe a few other libraries.

    But again not sure if that would help.

  10. #10
    Senior Member
    Join Date
    Mar 2016
    Posts
    198
    I agree, understanding the usage is important. Looking at the Marlin timer code for the MK64FX512 and MK66FX1M0, it looks like they are defining 2 16 bit timers. So I would figure out how to set up 2 16 bit timers on the 1062. However, I'm pretty sure that Marlin uses PWM in places so I would look to figure out if the timers were involved in that as it might change which timers I would use and how I'd use them.

  11. #11
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    The timers I am mostly interested in are the ones used to generate the step pulses for the stepper motors.

    I just did some simple tests and with the insane speeds of the Teensy4.0 I'm thinking maybe hardware timers are complete overkill?
    Or are there other benefits to hardware timers that I don't see?

  12. #12
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    To see if I could go without the complicated hardware timers, I ran a test ramping up a stepper to 100us period step speeds and this worked absolutely fine without using hardware interrupts.

    One strange I thing I noticed: if I break the serial USB connection my timing seems to go wrong completely..

    Here's a minimal example of the serial issue, tested on Teensy4.0 :
    Code:
    uint32_t lastTime = micros(); // keep track of time for LED blinking
    uint32_t period = 100;
    
    int timingError = 0;
    
    uint32_t serialLastTime = millis(); // keep track of time for serial feedback
    uint32_t serialPeriod = 200;
    
    //---------------------------------------------------------------------------------------------------------------------
    void setup() {
    
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, HIGH);
    
      while (!Serial) {
        // wait for serial to come up
      }
    
      Serial.begin(57600);
      Serial.println(
          "I am testing if serial connect / disconnect messes up my timing");
    
      serialLastTime = millis();
      lastTime = micros();
    }
    
    //---------------------------------------------------------------------------------------------------------------------
    void loop() {
      uint32_t nowUs = micros();
      if (nowUs >= lastTime + period) {
        timingError += abs((int)(nowUs - lastTime) - (int)period);
        lastTime += period;
    
        // briefly flash the LED
        digitalWrite(LED_BUILTIN, HIGH);
        delayMicroseconds((int)period / 2);
        digitalWrite(LED_BUILTIN, LOW);
      }
    
      uint32_t now = millis();
      if (now >= serialLastTime + serialPeriod && Serial) {
        //   if (now >= serialLastTime + serialPeriod ) { 
        //  creates visible pulses with LED staying OFF
    
        serialLastTime = now;
        Serial.println(timingError);
        timingError = 0; // reset timing error
      }
    }
    This will print out zeroes every 100ms, except when I disconnect and reconnect the Serial port..

    The version where I keep sending serial messages even when there's no serial port is significantly worse:
    Code:
    if (now >= serialLastTime + serialPeriod ) {
    instead of
    Code:
    if (now >= serialLastTime + serialPeriod && Serial) {
    What could be going on?

  13. #13
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,196
    Quote Originally Posted by TimK View Post
    The timers I am mostly interested in are the ones used to generate the step pulses for the stepper motors.

    I just did some simple tests and with the insane speeds of the Teensy4.0 I'm thinking maybe hardware timers are complete overkill?
    Or are there other benefits to hardware timers that I don't see?
    In that case another contribution by @luni may offer a solution: github.com/luni64/TeensyStep

  14. #14
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    12,196
    Before writing monitor availableForWrite() - was a recent post on this by Paul -

  15. #15
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    Thank you defragster! I'm going to test that right away.

  16. #16
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    YES!
    I might have not discovered anything new here, but at least i proved it to myself :-)

    Timing errors while connecting and disconnecting the serial port without Serial.availableForWrite():
    Click image for larger version. 

Name:	Screenshot 2020-08-02 at 12.54.29.png 
Views:	7 
Size:	14.3 KB 
ID:	21240

    and with
    Code:
    if (now >= serialLastTime + serialPeriod && Serial.availableForWrite() > 8) {
    Click image for larger version. 

Name:	Screenshot 2020-08-02 at 12.55.43.png 
Views:	11 
Size:	17.7 KB 
ID:	21241

    The difference is huge, but as you can see there are still tiny errors. I wonder where they come from?

  17. #17
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    22,488
    Any chance you could explain how to run this test?

    What are those plots? Are they from a logic analyzer or USB oscilloscope? Is that the voltage on pin 13? Or are you collecting data somehow and plotting it with specific software?

    And could you give the latest code, so I can just copy the whole thing into Arduino and run it here on a Teensy 4.0 without the error-prone process of splicing in the changes.

  18. #18
    Junior Member TimK's Avatar
    Join Date
    Jul 2020
    Location
    Antwerp - Paris
    Posts
    9
    Hi Paul I love your work!

    The plot is just some test software I use to debug. It plots out values sent over serial similar to the Arduino IDE's "Serial Plotter" but without the annoying rescaling. I have some more interesting display options, auto-connecting and other things I need for debugging and analysing code.
    I didn't hook this up to my scope yet.

    So what you see is literally zeros sent over the serial USB, peaks are higher numbers.

    This is the code with the addition of Serial.availableForWrite:
    The original line is still there, I just commented it out.

    Code:
    uint32_t lastTime = micros(); // keep track of time for LED blinking
    uint32_t period = 100;
    
    int timingError = 0;
    
    uint32_t serialLastTime = millis(); // keep track of time for serial feedback
    uint32_t serialPeriod = 200;
    
    //---------------------------------------------------------------------------------------------------------------------
    void setup() {
    
      pinMode(LED_BUILTIN, OUTPUT);
      digitalWrite(LED_BUILTIN, HIGH);
    
      while (!Serial) {
        // wait for serial to come up
      }
    
      Serial.begin(57600);
      Serial.println(
          "I am testing if serial connect / disconnect messes up my timing");
    
      serialLastTime = millis();
      lastTime = micros();
    }
    
    //---------------------------------------------------------------------------------------------------------------------
    void loop() {
      uint32_t nowUs = micros();
      if (nowUs >= lastTime + period) {
        timingError += abs((int)(nowUs - lastTime) - (int)period);
        lastTime += period;
    
        // briefly flash the LED
        digitalWrite(LED_BUILTIN, HIGH);
        delayMicroseconds((int)period / 2);
        digitalWrite(LED_BUILTIN, LOW);
      }
    
      uint32_t now = millis();
      // if (now >= serialLastTime + serialPeriod) { // <<< original line
      if (now >= serialLastTime + serialPeriod &&
          Serial.availableForWrite() > 8) { 
    
        serialLastTime = now;
        Serial.println(timingError);
        timingError = 0; // reset timing error
      }
    }

  19. #19
    Senior Member
    Join Date
    Mar 2016
    Posts
    198
    Just to be 100% sure I'm still following you, you're goal is to make changes to Marlin's timer HAL code to get it to run on the iMXRT1062. Software timing relies on all the other code behaving. Even in your little test program, there is other software involved. With a hardware timer you get an interrupt asserted exactly when you asked for it. As long as the rest of the code behaves with respect to interrupt disabling/enabling (which I am sure the rest of Marlin 2.0 does), a HW timer will get more consistent results. Inconsistent step pulses will give you positioning or extrusion errors, depending on which stepper motor it's for. They may be small but I have no way of knowing that.

    That said, I don't see how you would use SW timing in the HAL code. It expects an interrupt to be generated at a specific time.

    If it is, as you said, only for step pulse generation then it shouldn't be that hard and you have example code in a number of places to draw from.

  20. #20
    Senior Member
    Join Date
    Jul 2020
    Posts
    110
    If the board gives you a hardware timer, use it. In the future, you are probably going to add some code that does something or other, it's going to nudge the timing a little, and your software interrupt is going to be late sending a pulse. That's no bueno. Even if it only happens occasionally, consider what even a few dozen missed steps can do to a 15-hour print. Layers getting squished or shifted, etc.

    You probably have good reasons to port Marlin. If it was me, I would look at Repetier or Smoothie. Both ran better for me. Smoothie's codebase can tell you some things about generating steps on ARM, since it was designed from the ground up for 32-bit ARM controllers. The codebase is (in my opinion) laid out better as well. It also gives you a (not very fancy) working web UI for uploading G-code, moving the effector around, etc.

  21. #21
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    7,432
    Sorry for in advance off topic question:

    As I mentioned about a year ago in another thread (https://forum.pjrc.com/threads/56563...ight=printrbot) I have a printrbot Metal 3d printer with a Printrboard Rev F5, which the USB connector broke off. Printrbot has folded and UBIS was selling a new board for it a year ago, but I no longer see it listed on their website.

    Any recommendations for a replacement board? Would be great if Teensy based. Preferable one that is mostly if not fully populated.

    Thanks,

    Kurt

  22. #22
    Senior Member
    Join Date
    Jul 2020
    Posts
    110
    Quote Originally Posted by KurtE View Post
    Any recommendations for a replacement board? Would be great if Teensy based. Preferable one that is mostly if not fully populated.
    Smoothie or Duet if you just want to get down to business and print some things.

    If you want a ~Project~ to keep your hands busy, it's right here in this thread.

  23. #23
    Senior Member
    Join Date
    Mar 2016
    Posts
    198
    It looks like there is a Marlin port for the T3.5 and T3.6. The timer code TimK linked to has ifdefs for both. The iMXRT1062 is overkill and I bet the T3.5 and T3.6 are too. I've thought about making a 3DP breakout board for Marlin/T4.x though there are plenty of solutions already out there. Still, watching this thread hoping someone might move the ball towards the goal.

  24. #24
    Junior Member CrazzyFrenchDude's Avatar
    Join Date
    Aug 2020
    Location
    France
    Posts
    3
    Hello guys nice being here, I am from France and we, some of the Open PnP community and I, are actually having a work in progress, the PeeNaPle_V1.1,
    a breadboard for Teensy4.1 Open PnP oriented! So I am gathering informations here and there to make it happen. the board is almost done, stuck with
    the pin designation, there seem to be various possibilities depending on how you use the MXP! Here is a little snick Pict, we would love to have either Marlin
    or GrblHAL running on this board at full potential If you have any suggestion feel free to let me know, and one point to precise I am a very New B in coding
    more of a pcb designer, so please bear patience if you can! with that said , going back to kicad, to send board to PCBA! Cheers!
    Click image for larger version. 

Name:	Screenshot 2020-08-11 at 23.12.35.jpg 
Views:	24 
Size:	194.8 KB 
ID:	21347

  25. #25
    Senior Member
    Join Date
    Jul 2020
    Posts
    110
    Looks like you have support for 8 axes, which is... absolutely wonderful.

    What PCB house do you like to produce your boards? I have used Seeed in the past for a few things. Good quality, but the allowed parts can be limiting.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •