Last active
December 14, 2019 19:51
-
-
Save nmz787/edd964e9f06ade61de75fbc38bee9b8e to your computer and use it in GitHub Desktop.
ok, seems I have 2 glitch-free PWM channels which are 180 degrees out-of-phase... controllable for pulse width and period at the top with two variables. TIM1 starts TIM2 and TIM5... then after a number of interrupts on TIM2, it shuts itself down and attaches a shutdown-timer to TIM3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pyb | |
from pyb import Timer | |
import micropython | |
import stm | |
#john's sript actual pulse width 181 us, 448 us period (pulse to pulse) | |
# Use with pyb.freq(96000000) and prescaler=11 for .25 usec timer ticks. | |
xfmr_pulse_period = 1570 # (= usec * 4) Same as toggle_half_cycle duration. | |
xfmr_pulse_w = 332 # (= usec * 4) | |
max_push_pulls = 8 | |
def force_inactive1(): | |
# Put (t2ch2/t2ch1) mode to FORCED_INACTIVE to start... | |
# TODO which isn it, ch1 or ch2? | |
# TODO link to PDF and page number for register field description | |
ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
ccmr1 &= 0b1111111110001111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0000000001000000 | |
stm.mem16[stm.TIM2 + stm.TIM_CCMR1] = ccmr1 | |
def force_inactive2(): | |
# Put (t2ch2/t2ch1) mode to FORCED_INACTIVE to start... | |
# TODO which isn it, ch1 or ch2? | |
# TODO link to PDF and page number for register field description | |
ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
ccmr1 &= 0b1000111111111111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0100000000000000 | |
stm.mem16[stm.TIM2 + stm.TIM_CCMR1] = ccmr1 | |
def force_inactive5(): | |
# Put (t2ch2/t2ch1) mode to FORCED_INACTIVE to start... | |
# TODO which isn it, ch1 or ch2? | |
# TODO link to PDF and page number for register field description | |
ccmr1 = stm.mem16[stm.TIM5 + stm.TIM_CCMR1] | |
ccmr1 &= 0b1000111110001111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0100000001000000 | |
stm.mem16[stm.TIM5 + stm.TIM_CCMR1] = ccmr1 | |
def force_inactive(): | |
# Put t2ch2 t2ch1 mode to FORCED_INACTIVE to start... | |
ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
ccmr1 &= 0b1000111110001111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0100000001000000 | |
stm.mem16[stm.TIM2 + stm.TIM_CCMR1] = ccmr1 | |
def ccer_set(enable=True): | |
# Put t2ch2 t2ch1 mode to FORCED_INACTIVE to start... | |
#ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
val = stm.mem16[stm.TIM2 + stm.TIM_CCER] | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CC4P CC4E CC3NP CC3NE CC3P CC3E CC2NP CC2NE CC2P CC2E CC1NP CC1NE CC1P CC1E | |
val &= 0b1111111111101110 # TIM_CC2E TIM_CC1E | |
if enable: | |
val |= 0b0000000000010001 | |
#else: | |
# val |= 0b0000000000000000 | |
stm.mem16[stm.TIM2 + stm.TIM_CCER] = val | |
def ccer_set5(enable=True): | |
# Put t2ch2 t2ch1 mode to FORCED_INACTIVE to start... | |
#ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
val = stm.mem16[stm.TIM5 + stm.TIM_CCER] | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CC4P CC4E CC3NP CC3NE CC3P CC3E CC2NP CC2NE CC2P CC2E CC1NP CC1NE CC1P CC1E | |
val &= 0b1111111111101110 # TIM_CC2E TIM_CC1E | |
if enable: | |
val |= 0b0000000000010001 | |
# else: | |
# val |= 0b0000000000000000 | |
stm.mem16[stm.TIM5 + stm.TIM_CCER] = val | |
def tim1_cr1_set(enable=True): | |
val = stm.mem16[stm.TIM1 + stm.TIM_CR1] | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
val &= 0b1111111111111110 # CEN off | |
if enable: | |
val |= 0b0000000000000001 # CEN on | |
stm.mem16[stm.TIM1 + stm.TIM_CR1] = val | |
def tim2_cr1_set(enable=True): | |
# Put t2ch2 t2ch1 mode to FORCED_INACTIVE to start... | |
#ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
val = stm.mem16[stm.TIM2 + stm.TIM_CR1] | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
val &= 0b1111111111111110 # CEN off | |
if enable: | |
val |= 0b0000000000000001 # CEN on | |
stm.mem16[stm.TIM2 + stm.TIM_CR1] = val | |
@micropython.native | |
def tim2_cr1_disable_clock(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
stm.mem16[stm.TIM2] &= 0b1111111111111110 # CEN off | |
#stm.mem16[stm.TIM2]&=((~1) & 0xffffffff) | |
@micropython.native | |
def tim5_cr1_disable_clock(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
stm.mem16[stm.TIM5] &= 0b1111111111111110 # CEN off | |
#stm.mem16[stm.TIM5]&=((~1) & 0xffffffff) | |
@micropython.native | |
def tim3_cr1_disable_clock(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
stm.mem16[stm.TIM3] &= 0b1111111111111110 # CEN off | |
def tim5_cr1_set(enable=True): | |
# Put t2ch2 t2ch1 mode to FORCED_INACTIVE to start... | |
#ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
val = stm.mem16[stm.TIM5 + stm.TIM_CR1] | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved CKD[1:0] ARPE CMS DIR OPM URS UDIS CEN | |
val &= 0b1111111111111110 # CEN off | |
if enable: | |
val |= 0b0000000000000001 # CEN on | |
stm.mem16[stm.TIM5 + stm.TIM_CR1] = val | |
def tim1_cr2_set(enable=True): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved TI1S MMS[2:0] CCDS Reserved | |
val = stm.mem16[stm.TIM1 + stm.TIM_CR2] | |
val &= 0b1111111110001111 | |
val |= 0b0000000000100000 | |
stm.mem16[stm.TIM1 + stm.TIM_CR2] = val | |
def tim2_cr2_set(enable=True): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved TI1S MMS[2:0] CCDS Reserved | |
val = stm.mem16[stm.TIM2 + stm.TIM_CR2] | |
val &= 0b1111111110001111 | |
val |= 0b0000000000000000 | |
stm.mem16[stm.TIM2 + stm.TIM_CR2] = val | |
def tim5_cr2_set(enable=True): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# Reserved TI1S MMS[2:0] CCDS Reserved | |
pass | |
def tim2_smcr_(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# ETP ECE ETPS[1:0] ETF[3:0] MSM TS[2:0] Res. SMS[2:0] | |
val = stm.mem16[stm.TIM2 + stm.TIM_SMCR] | |
val &= 0b1111111110001000 | |
val |= 0b0000000000000110 | |
stm.mem16[stm.TIM2 + stm.TIM_SMCR] = val | |
def tim3_smcr_(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# ETP ECE ETPS[1:0] ETF[3:0] MSM TS[2:0] Res. SMS[2:0] | |
val = stm.mem16[stm.TIM3 + stm.TIM_SMCR] | |
val &= 0b1111111110001000 | |
val |= 0b0000000000000110 | |
stm.mem16[stm.TIM3 + stm.TIM_SMCR] = val | |
def tim5_smcr_(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# ETP ECE ETPS[1:0] ETF[3:0] MSM TS[2:0] Res. SMS[2:0] | |
val = stm.mem16[stm.TIM5 + stm.TIM_SMCR] | |
val &= 0b1111111110001000 | |
val |= 0b0000000000000110 | |
stm.mem16[stm.TIM5 + stm.TIM_SMCR] = val | |
def preload_enable(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# OC2CE OC2M[2:0] OC2PE OC2FE CC2S[1:0] OC1CE OC1M[2:0] OC1PE OC1FE CC1S[1:0] | |
ccmr1 = stm.mem16[stm.TIM2 + stm.TIM_CCMR1] | |
#ccmr1 &= 0b1111111111111111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0000100000001000 | |
stm.mem16[stm.TIM2 + stm.TIM_CCMR1] = ccmr1 | |
def preload_enable5(): | |
# 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 | |
# OC2CE OC2M[2:0] OC2PE OC2FE CC2S[1:0] OC1CE OC1M[2:0] OC1PE OC1FE CC1S[1:0] | |
ccmr1 = stm.mem16[stm.TIM5 + stm.TIM_CCMR1] | |
#ccmr1 &= 0b1111111111111111 # OC2M "100"....OC1M "100" | |
ccmr1 |= 0b0000100000001000 | |
stm.mem16[stm.TIM5 + stm.TIM_CCMR1] = ccmr1 | |
micropython.alloc_emergency_exception_buf(100) | |
print('\nStarting now\n') | |
lower_events = 0 | |
events = 0 | |
events_max_push_pulls = max_push_pulls | |
half_pulse= xfmr_pulse_w//2 | |
adc = pyb.ADC(pyb.Pin.board.JP29) | |
#preload_enable() | |
t1 = pyb.Timer(1, prescaler=1, period=0x0FFFFFFF) | |
tim1_cr1_set(False) | |
# Timer 2 to give .125 usec timer ticks counting up: | |
t2 = pyb.Timer(2, prescaler=11, period=xfmr_pulse_period, mode=Timer.CENTER) | |
tim2_cr1_disable_clock() | |
# 26 is delay for start-up time for attaching callback in the disable-code | |
t3 = pyb.Timer(3, prescaler=11, period=xfmr_pulse_period+26, mode=Timer.CENTER) | |
tim3_cr1_disable_clock() | |
t3.counter(0) | |
t5 = pyb.Timer(5, prescaler=11, period=xfmr_pulse_period, mode=Timer.CENTER) | |
tim5_cr1_disable_clock() | |
#force_inactive5() | |
#preload_enable() | |
#preload_enable5() | |
#force_inactive() | |
#ccer_set(False) | |
force_inactive5() | |
force_inactive() | |
t2.counter(0) | |
t5.counter(0) | |
tim5_cr1_disable_clock() | |
tim1_cr2_set() | |
tim2_smcr_() | |
tim3_smcr_() | |
tim5_smcr_() | |
# upper trace, PA0 | |
upper = t5.channel(1, pyb.Timer.PWM, pulse_width=xfmr_pulse_w, | |
polarity=pyb.Timer.HIGH, pin=pyb.Pin.board.JP25) | |
tim5_cr1_disable_clock() | |
ccer_set5(False) | |
#tim5_cr1_set(False) | |
#tim5_cr1_disable_clock() | |
# bottom trace, PA1 | |
lower = t2.channel(2, pyb.Timer.PWM, pulse_width=xfmr_pulse_w, | |
polarity=pyb.Timer.HIGH, pin=pyb.Pin.board.JP26) | |
#tim2_cr1_set(False) | |
#tim2_cr1_set_alternate(False) | |
tim2_cr1_disable_clock() | |
#ic = t1.channel(4, Timer.IC, pin=pyb.Pin.board.JP26, polarity=pyb.Timer.BOTH) | |
# adc_timer = t1.channel(4, pyb.Timer.OC_TIMING) | |
# def adc_cb(the_active_timer): | |
# print(adc.read()) | |
# adc_timer.callback(adc_cb) | |
#@micropython.native | |
def disable_upper(the_active_timer): | |
global events | |
#print('upper') | |
events += 1 | |
if events==events_max_push_pulls: | |
#t2.deinit() | |
#ccer_set5(False) | |
while pyb.Pin.board.JP25.value(): | |
print('upper') | |
print(adc.read()) | |
#ccer_set5(False) | |
#stm.mem16[stm.TIM2 + stm.TIM_CR1] = 0 | |
#tim5_cr1_set(False) | |
#t2.deinit() | |
#the_active_timer.deinit() | |
force_inactive5() | |
force_inactive() | |
def shutdown_timer(the_active_timer): | |
force_inactive5() | |
#@micropython.native | |
def disable_lower(the_active_timer): | |
global lower_events | |
#print('lower') | |
lower_events+=1 | |
if lower_events==events_max_push_pulls: | |
#the_active_timer.period(half_pulse) | |
#lower.pulse_width(0) | |
while pyb.Pin.board.JP26.value(): | |
print('lower') | |
print(adc.read()) | |
stm.mem16[stm.TIM1 + stm.TIM_CR1] = 0 | |
stm.mem16[stm.TIM2 + stm.TIM_CR1] = 0 | |
#stm.mem16[stm.TIM5 + stm.TIM_CR1] = 0 | |
#pyb.Pin.board.JP25.setvalue(0) | |
t3.callback(shutdown_timer) | |
#t1.deinit() | |
#t5.deinit() | |
#the_active_timer.deinit() | |
else: | |
ccer_set5() | |
#print(bin(stm.mem16[stm.TIM2 + stm.TIM_CCER])) | |
#t5.counter(0) | |
#cc_set5(False) | |
#t2.counter(xfmr_pulse_period - (half_pulse//2)) | |
#cc_set5(False) | |
@micropython.asm_thumb | |
def set_right(r0, r1): | |
"TIM2_CR1_data, TIM5_CR1_data" | |
movwt(r2, stm.TIM2) | |
strh(r0, [r2, stm.TIM_CR1]) | |
nop() | |
movwt(r3, stm.TIM5) | |
strh(r1, [r3, stm.TIM_CR1]) | |
@micropython.native | |
def last(): | |
lower.callback(disable_lower) | |
tim2_cr1_set(False) | |
upper.callback(disable_upper) | |
tim5_cr1_set(False) | |
#t2.counter() | |
#tim2_cr1_set() | |
#_nop() | |
#tim5_cr1_set() | |
lower.callback(disable_lower) | |
tim2_cr1_disable_clock() | |
# tim2_cr1_set(False) | |
#upper.callback(disable_upper) | |
tim5_cr1_disable_clock() | |
# tim5_cr1_set(False) | |
#force_inactive5() | |
#force_inactive() | |
#last() | |
t5.counter(0) | |
t2.counter(xfmr_pulse_period) | |
# set_right((stm.mem16[stm.TIM2 + stm.TIM_CR1] & 0b1111111111111110 )| 0b0000000000000001, | |
# (stm.mem16[stm.TIM5 + stm.TIM_CR1] & 0b1111111111111110 )| 0b0000000000000001, | |
# ) | |
print(bin(stm.mem16[stm.TIM2+stm.TIM_CR2])) | |
print(bin(stm.mem16[stm.TIM5+stm.TIM_CR2])) | |
stm.mem16[stm.TIM2+stm.TIM_CR2]|= 1<<4 | |
stm.mem16[stm.TIM3+stm.TIM_CR2]|= 1<<4 | |
stm.mem16[stm.TIM5+stm.TIM_CR2]|= 1<<4 | |
print(bin(stm.mem16[stm.TIM2+stm.TIM_CR2])) | |
print(bin(stm.mem16[stm.TIM5+stm.TIM_CR2])) | |
tim1_cr2_set() | |
tim2_smcr_() | |
tim3_smcr_() | |
tim5_smcr_() | |
tim1_cr1_set() | |
# Using one timer to enable another timer | |
# In this example, we control the enable of Timer 2 with the output compare 1 of Timer 1. | |
# Refer to Figure 127 for connections. Timer 2 counts on the divided internal clock only when | |
# OC1REF of Timer 1 is high. Both counter clock frequencies are divided by 3 by the | |
# prescaler compared to CK_INT (fCK_CNT = fCK_INT/3). | |
# • Configure Timer 1 master mode to send its Output Compare 1 Reference (OC1REF) | |
# signal as trigger output (MMS=100 in the TIM1_CR2 register). | |
# • Configure the Timer 1 OC1REF waveform (TIM1_CCMR1 register). | |
# • Configure Timer 2 to get the input trigger from Timer 1 (TS=000 in the TIM2_SMCR register). | |
# • Configure Timer 2 in gated mode (SMS=101 in TIM2_SMCR register). | |
# • Enable Timer 2 by writing ‘1 in the CEN bit (TIM2_CR1 register). | |
# • Start Timer 1 by writing ‘1 in the CEN bit (TIM1_CR1 register). | |
# In the next example, we synchronize Timer 1 and Timer 2. Timer 1 is the master and starts | |
# from 0. Timer 2 is the slave and starts from 0xE7. The prescaler ratio is the same for both | |
# timers. Timer 2 stops when Timer 1 is disabled by writing ‘0 to the CEN bit in the TIM1_CR1 | |
# register: | |
# • Configure Timer 1 master mode to send its Output Compare 1 Reference (OC1REF) | |
# signal as trigger output (MMS=100 in the TIM1_CR2 register). | |
# • Configure the Timer 1 OC1REF waveform (TIM1_CCMR1 register). | |
# • Configure Timer 2 to get the input trigger from Timer 1 (TS=000 in the TIM2_SMCR register). | |
# • Configure Timer 2 in gated mode (SMS=101 in TIM2_SMCR register). | |
# • Reset Timer 1 by writing ‘1 in UG bit (TIM1_EGR register). | |
# • Reset Timer 2 by writing ‘1 in UG bit (TIM2_EGR register). | |
# • Initialize Timer 2 to 0xE7 by writing ‘0xE7’ in the timer 2 counter (TIM2_CNTL). | |
# • Enable Timer 2 by writing ‘1 in the CEN bit (TIM2_CR1 register). | |
# • Start Timer 1 by writing ‘1 in the CEN bit (TIM1_CR1 register). | |
# • Stop Timer 1 by writing ‘0 in the CEN bit (TIM1_CR1 register). | |
# Using one timer to start another timer | |
# In this example, we set the enable of Timer 2 with the update event of Timer 1. Refer to | |
# Figure 127 for connections. Timer 2 starts counting from its current value (which can be | |
# nonzero) on the divided internal clock as soon as the update event is generated by Timer 1. | |
# When Timer 2 receives the trigger signal its CEN bit is automatically set and the counter | |
# counts until we write ‘0 to the CEN bit in the TIM2_CR1 register. Both counter clock | |
# frequencies are divided by 3 by the prescaler compared to CK_INT (fCK_CNT = fCK_INT/3). | |
## • Configure Timer 1 master mode to send its Update Event (UEV) as trigger output (MMS=010 in the TIM1_CR2 register). | |
# • Configure the Timer 1 period (TIM1_ARR registers). | |
# • Configure Timer 2 to get the input trigger from Timer 1 (TS=000 in the TIM2_SMCR | |
# register). | |
# • Configure Timer 2 in trigger mode (SMS=110 in TIM2_SMCR register). | |
# • Start Timer 1 by writing ‘1 in the CEN bit (TIM1_CR1 register) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment