educa
Active member
Hello,
Excuse my direct approach, but I am somebody who is interested in developing software with teensy 3.6
The reason why I would like to use teensy 3.6 is because of the very high speed and capabilities of this board + quite some ram available.
This is NOT for making the next generation of "blink the led".
My name is Bart Libert and I want to write my own gcode interpreter for laser cutter. This is high speed stepper signal generation (preferably upto 100kHz steprates) with 10x interpolation, so with a virtual 1Mhz steprate.
I already wrote a fully functioning prototype for arduino due (SAM3XAE Arm Cortex-M3) which does use a few important features, but Arduino DUE is EOL and I prefer to use a more supported product.
The things I would have to be able to do are:
1) I need to be able to direcly set a pin HIGH or LOW without using the library (for pure speed purposes, because digitalWrite eats too many cycles)
2) 1 hardware pwm signal with preferably a +-20kHz frequency. I know this can be setup using library code but it would be very nice to be able to
directly set this using registers (for best possible speed)
3) I need 3 (and if possible 4) IO pins which can be set high and low by a timer. On arduino due there are multiple channels to a timer and there I managed to do this. The fact is that I want 3 (or 4) independent counters which are by default stopped. Then when I start the counter, it must SET a pin (whichever pin it is on the teensy, I'll adapt the connection wires) and then when it reaches a certain counter value, the timer should lower the pin signal, set the counter back to 0 and stop the counter. So it should
- On initialisation the timer (connected to a hardware pin) should be set at a counter value of 0 and the corresponding hardware pin should be LOW + the counter must NOT start running.
- At a certain point in my program I want to give the counter the command to start and when it starts, it should SET its corresponding hardware pin high, start counting and when the counter reaches a certain compare value, it should set the hardware pin LOW again, zero the counter value and stop the timer counter.
This above is needed 3 (or even better 4) times and they should run independent from eachother. On the Arduino DUE I used Timer 2 channel 0,1 and 2 for that and thes came out as digital pins 5,3 and 11
Can anyone please tell me if the teensy 3.6 is capable of doing this? I allready downloaded the CPU manual (a whopping 2237 pages) and have to say it does not look a lot like the Atmel SAM3XAE which is also arm. So probably the complete peripheral set is regulated slightly different?
To proove that I really don't as without knowing what I say, this is the code I used on arduino DUE for the initialisation of the timers and pwm
================================================================================================================================================
And then enabling a pin for a certain duration by enabling the timer is done like this
======================================================================================
Excuse my direct approach, but I am somebody who is interested in developing software with teensy 3.6
The reason why I would like to use teensy 3.6 is because of the very high speed and capabilities of this board + quite some ram available.
This is NOT for making the next generation of "blink the led".
My name is Bart Libert and I want to write my own gcode interpreter for laser cutter. This is high speed stepper signal generation (preferably upto 100kHz steprates) with 10x interpolation, so with a virtual 1Mhz steprate.
I already wrote a fully functioning prototype for arduino due (SAM3XAE Arm Cortex-M3) which does use a few important features, but Arduino DUE is EOL and I prefer to use a more supported product.
The things I would have to be able to do are:
1) I need to be able to direcly set a pin HIGH or LOW without using the library (for pure speed purposes, because digitalWrite eats too many cycles)
2) 1 hardware pwm signal with preferably a +-20kHz frequency. I know this can be setup using library code but it would be very nice to be able to
directly set this using registers (for best possible speed)
3) I need 3 (and if possible 4) IO pins which can be set high and low by a timer. On arduino due there are multiple channels to a timer and there I managed to do this. The fact is that I want 3 (or 4) independent counters which are by default stopped. Then when I start the counter, it must SET a pin (whichever pin it is on the teensy, I'll adapt the connection wires) and then when it reaches a certain counter value, the timer should lower the pin signal, set the counter back to 0 and stop the counter. So it should
- On initialisation the timer (connected to a hardware pin) should be set at a counter value of 0 and the corresponding hardware pin should be LOW + the counter must NOT start running.
- At a certain point in my program I want to give the counter the command to start and when it starts, it should SET its corresponding hardware pin high, start counting and when the counter reaches a certain compare value, it should set the hardware pin LOW again, zero the counter value and stop the timer counter.
This above is needed 3 (or even better 4) times and they should run independent from eachother. On the Arduino DUE I used Timer 2 channel 0,1 and 2 for that and thes came out as digital pins 5,3 and 11
Can anyone please tell me if the teensy 3.6 is capable of doing this? I allready downloaded the CPU manual (a whopping 2237 pages) and have to say it does not look a lot like the Atmel SAM3XAE which is also arm. So probably the complete peripheral set is regulated slightly different?
To proove that I really don't as without knowing what I say, this is the code I used on arduino DUE for the initialisation of the timers and pwm
================================================================================================================================================
Code:
//Prepare timers that will help generate the pulses for xStep, yStep and laser shoot.
pmc_set_writeprotect(false); //Turn off write protection on Power Management Controller
pmc_enable_periph_clk(TC6_IRQn); // Enable the peripheral clock by IRQ for Timer 2 channel 0 : X step pulse
pmc_enable_periph_clk(TC7_IRQn); // Enable the peripheral clock by IRQ for Timer 2 channel 1 : Y step pulse
pmc_enable_periph_clk(TC8_IRQn); // Enable the peripheral clock by IRQ for Timer 2 channel 2 : Laser shoot pulse
//Specific preparation for Timer 2 channel 0 (X step pulse)
TC_Configure(TC2, 0, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR | 64); // Configure the timer on its specified channel. Timer is stopped after config and must be started in code.
TC_SetRA(TC2, 0, 1); // Set the counter value where the output of TIOA goes high in register RA (datasheet p.867)
TC_SetRC(TC2, 0, 420); //Set the counter value (3ms) where the output of TIOA goes low and the counter is reset in register RC (datasheet p.867)
REG_PIOC_ABSR |= PIO_ABSR_P25; // Switch the multiplexer to peripheral B for TIOA6 (pin 5 on due)
REG_PIOC_PDR |= PIO_ABSR_P25; // Disable PIO for TIOA6 pin 5 on due
//Specific preparation for Timer 2 channel 1 (Y step pulse)
TC_Configure(TC2, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR | 64); // Configure the timer on its specified channel. Timer is stopped after config and must be started in code.
TC_SetRA(TC2, 1, 1); // Set the counter value where the output of TIOA goes high in register RA (datasheet p.867)
TC_SetRC(TC2, 1, 420); //Set the counter value (6ms) where the output of TIOA goes low and the counter is reset in register RC (datasheet p.867)
REG_PIOC_ABSR |= PIO_ABSR_P28; // Switch the multiplexer to peripheral B for TIOA7 (pin 3 on due)
REG_PIOC_PDR |= PIO_ABSR_P28; // Disable PIO for TIOA7 pin 3 on due
//Specific preparation for Timer 2 channel 2 (Laser shoot pulse)
TC_Configure(TC2, 2, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR | 64); // Configure the timer on its specified channel. Timer is stopped after config and must be started in code.
TC_SetRA(TC2, 2, 1); // Set the counter value where the output of TIOA goes high in register RA (datasheet p.867)
TC_SetRC(TC2, 2, 125925); //Set the counter value (9ms) where the output of TIOA goes low and the counter is reset in register RC (datasheet p.867)
REG_PIOD_ABSR |= PIO_ABSR_P7; // Switch the multiplexer to peripheral B for TIOA8 (pin 11 on due)
REG_PIOD_PDR |= PIO_ABSR_P7; // Disable PIO for TIOA8 pin 11 on due
//Specific preparation to enable a 20kHz PWM signal on digital pin 34
pmc_enable_periph_clk (PWM_INTERFACE_ID) ; // turn on clocking to PWM unit
PWMC_ConfigureChannel (PWM, 0, 1, 0, 0) ; // PWM channel 0, clock = MCLK/2 = 42MHz
PWMC_SetPeriod (PWM, 0, 2100) ; // Channel 0 period = 2100 pwm clocks (20kHz)
PWMC_SetDutyCycle (PWM, 0, 80 * 2100 / 100) ; // Channel 0 duty set to 80%
PWMC_EnableChannel (PWM, 0) ; // enable channel 0
PIOC->PIO_PDR = 1 << 2 ; // disable PIO control on PC2 (pin34) by setting bit 2 of the PIO_PDR register for PIO controller PIOC
PIOC->PIO_IDR = 1 << 2 ; // disable PIO interrupts on PC2 (pin34) by setting bit 2 of the PIO_IDR register for PIO controller PIOC
PIOC->PIO_ABSR |= 1 << 2 ; // switch PC2 (pin34) to B peripheral, which carries PWM channel 0 ?
//Prepare the Xdir and Ydir pins for startup and make sure they are low
pinMode(xDir, OUTPUT);
g_APinDescription[xDir].pPort -> PIO_CODR = g_APinDescription[xDir].ulPin; //xDir low
pinMode(yDir, OUTPUT);
g_APinDescription[yDir].pPort -> PIO_CODR = g_APinDescription[yDir].ulPin; //yDir low
And then enabling a pin for a certain duration by enabling the timer is done like this
======================================================================================
Code:
TC2->TC_CHANNEL[2].TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // let laser shoot with a timer regulated signal