# cPy - RW2050 (Esp32 with external hardware) for simulation purposes
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2024-10-30  initial release

import	time
# from	mve_vl53l0x	import	VL53L0X

# Implemented:
# Pcf8547(i2c, addr=0x20)
#    Pcf8547.setOut(self, data)
#    Pcf8547.getInp()				-->  int
# Vl53l(i2c)
#    Vl53l.start()
#    Vl53l.read()					-->  int
# L298(pin_en, pin_dir, freq=5000)
#    L298.setImm(pwm, kick=0)
#    L298.accel(setp=None, step=None)
# BD62110(pin_a, pin_b, freq=5000)
#    BD62110.setImm(pwm, kick=0)
#    BD62110.accel(setp=None, step=None)
#    BD62110.atSetp()
#    BD62110.deinit()
# Toti(pin_toti, callback=None)
#    Toti.isActive()				-->  bool
#    Toti.exe20()
# Aspect(pin_red, pin_green, pin_yellow_1=None, pin_yellow_2=None, invert=False):
#    Aspect.setAspect(a, flashing=False)

# ===================================== RW2050 ports ===================================

portA	= (16, 18, 33, 35, 37, 39, 40, 38)				# pins port A
portB   = (36, 34, 21, 17, 10,  8,  6,  4)				# pins port B
portC   = ( 2,  1,  3,  5,  7,  9, 11, 12)				# pins port C (RW2050 servo's)
portD   = (14, 13)

# ========================================= PCF8547 ====================================

# I2C driver for PCF8547 octal I/O expander
class Pcf8547:
    
    def __init__(self, i2c, addr=0x20):
        ...


    # Set 8 outputs, pull down, to data (0..255), T = 500 uSec
    def setOut(self, data):
        ...


    # Return 8 read data bits (0..255), T = 500 uSec
    def getInp(self):
        ...

# ========================================= VL53L0X ====================================

# I2C driver for VL53L0X time of flight sensor, range 30..330 mm at address $29
class Vl53l:
    
    def __init__(self, i2c):
        ...


    # start of measurement = 8 mSec followed by a setup from 32 mSec
    def start(self):
        ...


    # reading measured value and abort measuring 7 + 6 mSec. spread approx 10 mm
    def read(self):
        ...
    
# =================================== L298 =====================================

# Driver for L298 modified H-Bridge with enable and direction
class L298:
    
    def __init__(self, pin_en, pin_dir, freq=5000):
        ...
        
        
    # Set PWM output to pwm immediately. range -511..+511
    def _doPWM(self, pwm):
        ...
            
            
    # Set PWM immediate: -511..0..+511. 511 = 100%
    def setImm(self, pwm, kick=0):
        ...


    # Accelerate to v with step at each call. Return True if pwm = v
    # step > 0. If setp or step is None use previous values
    # Return True if speed = setp
    def accel(self, setp=None, step=None):
        ...

# =================================== L298 =====================================

# Driver for BD62110 two wire H-Bridge
class BD62110:
    
    def __init__(self, pin_a, pin_b, freq=5000):
        ...
        
        
    # Set PWM output to pwm. range -1023..+1023
    def _doPWM(self, pwm):
        ...


    # Set PWM immediate: -1023..+1023, kick -1023..+1023 @ 30 mSec
    def setImm(self, pwm, kick=0):
        ...


    # Accelerate to v with step at each call typ @ 100 mSec; step = 10 -- 100 Sec FSD.
    # Return True if setp = pwm
    # If setp or step is None use previous values
    def accel(self, setp=None, step=None):
        ...


    # return True if pwm = setp
    def atSetp(self):
        ...
    
    
    # release resources
    def deinit(self):
        ...

# ============================== Toti ====================================

# use pin_toti as Train on track indicator (detecting input pulses)
class Toti:
    
    def __init__(self, pin_toti, callback=None):
        ...
        
        
    def _onEdge(self, pin):
        ...
        
        
    # Return True if train on track
    def isActive(self):
        ...
    
    
    # testing train on track. to be called at at 50 Hz
    def exe20(self):
        ...

# ======================================== Signal =====================================

# Driver for up to 4 aspect signal
class Aspect:
    aspects = {'r'  : (True,  False, False, False), 'g' : (False, True,  False, False),
               'y'  : (False, False, True,  False), 'y2': (False, False, False, True),
               'all': (True,  True,  True,  True)}


    def __init__(self, pin_red, pin_green, pin_yellow=None, pin_yellow2=None, invert=False):
        ...


    # set aspect i.e.: 'none', 'r', 'g', ['y', 'y2'] 'all'     
    def setAspect(self, aspect, flashing=False):
        ...


    def exe500(self):
        ...
        

    def _setAspect(self, aspect):
        ...

# ========================================= End =======================================        
