MustafaMulla29/rp2040-bldc-motor-controller-new

A USB‑C PD–powered RP2040 BLDC motor controller PCB with 3.3 V logic, MCT8329A sensorless commutation, three MOSFET half-bridges, protected power switching, USB data, controls, and motor connectors.

Version
0.3.82
License
unset
Stars
0

firmware/power_manager.py

"""Configurable-PD bring-up console. Intentionally keeps motor drive OFF.

Copy firmware/*.py to RP2040 MicroPython and run this file over USB DATA.
Commands: voltage 5 | voltage 9 | voltage 15 | voltage 20. SW4 must be OFF.
This verifies supply supervision; it is NOT qualified commutation firmware.
"""
from machine import Pin, ADC, I2C, WDT
import time, sys, select
from power_policy import valid_motor_contract, adc_millivolts
from pd_profile import verify_runtime, nvm_is_9v
from pd_nvm import NVM
from select_pd_voltage import VoltageSelector

speed = Pin(2, Pin.OUT, value=0)
arm = Pin(3, Pin.OUT, value=0)
pd_ok2 = Pin(6, Pin.IN)
led = Pin(25, Pin.OUT, value=0)
bus = I2C(1, sda=Pin(22), scl=Pin(23), freq=100_000)
wdt = WDT(timeout=2000)
vbus_adc, motor_adc = ADC(26), ADC(27)

def disarm():
    arm.off()
    speed.off()

def sample():
    return dict(vbus_mv=adc_millivolts(vbus_adc.read_u16()),
                vmotor_mv=adc_millivolts(motor_adc.read_u16()),
                pd_ok2_low=not pd_ok2.value())

selector = VoltageSelector(bus, disarm, sample, time, service=wdt.feed)
poll = select.poll()
poll.register(sys.stdin, select.POLLIN)
line = ''
print("PD bring-up: motor held OFF. Set SW4 OFF; type voltage 5/9/15/20")
try:
    if not nvm_is_9v(NVM(bus).read()):
        raise OSError("Provision and cold-boot verify 9 V default NVM first")
    while True:
        try:
            while poll.poll(0):
                ch = sys.stdin.read(1)
                if ch in ('\r', '\n'):
                    if line:
                        words = line.split()
                        line = ''
                        if len(words) != 2 or words[0] != 'voltage' or words[1] not in ('5','9','15','20'):
                            raise ValueError("Use voltage 5, voltage 9, voltage 15 or voltage 20")
                        selector.select(int(words[1])*1000)
                        print("Selected %d V; motor remains OFF" % (selector.selected_mv//1000))
                elif len(line) < 64: line += ch
                else:
                    line = ''
                    raise ValueError("Command too long")
            s = sample()
            verify_runtime(bus, selected_mv=selector.selected_mv)
            rdo = int.from_bytes(bus.readfrom_mem(0x28, 0x91, 4), 'little')
            pe = bus.readfrom_mem(0x28, 0x29, 1)[0]
            valid = valid_motor_contract(s['vbus_mv'],rdo,pe,s['pd_ok2_low'],selector.selected_mv)
            led.value(valid)
        except (OSError, ValueError) as error:
            led.off()
            print(error)
        disarm()
        wdt.feed()
        time.sleep_ms(100)
finally:
    disarm()
    led.off()