def test_0(dut): pt=esc.phase_table(phase_max=12) v = -1 # rotor angular velocity a = 0*tau/24 # rotor angle comp = bldc.comparator_bits(bldc.emf(a,v)) phase = rotor_phase(a, pt) yield dut.comp.eq(comp) yield dut.phase.eq(phase) yield assert (yield dut.glitch) == 0 # settled inputs with valid state yield from print_state(dut, a, v, pt=pt) yield yield from print_state(dut, a, v, pt=pt) yield assert (yield dut.glitch) == 0 # settled inputs with valid state a=2*tau for i in range(48): print(f"\nstep") v = -1 # rotor angular velocity a += v *tau/24 # rotor angle comp = bldc.comparator_bits(bldc.emf(a,v)) phase = rotor_phase(a, pt) yield dut.comp.eq(comp) yield dut.phase.eq(phase) yield yield from print_state(dut, a, v, pt=pt) assert (yield dut.glitch) == 0 # settled inputs with valid state yield yield from print_state(dut, a, v, pt=pt) assert (yield dut.glitch) == 0 # settled inputs with valid state
def print_state(dut, a, v, pt=esc.phase_table(phase_max=12)): print(f"comp = {(yield dut.comp)}") print(f"strobe = {(yield dut.strobe)}") print(f"phase_observation = {(yield dut.phase_observation)}") print(f"glitch = {(yield dut.glitch)}") print(f"phase = {(yield dut.phase)}") print(f"rotor angle = {a}") print(f"rotor phase = {rotor_phase(a, pt)}") print(f"back emf = {bldc.emf(a,v)}") print(f"comparators = {bldc.comparator_bits(bldc.emf(a,v))}")
def test_0(dut): pt = esc.phase_table(phase_max=12) hall_seq = [1, 3, 2, 6, 4, 5] hall_seq = hall_seq + hall_seq yield dut.hall.eq(hall_seq[-1]) yield assert (yield dut.hall_glitch ) == 1 # transition from zero has no defined position assert (yield dut.strobe) == 0 # exiting error state, don't strobe yield assert (yield dut.hall_glitch) == 0 # settled inputs with valid state assert (yield dut.strobe) == 0 # strobe is off for settled input for h in hall_seq: print("forward") yield dut.hall.eq(h) yield yield from print_state(dut) assert (yield dut.strobe) == 1 # strobe is on after valid transition yield yield from print_state(dut) assert (yield dut.strobe) == 0 # strobe is off for settled input yield yield from print_state(dut) yield dut.hall.eq(hall_seq[0]) yield yield hall_seq.reverse() for h in hall_seq: print("reverse") yield dut.hall.eq(h) yield yield from print_state(dut) assert (yield dut.strobe) == 1 # strobe is on after valid transition yield yield from print_state(dut) assert (yield dut.strobe) == 0 # strobe is off for settled input yield yield from print_state(dut)
assert (yield dut.strobe) == 0 # strobe is off for settled input yield yield from print_state(dut) yield dut.hall.eq(hall_seq[0]) yield yield hall_seq.reverse() for h in hall_seq: print("reverse") yield dut.hall.eq(h) yield yield from print_state(dut) assert (yield dut.strobe) == 1 # strobe is on after valid transition yield yield from print_state(dut) assert (yield dut.strobe) == 0 # strobe is off for settled input yield yield from print_state(dut) def testbench(dut): print("testing hall observer device") yield from test_0(dut) if __name__ == "__main__": pt = esc.phase_table(phase_max=12) hall_observer = esc.ObserverHall(pt) run_simulation(hall_observer, testbench(hall_observer))
def rotor_phase(angle, pt=esc.phase_table(phase_max=12)): return int(6 * angle / tau) % 6
def print_state(dut, a, v, pt=esc.phase_table(phase_max=12)): print(f"comp_pins = {(yield dut.comp_pins)}") print(f"hall_pins = {(yield dut.hall_pins)}")
def test_0(dut): v = -1000000*(tau/60) # rotor angular velocity a = 6*tau/24 # rotor angle for ms in range(3): print(f"ms={ms}") for us in range(1000): for clk in range(16): yield from dut.update(a,v) yield a += v*(dut.clk_period/1e9) def testbench(dut): print("testing emf observer device") yield from test_0(dut) if __name__ == "__main__": clk_period = int(1e9/16e6) pt = esc.phase_table(phase_max=12*(2**23)) emf_observer = ESCInspector(pt, clk_period) run_simulation(emf_observer, testbench(emf_observer),clocks={"sys": 63}, vcd_name="esc_full.vcd")
def main(): parser = argparse.ArgumentParser( description="Build TinyFPGA_BX Main Gateware") parser.add_argument( "--seed", default=0, help="seed to use in nextpnr" ) parser.add_argument( "--placer", default="heap", choices=["sa", "heap"], help="which placer to use in nextpnr" ) args = parser.parse_args() soc = BaseSoC(pnr_seed=args.seed, pnr_placer=args.placer, usb_bridge=True) channels=2 #ppm_loop_pin = Signal() pwm_pins = [Signal() for _ in range(channels)] ppm_input_extension = [("ppm_input_pin", 0, Pins("GPIO:2"), IOStandard("LVCMOS33"))] soc.platform.add_extension(ppm_input_extension) ppm_input_pin = soc.platform.request("ppm_input_pin", 0) soc.submodules.ppm_input = liteppm.PPMinputRegister(ppm_input_pin, servo_pads=pwm_pins, channels=channels) soc.add_csr("ppm_input") ppm_output_extension = [("ppm_output_pin", 0, Pins("GPIO:3"), IOStandard("LVCMOS33"))] soc.platform.add_extension(ppm_output_extension) ppm_output_pin = soc.platform.request("ppm_output_pin", 0) soc.submodules.ppm_output = liteppm.PPMoutputRegister(ppm_output_pin, channels=channels) soc.add_csr("ppm_output") #pwm_input_extension = [("pwm_input_pin", 0, Pins("GPIO:4"), IOStandard("LVCMOS33"))] #soc.platform.add_extension(pwm_input_extension) #pwm_input_pin = soc.platform.request("pwm_input_pin", 0) soc.submodules.pwm_input = liteppm.PWMinputRegister(ppm_input_pin) soc.add_csr("pwm_input") user_led = soc.platform.request("user_led", 0) soc.submodules.blink = Blink(user_led, ppm_input_pin) inverter_extension = [ ("inverter", 0, Subsignal("al", Pins("GPIO:4")), Subsignal("ah", Pins("GPIO:5")), Subsignal("bl", Pins("GPIO:6")), Subsignal("bh", Pins("GPIO:7")), Subsignal("cl", Pins("GPIO:8")), Subsignal("ch", Pins("GPIO:9")), IOStandard("LVCMOS33") ) ] comparator_extension = [ ("comparators", 0, Subsignal("a", Pins("GPIO:10")), Subsignal("b", Pins("GPIO:11")), Subsignal("c", Pins("GPIO:12")), IOStandard("LVCMOS33") ) ] hall_extension = [ ("hall", 0, Subsignal("a", Pins("GPIO:13")), Subsignal("b", Pins("GPIO:14")), Subsignal("c", Pins("GPIO:15")), IOStandard("LVCMOS33") ) ] soc.platform.add_extension(inverter_extension) soc.platform.add_extension(comparator_extension) soc.platform.add_extension(hall_extension) inverter_pads = soc.platform.request("inverter") comp_pads = soc.platform.request("comparators") hall_pads = soc.platform.request("hall") inverter_pins = [ [inverter_pads.al, inverter_pads.ah], [inverter_pads.bl, inverter_pads.bh], [inverter_pads.cl, inverter_pads.ch] ] comp_pins = Cat(comp_pads.a, comp_pads.b, comp_pads.c) hall_pins = Cat(hall_pads.a, hall_pads.b, hall_pads.c) pt = esc.phase_table(phase_max=12*(2**23)) clk_period = 1e9/16e6 servo_pin = ppm_input_pin soc.submodules.esc = esc.ESC(pt, clk_period, inverter_pins, comp_pins, hall_pins, servo_pin) soc.submodules.triv_reg = TrivialRegister() soc.add_csr("triv_reg") builder = Builder(soc, output_dir="build", csr_csv="build/csr.csv", compile_software=False) vns = builder.build() soc.do_exit(vns)