import time
from machine import Pin, Timer
from rp2 import asm_pio, StateMachine, PIO
PWM_Frequency_Hz = 500
PWM_Duty_Step = 10
PWM_Duty_Min = 10
PWM_Duty_Max = 100
PWM_Duty_Num_Samples = 10
DataPin = Pin(15, Pin.OUT)
ClockPin = Pin(19, Pin.OUT)
LatchPin = Pin(18, Pin.OUT)
mduty = 0
timer = 0
pindex = 0
mindex = 0
t3 = 0
t4 = 0
@asm_pio( out_shiftdir=PIO.SHIFT_RIGHT,
autopull=True, pull_thresh=8,
out_init=(PIO.OUT_LOW),
sideset_init=(PIO.OUT_LOW,PIO.OUT_LOW) )
def send_out():
wrap_target()
set(x,7) .side(0b00) # set X to 7 (use X as bit counter)
# shift 8 bits out to the SCLK pin, LSB first
label('loop')
out(pins,1) .side(0b00) # shift 1 bit from OSR to the first out pin
# drive SCLK pin low
jmp(x_dec,'loop') .side(0b10) # branch to loop if X is not zero, decrement X
# drive SCLK pin high
pull(ifempty) .side(0b01) # get a word from TX-FIFO into OSR, stall if empty
# drive LOAD pin high
wrap()
sm = StateMachine(0, send_out, out_base=DataPin,
sideset_base=LatchPin, freq=1_000_000)
#sm = StateMachine(0, send_out, out_base=DataPin,
# sideset_base=LatchPin)
# 0 1 2 3 4 5 6 7 8 9 perc.
pwm_values=[[0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00], # 0
[0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00], # 10
[0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x80,0x00,0x00], # 20
[0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x80], # 30
[0x80,0x00,0x80,0x00,0x00,0x00,0x80,0x00,0x80,0x00], # 40
[0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80], # 50
[0x00,0x80,0x00,0x80,0x80,0x80,0x00,0x80,0x00,0x80], # 60
[0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x80,0x00], # 70
[0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x80], # 80
[0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80], # 90
[0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80]] # 100
def pwm_pin(timer):
global sm
global mduty
global pindex
global pwm_values
global mindex
global t3
global t4
t3 = time.time_ns()
duty_cycle = mduty
#index = int(duty_cycle / PWM_Duty_Step)
#print ("duty_cycle =",duty_cycle,"%, index =", index)
data = pwm_values[mindex][pindex]
sm.put(data)
#print (hex(data), end=" ")
pindex = pindex + 1
if pindex >= PWM_Duty_Num_Samples:
pindex = 0
t4 = time.time_ns()
def pwm_init(frequency):
global mduty
global timer
global pindex
global sm
mduty = 0
pindex = 0
timer = Timer()
timer.init(freq=(frequency * 10),mode=Timer.PERIODIC, callback=pwm_pin)
sm.active(1) # run the SM
def pwm_deinit():
global timer
global sm
pwm_set(0)
time.sleep(1)
print ("deinit")
sm.active(0)
print ("Stop SM")
print ("Deinit timer")
if (timer != 0):
timer.deinit()
def pwm_set(duty):
global mduty
global mindex
mduty = duty
mindex = int(duty / PWM_Duty_Step)
try:
#PWM_Frequency_Hz
pwm_init(PWM_Frequency_Hz)
print("")
print ("Start PWM PIO")
t1 = time.time_ns()
for d in range(PWM_Duty_Min, PWM_Duty_Max + PWM_Duty_Step, PWM_Duty_Step):
#print ("duty =", d, "%")
pwm_set(d)
time.sleep_ms(int(float(1.0/PWM_Frequency_Hz) * 1000.0))
#pwm_set(10)
#time.sleep(1)
print ("Diff time t3/t4 ns timer = ", ((t4-t3)/1000.0), "us")
t2 = time.time_ns()
print("Start time = ", t1)
print ("Stop time = ",t2)
print ("Diff time ns timer = ", ((t2-t1)/1000.0), "ms")
print ("Stop PWM PIO")
pwm_deinit()
print ("Finished")
except KeyboardInterrupt:
pass
#finally:
#sm.put(0x00)
#time.sleep_ms(100)
#sm.active(0)
#time.sleep_ms(500)