You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

163 lines
5.0 KiB

  1. from adafruit_blinka import Enum, Lockable, agnostic
  2. class I2C(Lockable):
  3. def __init__(self, scl, sda, frequency=400000):
  4. self.init(scl, sda, frequency)
  5. def init(self, scl, sda, frequency):
  6. self.deinit()
  7. from machine import I2C as _I2C
  8. from microcontroller.pin import i2cPorts
  9. for portId, portScl, portSda in i2cPorts:
  10. if scl == portScl and sda == portSda:
  11. self._i2c = I2C(portId, mode=_I2C.MASTER, baudrate=frequency)
  12. break
  13. else:
  14. raise NotImplementedError("No Hardware I2C on (scl,sda)={}\nValid UART ports".format(
  15. (scl, sda), i2cPorts))
  16. def deinit(self):
  17. try:
  18. del self._i2c
  19. except AttributeError:
  20. pass
  21. def __enter__(self):
  22. return self
  23. def __exit__(self, exc_type, exc_value, traceback):
  24. self.deinit()
  25. def scan(self):
  26. return self._i2c.scan()
  27. def readfrom_into(self, address, buffer, start=0, end=None):
  28. if start is not 0 or end is not None:
  29. if end is None:
  30. end = len(buffer)
  31. buffer = memoryview(buffer)[start:end]
  32. stop = True # remove for efficiency later
  33. return self._i2c.readfrom_into(address, buffer, stop)
  34. def writeto(self, address, buffer, start=0, end=None, stop=True):
  35. if start is not 0 or end is not None:
  36. if end is None:
  37. return self._i2c.writeto(address, memoryview(buffer)[start:], stop)
  38. else:
  39. return self._i2c.writeto(address, memoryview(buffer)[start:end], stop)
  40. return self._i2c.writeto(address, buffer, stop)
  41. class SPI(Lockable):
  42. def __init__(self, clock, MOSI=None, MISO=None):
  43. from microcontroller.pin import spiPorts
  44. for portId, portSck, portMosi, portMiso in spiPorts:
  45. if clock == portSck and MOSI == portMosi and MISO == portMiso:
  46. self._spi = SPI(portId)
  47. self._pins = (portSck, portMosi, portMiso)
  48. break
  49. else:
  50. raise NotImplementedError(
  51. "No Hardware SPI on (clock, MOSI, MISO)={}\nValid SPI ports:{}".
  52. format((clock, MOSI, MISO), spiPorts))
  53. def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
  54. if self._locked:
  55. from machine import Pin
  56. # TODO check if #init ignores MOSI=None rather than unsetting, to save _pinIds attribute
  57. self._spi.init(
  58. baudrate=baudrate,
  59. polarity=polarity,
  60. phase=phase,
  61. bits=bits,
  62. firstbit=SPI.MSB,
  63. sck=Pin(self._pins[0].id),
  64. mosi=Pin(self._pins[1].id),
  65. miso=Pin(self._pins[2].id)
  66. )
  67. else:
  68. raise RuntimeError("First call try_lock()")
  69. def deinit(self):
  70. self._spi = None
  71. self._pinIds = None
  72. def write(self, buf):
  73. return self._spi.write(buf)
  74. def readinto(self, buf):
  75. return self.readinto(buf)
  76. def write_readinto(self, buffer_out, buffer_in):
  77. return self.write_readinto(buffer_out, buffer_in)
  78. class UART(Lockable):
  79. class Parity(Enum):
  80. pass
  81. Parity.ODD = Parity()
  82. Parity.EVEN = Parity()
  83. def __init__(self,
  84. tx,
  85. rx,
  86. baudrate=9600,
  87. bits=8,
  88. parity=None,
  89. stop=1,
  90. timeout=1000,
  91. receiver_buffer_size=64,
  92. flow=None):
  93. from machine import UART as _UART
  94. from microcontroller.pin import uartPorts
  95. self.baudrate = baudrate
  96. if flow is not None: # default 0
  97. raise NotImplementedError(
  98. "Parameter '{}' unsupported on {}".format(
  99. "flow", agnostic.board))
  100. # translate parity flag for Micropython
  101. if parity is UART.Parity.ODD:
  102. parity = 1
  103. elif parity is UART.Parity.EVEN:
  104. parity = 0
  105. elif parity is None:
  106. pass
  107. else:
  108. raise ValueError("Invalid parity")
  109. # check tx and rx have hardware support
  110. for portId, portTx, portRx in uartPorts: #
  111. if portTx == tx and portRx == rx:
  112. self._uart = _UART(
  113. portId,
  114. baudrate,
  115. bits=bits,
  116. parity=parity,
  117. stop=stop,
  118. timeout=timeout,
  119. read_buf_len=receiver_buffer_size
  120. )
  121. break
  122. else:
  123. raise NotImplementedError(
  124. "No Hardware UART on (tx,rx)={}\nValid UART ports".format(
  125. (tx, rx), uartPorts))
  126. def deinit(self):
  127. self._uart = None
  128. def read(self, nbytes=None):
  129. return self._uart.read(nbytes)
  130. def readinto(self, buf, nbytes=None):
  131. return self._uart.readinto(buf, nbytes)
  132. def readline(self):
  133. return self._uart.readline()
  134. def write(self, buf):
  135. return self._uart.write(buf)