From f28f8ba56809fd56e777eabceae21127f95b89ed Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Mon, 10 Apr 2017 13:32:19 -0700 Subject: Split up nativeio. This was done to allow greatly granularity when deciding what functionality is built into each board's build. For example, this way pulseio can be omitted to allow for something else such as touchio. --- README.md | 2 +- atmel-samd/Makefile | 41 +- atmel-samd/common-hal/analogio/AnalogIn.c | 116 ++++++ atmel-samd/common-hal/analogio/AnalogIn.h | 49 +++ atmel-samd/common-hal/analogio/AnalogOut.c | 71 ++++ atmel-samd/common-hal/analogio/AnalogOut.h | 41 ++ atmel-samd/common-hal/analogio/__init__.c | 1 + atmel-samd/common-hal/busio/I2C.c | 198 ++++++++++ atmel-samd/common-hal/busio/I2C.h | 43 +++ atmel-samd/common-hal/busio/OneWire.h | 33 ++ atmel-samd/common-hal/busio/SPI.c | 231 +++++++++++ atmel-samd/common-hal/busio/SPI.h | 45 +++ atmel-samd/common-hal/busio/UART.c | 377 ++++++++++++++++++ atmel-samd/common-hal/busio/UART.h | 50 +++ atmel-samd/common-hal/busio/__init__.c | 1 + atmel-samd/common-hal/digitalio/DigitalInOut.c | 183 +++++++++ atmel-samd/common-hal/digitalio/DigitalInOut.h | 40 ++ atmel-samd/common-hal/digitalio/__init__.c | 1 + atmel-samd/common-hal/nativeio/AnalogIn.c | 116 ------ atmel-samd/common-hal/nativeio/AnalogIn.h | 32 -- atmel-samd/common-hal/nativeio/AnalogOut.c | 71 ---- atmel-samd/common-hal/nativeio/DigitalInOut.c | 183 --------- atmel-samd/common-hal/nativeio/DigitalInOut.h | 39 -- atmel-samd/common-hal/nativeio/I2C.c | 201 ---------- atmel-samd/common-hal/nativeio/PWMOut.c | 331 ---------------- atmel-samd/common-hal/nativeio/PWMOut.h | 32 -- atmel-samd/common-hal/nativeio/PulseIn.c | 220 ----------- atmel-samd/common-hal/nativeio/PulseIn.h | 32 -- atmel-samd/common-hal/nativeio/PulseOut.c | 163 -------- atmel-samd/common-hal/nativeio/PulseOut.h | 32 -- atmel-samd/common-hal/nativeio/SPI.c | 234 ------------ atmel-samd/common-hal/nativeio/TouchIn.c | 306 --------------- atmel-samd/common-hal/nativeio/TouchInStub.c | 45 --- atmel-samd/common-hal/nativeio/UART.c | 377 ------------------ atmel-samd/common-hal/nativeio/__init__.c | 1 - atmel-samd/common-hal/nativeio/types.h | 142 ------- atmel-samd/common-hal/neopixel_write/__init__.c | 3 +- atmel-samd/common-hal/pulseio/PWMOut.c | 331 ++++++++++++++++ atmel-samd/common-hal/pulseio/PWMOut.h | 49 +++ atmel-samd/common-hal/pulseio/PulseIn.c | 221 +++++++++++ atmel-samd/common-hal/pulseio/PulseIn.h | 49 +++ atmel-samd/common-hal/pulseio/PulseOut.c | 164 ++++++++ atmel-samd/common-hal/pulseio/PulseOut.h | 44 +++ atmel-samd/common-hal/pulseio/__init__.c | 1 + atmel-samd/common-hal/touchio/TouchIn.c | 306 +++++++++++++++ atmel-samd/common-hal/touchio/TouchIn.h | 42 ++ atmel-samd/common-hal/touchio/__init__.c | 1 + atmel-samd/main.c | 10 +- atmel-samd/mpconfigport.h | 12 +- atmel-samd/rgb_led_status.c | 8 +- docs/common_hal.md | 40 +- docs/design_guide.rst | 4 +- esp8266/Makefile | 28 +- esp8266/common-hal/analogio/AnalogIn.c | 60 +++ esp8266/common-hal/analogio/AnalogIn.h | 39 ++ esp8266/common-hal/analogio/AnalogOut.c | 46 +++ esp8266/common-hal/analogio/AnalogOut.h | 37 ++ esp8266/common-hal/analogio/__init__.c | 1 + esp8266/common-hal/busio/I2C.h | 33 ++ esp8266/common-hal/busio/OneWire.h | 33 ++ esp8266/common-hal/busio/SPI.c | 176 +++++++++ esp8266/common-hal/busio/SPI.h | 39 ++ esp8266/common-hal/busio/UART.c | 120 ++++++ esp8266/common-hal/busio/UART.h | 38 ++ esp8266/common-hal/busio/__init__.c | 1 + esp8266/common-hal/digitalio/DigitalInOut.c | 176 +++++++++ esp8266/common-hal/digitalio/DigitalInOut.h | 40 ++ esp8266/common-hal/digitalio/__init__.c | 1 + esp8266/common-hal/nativeio/AnalogIn.c | 60 --- esp8266/common-hal/nativeio/AnalogOut.c | 47 --- esp8266/common-hal/nativeio/DigitalInOut.c | 176 --------- esp8266/common-hal/nativeio/DigitalInOut.h | 39 -- esp8266/common-hal/nativeio/PWMOut.c | 118 ------ esp8266/common-hal/nativeio/PWMOut.h | 32 -- esp8266/common-hal/nativeio/PulseIn.c | 69 ---- esp8266/common-hal/nativeio/PulseOut.c | 42 -- esp8266/common-hal/nativeio/SPI.c | 176 --------- esp8266/common-hal/nativeio/TouchIn.c | 46 --- esp8266/common-hal/nativeio/UART.c | 120 ------ esp8266/common-hal/nativeio/__init__.c | 1 - esp8266/common-hal/nativeio/types.h | 78 ---- esp8266/common-hal/neopixel_write/__init__.c | 2 +- esp8266/common-hal/pulseio/PWMOut.c | 118 ++++++ esp8266/common-hal/pulseio/PWMOut.h | 40 ++ esp8266/common-hal/pulseio/PulseIn.c | 69 ++++ esp8266/common-hal/pulseio/PulseIn.h | 38 ++ esp8266/common-hal/pulseio/PulseOut.c | 42 ++ esp8266/common-hal/pulseio/PulseOut.h | 38 ++ esp8266/common-hal/pulseio/__init__.c | 1 + esp8266/esp_mphal.c | 2 +- esp8266/espuart.c | 281 ++++++++++++++ esp8266/espuart.h | 103 +++++ esp8266/machine_uart.c | 2 +- esp8266/main.c | 2 +- esp8266/modesp.c | 2 +- esp8266/mpconfigport.h | 10 +- esp8266/uart.c | 281 -------------- esp8266/uart.h | 103 ----- shared-bindings/analogio/AnalogIn.c | 164 ++++++++ shared-bindings/analogio/AnalogIn.h | 40 ++ shared-bindings/analogio/AnalogOut.c | 147 +++++++ shared-bindings/analogio/AnalogOut.h | 39 ++ shared-bindings/analogio/__init__.c | 84 ++++ shared-bindings/analogio/__init__.h | 34 ++ shared-bindings/bitbangio/OneWire.h | 6 +- shared-bindings/bitbangio/__init__.c | 11 +- shared-bindings/busio/I2C.c | 286 ++++++++++++++ shared-bindings/busio/I2C.h | 70 ++++ shared-bindings/busio/OneWire.c | 169 ++++++++ shared-bindings/busio/OneWire.h | 42 ++ shared-bindings/busio/SPI.c | 304 +++++++++++++++ shared-bindings/busio/SPI.h | 57 +++ shared-bindings/busio/UART.c | 290 ++++++++++++++ shared-bindings/busio/UART.h | 60 +++ shared-bindings/busio/__init__.c | 98 +++++ shared-bindings/busio/__init__.h | 34 ++ shared-bindings/digitalio/DigitalInOut.c | 486 ++++++++++++++++++++++++ shared-bindings/digitalio/DigitalInOut.h | 68 ++++ shared-bindings/digitalio/__init__.c | 95 +++++ shared-bindings/digitalio/__init__.h | 34 ++ shared-bindings/nativeio/AnalogIn.c | 164 -------- shared-bindings/nativeio/AnalogIn.h | 40 -- shared-bindings/nativeio/AnalogOut.c | 147 ------- shared-bindings/nativeio/AnalogOut.h | 39 -- shared-bindings/nativeio/DigitalInOut.c | 486 ------------------------ shared-bindings/nativeio/DigitalInOut.h | 68 ---- shared-bindings/nativeio/I2C.c | 286 -------------- shared-bindings/nativeio/I2C.h | 70 ---- shared-bindings/nativeio/OneWire.c | 169 -------- shared-bindings/nativeio/OneWire.h | 42 -- shared-bindings/nativeio/PWMOut.c | 221 ----------- shared-bindings/nativeio/PWMOut.h | 45 --- shared-bindings/nativeio/PulseIn.c | 285 -------------- shared-bindings/nativeio/PulseIn.h | 46 --- shared-bindings/nativeio/PulseOut.c | 150 -------- shared-bindings/nativeio/PulseOut.h | 41 -- shared-bindings/nativeio/SPI.c | 304 --------------- shared-bindings/nativeio/SPI.h | 57 --- shared-bindings/nativeio/TouchIn.c | 139 ------- shared-bindings/nativeio/TouchIn.h | 39 -- shared-bindings/nativeio/UART.c | 290 -------------- shared-bindings/nativeio/UART.h | 60 --- shared-bindings/nativeio/__init__.c | 140 ------- shared-bindings/nativeio/__init__.h | 34 -- shared-bindings/neopixel_write/__init__.c | 12 +- shared-bindings/neopixel_write/__init__.h | 4 +- shared-bindings/pulseio/PWMOut.c | 221 +++++++++++ shared-bindings/pulseio/PWMOut.h | 45 +++ shared-bindings/pulseio/PulseIn.c | 285 ++++++++++++++ shared-bindings/pulseio/PulseIn.h | 46 +++ shared-bindings/pulseio/PulseOut.c | 150 ++++++++ shared-bindings/pulseio/PulseOut.h | 42 ++ shared-bindings/pulseio/__init__.c | 87 +++++ shared-bindings/pulseio/__init__.h | 34 ++ shared-bindings/touchio/TouchIn.c | 139 +++++++ shared-bindings/touchio/TouchIn.h | 39 ++ shared-bindings/touchio/__init__.c | 82 ++++ shared-bindings/touchio/__init__.h | 34 ++ shared-bindings/usb_hid/Device.h | 6 +- shared-bindings/usb_hid/__init__.h | 2 - shared-module/bitbangio/I2C.c | 32 +- shared-module/bitbangio/OneWire.c | 24 +- shared-module/bitbangio/SPI.c | 56 +-- shared-module/bitbangio/types.h | 14 +- shared-module/busio/I2C.c | 66 ++++ shared-module/busio/I2C.h | 39 ++ shared-module/busio/OneWire.c | 52 +++ shared-module/busio/OneWire.h | 39 ++ shared-module/nativeio/I2C.c | 66 ---- shared-module/nativeio/I2C.h | 42 -- shared-module/nativeio/OneWire.c | 52 --- shared-module/nativeio/OneWire.h | 42 -- 172 files changed, 8442 insertions(+), 7661 deletions(-) create mode 100644 atmel-samd/common-hal/analogio/AnalogIn.c create mode 100644 atmel-samd/common-hal/analogio/AnalogIn.h create mode 100644 atmel-samd/common-hal/analogio/AnalogOut.c create mode 100644 atmel-samd/common-hal/analogio/AnalogOut.h create mode 100644 atmel-samd/common-hal/analogio/__init__.c create mode 100644 atmel-samd/common-hal/busio/I2C.c create mode 100644 atmel-samd/common-hal/busio/I2C.h create mode 100644 atmel-samd/common-hal/busio/OneWire.h create mode 100644 atmel-samd/common-hal/busio/SPI.c create mode 100644 atmel-samd/common-hal/busio/SPI.h create mode 100644 atmel-samd/common-hal/busio/UART.c create mode 100644 atmel-samd/common-hal/busio/UART.h create mode 100644 atmel-samd/common-hal/busio/__init__.c create mode 100644 atmel-samd/common-hal/digitalio/DigitalInOut.c create mode 100644 atmel-samd/common-hal/digitalio/DigitalInOut.h create mode 100644 atmel-samd/common-hal/digitalio/__init__.c delete mode 100644 atmel-samd/common-hal/nativeio/AnalogIn.c delete mode 100644 atmel-samd/common-hal/nativeio/AnalogIn.h delete mode 100644 atmel-samd/common-hal/nativeio/AnalogOut.c delete mode 100644 atmel-samd/common-hal/nativeio/DigitalInOut.c delete mode 100644 atmel-samd/common-hal/nativeio/DigitalInOut.h delete mode 100644 atmel-samd/common-hal/nativeio/I2C.c delete mode 100644 atmel-samd/common-hal/nativeio/PWMOut.c delete mode 100644 atmel-samd/common-hal/nativeio/PWMOut.h delete mode 100644 atmel-samd/common-hal/nativeio/PulseIn.c delete mode 100644 atmel-samd/common-hal/nativeio/PulseIn.h delete mode 100644 atmel-samd/common-hal/nativeio/PulseOut.c delete mode 100644 atmel-samd/common-hal/nativeio/PulseOut.h delete mode 100644 atmel-samd/common-hal/nativeio/SPI.c delete mode 100644 atmel-samd/common-hal/nativeio/TouchIn.c delete mode 100644 atmel-samd/common-hal/nativeio/TouchInStub.c delete mode 100644 atmel-samd/common-hal/nativeio/UART.c delete mode 100644 atmel-samd/common-hal/nativeio/__init__.c delete mode 100644 atmel-samd/common-hal/nativeio/types.h create mode 100644 atmel-samd/common-hal/pulseio/PWMOut.c create mode 100644 atmel-samd/common-hal/pulseio/PWMOut.h create mode 100644 atmel-samd/common-hal/pulseio/PulseIn.c create mode 100644 atmel-samd/common-hal/pulseio/PulseIn.h create mode 100644 atmel-samd/common-hal/pulseio/PulseOut.c create mode 100644 atmel-samd/common-hal/pulseio/PulseOut.h create mode 100644 atmel-samd/common-hal/pulseio/__init__.c create mode 100644 atmel-samd/common-hal/touchio/TouchIn.c create mode 100644 atmel-samd/common-hal/touchio/TouchIn.h create mode 100644 atmel-samd/common-hal/touchio/__init__.c create mode 100644 esp8266/common-hal/analogio/AnalogIn.c create mode 100644 esp8266/common-hal/analogio/AnalogIn.h create mode 100644 esp8266/common-hal/analogio/AnalogOut.c create mode 100644 esp8266/common-hal/analogio/AnalogOut.h create mode 100644 esp8266/common-hal/analogio/__init__.c create mode 100644 esp8266/common-hal/busio/I2C.h create mode 100644 esp8266/common-hal/busio/OneWire.h create mode 100644 esp8266/common-hal/busio/SPI.c create mode 100644 esp8266/common-hal/busio/SPI.h create mode 100644 esp8266/common-hal/busio/UART.c create mode 100644 esp8266/common-hal/busio/UART.h create mode 100644 esp8266/common-hal/busio/__init__.c create mode 100644 esp8266/common-hal/digitalio/DigitalInOut.c create mode 100644 esp8266/common-hal/digitalio/DigitalInOut.h create mode 100644 esp8266/common-hal/digitalio/__init__.c delete mode 100644 esp8266/common-hal/nativeio/AnalogIn.c delete mode 100644 esp8266/common-hal/nativeio/AnalogOut.c delete mode 100644 esp8266/common-hal/nativeio/DigitalInOut.c delete mode 100644 esp8266/common-hal/nativeio/DigitalInOut.h delete mode 100644 esp8266/common-hal/nativeio/PWMOut.c delete mode 100644 esp8266/common-hal/nativeio/PWMOut.h delete mode 100644 esp8266/common-hal/nativeio/PulseIn.c delete mode 100644 esp8266/common-hal/nativeio/PulseOut.c delete mode 100644 esp8266/common-hal/nativeio/SPI.c delete mode 100644 esp8266/common-hal/nativeio/TouchIn.c delete mode 100644 esp8266/common-hal/nativeio/UART.c delete mode 100644 esp8266/common-hal/nativeio/__init__.c delete mode 100644 esp8266/common-hal/nativeio/types.h create mode 100644 esp8266/common-hal/pulseio/PWMOut.c create mode 100644 esp8266/common-hal/pulseio/PWMOut.h create mode 100644 esp8266/common-hal/pulseio/PulseIn.c create mode 100644 esp8266/common-hal/pulseio/PulseIn.h create mode 100644 esp8266/common-hal/pulseio/PulseOut.c create mode 100644 esp8266/common-hal/pulseio/PulseOut.h create mode 100644 esp8266/common-hal/pulseio/__init__.c create mode 100644 esp8266/espuart.c create mode 100644 esp8266/espuart.h delete mode 100644 esp8266/uart.c delete mode 100644 esp8266/uart.h create mode 100644 shared-bindings/analogio/AnalogIn.c create mode 100644 shared-bindings/analogio/AnalogIn.h create mode 100644 shared-bindings/analogio/AnalogOut.c create mode 100644 shared-bindings/analogio/AnalogOut.h create mode 100644 shared-bindings/analogio/__init__.c create mode 100644 shared-bindings/analogio/__init__.h create mode 100644 shared-bindings/busio/I2C.c create mode 100644 shared-bindings/busio/I2C.h create mode 100644 shared-bindings/busio/OneWire.c create mode 100644 shared-bindings/busio/OneWire.h create mode 100644 shared-bindings/busio/SPI.c create mode 100644 shared-bindings/busio/SPI.h create mode 100644 shared-bindings/busio/UART.c create mode 100644 shared-bindings/busio/UART.h create mode 100644 shared-bindings/busio/__init__.c create mode 100644 shared-bindings/busio/__init__.h create mode 100644 shared-bindings/digitalio/DigitalInOut.c create mode 100644 shared-bindings/digitalio/DigitalInOut.h create mode 100644 shared-bindings/digitalio/__init__.c create mode 100644 shared-bindings/digitalio/__init__.h delete mode 100644 shared-bindings/nativeio/AnalogIn.c delete mode 100644 shared-bindings/nativeio/AnalogIn.h delete mode 100644 shared-bindings/nativeio/AnalogOut.c delete mode 100644 shared-bindings/nativeio/AnalogOut.h delete mode 100644 shared-bindings/nativeio/DigitalInOut.c delete mode 100644 shared-bindings/nativeio/DigitalInOut.h delete mode 100644 shared-bindings/nativeio/I2C.c delete mode 100644 shared-bindings/nativeio/I2C.h delete mode 100644 shared-bindings/nativeio/OneWire.c delete mode 100644 shared-bindings/nativeio/OneWire.h delete mode 100644 shared-bindings/nativeio/PWMOut.c delete mode 100644 shared-bindings/nativeio/PWMOut.h delete mode 100644 shared-bindings/nativeio/PulseIn.c delete mode 100644 shared-bindings/nativeio/PulseIn.h delete mode 100644 shared-bindings/nativeio/PulseOut.c delete mode 100644 shared-bindings/nativeio/PulseOut.h delete mode 100644 shared-bindings/nativeio/SPI.c delete mode 100644 shared-bindings/nativeio/SPI.h delete mode 100644 shared-bindings/nativeio/TouchIn.c delete mode 100644 shared-bindings/nativeio/TouchIn.h delete mode 100644 shared-bindings/nativeio/UART.c delete mode 100644 shared-bindings/nativeio/UART.h delete mode 100644 shared-bindings/nativeio/__init__.c delete mode 100644 shared-bindings/nativeio/__init__.h create mode 100644 shared-bindings/pulseio/PWMOut.c create mode 100644 shared-bindings/pulseio/PWMOut.h create mode 100644 shared-bindings/pulseio/PulseIn.c create mode 100644 shared-bindings/pulseio/PulseIn.h create mode 100644 shared-bindings/pulseio/PulseOut.c create mode 100644 shared-bindings/pulseio/PulseOut.h create mode 100644 shared-bindings/pulseio/__init__.c create mode 100644 shared-bindings/pulseio/__init__.h create mode 100644 shared-bindings/touchio/TouchIn.c create mode 100644 shared-bindings/touchio/TouchIn.h create mode 100644 shared-bindings/touchio/__init__.c create mode 100644 shared-bindings/touchio/__init__.h create mode 100644 shared-module/busio/I2C.c create mode 100644 shared-module/busio/I2C.h create mode 100644 shared-module/busio/OneWire.c create mode 100644 shared-module/busio/OneWire.h delete mode 100644 shared-module/nativeio/I2C.c delete mode 100644 shared-module/nativeio/I2C.h delete mode 100644 shared-module/nativeio/OneWire.c delete mode 100644 shared-module/nativeio/OneWire.h diff --git a/README.md b/README.md index d66d98b8f..1b35f4e2e 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ project admins. Please join the [Gitter chat](https://gitter.im/adafruit/circuit * Port for Atmel SAMD21 (Commonly known as M0 in product names.) * No `machine` API on Atmel SAMD21 port. * Only supports Atmel SAMD21 and ESP8266 ports. -* Unified hardware API: [`nativeio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/nativeio/__init__.html), [`microcontroller`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/microcontroller/__init__.html), [`board`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/__init__.html), [`bitbangio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/__init__.html) (Only available on atmel-samd21 and ESP8266 currently.) +* Unified hardware APIs: [`analogio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/analogio/__init__.html), [`busio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/busio/__init__.html), [`digitalio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/digitalio/__init__.html), [`pulseio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/pulseio/__init__.html), [`touchio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/touchio/__init__.html), [`microcontroller`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/microcontroller/__init__.html), [`board`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/board/__init__.html), [`bitbangio`](https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/__init__.html) (Only available on atmel-samd21 and ESP8266 currently.) * Tracks MicroPython's releases (not master). * No module aliasing. (`uos` and `utime` are not available as `os` and `time` respectively.) * Modules with a CPython counterpart, such as `time`, are strict [subsets](https://circuitpython.readthedocs.io/en/latest/shared-bindings/time/__init__.html) of their [CPython version](https://docs.python.org/3.4/library/time.html?highlight=time#module-time). Therefore, code from CircuitPython is runnable on CPython but not necessarily the reverse. diff --git a/atmel-samd/Makefile b/atmel-samd/Makefile index fb950a440..792e93081 100644 --- a/atmel-samd/Makefile +++ b/atmel-samd/Makefile @@ -221,41 +221,42 @@ SRC_BINDINGS = \ board/__init__.c \ microcontroller/__init__.c \ microcontroller/Pin.c \ - nativeio/__init__.c \ - nativeio/AnalogIn.c \ - nativeio/AnalogOut.c \ - nativeio/DigitalInOut.c \ - nativeio/I2C.c \ - nativeio/PulseIn.c \ - nativeio/PulseOut.c \ - nativeio/PWMOut.c \ - nativeio/SPI.c \ - nativeio/UART.c \ + analogio/__init__.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ + pulseio/__init__.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/PWMOut.c \ + busio/__init__.c \ + busio/I2C.c \ + busio/SPI.c \ + busio/UART.c \ neopixel_write/__init__.c \ time/__init__.c \ usb_hid/__init__.c \ usb_hid/Device.c -SRC_BINDINGS_EXPANDED = $(addprefix shared-bindings/, $(SRC_BINDINGS)) \ - $(addprefix common-hal/, $(SRC_BINDINGS)) - # Handle touch support on its own since it only fits in the image when external # flash is used to store the file system. -SRC_BINDINGS_EXPANDED += shared-bindings/nativeio/TouchIn.c - -ifeq ($(FLASH_IMPL),internal_flash.c) -SRC_BINDINGS_EXPANDED += common-hal/nativeio/TouchInStub.c -else -SRC_BINDINGS_EXPANDED += common-hal/nativeio/TouchIn.c +# TODO(tannewt): Remove this after we switch to freetouch and rely on the linker +# to drop classes we don't need. +ifneq ($(FLASH_IMPL),internal_flash.c) +SRC_BINDINGS += touchio/__init__.c touchio/TouchIn.c endif +SRC_BINDINGS_EXPANDED = $(addprefix shared-bindings/, $(SRC_BINDINGS)) \ + $(addprefix common-hal/, $(SRC_BINDINGS)) + SRC_SHARED_MODULE = \ help.c \ bitbangio/__init__.c \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ - nativeio/OneWire.c \ + busio/OneWire.c \ uheap/__init__.c \ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ diff --git a/atmel-samd/common-hal/analogio/AnalogIn.c b/atmel-samd/common-hal/analogio/AnalogIn.c new file mode 100644 index 000000000..59ea3b899 --- /dev/null +++ b/atmel-samd/common-hal/analogio/AnalogIn.c @@ -0,0 +1,116 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/analogio/AnalogIn.h" + +#include + +#include "py/gc.h" +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "shared-bindings/analogio/AnalogIn.h" + +#include "asf/sam0/drivers/adc/adc.h" +#include "samd21_pins.h" + +// Number of active ADC channels. +volatile uint8_t active_channel_count; +struct adc_module *adc_instance = NULL; + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, + const mcu_pin_obj_t *pin) { + if (!pin->has_adc) { + // No ADC function on that pin + mp_raise_ValueError("Pin does not have ADC capabilities"); + } + + self->pin = pin; + + if (adc_instance == NULL) { + struct adc_config config_adc; + adc_get_config_defaults(&config_adc); + + config_adc.reference = ADC_REFERENCE_INTVCC1; + config_adc.gain_factor = ADC_GAIN_FACTOR_DIV2; + config_adc.positive_input = self->pin->adc_input; + config_adc.resolution = ADC_RESOLUTION_16BIT; + config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV128; + + // Allocate the instance on the heap so we only use the memory when we + // need it. + adc_instance = gc_alloc(sizeof(struct adc_module), false); + + adc_init(adc_instance, ADC, &config_adc); + } + + self->adc_instance = adc_instance; + active_channel_count++; +} + +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t *self) { + active_channel_count--; + if (active_channel_count == 0) { + adc_reset(adc_instance); + gc_free(adc_instance); + // Set our reference to NULL so the GC doesn't mistakenly see the + // pointer in memory. + adc_instance = NULL; + } + reset_pin(self->pin->pin); +} + +void analogin_reset() { + if (adc_instance != NULL) { + adc_reset(adc_instance); + adc_instance = NULL; + } + active_channel_count = 0; +} + +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + adc_set_positive_input(adc_instance, self->pin->adc_input); + + adc_enable(adc_instance); + adc_start_conversion(adc_instance); + + uint16_t data; + enum status_code status = adc_read(adc_instance, &data); + while (status == STATUS_BUSY) { + status = adc_read(adc_instance, &data); + } + if (status == STATUS_ERR_OVERFLOW) { + // TODO(tannewt): Throw an error. + } + + adc_disable(adc_instance); + return data; +} + +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { + return 3.3f; +} diff --git a/atmel-samd/common-hal/analogio/AnalogIn.h b/atmel-samd/common-hal/analogio/AnalogIn.h new file mode 100644 index 000000000..78c7b82e8 --- /dev/null +++ b/atmel-samd/common-hal/analogio/AnalogIn.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H__ + +#include "common-hal/microcontroller/types.h" + +// Don't reorder these includes because they are dependencies of adc_feature.h. +// They should really be included by adc_feature.h. +#include +#include "asf/sam0/drivers/system/clock/gclk.h" +#include "asf/sam0/utils/cmsis/samd21/include/component/adc.h" +#include "asf/sam0/drivers/adc/adc_sam_d_r/adc_feature.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + struct adc_module * adc_instance; +} analogio_analogin_obj_t; + +void analogin_reset(void); + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGIN_H__ diff --git a/atmel-samd/common-hal/analogio/AnalogOut.c b/atmel-samd/common-hal/analogio/AnalogOut.c new file mode 100644 index 000000000..a618a6eeb --- /dev/null +++ b/atmel-samd/common-hal/analogio/AnalogOut.c @@ -0,0 +1,71 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/mperrno.h" +#include "py/runtime.h" + +#include "shared-bindings/analogio/AnalogOut.h" + +#include "asf/sam0/drivers/dac/dac.h" +#include "samd21_pins.h" + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, + const mcu_pin_obj_t *pin) { + if (pin->pin != PIN_PA02) { + mp_raise_ValueError("AnalogOut not supported on given pin"); + return; + } + struct dac_config config_dac; + dac_get_config_defaults(&config_dac); + config_dac.reference = DAC_REFERENCE_AVCC; + enum status_code status = dac_init(&self->dac_instance, DAC, &config_dac); + if (status != STATUS_OK) { + mp_raise_OSError(MP_EIO); + return; + } + + struct dac_chan_config config_analogout_chan; + dac_chan_get_config_defaults(&config_analogout_chan); + dac_chan_set_config(&self->dac_instance, DAC_CHANNEL_0, &config_analogout_chan); + dac_chan_enable(&self->dac_instance, DAC_CHANNEL_0); + + dac_enable(&self->dac_instance); +} + +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { + dac_disable(&self->dac_instance); + dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0); + reset_pin(PIN_PA02); +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { + // Input is 16 bit but we only support 10 bit so we shift the input. + dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, value >> 6); +} diff --git a/atmel-samd/common-hal/analogio/AnalogOut.h b/atmel-samd/common-hal/analogio/AnalogOut.h new file mode 100644 index 000000000..f74592d6a --- /dev/null +++ b/atmel-samd/common-hal/analogio/AnalogOut.h @@ -0,0 +1,41 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ + +#include "common-hal/microcontroller/types.h" + +#include "asf/sam0/drivers/dac/dac.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct dac_module dac_instance; +} analogio_analogout_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ diff --git a/atmel-samd/common-hal/analogio/__init__.c b/atmel-samd/common-hal/analogio/__init__.c new file mode 100644 index 000000000..eea58c77d --- /dev/null +++ b/atmel-samd/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/atmel-samd/common-hal/busio/I2C.c b/atmel-samd/common-hal/busio/I2C.c new file mode 100644 index 000000000..7b7c6a52c --- /dev/null +++ b/atmel-samd/common-hal/busio/I2C.c @@ -0,0 +1,198 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/busio/I2C.h" +#include "py/mperrno.h" +#include "py/nlr.h" +#include "py/runtime.h" + +#include "asf/sam0/drivers/sercom/i2c/i2c_master.h" +#include "samd21_pins.h" + +// We use ENABLE registers below we don't want to treat as a macro. +#undef ENABLE + +// Number of times to try to send packet if failed. +#define TIMEOUT 1 + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency) { + struct i2c_master_config config_i2c_master; + i2c_master_get_config_defaults(&config_i2c_master); + // Struct takes the argument in Khz not Hz. + config_i2c_master.baud_rate = frequency / 1000; + Sercom* sercom = NULL; + uint32_t sda_pinmux = 0; + uint32_t scl_pinmux = 0; + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + Sercom* potential_sercom = sda->sercom[i].sercom; + if (potential_sercom == NULL || + potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || + sda->sercom[i].pad != 0) { + continue; + } + sda_pinmux = PINMUX(sda->pin, (i == 0) ? MUX_C : MUX_D); + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (potential_sercom == scl->sercom[j].sercom && + scl->sercom[j].pad == 1) { + scl_pinmux = PINMUX(scl->pin, (j == 0) ? MUX_C : MUX_D); + sercom = potential_sercom; + break; + } + } + if (sercom != NULL) { + break; + } + } + if (sercom == NULL) { + mp_raise_ValueError("Invalid pins"); + } + + config_i2c_master.pinmux_pad0 = sda_pinmux; // SDA + config_i2c_master.pinmux_pad1 = scl_pinmux; // SCL + config_i2c_master.buffer_timeout = 10000; + + self->sda_pin = sda->pin; + self->scl_pin = scl->pin; + + enum status_code status = i2c_master_init(&self->i2c_master_instance, + sercom, &config_i2c_master); + + if (status != STATUS_OK) { + common_hal_busio_i2c_deinit(self); + if (status == STATUS_ERR_BAUDRATE_UNAVAILABLE) { + mp_raise_ValueError("Unsupported baudrate"); + } else { + mp_raise_OSError(MP_EIO); + } + } + + i2c_master_enable(&self->i2c_master_instance); +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + i2c_master_reset(&self->i2c_master_instance); + reset_pin(self->sda_pin); + reset_pin(self->scl_pin); +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + uint8_t buf; + struct i2c_master_packet packet = { + .address = addr, + .data_length = 0, + .data = &buf, + .ten_bit_address = false, + .high_speed = false, + .hs_master_code = 0x0, + }; + + enum status_code status = i2c_master_write_packet_wait( + &self->i2c_master_instance, &packet); + return status == STATUS_OK; +} + +void common_hal_busio_i2c_configure(busio_i2c_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + return; +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + self->has_lock = i2c_master_lock(&self->i2c_master_instance) == STATUS_OK; + return self->has_lock; +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + self->has_lock = false; + i2c_master_unlock(&self->i2c_master_instance); +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t *data, size_t len, bool transmit_stop_bit) { + struct i2c_master_packet packet = { + .address = addr, + .data_length = len, + .data = (uint8_t *) data, + .ten_bit_address = false, + .high_speed = false, + .hs_master_code = 0x0, + }; + + uint16_t timeout = 0; + enum status_code status = STATUS_BUSY; + while (status != STATUS_OK) { + if (transmit_stop_bit) { + status = i2c_master_write_packet_wait(&self->i2c_master_instance, + &packet); + } else { + status = i2c_master_write_packet_wait_no_stop( + &self->i2c_master_instance, &packet); + } + /* Increment timeout counter and check if timed out. */ + if (timeout++ == TIMEOUT) { + break; + } + } + if (status == STATUS_OK) { + return 0; + } else if (status == STATUS_ERR_BAD_ADDRESS) { + return MP_ENODEV; + } + return MP_EIO; +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t *data, size_t len) { + struct i2c_master_packet packet = { + .address = addr, + .data_length = len, + .data = data, + .ten_bit_address = false, + .high_speed = false, + .hs_master_code = 0x0, + }; + + uint16_t timeout = 0; + enum status_code status = STATUS_BUSY; + while (status != STATUS_OK) { + status = i2c_master_read_packet_wait(&self->i2c_master_instance, + &packet); + /* Increment timeout counter and check if timed out. */ + if (timeout++ == TIMEOUT) { + break; + } + } + if (status == STATUS_OK) { + return 0; + } else if (status == STATUS_ERR_BAD_ADDRESS) { + return MP_ENODEV; + } + return MP_EIO; +} diff --git a/atmel-samd/common-hal/busio/I2C.h b/atmel-samd/common-hal/busio/I2C.h new file mode 100644 index 000000000..8f09cb343 --- /dev/null +++ b/atmel-samd/common-hal/busio/I2C.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H__ + +#include "common-hal/microcontroller/types.h" + +#include "asf/sam0/drivers/sercom/i2c/i2c_master.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct i2c_master_module i2c_master_instance; + bool has_lock; + uint8_t scl_pin; + uint8_t sda_pin; +} busio_i2c_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_I2C_H__ diff --git a/atmel-samd/common-hal/busio/OneWire.h b/atmel-samd/common-hal/busio/OneWire.h new file mode 100644 index 000000000..8b61260fc --- /dev/null +++ b/atmel-samd/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H__ + +// Use bitbangio. +#include "shared-module/busio/OneWire.h" + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_ONEWIRE_H__ diff --git a/atmel-samd/common-hal/busio/SPI.c b/atmel-samd/common-hal/busio/SPI.c new file mode 100644 index 000000000..a7175f3d5 --- /dev/null +++ b/atmel-samd/common-hal/busio/SPI.c @@ -0,0 +1,231 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/busio/SPI.h" +#include "py/nlr.h" +#include "py/runtime.h" +#include "samd21_pins.h" + +// We use ENABLE registers below we don't want to treat as a macro. +#undef ENABLE + +// Number of times to try to send packet if failed. +#define TIMEOUT 1 + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + struct spi_config config_spi_master; + spi_get_config_defaults(&config_spi_master); + + Sercom* sercom = NULL; + uint32_t clock_pinmux = 0; + bool mosi_none = mosi == mp_const_none; + bool miso_none = miso == mp_const_none; + uint32_t mosi_pinmux = 0; + uint32_t miso_pinmux = 0; + uint8_t clock_pad = 0; + uint8_t mosi_pad = 0; + uint8_t miso_pad = 0; + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + Sercom* potential_sercom = clock->sercom[i].sercom; + if (potential_sercom == NULL || + potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { + continue; + } + clock_pinmux = PINMUX(clock->pin, (i == 0) ? MUX_C : MUX_D); + clock_pad = clock->sercom[i].pad; + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (!mosi_none) { + if(potential_sercom == mosi->sercom[j].sercom) { + mosi_pinmux = PINMUX(mosi->pin, (j == 0) ? MUX_C : MUX_D); + mosi_pad = mosi->sercom[j].pad; + if (miso_none) { + sercom = potential_sercom; + break; + } + } else { + continue; + } + } + if (!miso_none) { + for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { + if (potential_sercom == miso->sercom[k].sercom) { + miso_pinmux = PINMUX(miso->pin, (k == 0) ? MUX_C : MUX_D); + miso_pad = miso->sercom[k].pad; + sercom = potential_sercom; + break; + } + } + } + if (sercom != NULL) { + break; + } + } + if (sercom != NULL) { + break; + } + } + if (sercom == NULL) { + mp_raise_ValueError("Invalid pins"); + } + + // Depends on where MOSI and CLK are. + uint8_t dopo = 8; + if (clock_pad == 1) { + if (mosi_pad == 0) { + dopo = 0; + } else if (mosi_pad == 3) { + dopo = 2; + } + } else if (clock_pad == 3) { + if (mosi_pad == 0) { + dopo = 3; + } else if (mosi_pad == 2) { + dopo = 1; + } + } + if (dopo == 8) { + mp_raise_ValueError("MOSI and clock pins incompatible"); + } + + config_spi_master.mux_setting = (dopo << SERCOM_SPI_CTRLA_DOPO_Pos) | + (miso_pad << SERCOM_SPI_CTRLA_DIPO_Pos); + + // Map pad to pinmux through a short array. + uint32_t *pinmuxes[4] = {&config_spi_master.pinmux_pad0, + &config_spi_master.pinmux_pad1, + &config_spi_master.pinmux_pad2, + &config_spi_master.pinmux_pad3}; + *pinmuxes[clock_pad] = clock_pinmux; + self->clock_pin = clock->pin; + self->MOSI_pin = NO_PIN; + if (!mosi_none) { + *pinmuxes[mosi_pad] = mosi_pinmux; + self->MOSI_pin = mosi->pin; + } + self->MISO_pin = NO_PIN; + if (!miso_none) { + *pinmuxes[miso_pad] = miso_pinmux; + self->MISO_pin = miso->pin; + } + + // Always start at 250khz which is what SD cards need. They are sensitive to + // SPI bus noise before they are put into SPI mode. + self->current_baudrate = 250000; + config_spi_master.mode_specific.master.baudrate = self->current_baudrate; + + spi_init(&self->spi_master_instance, sercom, &config_spi_master); + + spi_enable(&self->spi_master_instance); +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + spi_disable(&self->spi_master_instance); + reset_pin(self->clock_pin); + reset_pin(self->MOSI_pin); + reset_pin(self->MISO_pin); +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + // TODO(tannewt): Check baudrate first before changing it. + if (baudrate != self->current_baudrate) { + enum status_code status = spi_set_baudrate(&self->spi_master_instance, baudrate); + if (status != STATUS_OK) { + return false; + } + } + + SercomSpi *const spi_module = &(self->spi_master_instance.hw->SPI); + // If the settings are already what we want then don't reset them. + if (spi_module->CTRLA.bit.CPHA == phase && + spi_module->CTRLA.bit.CPOL == polarity && + spi_module->CTRLB.bit.CHSIZE == (bits - 8)) { + return true; + } + + spi_disable(&self->spi_master_instance); + while (spi_is_syncing(&self->spi_master_instance)) { + /* Wait until the synchronization is complete */ + } + + spi_module->CTRLA.bit.CPHA = phase; + spi_module->CTRLA.bit.CPOL = polarity; + spi_module->CTRLB.bit.CHSIZE = bits - 8; + + while (spi_is_syncing(&self->spi_master_instance)) { + /* Wait until the synchronization is complete */ + } + + /* Enable the module */ + spi_enable(&self->spi_master_instance); + + while (spi_is_syncing(&self->spi_master_instance)) { + /* Wait until the synchronization is complete */ + } + + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + self->has_lock = spi_lock(&self->spi_master_instance) == STATUS_OK; + return self->has_lock; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->has_lock; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->has_lock = false; + spi_unlock(&self->spi_master_instance); +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t *data, size_t len) { + if (len == 0) { + return true; + } + enum status_code status = spi_write_buffer_wait( + &self->spi_master_instance, + data, + len); + return status == STATUS_OK; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t *data, size_t len, uint8_t write_value) { + if (len == 0) { + return true; + } + enum status_code status = spi_read_buffer_wait( + &self->spi_master_instance, + data, + len, + write_value); + return status == STATUS_OK; +} diff --git a/atmel-samd/common-hal/busio/SPI.h b/atmel-samd/common-hal/busio/SPI.h new file mode 100644 index 000000000..10dbe5734 --- /dev/null +++ b/atmel-samd/common-hal/busio/SPI.h @@ -0,0 +1,45 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H__ + +#include "common-hal/microcontroller/types.h" + +#include "asf/sam0/drivers/sercom/spi/spi.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct spi_module spi_master_instance; + bool has_lock; + uint8_t clock_pin; + uint8_t MOSI_pin; + uint8_t MISO_pin; + uint32_t current_baudrate; +} busio_spi_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_SPI_H__ diff --git a/atmel-samd/common-hal/busio/UART.c b/atmel-samd/common-hal/busio/UART.c new file mode 100644 index 000000000..8d39d5341 --- /dev/null +++ b/atmel-samd/common-hal/busio/UART.c @@ -0,0 +1,377 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" + +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/mperrno.h" +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/stream.h" +#include "samd21_pins.h" +#include "tick.h" + +#include "asf/sam0/drivers/sercom/sercom_interrupt.h" + +#undef ENABLE + +busio_uart_obj_t *_uart_instances[SERCOM_INST_NUM]; + +static void _sercom_default_handler( + const uint8_t instance) +{ + Assert(false); +} + +static void _busio_uart_interrupt_handler(uint8_t instance) +{ + /* Temporary variables */ + uint16_t interrupt_status; + uint8_t error_code; + + /* Get device instance from the look-up table */ + struct usart_module *module + = (struct usart_module *)_sercom_instances[instance]; + + busio_uart_obj_t *self = _uart_instances[instance]; + + /* Pointer to the hardware module instance */ + SercomUsart *const usart_hw = &(module->hw->USART); + + /* Wait for the synchronization to complete */ + _usart_wait_for_sync(module); + + /* Read and mask interrupt flag register */ + interrupt_status = usart_hw->INTFLAG.reg; + interrupt_status &= usart_hw->INTENSET.reg; + + /* Check if the Receive Complete interrupt has occurred, and that + * there's more data to receive */ + if (interrupt_status & SERCOM_USART_INTFLAG_RXC) { + /* Read out the status code and mask away all but the 4 LSBs*/ + error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK); + /* CTS status should not be considered as an error */ + if(error_code & SERCOM_USART_STATUS_CTS) { + error_code &= ~SERCOM_USART_STATUS_CTS; + } + /* Check if an error has occurred during the receiving */ + if (error_code) { + /* Check which error occurred */ + if (error_code & SERCOM_USART_STATUS_FERR) { + /* Store the error code and clear flag by writing 1 to it */ + usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR; + } else if (error_code & SERCOM_USART_STATUS_BUFOVF) { + /* Store the error code and clear flag by writing 1 to it */ + usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF; + } else if (error_code & SERCOM_USART_STATUS_PERR) { + /* Store the error code and clear flag by writing 1 to it */ + usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR; + } + self->rx_error = true; + } else { + /* Read current packet from DATA register, + * increment buffer pointer and decrement buffer length */ + uint16_t received_data = (usart_hw->DATA.reg & SERCOM_USART_DATA_MASK); + + common_hal_mcu_disable_interrupts(); + /* Read value will be at least 8-bits long */ + uint32_t buffer_end = (self->buffer_start + self->buffer_size) % self->buffer_length; + self->buffer[buffer_end] = received_data; + self->buffer_size++; + + if (module->character_size == USART_CHARACTER_SIZE_9BIT) { + /* 9-bit data, write next received byte to the buffer */ + self->buffer[buffer_end + 1] = (received_data >> 8); + self->buffer_size++; + } + + if (self->buffer_size > self->buffer_length) { + self->buffer_start++; + if (module->character_size == USART_CHARACTER_SIZE_9BIT) { + self->buffer_start++; + } + self->buffer_size = self->buffer_length; + } + common_hal_mcu_enable_interrupts(); + } + } +} + +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, + uint8_t receiver_buffer_size) { + Sercom* sercom = NULL; + uint32_t rx_pinmux = PINMUX_UNUSED; + uint8_t rx_pad = 5; // Unset pad + uint32_t tx_pinmux = PINMUX_UNUSED; + uint8_t tx_pad = 5; // Unset pad + for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { + Sercom* potential_sercom = NULL; + if (tx != NULL) { + potential_sercom = tx->sercom[i].sercom; + if (potential_sercom == NULL || + potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || + !(tx->sercom[i].pad == 0 || + tx->sercom[i].pad == 2)) { + continue; + } + tx_pinmux = PINMUX(tx->pin, (i == 0) ? MUX_C : MUX_D); + tx_pad = tx->sercom[i].pad; + if (rx == NULL) { + sercom = potential_sercom; + break; + } + } + for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { + if (((tx == NULL && rx->sercom[j].sercom->I2CM.CTRLA.bit.ENABLE == 0) || + potential_sercom == rx->sercom[j].sercom) && + rx->sercom[j].pad != tx_pad) { + rx_pinmux = PINMUX(rx->pin, (j == 0) ? MUX_C : MUX_D); + rx_pad = rx->sercom[j].pad; + sercom = rx->sercom[j].sercom; + break; + } + } + if (sercom != NULL) { + break; + } + } + if (sercom == NULL) { + mp_raise_ValueError("Invalid pins"); + } + if (tx == NULL) { + tx_pad = 0; + if (rx_pad == 0) { + tx_pad = 2; + } + } + if (rx == NULL) { + rx_pad = (tx_pad + 1) % 4; + } + struct usart_config config_usart; + usart_get_config_defaults(&config_usart); + config_usart.mux_setting = (SERCOM_USART_CTRLA_RXPO(rx_pad) | SERCOM_USART_CTRLA_TXPO(tx_pad / 2)); + + if (parity == PARITY_ODD) { + config_usart.parity = USART_PARITY_ODD; + } else if (parity == PARITY_EVEN) { + config_usart.parity = USART_PARITY_EVEN; + } + config_usart.stopbits = stop - 1; + config_usart.character_size = bits % 8; + config_usart.baudrate = baudrate; + + // Map pad to pinmux through a short array. + uint32_t *pinmuxes[4] = {&config_usart.pinmux_pad0, + &config_usart.pinmux_pad1, + &config_usart.pinmux_pad2, + &config_usart.pinmux_pad3}; + // Pin muxes have a default pin, set them to unused so that no other pins are changed. + for (int i = 0; i < 4; i++) { + *pinmuxes[i] = PINMUX_UNUSED; + } + + self->rx_pin = NO_PIN; + config_usart.receiver_enable = rx != NULL; + if (rx != NULL) { + *pinmuxes[rx_pad] = rx_pinmux; + self->rx_pin = rx->pin; + } + + self->tx_pin = NO_PIN; + config_usart.transmitter_enable = tx != NULL; + if (tx != NULL) { + *pinmuxes[tx_pad] = tx_pinmux; + self->tx_pin = tx->pin; + } + + self->timeout_ms = timeout; + + self->buffer_length = receiver_buffer_size; + self->buffer_length *= (bits + 7) / 8; + self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false); + if (self->buffer == NULL) { + mp_raise_msg(&mp_type_MemoryError, "Failed to allocate RX buffer"); + } + + if (usart_init(&self->uart_instance, sercom, &config_usart) != STATUS_OK) { + mp_raise_OSError(MP_EIO); + } + + // We use our own interrupt handler because we want a circular buffer + // instead of the jobs that ASF provides. + uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw); + _sercom_set_handler(instance_index, _busio_uart_interrupt_handler); + _sercom_instances[instance_index] = &self->uart_instance; + _uart_instances[instance_index] = self; + + /* Enable Global interrupt for module */ + system_interrupt_enable(_sercom_get_interrupt_vector(self->uart_instance.hw)); + + usart_enable(&self->uart_instance); + self->uart_instance.hw->USART.INTENSET.bit.RXC = true; +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + self->uart_instance.hw->USART.INTENCLR.bit.RXC = true; + + uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw); + _sercom_set_handler(instance_index, &_sercom_default_handler); + _sercom_instances[instance_index] = NULL; + _uart_instances[instance_index] = NULL; + + system_interrupt_disable(_sercom_get_interrupt_vector(self->uart_instance.hw)); + + usart_disable(&self->uart_instance); + reset_pin(self->rx_pin); + reset_pin(self->tx_pin); +} + +// Read characters. +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + size_t total_read = 0; + uint64_t start_ticks = ticks_ms; + while (total_read < len && ticks_ms - start_ticks < self->timeout_ms) { + if (self->buffer_size > 0) { + common_hal_mcu_disable_interrupts(); + data[total_read] = self->buffer[self->buffer_start]; + if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { + data[total_read + 1] = self->buffer[self->buffer_start + 1]; + self->buffer_start += 2; + self->buffer_size -= 2; + } else { + self->buffer_start++; + self->buffer_size--; + } + self->buffer_start = self->buffer_start % self->buffer_length; + common_hal_mcu_enable_interrupts(); + // Reset the timeout every character read. + total_read++; + start_ticks = ticks_ms; + } + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + if (total_read == 0) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + return total_read; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + /* Check that the transmitter is enabled */ + if (!(self->uart_instance.transmitter_enabled)) { + *errcode = MP_EIO; + return MP_STREAM_ERROR; + } + + /* Get a pointer to the hardware module instance */ + SercomUsart *const usart_hw = &(self->uart_instance.hw->USART); + + /* Wait until synchronization is complete */ + _usart_wait_for_sync(&self->uart_instance); + + uint16_t tx_pos = 0; + + bool ok = true; + uint64_t start_ticks = 0; + /* Blocks while buffer is being transferred */ + while (len--) { + /* Wait for the USART to be ready for new data and abort + * operation if it doesn't get ready within the timeout*/ + ok = false; + start_ticks = ticks_ms; + while (ticks_ms - start_ticks < self->timeout_ms) { + if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) { + ok = true; + break; + } + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + + if (!ok) { + break; + } + + /* Data to send is at least 8 bits long */ + uint16_t data_to_send = data[tx_pos++]; + + /* Check if the character size exceeds 8 bit */ + if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { + data_to_send |= (data[tx_pos++] << 8); + } + + /* Send the data through the USART module */ + + enum status_code status = usart_write_wait(&self->uart_instance, data_to_send); + if (status != STATUS_OK) { + ok = false; + } + } + + /* Wait until Transmit is complete or timeout */ + if (ok) { + ok = false; + start_ticks = ticks_ms; + while (ticks_ms - start_ticks < self->timeout_ms) { + if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) { + ok = true; + break; + } + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + } + + if (!ok && tx_pos == 0) { + *errcode = MP_EAGAIN; + return MP_STREAM_ERROR; + } + return tx_pos; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { + return self->buffer_size / 2; + } + return self->buffer_size; +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + if (!(self->uart_instance.transmitter_enabled)) { + return false; + } + return self->uart_instance.hw->USART.INTFLAG.bit.DRE; +} diff --git a/atmel-samd/common-hal/busio/UART.h b/atmel-samd/common-hal/busio/UART.h new file mode 100644 index 000000000..d9a001de4 --- /dev/null +++ b/atmel-samd/common-hal/busio/UART.h @@ -0,0 +1,50 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H__ + +#include "common-hal/microcontroller/types.h" + +#include "asf/sam0/drivers/sercom/usart/usart.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + struct usart_module uart_instance; + uint8_t rx_pin; + uint8_t tx_pin; + uint32_t timeout_ms; + bool rx_error; + // Index of the oldest received character. + uint32_t buffer_start; + // Index of the next available spot to store a character. + uint32_t buffer_size; + uint32_t buffer_length; + uint8_t* buffer; +} busio_uart_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_BUSIO_UART_H__ diff --git a/atmel-samd/common-hal/busio/__init__.c b/atmel-samd/common-hal/busio/__init__.c new file mode 100644 index 000000000..41761b674 --- /dev/null +++ b/atmel-samd/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/atmel-samd/common-hal/digitalio/DigitalInOut.c b/atmel-samd/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 000000000..391bf8992 --- /dev/null +++ b/atmel-samd/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,183 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "asf/sam0/drivers/port/port.h" +#include "asf/sam0/drivers/system/pinmux/pinmux.h" + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { + self->pin = pin; + + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_INPUT; + pin_conf.input_pull = PORT_PIN_PULL_NONE; + port_pin_set_config(self->pin->pin, &pin_conf); + return DIGITALINOUT_OK; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.powersave = true; + port_pin_set_config(self->pin->pin, &pin_conf); +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { + self->output = false; + + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t* self, bool value, + enum digitalinout_drive_mode_t drive_mode) { + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_INPUT; + pin_conf.input_pull = PORT_PIN_PULL_NONE; + port_pin_set_config(self->pin->pin, &pin_conf); + + self->output = true; + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + common_hal_digitalio_digitalinout_set_value(self, value); +} + +enum digitalinout_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t* self) { + return self->output? DIRECTION_OUT : DIRECTION_IN; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t* self, bool value) { + uint32_t pin = self->pin->pin; + PortGroup *const port_base = port_get_group_from_gpio_pin(pin); + uint32_t pin_mask = (1UL << (pin % 32)); + + /* Set the pin to high or low atomically based on the requested level */ + if (value) { + if (self->open_drain) { + port_base->DIRCLR.reg = pin_mask; + } else { + port_base->DIRSET.reg = pin_mask; + port_base->OUTSET.reg = pin_mask; + } + } else { + port_base->DIRSET.reg = pin_mask; + port_base->OUTCLR.reg = pin_mask; + } +} + +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t* self) { + uint32_t pin = self->pin->pin; + PortGroup *const port_base = port_get_group_from_gpio_pin(pin); + uint32_t pin_mask = (1UL << (pin % 32)); + if (!self->output) { + return (port_base->IN.reg & pin_mask); + } else { + if (self->open_drain && (port_base->DIR.reg & pin_mask) == 0) { + return true; + } else { + return (port_base->OUT.reg & pin_mask); + } + } +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t* self, + enum digitalinout_drive_mode_t drive_mode) { + bool value = common_hal_digitalio_digitalinout_get_value(self); + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + // True is implemented differently between modes so reset the value to make + // sure its correct for the new mode. + if (value) { + common_hal_digitalio_digitalinout_set_value(self, value); + } +} + +enum digitalinout_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t* self) { + if (self->open_drain) { + return DRIVE_MODE_OPEN_DRAIN; + } else { + return DRIVE_MODE_PUSH_PULL; + } +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { + enum port_pin_pull asf_pull = PORT_PIN_PULL_NONE; + switch (pull) { + case PULL_UP: + asf_pull = PORT_PIN_PULL_UP; + break; + case PULL_DOWN: + asf_pull = PORT_PIN_PULL_DOWN; + break; + case PULL_NONE: + default: + break; + } + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_INPUT; + pin_conf.input_pull = asf_pull; + port_pin_set_config(self->pin->pin, &pin_conf); +} + +enum digitalinout_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t* self) { + uint32_t pin = self->pin->pin; + PortGroup *const port_base = port_get_group_from_gpio_pin(pin); + uint32_t pin_mask = (1UL << (pin % 32)); + if (self->output) { + mp_raise_AttributeError("Cannot get pull while in output mode"); + return PULL_NONE; + } else { + if (port_base->PINCFG[pin % 32].bit.PULLEN == 0) { + return PULL_NONE; + } if ((port_base->OUT.reg & pin_mask) > 0) { + return PULL_UP; + } else { + return PULL_DOWN; + } + } +} diff --git a/atmel-samd/common-hal/digitalio/DigitalInOut.h b/atmel-samd/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 000000000..1490765ab --- /dev/null +++ b/atmel-samd/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + bool output; + bool open_drain; +} digitalio_digitalinout_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ diff --git a/atmel-samd/common-hal/digitalio/__init__.c b/atmel-samd/common-hal/digitalio/__init__.c new file mode 100644 index 000000000..20fad4595 --- /dev/null +++ b/atmel-samd/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/atmel-samd/common-hal/nativeio/AnalogIn.c b/atmel-samd/common-hal/nativeio/AnalogIn.c deleted file mode 100644 index 2203fc2ca..000000000 --- a/atmel-samd/common-hal/nativeio/AnalogIn.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "common-hal/nativeio/AnalogIn.h" - -#include - -#include "py/gc.h" -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "shared-bindings/nativeio/AnalogIn.h" - -#include "asf/sam0/drivers/adc/adc.h" -#include "samd21_pins.h" - -// Number of active ADC channels. -volatile uint8_t active_channel_count; -struct adc_module *adc_instance = NULL; - -void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, - const mcu_pin_obj_t *pin) { - if (!pin->has_adc) { - // No ADC function on that pin - mp_raise_ValueError("Pin does not have ADC capabilities"); - } - - self->pin = pin; - - if (adc_instance == NULL) { - struct adc_config config_adc; - adc_get_config_defaults(&config_adc); - - config_adc.reference = ADC_REFERENCE_INTVCC1; - config_adc.gain_factor = ADC_GAIN_FACTOR_DIV2; - config_adc.positive_input = self->pin->adc_input; - config_adc.resolution = ADC_RESOLUTION_16BIT; - config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV128; - - // Allocate the instance on the heap so we only use the memory when we - // need it. - adc_instance = gc_alloc(sizeof(struct adc_module), false); - - adc_init(adc_instance, ADC, &config_adc); - } - - self->adc_instance = adc_instance; - active_channel_count++; -} - -void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t *self) { - active_channel_count--; - if (active_channel_count == 0) { - adc_reset(adc_instance); - gc_free(adc_instance); - // Set our reference to NULL so the GC doesn't mistakenly see the - // pointer in memory. - adc_instance = NULL; - } - reset_pin(self->pin->pin); -} - -void analogin_reset() { - if (adc_instance != NULL) { - adc_reset(adc_instance); - adc_instance = NULL; - } - active_channel_count = 0; -} - -uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self) { - adc_set_positive_input(adc_instance, self->pin->adc_input); - - adc_enable(adc_instance); - adc_start_conversion(adc_instance); - - uint16_t data; - enum status_code status = adc_read(adc_instance, &data); - while (status == STATUS_BUSY) { - status = adc_read(adc_instance, &data); - } - if (status == STATUS_ERR_OVERFLOW) { - // TODO(tannewt): Throw an error. - } - - adc_disable(adc_instance); - return data; -} - -float common_hal_nativeio_analogin_get_reference_voltage(nativeio_analogin_obj_t *self) { - return 3.3f; -} diff --git a/atmel-samd/common-hal/nativeio/AnalogIn.h b/atmel-samd/common-hal/nativeio/AnalogIn.h deleted file mode 100644 index d975f6cb4..000000000 --- a/atmel-samd/common-hal/nativeio/AnalogIn.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_ANALOGIN_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_ANALOGIN_H__ - -void analogin_reset(void); - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_ANALOGIN_H__ diff --git a/atmel-samd/common-hal/nativeio/AnalogOut.c b/atmel-samd/common-hal/nativeio/AnalogOut.c deleted file mode 100644 index f36da1974..000000000 --- a/atmel-samd/common-hal/nativeio/AnalogOut.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "py/mperrno.h" -#include "py/runtime.h" - -#include "shared-bindings/nativeio/AnalogOut.h" - -#include "asf/sam0/drivers/dac/dac.h" -#include "samd21_pins.h" - -void common_hal_nativeio_analogout_construct(nativeio_analogout_obj_t* self, - const mcu_pin_obj_t *pin) { - if (pin->pin != PIN_PA02) { - mp_raise_ValueError("AnalogOut not supported on given pin"); - return; - } - struct dac_config config_dac; - dac_get_config_defaults(&config_dac); - config_dac.reference = DAC_REFERENCE_AVCC; - enum status_code status = dac_init(&self->dac_instance, DAC, &config_dac); - if (status != STATUS_OK) { - mp_raise_OSError(MP_EIO); - return; - } - - struct dac_chan_config config_analogout_chan; - dac_chan_get_config_defaults(&config_analogout_chan); - dac_chan_set_config(&self->dac_instance, DAC_CHANNEL_0, &config_analogout_chan); - dac_chan_enable(&self->dac_instance, DAC_CHANNEL_0); - - dac_enable(&self->dac_instance); -} - -void common_hal_nativeio_analogout_deinit(nativeio_analogout_obj_t *self) { - dac_disable(&self->dac_instance); - dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0); - reset_pin(PIN_PA02); -} - -void common_hal_nativeio_analogout_set_value(nativeio_analogout_obj_t *self, - uint16_t value) { - // Input is 16 bit but we only support 10 bit so we shift the input. - dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, value >> 6); -} diff --git a/atmel-samd/common-hal/nativeio/DigitalInOut.c b/atmel-samd/common-hal/nativeio/DigitalInOut.c deleted file mode 100644 index e09b5af17..000000000 --- a/atmel-samd/common-hal/nativeio/DigitalInOut.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/mphal.h" - -#include "shared-bindings/nativeio/DigitalInOut.h" - -#include "asf/sam0/drivers/port/port.h" -#include "asf/sam0/drivers/system/pinmux/pinmux.h" - -digitalinout_result_t common_hal_nativeio_digitalinout_construct( - nativeio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { - self->pin = pin; - - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_INPUT; - pin_conf.input_pull = PORT_PIN_PULL_NONE; - port_pin_set_config(self->pin->pin, &pin_conf); - return DIGITALINOUT_OK; -} - -void common_hal_nativeio_digitalinout_deinit(nativeio_digitalinout_obj_t* self) { - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.powersave = true; - port_pin_set_config(self->pin->pin, &pin_conf); -} - -void common_hal_nativeio_digitalinout_switch_to_input( - nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { - self->output = false; - - common_hal_nativeio_digitalinout_set_pull(self, pull); -} - -void common_hal_nativeio_digitalinout_switch_to_output( - nativeio_digitalinout_obj_t* self, bool value, - enum digitalinout_drive_mode_t drive_mode) { - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_INPUT; - pin_conf.input_pull = PORT_PIN_PULL_NONE; - port_pin_set_config(self->pin->pin, &pin_conf); - - self->output = true; - self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; - common_hal_nativeio_digitalinout_set_value(self, value); -} - -enum digitalinout_direction_t common_hal_nativeio_digitalinout_get_direction( - nativeio_digitalinout_obj_t* self) { - return self->output? DIRECTION_OUT : DIRECTION_IN; -} - -void common_hal_nativeio_digitalinout_set_value( - nativeio_digitalinout_obj_t* self, bool value) { - uint32_t pin = self->pin->pin; - PortGroup *const port_base = port_get_group_from_gpio_pin(pin); - uint32_t pin_mask = (1UL << (pin % 32)); - - /* Set the pin to high or low atomically based on the requested level */ - if (value) { - if (self->open_drain) { - port_base->DIRCLR.reg = pin_mask; - } else { - port_base->DIRSET.reg = pin_mask; - port_base->OUTSET.reg = pin_mask; - } - } else { - port_base->DIRSET.reg = pin_mask; - port_base->OUTCLR.reg = pin_mask; - } -} - -bool common_hal_nativeio_digitalinout_get_value( - nativeio_digitalinout_obj_t* self) { - uint32_t pin = self->pin->pin; - PortGroup *const port_base = port_get_group_from_gpio_pin(pin); - uint32_t pin_mask = (1UL << (pin % 32)); - if (!self->output) { - return (port_base->IN.reg & pin_mask); - } else { - if (self->open_drain && (port_base->DIR.reg & pin_mask) == 0) { - return true; - } else { - return (port_base->OUT.reg & pin_mask); - } - } -} - -void common_hal_nativeio_digitalinout_set_drive_mode( - nativeio_digitalinout_obj_t* self, - enum digitalinout_drive_mode_t drive_mode) { - bool value = common_hal_nativeio_digitalinout_get_value(self); - self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; - // True is implemented differently between modes so reset the value to make - // sure its correct for the new mode. - if (value) { - common_hal_nativeio_digitalinout_set_value(self, value); - } -} - -enum digitalinout_drive_mode_t common_hal_nativeio_digitalinout_get_drive_mode( - nativeio_digitalinout_obj_t* self) { - if (self->open_drain) { - return DRIVE_MODE_OPEN_DRAIN; - } else { - return DRIVE_MODE_PUSH_PULL; - } -} - -void common_hal_nativeio_digitalinout_set_pull( - nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { - enum port_pin_pull asf_pull = PORT_PIN_PULL_NONE; - switch (pull) { - case PULL_UP: - asf_pull = PORT_PIN_PULL_UP; - break; - case PULL_DOWN: - asf_pull = PORT_PIN_PULL_DOWN; - break; - case PULL_NONE: - default: - break; - } - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_INPUT; - pin_conf.input_pull = asf_pull; - port_pin_set_config(self->pin->pin, &pin_conf); -} - -enum digitalinout_pull_t common_hal_nativeio_digitalinout_get_pull( - nativeio_digitalinout_obj_t* self) { - uint32_t pin = self->pin->pin; - PortGroup *const port_base = port_get_group_from_gpio_pin(pin); - uint32_t pin_mask = (1UL << (pin % 32)); - if (self->output) { - mp_raise_AttributeError("Cannot get pull while in output mode"); - return PULL_NONE; - } else { - if (port_base->PINCFG[pin % 32].bit.PULLEN == 0) { - return PULL_NONE; - } if ((port_base->OUT.reg & pin_mask) > 0) { - return PULL_UP; - } else { - return PULL_DOWN; - } - } -} diff --git a/atmel-samd/common-hal/nativeio/DigitalInOut.h b/atmel-samd/common-hal/nativeio/DigitalInOut.h deleted file mode 100644 index f517e0d5b..000000000 --- a/atmel-samd/common-hal/nativeio/DigitalInOut.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - const mcu_pin_obj_t * pin; - bool output; - bool open_drain; -} nativeio_digitalinout_obj_t; - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ diff --git a/atmel-samd/common-hal/nativeio/I2C.c b/atmel-samd/common-hal/nativeio/I2C.c deleted file mode 100644 index fb5e76505..000000000 --- a/atmel-samd/common-hal/nativeio/I2C.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - // This file contains all of the port specific HAL functions for the machine - // module. - -#include "shared-bindings/nativeio/I2C.h" -#include "py/mperrno.h" -#include "py/nlr.h" -#include "py/runtime.h" - -#include "asf/sam0/drivers/sercom/i2c/i2c_master.h" -#include "samd21_pins.h" - -// We use ENABLE registers below we don't want to treat as a macro. -#undef ENABLE - -// Number of times to try to send packet if failed. -#define TIMEOUT 1 - -void common_hal_nativeio_i2c_construct(nativeio_i2c_obj_t *self, - const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t frequency) { - struct i2c_master_config config_i2c_master; - i2c_master_get_config_defaults(&config_i2c_master); - // Struct takes the argument in Khz not Hz. - config_i2c_master.baud_rate = frequency / 1000; - Sercom* sercom = NULL; - uint32_t sda_pinmux = 0; - uint32_t scl_pinmux = 0; - for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { - Sercom* potential_sercom = sda->sercom[i].sercom; - if (potential_sercom == NULL || - potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || - sda->sercom[i].pad != 0) { - continue; - } - sda_pinmux = PINMUX(sda->pin, (i == 0) ? MUX_C : MUX_D); - for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (potential_sercom == scl->sercom[j].sercom && - scl->sercom[j].pad == 1) { - scl_pinmux = PINMUX(scl->pin, (j == 0) ? MUX_C : MUX_D); - sercom = potential_sercom; - break; - } - } - if (sercom != NULL) { - break; - } - } - if (sercom == NULL) { - mp_raise_ValueError("Invalid pins"); - } - - config_i2c_master.pinmux_pad0 = sda_pinmux; // SDA - config_i2c_master.pinmux_pad1 = scl_pinmux; // SCL - config_i2c_master.buffer_timeout = 10000; - - self->sda_pin = sda->pin; - self->scl_pin = scl->pin; - - enum status_code status = i2c_master_init(&self->i2c_master_instance, - sercom, &config_i2c_master); - - if (status != STATUS_OK) { - common_hal_nativeio_i2c_deinit(self); - if (status == STATUS_ERR_BAUDRATE_UNAVAILABLE) { - mp_raise_ValueError("Unsupported baudrate"); - } else { - mp_raise_OSError(MP_EIO); - } - } - - i2c_master_enable(&self->i2c_master_instance); -} - -void common_hal_nativeio_i2c_deinit(nativeio_i2c_obj_t *self) { - i2c_master_reset(&self->i2c_master_instance); - reset_pin(self->sda_pin); - reset_pin(self->scl_pin); -} - -bool common_hal_nativeio_i2c_probe(nativeio_i2c_obj_t *self, uint8_t addr) { - uint8_t buf; - struct i2c_master_packet packet = { - .address = addr, - .data_length = 0, - .data = &buf, - .ten_bit_address = false, - .high_speed = false, - .hs_master_code = 0x0, - }; - - enum status_code status = i2c_master_write_packet_wait( - &self->i2c_master_instance, &packet); - return status == STATUS_OK; -} - -void common_hal_nativeio_i2c_configure(nativeio_i2c_obj_t *self, - uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - return; -} - -bool common_hal_nativeio_i2c_try_lock(nativeio_i2c_obj_t *self) { - self->has_lock = i2c_master_lock(&self->i2c_master_instance) == STATUS_OK; - return self->has_lock; -} - -bool common_hal_nativeio_i2c_has_lock(nativeio_i2c_obj_t *self) { - return self->has_lock; -} - -void common_hal_nativeio_i2c_unlock(nativeio_i2c_obj_t *self) { - self->has_lock = false; - i2c_master_unlock(&self->i2c_master_instance); -} - -uint8_t common_hal_nativeio_i2c_write(nativeio_i2c_obj_t *self, uint16_t addr, - const uint8_t *data, size_t len, bool transmit_stop_bit) { - struct i2c_master_packet packet = { - .address = addr, - .data_length = len, - .data = (uint8_t *) data, - .ten_bit_address = false, - .high_speed = false, - .hs_master_code = 0x0, - }; - - uint16_t timeout = 0; - enum status_code status = STATUS_BUSY; - while (status != STATUS_OK) { - if (transmit_stop_bit) { - status = i2c_master_write_packet_wait(&self->i2c_master_instance, - &packet); - } else { - status = i2c_master_write_packet_wait_no_stop( - &self->i2c_master_instance, &packet); - } - /* Increment timeout counter and check if timed out. */ - if (timeout++ == TIMEOUT) { - break; - } - } - if (status == STATUS_OK) { - return 0; - } else if (status == STATUS_ERR_BAD_ADDRESS) { - return MP_ENODEV; - } - return MP_EIO; -} - -uint8_t common_hal_nativeio_i2c_read(nativeio_i2c_obj_t *self, uint16_t addr, - uint8_t *data, size_t len) { - struct i2c_master_packet packet = { - .address = addr, - .data_length = len, - .data = data, - .ten_bit_address = false, - .high_speed = false, - .hs_master_code = 0x0, - }; - - uint16_t timeout = 0; - enum status_code status = STATUS_BUSY; - while (status != STATUS_OK) { - status = i2c_master_read_packet_wait(&self->i2c_master_instance, - &packet); - /* Increment timeout counter and check if timed out. */ - if (timeout++ == TIMEOUT) { - break; - } - } - if (status == STATUS_OK) { - return 0; - } else if (status == STATUS_ERR_BAD_ADDRESS) { - return MP_ENODEV; - } - return MP_EIO; -} diff --git a/atmel-samd/common-hal/nativeio/PWMOut.c b/atmel-samd/common-hal/nativeio/PWMOut.c deleted file mode 100644 index 73d83163a..000000000 --- a/atmel-samd/common-hal/nativeio/PWMOut.c +++ /dev/null @@ -1,331 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "py/runtime.h" -#include "common-hal/nativeio/PWMOut.h" -#include "shared-bindings/nativeio/PWMOut.h" - -#include "samd21_pins.h" - -#undef ENABLE - -uint32_t target_timer_frequencies[TC_INST_NUM + TCC_INST_NUM]; -uint8_t timer_refcount[TC_INST_NUM + TCC_INST_NUM]; -const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024}; - -// This bitmask keeps track of which channels of a TCC are currently claimed. -uint8_t tcc_channels[3] = {0xf0, 0xfc, 0xfc}; - -void pwmout_reset(void) { - // Reset all but TC5 - for (int i = 0; i < TC_INST_NUM + TCC_INST_NUM; i++) { - if (i == 5) { - target_timer_frequencies[i] = 1000; - timer_refcount[i] = 1; - } else { - target_timer_frequencies[i] = 0; - timer_refcount[i] = 0; - } - } - Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; - for (int i = 0; i < TCC_INST_NUM; i++) { - tccs[i]->CTRLA.bit.SWRST = 1; - } - Tc *tcs[TC_INST_NUM] = TC_INSTS; - for (int i = 0; i < TC_INST_NUM; i++) { - if (tcs[i] == TC5) { - continue; - } - tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; - } -} - -bool channel_ok(const pin_timer_t* t, uint8_t index) { - return (!t->is_tc && (tcc_channels[index] & (1 << t->channel)) == 0) || - t->is_tc; -} - -void common_hal_nativeio_pwmout_construct(nativeio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, - uint16_t duty, - uint32_t frequency, - bool variable_frequency) { - self->pin = pin; - self->variable_frequency = variable_frequency; - - if (pin->primary_timer.tc == 0 && pin->secondary_timer.tc == 0) { - mp_raise_ValueError("Invalid pin"); - } - - if (frequency == 0 || frequency > 6000000) { - mp_raise_ValueError("Invalid PWM frequency"); - } - - uint16_t primary_timer_index = 0xff; - uint16_t secondary_timer_index = 0xff; - if (pin->primary_timer.tc != NULL) { - primary_timer_index = (((uint32_t) pin->primary_timer.tcc) - ((uint32_t) TCC0)) / 0x400; - } - if (pin->secondary_timer.tc != NULL) { - secondary_timer_index = (((uint32_t) pin->secondary_timer.tcc) - ((uint32_t) TCC0)) / 0x400; - } - - // Figure out which timer we are using. - - // First see if a timer is already going with the frequency we want and our - // channel is unused. - // NOTE(shawcroft): The enable bit is in the same position for TC and TCC so - // we treat them all as TCC for checking ENABLE. - const pin_timer_t* t = NULL; - uint8_t index = 0; - if (!variable_frequency && - primary_timer_index != 0xff && - target_timer_frequencies[primary_timer_index] == frequency && - pin->primary_timer.tcc->CTRLA.bit.ENABLE == 1 && - channel_ok(&pin->primary_timer, primary_timer_index)) { - t = &pin->primary_timer; - index = primary_timer_index; - } else if (!variable_frequency && - secondary_timer_index != 0xff && - target_timer_frequencies[secondary_timer_index] == frequency && - pin->secondary_timer.tcc->CTRLA.bit.ENABLE == 1 && - channel_ok(&pin->secondary_timer, secondary_timer_index)) { - t = &pin->secondary_timer; - index = secondary_timer_index; - } else { - // Pick an unused timer if available. - - // Check the secondary timer first since its always a nicer TCC (when it - // exists) - if (pin->secondary_timer.tc != 0 && - timer_refcount[secondary_timer_index] == 0 && - pin->secondary_timer.tcc->CTRLA.bit.ENABLE == 0) { - t = &pin->secondary_timer; - index = secondary_timer_index; - } else if (pin->primary_timer.tc != 0 && - (!pin->primary_timer.is_tc || pin->primary_timer.channel == 1) && - timer_refcount[primary_timer_index] == 0) { - t = &pin->primary_timer; - index = primary_timer_index; - } - if (t == NULL) { - mp_raise_RuntimeError("All timers in use"); - return; - } - uint8_t resolution = 0; - if (t->is_tc) { - resolution = 16; - } else { - resolution = 24; - } - // First determine the divisor that gets us the highest resolution. - uint32_t system_clock = system_cpu_clock_get_hz(); - uint32_t top; - uint8_t divisor; - for (divisor = 0; divisor < 8; divisor++) { - top = (system_clock / prescaler[divisor] / frequency) - 1; - if (top < (1u << resolution)) { - break; - } - } - if (t->is_tc) { - struct tc_config config_tc; - tc_get_config_defaults(&config_tc); - - config_tc.counter_size = TC_COUNTER_SIZE_16BIT; - config_tc.clock_prescaler = TC_CTRLA_PRESCALER(divisor); - config_tc.wave_generation = TC_WAVE_GENERATION_MATCH_PWM; - config_tc.counter_16_bit.compare_capture_channel[0] = top; - - tc_init(&self->tc_instance, t->tc, &config_tc); - tc_enable(&self->tc_instance); - } else { - struct tcc_config config_tcc; - tcc_get_config_defaults(&config_tcc, t->tcc); - - config_tcc.counter.clock_prescaler = divisor; - config_tcc.counter.period = top; - config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM; - - tcc_init(&self->tcc_instance, t->tcc, &config_tcc); - tcc_enable(&self->tcc_instance); - } - - target_timer_frequencies[index] = frequency; - timer_refcount[index]++; - } - - if (!t->is_tc) { - if (variable_frequency) { - // We're changing frequency so claim all of the channels. - tcc_channels[index] = 0xff; - } else { - tcc_channels[index] |= (1 << t->channel); - } - } - - self->timer = t; - - // Connect the wave output to the outside world. - struct system_pinmux_config pin_config; - system_pinmux_get_config_defaults(&pin_config); - pin_config.mux_position = &self->pin->primary_timer == t ? MUX_E : MUX_F; - pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT; - system_pinmux_pin_set_config(pin->pin, &pin_config); - - common_hal_nativeio_pwmout_set_duty_cycle(self, duty); -} - -extern void common_hal_nativeio_pwmout_deinit(nativeio_pwmout_obj_t* self) { - const pin_timer_t* t = self->timer; - uint8_t index = (((uint32_t) t->tcc) - ((uint32_t) TCC0)) / 0x400; - timer_refcount[index]--; - if (!t->is_tc) { - tcc_channels[index] &= ~(1 << t->channel); - } - if (timer_refcount[index] == 0) { - target_timer_frequencies[index] = 0; - if (t->is_tc) { - tc_disable(&self->tc_instance); - } else { - if (t->tcc == TCC0) { - tcc_channels[index] = 0xf0; - } else { - tcc_channels[index] = 0xfc; - } - tcc_disable(&self->tcc_instance); - tcc_reset(&self->tcc_instance); - } - } - reset_pin(self->pin->pin); -} - -extern void common_hal_nativeio_pwmout_set_duty_cycle(nativeio_pwmout_obj_t* self, uint16_t duty) { - const pin_timer_t* t = self->timer; - if (t->is_tc) { - uint32_t top = ((uint32_t) t->tc->COUNT16.CC[0].reg + 1); - uint16_t adjusted_duty = top * duty / 0xffff; - tc_set_compare_value(&self->tc_instance, t->channel, adjusted_duty); - } else { - uint32_t top = t->tcc->PER.reg + 1; - uint32_t adjusted_duty = ((uint64_t) top) * duty / 0xffff; - tcc_set_compare_value(&self->tcc_instance, t->channel, adjusted_duty); - } -} - -uint16_t common_hal_nativeio_pwmout_get_duty_cycle(nativeio_pwmout_obj_t* self) { - const pin_timer_t* t = self->timer; - if (t->is_tc) { - uint16_t top = t->tc->COUNT16.CC[0].reg; - while (tc_is_syncing(&self->tc_instance)) { - /* Wait for sync */ - } - uint16_t cv = t->tc->COUNT16.CC[t->channel].reg; - return cv * 0xffff / top; - } else { - uint32_t top = t->tcc->PER.reg; - uint32_t cv = 0; - if ((t->tcc->STATUS.vec.CCBV & (1 << t->channel)) != 0) { - cv = t->tcc->CCB[t->channel].reg; - } else { - cv = t->tcc->CC[t->channel].reg; - } - return cv * 0xffff / top; - } -} - - -void common_hal_nativeio_pwmout_set_frequency(nativeio_pwmout_obj_t* self, - uint32_t frequency) { - if (frequency == 0 || frequency > 6000000) { - mp_raise_ValueError("Invalid PWM frequency"); - } - const pin_timer_t* t = self->timer; - uint8_t resolution; - if (t->is_tc) { - resolution = 16; - } else { - resolution = 24; - } - uint32_t system_clock = system_cpu_clock_get_hz(); - uint32_t new_top; - uint8_t new_divisor; - for (new_divisor = 0; new_divisor < 8; new_divisor++) { - new_top = (system_clock / prescaler[new_divisor] / frequency) - 1; - if (new_top < (1u << resolution)) { - break; - } - } - uint16_t old_duty = common_hal_nativeio_pwmout_get_duty_cycle(self); - uint8_t old_divisor; - if (t->is_tc) { - old_divisor = t->tc->COUNT16.CTRLA.bit.PRESCALER; - } else { - old_divisor = t->tcc->CTRLA.bit.PRESCALER; - } - if (new_divisor != old_divisor) { - if (t->is_tc) { - tc_disable(&self->tc_instance); - t->tc->COUNT16.CTRLA.bit.PRESCALER = new_divisor; - tc_enable(&self->tc_instance); - } else { - tcc_disable(&self->tcc_instance); - t->tcc->CTRLA.bit.PRESCALER = new_divisor; - tcc_enable(&self->tcc_instance); - } - } - if (t->is_tc) { - while (tc_is_syncing(&self->tc_instance)) { - /* Wait for sync */ - } - t->tc->COUNT16.CC[0].reg = new_top; - } else { - tcc_set_top_value(&self->tcc_instance, new_top); - } - - common_hal_nativeio_pwmout_set_duty_cycle(self, old_duty); -} - -uint32_t common_hal_nativeio_pwmout_get_frequency(nativeio_pwmout_obj_t* self) { - uint32_t system_clock = system_cpu_clock_get_hz(); - const pin_timer_t* t = self->timer; - uint32_t top; - uint8_t divisor; - if (t->is_tc) { - top = t->tc->COUNT16.CC[0].reg; - divisor = t->tc->COUNT16.CTRLA.bit.PRESCALER; - } else { - top = t->tcc->PER.reg; - divisor = t->tcc->CTRLA.bit.PRESCALER; - } - return (system_clock / prescaler[divisor]) / (top + 1); -} - -bool common_hal_nativeio_pwmout_get_variable_frequency(nativeio_pwmout_obj_t* self) { - return self->variable_frequency; -} diff --git a/atmel-samd/common-hal/nativeio/PWMOut.h b/atmel-samd/common-hal/nativeio/PWMOut.h deleted file mode 100644 index 56994e519..000000000 --- a/atmel-samd/common-hal/nativeio/PWMOut.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PWMOUT_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PWMOUT_H__ - -void pwmout_reset(void); - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PWMOUT_H__ diff --git a/atmel-samd/common-hal/nativeio/PulseIn.c b/atmel-samd/common-hal/nativeio/PulseIn.c deleted file mode 100644 index f5df2e8cd..000000000 --- a/atmel-samd/common-hal/nativeio/PulseIn.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "common-hal/nativeio/PulseIn.h" - -#include - -#include "asf/common2/services/delay/delay.h" -#include "asf/sam0/drivers/extint/extint.h" -#include "asf/sam0/drivers/extint/extint_callback.h" - -#include "mpconfigport.h" -#include "py/gc.h" -#include "py/runtime.h" -#include "samd21_pins.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/PulseIn.h" - -#include "tick.h" - -static nativeio_pulsein_obj_t *active_pulseins[EIC_NUMBER_OF_INTERRUPTS]; -static uint64_t last_ms[EIC_NUMBER_OF_INTERRUPTS]; -static uint16_t last_us[EIC_NUMBER_OF_INTERRUPTS]; - -void pulsein_reset(void) { - for (int i = 0; i < EIC_NUMBER_OF_INTERRUPTS; i++) { - active_pulseins[i] = NULL; - last_ms[i] = 0; - last_us[i] = 0; - } -} - -static void pulsein_set_config(nativeio_pulsein_obj_t* self, bool first_edge) { - struct extint_chan_conf config; - extint_chan_get_config_defaults(&config); - config.gpio_pin = self->pin; - config.gpio_pin_pull = EXTINT_PULL_NONE; - config.filter_input_signal = true; - - if (!first_edge) { - config.detection_criteria = EXTINT_DETECT_BOTH; - } else if (self->idle_state) { - config.detection_criteria = EXTINT_DETECT_FALLING; - } else { - config.detection_criteria = EXTINT_DETECT_RISING; - } - extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); - extint_chan_set_config(self->channel, &config); - // Clear any interrupts that may have triggered without notifying the CPU. - EIC->INTFLAG.reg |= (1UL << self->channel); - extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); -} - -static void pulsein_callback(void) { - // Grab the current time first. - uint16_t current_us = tc_get_count_value(&ms_timer); - uint64_t current_ms = ticks_ms; - nativeio_pulsein_obj_t* self = active_pulseins[extint_get_current_channel()]; - current_us = current_us * 1000 / self->ticks_per_ms; - if (self->first_edge) { - self->first_edge = false; - pulsein_set_config(self, false); - } else { - uint32_t ms_diff = current_ms - last_ms[self->channel]; - uint16_t us_diff = current_us - last_us[self->channel]; - if (last_us[self->channel] > current_us) { - us_diff = 1000 + current_us - last_us[self->channel]; - } - uint32_t total_diff = us_diff; - if (ms_diff > 1) { - total_diff += (ms_diff - 1) * 1000; - } - uint16_t duration = 0xffff; - if (total_diff < duration) { - duration = total_diff; - } - - uint16_t i = (self->start + self->len) % self->maxlen; - self->buffer[i] = duration; - if (self->len < self->maxlen) { - self->len++; - } else { - self->start++; - } - } - last_ms[self->channel] = current_ms; - last_us[self->channel] = current_us; -} - -void common_hal_nativeio_pulsein_construct(nativeio_pulsein_obj_t* self, - const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { - if (!pin->has_extint) { - mp_raise_RuntimeError("No hardware support on pin"); - } - // TODO(tannewt): Switch to checking actual extint peripheral state when other - // classes use extints. - if (active_pulseins[pin->extint_channel] != NULL) { - mp_raise_RuntimeError("EXTINT channel already in use"); - } - - self->buffer = (uint16_t *) gc_alloc(maxlen * sizeof(uint16_t), false); - if (self->buffer == NULL) { - mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t)); - } - self->channel = pin->extint_channel; - self->pin = pin->pin; - self->maxlen = maxlen; - self->idle_state = idle_state; - self->start = 0; - self->len = 0; - self->first_edge = true; - self->ticks_per_ms = (system_cpu_clock_get_hz() / 1000 - 1); - - active_pulseins[pin->extint_channel] = self; - - pulsein_set_config(self, true); - extint_register_callback( - pulsein_callback, - self->channel, - EXTINT_CALLBACK_TYPE_DETECT); - extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); -} - -void common_hal_nativeio_pulsein_deinit(nativeio_pulsein_obj_t* self) { - extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); - active_pulseins[self->channel] = NULL; - reset_pin(self->pin); -} - -void common_hal_nativeio_pulsein_pause(nativeio_pulsein_obj_t* self) { - extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); -} - -void common_hal_nativeio_pulsein_resume(nativeio_pulsein_obj_t* self, - uint16_t trigger_duration) { - // Send the trigger pulse. - if (trigger_duration > 0) { - struct port_config pin_conf; - port_get_config_defaults(&pin_conf); - - pin_conf.direction = PORT_PIN_DIR_OUTPUT; - pin_conf.input_pull = PORT_PIN_PULL_NONE; - port_pin_set_config(self->pin, &pin_conf); - port_pin_set_output_level(self->pin, !self->idle_state); - delay_us(trigger_duration); - port_pin_set_output_level(self->pin, self->idle_state); - } - - // Reconfigure the pin and make sure its set to detect the first edge. - last_ms[self->channel] = 0; - last_us[self->channel] = 0; - self->first_edge = true; - pulsein_set_config(self, true); -} - -void common_hal_nativeio_pulsein_clear(nativeio_pulsein_obj_t* self) { - common_hal_mcu_disable_interrupts(); - self->start = 0; - self->len = 0; - common_hal_mcu_enable_interrupts(); -} - -uint16_t common_hal_nativeio_pulsein_popleft(nativeio_pulsein_obj_t* self) { - if (self->len == 0) { - mp_raise_IndexError("pop from an empty PulseIn"); - } - common_hal_mcu_disable_interrupts(); - uint16_t value = self->buffer[self->start]; - self->start = (self->start + 1) % self->maxlen; - self->len--; - common_hal_mcu_enable_interrupts(); - - return value; -} - -uint16_t common_hal_nativeio_pulsein_get_maxlen(nativeio_pulsein_obj_t* self) { - return self->maxlen; -} - -uint16_t common_hal_nativeio_pulsein_get_len(nativeio_pulsein_obj_t* self) { - return self->len; -} - -uint16_t common_hal_nativeio_pulsein_get_item(nativeio_pulsein_obj_t* self, - int16_t index) { - common_hal_mcu_disable_interrupts(); - if (index < 0) { - index += self->len; - } - if (index < 0 || index >= self->len) { - common_hal_mcu_enable_interrupts(); - mp_raise_IndexError("index out of range"); - } - uint16_t value = self->buffer[(self->start + index) % self->maxlen]; - common_hal_mcu_enable_interrupts(); - return value; -} diff --git a/atmel-samd/common-hal/nativeio/PulseIn.h b/atmel-samd/common-hal/nativeio/PulseIn.h deleted file mode 100644 index 9d6169414..000000000 --- a/atmel-samd/common-hal/nativeio/PulseIn.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEIN_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEIN_H__ - -void pulsein_reset(void); - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEIN_H__ diff --git a/atmel-samd/common-hal/nativeio/PulseOut.c b/atmel-samd/common-hal/nativeio/PulseOut.c deleted file mode 100644 index 76ef849a1..000000000 --- a/atmel-samd/common-hal/nativeio/PulseOut.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "common-hal/nativeio/PulseOut.h" - -#include - -#include "asf/sam0/drivers/tc/tc_interrupt.h" - -#include "mpconfigport.h" -#include "py/runtime.h" -#include "shared-bindings/nativeio/PulseOut.h" - -#undef ENABLE - -// This timer is shared amongst all PulseOut objects under the assumption that -// the code is single threaded. -static struct tc_module tc_instance; -static uint8_t refcount = 0; - -static __IO PORT_PINCFG_Type *active_pincfg = NULL; -static uint16_t *pulse_buffer = NULL; -static volatile uint16_t pulse_index = 0; -static uint16_t pulse_length; -static volatile uint32_t current_compare = 0; - -static void turn_on(__IO PORT_PINCFG_Type * pincfg) { - pincfg->reg = PORT_PINCFG_PMUXEN; -} - -static void turn_off(__IO PORT_PINCFG_Type * pincfg) { - pincfg->reg = PORT_PINCFG_RESETVALUE; -} - -void pulse_finish(struct tc_module *const module) { - pulse_index++; - - if (active_pincfg == NULL) { - return; - } - // Always turn it off. - turn_off(active_pincfg); - if (pulse_index >= pulse_length) { - return; - } - current_compare = (current_compare + pulse_buffer[pulse_index] * 3 / 4) & 0xffff; - tc_set_compare_value(&tc_instance, TC_COMPARE_CAPTURE_CHANNEL_0, current_compare); - if (pulse_index % 2 == 0) { - turn_on(active_pincfg); - } -} - -void pulseout_reset() { - refcount = 0; - active_pincfg = NULL; -} - -void common_hal_nativeio_pulseout_construct(nativeio_pulseout_obj_t* self, - const nativeio_pwmout_obj_t* carrier) { - if (refcount == 0) { - // Find a spare timer. - Tc *t = NULL; - Tc *tcs[TC_INST_NUM] = TC_INSTS; - for (uint8_t i = TC_INST_NUM; i > 0; i--) { - if (tcs[i - 1]->COUNT16.CTRLA.bit.ENABLE == 0) { - t = tcs[i - 1]; - break; - } - } - if (t == NULL) { - mp_raise_RuntimeError("All timers in use"); - } - - struct tc_config config_tc; - tc_get_config_defaults(&config_tc); - - config_tc.counter_size = TC_COUNTER_SIZE_16BIT; - config_tc.clock_prescaler = TC_CTRLA_PRESCALER_DIV64; - config_tc.wave_generation = TC_WAVE_GENERATION_NORMAL_FREQ; - - tc_init(&tc_instance, t, &config_tc); - tc_register_callback(&tc_instance, pulse_finish, TC_CALLBACK_CC_CHANNEL0); - tc_enable(&tc_instance); - tc_stop_counter(&tc_instance); - } - refcount++; - - self->pin = carrier->pin->pin; - - PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin); - self->pincfg = &port_base->PINCFG[self->pin % 32]; - - // Set the port to output a zero. - port_base->OUTCLR.reg = 1 << (self->pin % 32); - port_base->DIRSET.reg = 1 << (self->pin % 32); - - // Turn off the pinmux which should connect the port output. - turn_off(self->pincfg); -} - -void common_hal_nativeio_pulseout_deinit(nativeio_pulseout_obj_t* self) { - PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin); - port_base->DIRCLR.reg = 1 << (self->pin % 32); - - turn_on(self->pincfg); - - refcount--; - if (refcount == 0) { - tc_reset(&tc_instance); - } -} - -void common_hal_nativeio_pulseout_send(nativeio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { - if (active_pincfg != NULL) { - mp_raise_RuntimeError("Another send is already active"); - } - active_pincfg = self->pincfg; - pulse_buffer = pulses; - pulse_index = 0; - pulse_length = length; - - current_compare = pulses[0] * 3 / 4; - tc_set_compare_value(&tc_instance, TC_COMPARE_CAPTURE_CHANNEL_0, current_compare); - - tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0); - turn_on(active_pincfg); - tc_start_counter(&tc_instance); - - while(pulse_index < length) { - // Do other things while we wait. The interrupts will handle sending the - // signal. - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - } - - tc_stop_counter(&tc_instance); - tc_disable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0); - active_pincfg = NULL; -} diff --git a/atmel-samd/common-hal/nativeio/PulseOut.h b/atmel-samd/common-hal/nativeio/PulseOut.h deleted file mode 100644 index 721670bef..000000000 --- a/atmel-samd/common-hal/nativeio/PulseOut.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEOUT_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEOUT_H__ - -void pulseout_reset(void); - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_PULSEOUT_H__ diff --git a/atmel-samd/common-hal/nativeio/SPI.c b/atmel-samd/common-hal/nativeio/SPI.c deleted file mode 100644 index 3dec31a10..000000000 --- a/atmel-samd/common-hal/nativeio/SPI.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - // This file contains all of the port specific HAL functions for the machine - // module. - -#include "shared-bindings/nativeio/SPI.h" -#include "py/nlr.h" -#include "py/runtime.h" -#include "samd21_pins.h" - -// We use ENABLE registers below we don't want to treat as a macro. -#undef ENABLE - -// Number of times to try to send packet if failed. -#define TIMEOUT 1 - -void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, - const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, - const mcu_pin_obj_t * miso) { - struct spi_config config_spi_master; - spi_get_config_defaults(&config_spi_master); - - Sercom* sercom = NULL; - uint32_t clock_pinmux = 0; - bool mosi_none = mosi == mp_const_none; - bool miso_none = miso == mp_const_none; - uint32_t mosi_pinmux = 0; - uint32_t miso_pinmux = 0; - uint8_t clock_pad = 0; - uint8_t mosi_pad = 0; - uint8_t miso_pad = 0; - for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { - Sercom* potential_sercom = clock->sercom[i].sercom; - if (potential_sercom == NULL || - potential_sercom->SPI.CTRLA.bit.ENABLE != 0) { - continue; - } - clock_pinmux = PINMUX(clock->pin, (i == 0) ? MUX_C : MUX_D); - clock_pad = clock->sercom[i].pad; - for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (!mosi_none) { - if(potential_sercom == mosi->sercom[j].sercom) { - mosi_pinmux = PINMUX(mosi->pin, (j == 0) ? MUX_C : MUX_D); - mosi_pad = mosi->sercom[j].pad; - if (miso_none) { - sercom = potential_sercom; - break; - } - } else { - continue; - } - } - if (!miso_none) { - for (int k = 0; k < NUM_SERCOMS_PER_PIN; k++) { - if (potential_sercom == miso->sercom[k].sercom) { - miso_pinmux = PINMUX(miso->pin, (k == 0) ? MUX_C : MUX_D); - miso_pad = miso->sercom[k].pad; - sercom = potential_sercom; - break; - } - } - } - if (sercom != NULL) { - break; - } - } - if (sercom != NULL) { - break; - } - } - if (sercom == NULL) { - mp_raise_ValueError("Invalid pins"); - } - - // Depends on where MOSI and CLK are. - uint8_t dopo = 8; - if (clock_pad == 1) { - if (mosi_pad == 0) { - dopo = 0; - } else if (mosi_pad == 3) { - dopo = 2; - } - } else if (clock_pad == 3) { - if (mosi_pad == 0) { - dopo = 3; - } else if (mosi_pad == 2) { - dopo = 1; - } - } - if (dopo == 8) { - mp_raise_ValueError("MOSI and clock pins incompatible"); - } - - config_spi_master.mux_setting = (dopo << SERCOM_SPI_CTRLA_DOPO_Pos) | - (miso_pad << SERCOM_SPI_CTRLA_DIPO_Pos); - - // Map pad to pinmux through a short array. - uint32_t *pinmuxes[4] = {&config_spi_master.pinmux_pad0, - &config_spi_master.pinmux_pad1, - &config_spi_master.pinmux_pad2, - &config_spi_master.pinmux_pad3}; - *pinmuxes[clock_pad] = clock_pinmux; - self->clock_pin = clock->pin; - self->MOSI_pin = NO_PIN; - if (!mosi_none) { - *pinmuxes[mosi_pad] = mosi_pinmux; - self->MOSI_pin = mosi->pin; - } - self->MISO_pin = NO_PIN; - if (!miso_none) { - *pinmuxes[miso_pad] = miso_pinmux; - self->MISO_pin = miso->pin; - } - - // Always start at 250khz which is what SD cards need. They are sensitive to - // SPI bus noise before they are put into SPI mode. - self->current_baudrate = 250000; - config_spi_master.mode_specific.master.baudrate = self->current_baudrate; - - spi_init(&self->spi_master_instance, sercom, &config_spi_master); - - spi_enable(&self->spi_master_instance); -} - -void common_hal_nativeio_spi_deinit(nativeio_spi_obj_t *self) { - spi_disable(&self->spi_master_instance); - reset_pin(self->clock_pin); - reset_pin(self->MOSI_pin); - reset_pin(self->MISO_pin); -} - -bool common_hal_nativeio_spi_configure(nativeio_spi_obj_t *self, - uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - // TODO(tannewt): Check baudrate first before changing it. - if (baudrate != self->current_baudrate) { - enum status_code status = spi_set_baudrate(&self->spi_master_instance, baudrate); - if (status != STATUS_OK) { - return false; - } - } - - SercomSpi *const spi_module = &(self->spi_master_instance.hw->SPI); - // If the settings are already what we want then don't reset them. - if (spi_module->CTRLA.bit.CPHA == phase && - spi_module->CTRLA.bit.CPOL == polarity && - spi_module->CTRLB.bit.CHSIZE == (bits - 8)) { - return true; - } - - spi_disable(&self->spi_master_instance); - while (spi_is_syncing(&self->spi_master_instance)) { - /* Wait until the synchronization is complete */ - } - - spi_module->CTRLA.bit.CPHA = phase; - spi_module->CTRLA.bit.CPOL = polarity; - spi_module->CTRLB.bit.CHSIZE = bits - 8; - - while (spi_is_syncing(&self->spi_master_instance)) { - /* Wait until the synchronization is complete */ - } - - /* Enable the module */ - spi_enable(&self->spi_master_instance); - - while (spi_is_syncing(&self->spi_master_instance)) { - /* Wait until the synchronization is complete */ - } - - return true; -} - -bool common_hal_nativeio_spi_try_lock(nativeio_spi_obj_t *self) { - self->has_lock = spi_lock(&self->spi_master_instance) == STATUS_OK; - return self->has_lock; -} - -bool common_hal_nativeio_spi_has_lock(nativeio_spi_obj_t *self) { - return self->has_lock; -} - -void common_hal_nativeio_spi_unlock(nativeio_spi_obj_t *self) { - self->has_lock = false; - spi_unlock(&self->spi_master_instance); -} - -bool common_hal_nativeio_spi_write(nativeio_spi_obj_t *self, - const uint8_t *data, size_t len) { - if (len == 0) { - return true; - } - enum status_code status = spi_write_buffer_wait( - &self->spi_master_instance, - data, - len); - return status == STATUS_OK; -} - -bool common_hal_nativeio_spi_read(nativeio_spi_obj_t *self, - uint8_t *data, size_t len, uint8_t write_value) { - if (len == 0) { - return true; - } - enum status_code status = spi_read_buffer_wait( - &self->spi_master_instance, - data, - len, - write_value); - return status == STATUS_OK; -} diff --git a/atmel-samd/common-hal/nativeio/TouchIn.c b/atmel-samd/common-hal/nativeio/TouchIn.c deleted file mode 100644 index a98d235ef..000000000 --- a/atmel-samd/common-hal/nativeio/TouchIn.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "py/nlr.h" -#include "py/mperrno.h" -#include "py/runtime.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "shared-bindings/nativeio/TouchIn.h" - -#include "tick.h" - -#include "QTouch/touch_api_ptc.h" - -#define DEF_SELFCAP_CAL_SEQ1_COUNT 8 -#define DEF_SELFCAP_CAL_SEQ2_COUNT 4 -#define DEF_SELFCAP_CC_CAL_CLK_PRESCALE_PER_NODE DEF_SELFCAP_CLK_PRESCALE_PER_NODE -#define DEF_SELFCAP_CC_CAL_SENSE_RESISTOR_PER_NODE DEF_SELFCAP_SENSE_RESISTOR_PER_NODE -#define DEF_SELFCAP_QUICK_REBURST_ENABLE 1u - -/** - * Mutual Cap sensors measured data pointer. - * Note: This pointer is initialized by the QTouch library once the - * touch_mutlcap_sensors_init API is called. */ -touch_measure_data_t *p_mutlcap_measure_data = NULL; - -/** - * Self Cap sensors measured data pointer. - * Note: This pointer is initialized by the QTouch library once the - * touch_selfcap_sensors_init API is called. */ -touch_measure_data_t *p_selfcap_measure_data = NULL; - - -/** - * Self Cap sensors data block provided as input to Touch library. - */ -static uint8_t selfcap_data_blk[PRIV_SELFCAP_DATA_BLK_SIZE]; - -/** - * Self Cap sensors Pins Info. - */ - -uint32_t selfcap_y_nodes[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_LINES}; - -filter_level_t selfcap_filter_level_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_FILTER_LEVEL_PER_NODE}; - -uint8_t selfcap_auto_os_per_node[DEF_SELFCAP_NUM_CHANNELS]= {DEF_SELFCAP_AUTO_OS_PER_NODE}; - -gain_t selfcap_gain_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_GAIN_PER_NODE}; - -rsel_val_t selfcap_resistor_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_SENSE_RESISTOR_PER_NODE}; - -prsc_div_sel_t selfcap_prsc_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_CLK_PRESCALE_PER_NODE}; - -prsc_div_sel_t selfcap_boot_prsc_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_CC_CAL_CLK_PRESCALE_PER_NODE}; - -rsel_val_t selfcap_boot_resistor_per_node[DEF_SELFCAP_NUM_CHANNELS] = { DEF_SELFCAP_CC_CAL_SENSE_RESISTOR_PER_NODE}; - -freq_hop_sel_t selfcap_freq_hops[3u] = {DEF_SELFCAP_HOP_FREQS}; - -/** - * Self Cap Configuration structure provided as input to Touch Library. - * - * Note: Use the touch.h configuration header file to fill in - * the elements of this structure. DO NOT modify any of the input values - * directly in this structure. - */ -touch_selfcap_config_t selfcap_config = { - 0, /* Self Cap number of channels. */ - 0, /* Self Cap number of sensors. */ - DEF_SELFCAP_NUM_ROTORS_SLIDERS, /* Self Cap number of rotors and - * sliders. */ - - /* Self Cap GLOBAL SENSOR CONFIGURATION INFO. */ - { - DEF_SELFCAP_DI, /* uint8_t di; Sensor detect - * integration (DI) limit. */ - - /* Interchanging Negative and Positive Drift rate, since Signal - * increases on Touch. */ - DEF_SELFCAP_ATCH_DRIFT_RATE, /* uint8_t neg_drift_rate; - * Sensor - * negative drift rate. */ - DEF_SELFCAP_TCH_DRIFT_RATE, /* uint8_t pos_drift_rate; - * Sensor - * positive drift rate. */ - DEF_SELFCAP_MAX_ON_DURATION, /* uint8_t max_on_duration; - * Sensor - * maximum on duration. */ - DEF_SELFCAP_DRIFT_HOLD_TIME, /* uint8_t drift_hold_time; - * Sensor - * drift hold time. */ - DEF_SELFCAP_ATCH_RECAL_DELAY, /* uint8_t pos_recal_delay; - * Sensor positive recalibration - * delay. */ - - DEF_SELFCAP_CAL_SEQ1_COUNT, - DEF_SELFCAP_CAL_SEQ2_COUNT, - DEF_SELFCAP_ATCH_RECAL_THRESHOLD, /* recal_threshold_t - * recal_threshold; Sensor - * recalibration threshold. */ - DEF_SELFCAP_TOUCH_POSTPROCESS_MODE, - DEF_SELFCAP_AUTO_OS_SIGNAL_STABILITY_LIMIT, - DEF_SELFCAP_FREQ_AUTO_TUNE_SIGNAL_STABILITY_LIMIT, - DEF_SELFCAP_FREQ_AUTO_TUNE_IN_CNT, - DEF_SELFCAP_NOISE_MEAS_SIGNAL_STABILITY_LIMIT, /* signal - *stability */ - DEF_SELFCAP_NOISE_LIMIT, - DEF_SELFCAP_LOCKOUT_SEL, - DEF_SELFCAP_LOCKOUT_CNTDOWN, - #if ((SAMC20) || (SAMC21) || (SAML22)) - DEF_SELF_CAP_CSD_VALUE, - #endif - }, - { - selfcap_gain_per_node, /* Self Cap channel gain setting. */ - DEF_SELFCAP_FREQ_MODE, /* Self Cap noise counter measure - * enable/disable. */ - selfcap_prsc_per_node, - selfcap_resistor_per_node, - selfcap_boot_prsc_per_node, - selfcap_boot_resistor_per_node, - selfcap_freq_hops, - selfcap_filter_level_per_node, /* Self Cap filter level setting. */ - selfcap_auto_os_per_node, /* Self Cap auto oversamples - *setting. */ - }, - selfcap_data_blk, /* Self Cap data block index. */ - PRIV_SELFCAP_DATA_BLK_SIZE, /* Self Cap data block size. */ - selfcap_y_nodes, /* Self Cap channel nodes. */ - DEF_SELFCAP_QUICK_REBURST_ENABLE, - DEF_SELFCAP_FILTER_CALLBACK, /* Self Cap filter callback - * function - * pointer. */ - DEF_SELFCAP_FREQ_AUTO_TUNE_ENABLE, - DEF_SELFCAP_NOISE_MEAS_ENABLE, - DEF_SELFCAP_NOISE_MEAS_BUFFER_CNT, - DEF_SELFCAP_MOIS_TOLERANCE_ENABLE, - DEF_SELFCAP_NUM_MOIS_GROUPS, - DEF_SELFCAP_MOIS_QUICK_REBURST_ENABLE, - DEF_SELFCAP_PTC_GPIO_STATE, - .tlib_feature_list ={ - .lk_chk = DEF_LOCKOUT_FUNC, - .auto_os_init = DEF_AUTO_OS_FUNC,//auto_os_resolve, - .auto_tune_init = DEF_SELF_AUTO_TUNE_FUNC,// self_auto_tuning - .enable_aks = DEF_AKS_FUNC, /*AKS grouping function */ - } -}; - -/** - * Touch Library input configuration structure. - */ -touch_config_t touch_config = { - NULL, - &selfcap_config, /* Pointer to Self Cap configuration - * structure. */ - DEF_TOUCH_PTC_ISR_LVL, /* PTC interrupt level. */ -}; - -nativeio_touchin_obj_t *active_touchin_obj[DEF_SELFCAP_NUM_CHANNELS]; - -void common_hal_nativeio_touchin_construct(nativeio_touchin_obj_t* self, - const mcu_pin_obj_t *pin) { - if (!pin->has_touch) { - mp_raise_ValueError("Invalid pin"); - } - - if (selfcap_config.num_channels > 0) { - // Deinit the touch sensor, we're going to reinitialize it. - touch_selfcap_sensors_deinit(); - - // Remove holes in the active list from sensors that may have been - // disabled. - int first_hole = -1; - for (int i = 0; i < selfcap_config.num_channels; i++) { - if (active_touchin_obj[i] == NULL && first_hole == -1) { - first_hole = i; - } else if (active_touchin_obj[i] != NULL && first_hole != -1) { - active_touchin_obj[first_hole] = active_touchin_obj[i]; - first_hole = i; - } - } - if (first_hole > -1) { - selfcap_config.num_channels = first_hole; - selfcap_config.num_sensors = first_hole; - } - } - - // Add our sensor to the end of the list. - self->pin = pin; - selfcap_y_nodes[selfcap_config.num_channels++] = Y(pin->touch_y_line); - active_touchin_obj[selfcap_config.num_sensors++] = self; - - /* Setup and enable generic clock source for PTC module. */ - struct system_gclk_chan_config gclk_chan_conf; - system_gclk_chan_get_config_defaults(&gclk_chan_conf); - gclk_chan_conf.source_generator = GCLK_GENERATOR_3; - system_gclk_chan_set_config(PTC_GCLK_ID, &gclk_chan_conf); - system_gclk_chan_enable(PTC_GCLK_ID); - system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_PTC); - - touch_ret_t status; - /* Initialize touch library for Self Cap operation. */ - status = touch_selfcap_sensors_init_with_rs_table(&touch_config, - PRIV_SELFCAP_RS_TABLE_INIT, PRIV_NM_TABLE_INIT, - PRIV_FREQ_AUTO_TUNE_CHK, PRIV_MOIS_TOLERANCE_CHK); - if (status != TOUCH_SUCCESS) { - mp_raise_OSError(MP_EIO); - } - for (int i = 0; i < selfcap_config.num_channels; i++) { - status = touch_selfcap_sensor_config(SENSOR_TYPE_KEY, i, i, - NO_AKS_GROUP, 10u, HYST_25, RES_8_BIT, &active_touchin_obj[i]->sensor_id); - if (status != TOUCH_SUCCESS) { - mp_raise_OSError(MP_EIO); - } - } - status = touch_selfcap_sensors_calibrate(AUTO_TUNE_RSEL); - if (status != TOUCH_SUCCESS) { - mp_raise_OSError(MP_EIO); - } - - // Run a measurement to get calibrated. - common_hal_nativeio_touchin_get_value(self); -} - -// This may get called twice, once on exit or deinit and once from the finaliser -// (__del__). We need the finaliser to reduce the chance of us writing to memory -// we no longer own because we keep track of Python pointers in active_touchin_obj. -void common_hal_nativeio_touchin_deinit(nativeio_touchin_obj_t* self) { - touch_selfcap_sensor_disable(self->sensor_id); - // Remove ourselves from the list of active objects. We don't change the - // selfcap settings at all because we don't want to reinit now. Instead, - // we'll collect blank spots later on reinit. - for (int i = 0; i < DEF_SELFCAP_NUM_CHANNELS; i++) { - if (active_touchin_obj[i] == self) { - active_touchin_obj[i] = NULL; - break; - } - } -} - -volatile bool touch_read_ready = false; -volatile touch_acq_status_t touch_acq_status; - -void touch_selfcap_measure_complete_callback(void) -{ - touch_read_ready = true; - touch_acq_status = p_selfcap_measure_data->acq_status; -} - -bool common_hal_nativeio_touchin_get_value(nativeio_touchin_obj_t *self) { - if (p_selfcap_measure_data->acq_status & TOUCH_CC_CALIB_ERROR) { - mp_raise_RuntimeError("Touch calibration error"); - } - touch_acq_status = TOUCH_BURST_AGAIN; - uint64_t start_ticks = ticks_ms; - while((touch_acq_status & TOUCH_BURST_AGAIN) && ticks_ms - start_ticks < 1000) { - touch_read_ready = false; - touch_ret_t touch_ret = touch_selfcap_sensors_measure( - ticks_ms, - NORMAL_ACQ_MODE, - touch_selfcap_measure_complete_callback); - - if (touch_ret != TOUCH_SUCCESS) { - mp_raise_OSError(MP_EIO); - } - - while(!touch_read_ready && ticks_ms - start_ticks < 1000) { - // wait - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - } - } - - if (touch_acq_status & TOUCH_BURST_AGAIN) { - mp_raise_OSError(MP_EIO); - } - - return (p_selfcap_measure_data->p_sensor_states[self->sensor_id / 8] & (1 << (self->sensor_id % 8))) != 0; -} diff --git a/atmel-samd/common-hal/nativeio/TouchInStub.c b/atmel-samd/common-hal/nativeio/TouchInStub.c deleted file mode 100644 index cfdc1249f..000000000 --- a/atmel-samd/common-hal/nativeio/TouchInStub.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "shared-bindings/nativeio/TouchIn.h" - -void common_hal_nativeio_touchin_construct(nativeio_touchin_obj_t* self, - const mcu_pin_obj_t *pin) { - mp_raise_NotImplementedError("No capacitive touch support"); -} - -void common_hal_nativeio_touchin_deinit(nativeio_touchin_obj_t* self) { -} - -bool common_hal_nativeio_touchin_get_value(nativeio_touchin_obj_t *self) { - return false; -} diff --git a/atmel-samd/common-hal/nativeio/UART.c b/atmel-samd/common-hal/nativeio/UART.c deleted file mode 100644 index cc4216348..000000000 --- a/atmel-samd/common-hal/nativeio/UART.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/UART.h" - -#include "mpconfigport.h" -#include "py/gc.h" -#include "py/mperrno.h" -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/stream.h" -#include "samd21_pins.h" -#include "tick.h" - -#include "asf/sam0/drivers/sercom/sercom_interrupt.h" - -#undef ENABLE - -nativeio_uart_obj_t *_uart_instances[SERCOM_INST_NUM]; - -static void _sercom_default_handler( - const uint8_t instance) -{ - Assert(false); -} - -static void _nativeio_uart_interrupt_handler(uint8_t instance) -{ - /* Temporary variables */ - uint16_t interrupt_status; - uint8_t error_code; - - /* Get device instance from the look-up table */ - struct usart_module *module - = (struct usart_module *)_sercom_instances[instance]; - - nativeio_uart_obj_t *self = _uart_instances[instance]; - - /* Pointer to the hardware module instance */ - SercomUsart *const usart_hw = &(module->hw->USART); - - /* Wait for the synchronization to complete */ - _usart_wait_for_sync(module); - - /* Read and mask interrupt flag register */ - interrupt_status = usart_hw->INTFLAG.reg; - interrupt_status &= usart_hw->INTENSET.reg; - - /* Check if the Receive Complete interrupt has occurred, and that - * there's more data to receive */ - if (interrupt_status & SERCOM_USART_INTFLAG_RXC) { - /* Read out the status code and mask away all but the 4 LSBs*/ - error_code = (uint8_t)(usart_hw->STATUS.reg & SERCOM_USART_STATUS_MASK); - /* CTS status should not be considered as an error */ - if(error_code & SERCOM_USART_STATUS_CTS) { - error_code &= ~SERCOM_USART_STATUS_CTS; - } - /* Check if an error has occurred during the receiving */ - if (error_code) { - /* Check which error occurred */ - if (error_code & SERCOM_USART_STATUS_FERR) { - /* Store the error code and clear flag by writing 1 to it */ - usart_hw->STATUS.reg = SERCOM_USART_STATUS_FERR; - } else if (error_code & SERCOM_USART_STATUS_BUFOVF) { - /* Store the error code and clear flag by writing 1 to it */ - usart_hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF; - } else if (error_code & SERCOM_USART_STATUS_PERR) { - /* Store the error code and clear flag by writing 1 to it */ - usart_hw->STATUS.reg = SERCOM_USART_STATUS_PERR; - } - self->rx_error = true; - } else { - /* Read current packet from DATA register, - * increment buffer pointer and decrement buffer length */ - uint16_t received_data = (usart_hw->DATA.reg & SERCOM_USART_DATA_MASK); - - common_hal_mcu_disable_interrupts(); - /* Read value will be at least 8-bits long */ - uint32_t buffer_end = (self->buffer_start + self->buffer_size) % self->buffer_length; - self->buffer[buffer_end] = received_data; - self->buffer_size++; - - if (module->character_size == USART_CHARACTER_SIZE_9BIT) { - /* 9-bit data, write next received byte to the buffer */ - self->buffer[buffer_end + 1] = (received_data >> 8); - self->buffer_size++; - } - - if (self->buffer_size > self->buffer_length) { - self->buffer_start++; - if (module->character_size == USART_CHARACTER_SIZE_9BIT) { - self->buffer_start++; - } - self->buffer_size = self->buffer_length; - } - common_hal_mcu_enable_interrupts(); - } - } -} - -void common_hal_nativeio_uart_construct(nativeio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, - uint8_t receiver_buffer_size) { - Sercom* sercom = NULL; - uint32_t rx_pinmux = PINMUX_UNUSED; - uint8_t rx_pad = 5; // Unset pad - uint32_t tx_pinmux = PINMUX_UNUSED; - uint8_t tx_pad = 5; // Unset pad - for (int i = 0; i < NUM_SERCOMS_PER_PIN; i++) { - Sercom* potential_sercom = NULL; - if (tx != NULL) { - potential_sercom = tx->sercom[i].sercom; - if (potential_sercom == NULL || - potential_sercom->I2CM.CTRLA.bit.ENABLE != 0 || - !(tx->sercom[i].pad == 0 || - tx->sercom[i].pad == 2)) { - continue; - } - tx_pinmux = PINMUX(tx->pin, (i == 0) ? MUX_C : MUX_D); - tx_pad = tx->sercom[i].pad; - if (rx == NULL) { - sercom = potential_sercom; - break; - } - } - for (int j = 0; j < NUM_SERCOMS_PER_PIN; j++) { - if (((tx == NULL && rx->sercom[j].sercom->I2CM.CTRLA.bit.ENABLE == 0) || - potential_sercom == rx->sercom[j].sercom) && - rx->sercom[j].pad != tx_pad) { - rx_pinmux = PINMUX(rx->pin, (j == 0) ? MUX_C : MUX_D); - rx_pad = rx->sercom[j].pad; - sercom = rx->sercom[j].sercom; - break; - } - } - if (sercom != NULL) { - break; - } - } - if (sercom == NULL) { - mp_raise_ValueError("Invalid pins"); - } - if (tx == NULL) { - tx_pad = 0; - if (rx_pad == 0) { - tx_pad = 2; - } - } - if (rx == NULL) { - rx_pad = (tx_pad + 1) % 4; - } - struct usart_config config_usart; - usart_get_config_defaults(&config_usart); - config_usart.mux_setting = (SERCOM_USART_CTRLA_RXPO(rx_pad) | SERCOM_USART_CTRLA_TXPO(tx_pad / 2)); - - if (parity == PARITY_ODD) { - config_usart.parity = USART_PARITY_ODD; - } else if (parity == PARITY_EVEN) { - config_usart.parity = USART_PARITY_EVEN; - } - config_usart.stopbits = stop - 1; - config_usart.character_size = bits % 8; - config_usart.baudrate = baudrate; - - // Map pad to pinmux through a short array. - uint32_t *pinmuxes[4] = {&config_usart.pinmux_pad0, - &config_usart.pinmux_pad1, - &config_usart.pinmux_pad2, - &config_usart.pinmux_pad3}; - // Pin muxes have a default pin, set them to unused so that no other pins are changed. - for (int i = 0; i < 4; i++) { - *pinmuxes[i] = PINMUX_UNUSED; - } - - self->rx_pin = NO_PIN; - config_usart.receiver_enable = rx != NULL; - if (rx != NULL) { - *pinmuxes[rx_pad] = rx_pinmux; - self->rx_pin = rx->pin; - } - - self->tx_pin = NO_PIN; - config_usart.transmitter_enable = tx != NULL; - if (tx != NULL) { - *pinmuxes[tx_pad] = tx_pinmux; - self->tx_pin = tx->pin; - } - - self->timeout_ms = timeout; - - self->buffer_length = receiver_buffer_size; - self->buffer_length *= (bits + 7) / 8; - self->buffer = (uint8_t *) gc_alloc(self->buffer_length * sizeof(uint8_t), false); - if (self->buffer == NULL) { - mp_raise_msg(&mp_type_MemoryError, "Failed to allocate RX buffer"); - } - - if (usart_init(&self->uart_instance, sercom, &config_usart) != STATUS_OK) { - mp_raise_OSError(MP_EIO); - } - - // We use our own interrupt handler because we want a circular buffer - // instead of the jobs that ASF provides. - uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw); - _sercom_set_handler(instance_index, _nativeio_uart_interrupt_handler); - _sercom_instances[instance_index] = &self->uart_instance; - _uart_instances[instance_index] = self; - - /* Enable Global interrupt for module */ - system_interrupt_enable(_sercom_get_interrupt_vector(self->uart_instance.hw)); - - usart_enable(&self->uart_instance); - self->uart_instance.hw->USART.INTENSET.bit.RXC = true; -} - -void common_hal_nativeio_uart_deinit(nativeio_uart_obj_t *self) { - self->uart_instance.hw->USART.INTENCLR.bit.RXC = true; - - uint8_t instance_index = _sercom_get_sercom_inst_index(self->uart_instance.hw); - _sercom_set_handler(instance_index, &_sercom_default_handler); - _sercom_instances[instance_index] = NULL; - _uart_instances[instance_index] = NULL; - - system_interrupt_disable(_sercom_get_interrupt_vector(self->uart_instance.hw)); - - usart_disable(&self->uart_instance); - reset_pin(self->rx_pin); - reset_pin(self->tx_pin); -} - -// Read characters. -size_t common_hal_nativeio_uart_read(nativeio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { - size_t total_read = 0; - uint64_t start_ticks = ticks_ms; - while (total_read < len && ticks_ms - start_ticks < self->timeout_ms) { - if (self->buffer_size > 0) { - common_hal_mcu_disable_interrupts(); - data[total_read] = self->buffer[self->buffer_start]; - if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { - data[total_read + 1] = self->buffer[self->buffer_start + 1]; - self->buffer_start += 2; - self->buffer_size -= 2; - } else { - self->buffer_start++; - self->buffer_size--; - } - self->buffer_start = self->buffer_start % self->buffer_length; - common_hal_mcu_enable_interrupts(); - // Reset the timeout every character read. - total_read++; - start_ticks = ticks_ms; - } - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - } - if (total_read == 0) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - return total_read; -} - -// Write characters. -size_t common_hal_nativeio_uart_write(nativeio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { - /* Check that the transmitter is enabled */ - if (!(self->uart_instance.transmitter_enabled)) { - *errcode = MP_EIO; - return MP_STREAM_ERROR; - } - - /* Get a pointer to the hardware module instance */ - SercomUsart *const usart_hw = &(self->uart_instance.hw->USART); - - /* Wait until synchronization is complete */ - _usart_wait_for_sync(&self->uart_instance); - - uint16_t tx_pos = 0; - - bool ok = true; - uint64_t start_ticks = 0; - /* Blocks while buffer is being transferred */ - while (len--) { - /* Wait for the USART to be ready for new data and abort - * operation if it doesn't get ready within the timeout*/ - ok = false; - start_ticks = ticks_ms; - while (ticks_ms - start_ticks < self->timeout_ms) { - if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) { - ok = true; - break; - } - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - } - - if (!ok) { - break; - } - - /* Data to send is at least 8 bits long */ - uint16_t data_to_send = data[tx_pos++]; - - /* Check if the character size exceeds 8 bit */ - if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { - data_to_send |= (data[tx_pos++] << 8); - } - - /* Send the data through the USART module */ - - enum status_code status = usart_write_wait(&self->uart_instance, data_to_send); - if (status != STATUS_OK) { - ok = false; - } - } - - /* Wait until Transmit is complete or timeout */ - if (ok) { - ok = false; - start_ticks = ticks_ms; - while (ticks_ms - start_ticks < self->timeout_ms) { - if (usart_hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) { - ok = true; - break; - } - #ifdef MICROPY_VM_HOOK_LOOP - MICROPY_VM_HOOK_LOOP - #endif - } - } - - if (!ok && tx_pos == 0) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - return tx_pos; -} - -uint32_t common_hal_nativeio_uart_rx_characters_available(nativeio_uart_obj_t *self) { - if (self->uart_instance.character_size == USART_CHARACTER_SIZE_9BIT) { - return self->buffer_size / 2; - } - return self->buffer_size; -} - -bool common_hal_nativeio_uart_ready_to_tx(nativeio_uart_obj_t *self) { - if (!(self->uart_instance.transmitter_enabled)) { - return false; - } - return self->uart_instance.hw->USART.INTFLAG.bit.DRE; -} diff --git a/atmel-samd/common-hal/nativeio/__init__.c b/atmel-samd/common-hal/nativeio/__init__.c deleted file mode 100644 index e0ec8acfb..000000000 --- a/atmel-samd/common-hal/nativeio/__init__.c +++ /dev/null @@ -1 +0,0 @@ -// No nativeio module functions. diff --git a/atmel-samd/common-hal/nativeio/types.h b/atmel-samd/common-hal/nativeio/types.h deleted file mode 100644 index 9f8c19e9d..000000000 --- a/atmel-samd/common-hal/nativeio/types.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This defines the types used to underly the standard nativeio Python objects. -// The shared API is defined in terms of these types. - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ - -#include "common-hal/microcontroller/types.h" - -// Don't reorder these includes because they are dependencies of adc_feature.h. -// They should really be included by adc_feature.h. -#include -#include "asf/sam0/drivers/system/clock/gclk.h" -#include "asf/sam0/utils/cmsis/samd21/include/component/adc.h" -#include "asf/sam0/drivers/adc/adc_sam_d_r/adc_feature.h" - -#include "asf/sam0/drivers/dac/dac.h" -#include "asf/sam0/drivers/sercom/i2c/i2c_master.h" -#include "asf/sam0/drivers/sercom/spi/spi.h" -#include "asf/sam0/drivers/sercom/usart/usart.h" -#include "asf/sam0/drivers/tc/tc.h" -#include "asf/sam0/drivers/tcc/tcc.h" -// Only support TouchIn when external SPI flash is used. -#ifdef SPI_FLASH_SECTOR_SIZE -#include "QTouch/touch_api_ptc.h" -#endif - -#include "py/obj.h" - -// Import bitbang implemented types. Must be after DigitalInOut because they -// likely depend on it. -#include "shared-module/nativeio/OneWire.h" - -typedef struct { - mp_obj_base_t base; - const mcu_pin_obj_t * pin; - struct adc_module * adc_instance; -} nativeio_analogin_obj_t; - -typedef struct { - mp_obj_base_t base; - struct dac_module dac_instance; -} nativeio_analogout_obj_t; - -typedef struct { - mp_obj_base_t base; - struct i2c_master_module i2c_master_instance; - bool has_lock; - uint8_t scl_pin; - uint8_t sda_pin; -} nativeio_i2c_obj_t; - -typedef struct { - mp_obj_base_t base; - struct spi_module spi_master_instance; - bool has_lock; - uint8_t clock_pin; - uint8_t MOSI_pin; - uint8_t MISO_pin; - uint32_t current_baudrate; -} nativeio_spi_obj_t; - -typedef struct { - mp_obj_base_t base; - uint8_t channel; - uint8_t pin; - uint16_t* buffer; - uint16_t maxlen; - bool idle_state; - volatile uint16_t start; - volatile uint16_t len; - volatile bool first_edge; - uint16_t ticks_per_ms; -} nativeio_pulsein_obj_t; - -typedef struct { - mp_obj_base_t base; - __IO PORT_PINCFG_Type *pincfg; - uint8_t pin; -} nativeio_pulseout_obj_t; - -typedef struct { - mp_obj_base_t base; - const mcu_pin_obj_t *pin; - const pin_timer_t* timer; - bool variable_frequency; - union { - struct tc_module tc_instance; - struct tcc_module tcc_instance; - }; -} nativeio_pwmout_obj_t; - -typedef struct { - mp_obj_base_t base; - // Only support TouchIn when external SPI flash is used. - #ifdef SPI_FLASH_SECTOR_SIZE - const mcu_pin_obj_t * pin; - sensor_id_t sensor_id; - #endif -} nativeio_touchin_obj_t; - -typedef struct { - mp_obj_base_t base; - struct usart_module uart_instance; - uint8_t rx_pin; - uint8_t tx_pin; - uint32_t timeout_ms; - bool rx_error; - // Index of the oldest received character. - uint32_t buffer_start; - // Index of the next available spot to store a character. - uint32_t buffer_size; - uint32_t buffer_length; - uint8_t* buffer; -} nativeio_uart_obj_t; - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ diff --git a/atmel-samd/common-hal/neopixel_write/__init__.c b/atmel-samd/common-hal/neopixel_write/__init__.c index ff0e99cd8..27dc7d6ad 100644 --- a/atmel-samd/common-hal/neopixel_write/__init__.c +++ b/atmel-samd/common-hal/neopixel_write/__init__.c @@ -29,8 +29,9 @@ #include "shared-bindings/neopixel_write/__init__.h" #include "asf/common2/services/delay/delay.h" +#include "asf/sam0/drivers/port/port.h" -void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { +void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { // This is adapted directly from the Adafruit NeoPixel library SAMD21G18A code: // https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp uint8_t *ptr, *end, p, bitMask; diff --git a/atmel-samd/common-hal/pulseio/PWMOut.c b/atmel-samd/common-hal/pulseio/PWMOut.c new file mode 100644 index 000000000..863f2084e --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PWMOut.c @@ -0,0 +1,331 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/runtime.h" +#include "common-hal/pulseio/PWMOut.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "samd21_pins.h" + +#undef ENABLE + +uint32_t target_timer_frequencies[TC_INST_NUM + TCC_INST_NUM]; +uint8_t timer_refcount[TC_INST_NUM + TCC_INST_NUM]; +const uint16_t prescaler[8] = {1, 2, 4, 8, 16, 64, 256, 1024}; + +// This bitmask keeps track of which channels of a TCC are currently claimed. +uint8_t tcc_channels[3] = {0xf0, 0xfc, 0xfc}; + +void pwmout_reset(void) { + // Reset all but TC5 + for (int i = 0; i < TC_INST_NUM + TCC_INST_NUM; i++) { + if (i == 5) { + target_timer_frequencies[i] = 1000; + timer_refcount[i] = 1; + } else { + target_timer_frequencies[i] = 0; + timer_refcount[i] = 0; + } + } + Tcc *tccs[TCC_INST_NUM] = TCC_INSTS; + for (int i = 0; i < TCC_INST_NUM; i++) { + tccs[i]->CTRLA.bit.SWRST = 1; + } + Tc *tcs[TC_INST_NUM] = TC_INSTS; + for (int i = 0; i < TC_INST_NUM; i++) { + if (tcs[i] == TC5) { + continue; + } + tcs[i]->COUNT16.CTRLA.bit.SWRST = 1; + } +} + +bool channel_ok(const pin_timer_t* t, uint8_t index) { + return (!t->is_tc && (tcc_channels[index] & (1 << t->channel)) == 0) || + t->is_tc; +} + +void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, + uint16_t duty, + uint32_t frequency, + bool variable_frequency) { + self->pin = pin; + self->variable_frequency = variable_frequency; + + if (pin->primary_timer.tc == 0 && pin->secondary_timer.tc == 0) { + mp_raise_ValueError("Invalid pin"); + } + + if (frequency == 0 || frequency > 6000000) { + mp_raise_ValueError("Invalid PWM frequency"); + } + + uint16_t primary_timer_index = 0xff; + uint16_t secondary_timer_index = 0xff; + if (pin->primary_timer.tc != NULL) { + primary_timer_index = (((uint32_t) pin->primary_timer.tcc) - ((uint32_t) TCC0)) / 0x400; + } + if (pin->secondary_timer.tc != NULL) { + secondary_timer_index = (((uint32_t) pin->secondary_timer.tcc) - ((uint32_t) TCC0)) / 0x400; + } + + // Figure out which timer we are using. + + // First see if a timer is already going with the frequency we want and our + // channel is unused. + // NOTE(shawcroft): The enable bit is in the same position for TC and TCC so + // we treat them all as TCC for checking ENABLE. + const pin_timer_t* t = NULL; + uint8_t index = 0; + if (!variable_frequency && + primary_timer_index != 0xff && + target_timer_frequencies[primary_timer_index] == frequency && + pin->primary_timer.tcc->CTRLA.bit.ENABLE == 1 && + channel_ok(&pin->primary_timer, primary_timer_index)) { + t = &pin->primary_timer; + index = primary_timer_index; + } else if (!variable_frequency && + secondary_timer_index != 0xff && + target_timer_frequencies[secondary_timer_index] == frequency && + pin->secondary_timer.tcc->CTRLA.bit.ENABLE == 1 && + channel_ok(&pin->secondary_timer, secondary_timer_index)) { + t = &pin->secondary_timer; + index = secondary_timer_index; + } else { + // Pick an unused timer if available. + + // Check the secondary timer first since its always a nicer TCC (when it + // exists) + if (pin->secondary_timer.tc != 0 && + timer_refcount[secondary_timer_index] == 0 && + pin->secondary_timer.tcc->CTRLA.bit.ENABLE == 0) { + t = &pin->secondary_timer; + index = secondary_timer_index; + } else if (pin->primary_timer.tc != 0 && + (!pin->primary_timer.is_tc || pin->primary_timer.channel == 1) && + timer_refcount[primary_timer_index] == 0) { + t = &pin->primary_timer; + index = primary_timer_index; + } + if (t == NULL) { + mp_raise_RuntimeError("All timers in use"); + return; + } + uint8_t resolution = 0; + if (t->is_tc) { + resolution = 16; + } else { + resolution = 24; + } + // First determine the divisor that gets us the highest resolution. + uint32_t system_clock = system_cpu_clock_get_hz(); + uint32_t top; + uint8_t divisor; + for (divisor = 0; divisor < 8; divisor++) { + top = (system_clock / prescaler[divisor] / frequency) - 1; + if (top < (1u << resolution)) { + break; + } + } + if (t->is_tc) { + struct tc_config config_tc; + tc_get_config_defaults(&config_tc); + + config_tc.counter_size = TC_COUNTER_SIZE_16BIT; + config_tc.clock_prescaler = TC_CTRLA_PRESCALER(divisor); + config_tc.wave_generation = TC_WAVE_GENERATION_MATCH_PWM; + config_tc.counter_16_bit.compare_capture_channel[0] = top; + + tc_init(&self->tc_instance, t->tc, &config_tc); + tc_enable(&self->tc_instance); + } else { + struct tcc_config config_tcc; + tcc_get_config_defaults(&config_tcc, t->tcc); + + config_tcc.counter.clock_prescaler = divisor; + config_tcc.counter.period = top; + config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM; + + tcc_init(&self->tcc_instance, t->tcc, &config_tcc); + tcc_enable(&self->tcc_instance); + } + + target_timer_frequencies[index] = frequency; + timer_refcount[index]++; + } + + if (!t->is_tc) { + if (variable_frequency) { + // We're changing frequency so claim all of the channels. + tcc_channels[index] = 0xff; + } else { + tcc_channels[index] |= (1 << t->channel); + } + } + + self->timer = t; + + // Connect the wave output to the outside world. + struct system_pinmux_config pin_config; + system_pinmux_get_config_defaults(&pin_config); + pin_config.mux_position = &self->pin->primary_timer == t ? MUX_E : MUX_F; + pin_config.direction = SYSTEM_PINMUX_PIN_DIR_OUTPUT; + system_pinmux_pin_set_config(pin->pin, &pin_config); + + common_hal_pulseio_pwmout_set_duty_cycle(self, duty); +} + +extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + const pin_timer_t* t = self->timer; + uint8_t index = (((uint32_t) t->tcc) - ((uint32_t) TCC0)) / 0x400; + timer_refcount[index]--; + if (!t->is_tc) { + tcc_channels[index] &= ~(1 << t->channel); + } + if (timer_refcount[index] == 0) { + target_timer_frequencies[index] = 0; + if (t->is_tc) { + tc_disable(&self->tc_instance); + } else { + if (t->tcc == TCC0) { + tcc_channels[index] = 0xf0; + } else { + tcc_channels[index] = 0xfc; + } + tcc_disable(&self->tcc_instance); + tcc_reset(&self->tcc_instance); + } + } + reset_pin(self->pin->pin); +} + +extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { + const pin_timer_t* t = self->timer; + if (t->is_tc) { + uint32_t top = ((uint32_t) t->tc->COUNT16.CC[0].reg + 1); + uint16_t adjusted_duty = top * duty / 0xffff; + tc_set_compare_value(&self->tc_instance, t->channel, adjusted_duty); + } else { + uint32_t top = t->tcc->PER.reg + 1; + uint32_t adjusted_duty = ((uint64_t) top) * duty / 0xffff; + tcc_set_compare_value(&self->tcc_instance, t->channel, adjusted_duty); + } +} + +uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { + const pin_timer_t* t = self->timer; + if (t->is_tc) { + uint16_t top = t->tc->COUNT16.CC[0].reg; + while (tc_is_syncing(&self->tc_instance)) { + /* Wait for sync */ + } + uint16_t cv = t->tc->COUNT16.CC[t->channel].reg; + return cv * 0xffff / top; + } else { + uint32_t top = t->tcc->PER.reg; + uint32_t cv = 0; + if ((t->tcc->STATUS.vec.CCBV & (1 << t->channel)) != 0) { + cv = t->tcc->CCB[t->channel].reg; + } else { + cv = t->tcc->CC[t->channel].reg; + } + return cv * 0xffff / top; + } +} + + +void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, + uint32_t frequency) { + if (frequency == 0 || frequency > 6000000) { + mp_raise_ValueError("Invalid PWM frequency"); + } + const pin_timer_t* t = self->timer; + uint8_t resolution; + if (t->is_tc) { + resolution = 16; + } else { + resolution = 24; + } + uint32_t system_clock = system_cpu_clock_get_hz(); + uint32_t new_top; + uint8_t new_divisor; + for (new_divisor = 0; new_divisor < 8; new_divisor++) { + new_top = (system_clock / prescaler[new_divisor] / frequency) - 1; + if (new_top < (1u << resolution)) { + break; + } + } + uint16_t old_duty = common_hal_pulseio_pwmout_get_duty_cycle(self); + uint8_t old_divisor; + if (t->is_tc) { + old_divisor = t->tc->COUNT16.CTRLA.bit.PRESCALER; + } else { + old_divisor = t->tcc->CTRLA.bit.PRESCALER; + } + if (new_divisor != old_divisor) { + if (t->is_tc) { + tc_disable(&self->tc_instance); + t->tc->COUNT16.CTRLA.bit.PRESCALER = new_divisor; + tc_enable(&self->tc_instance); + } else { + tcc_disable(&self->tcc_instance); + t->tcc->CTRLA.bit.PRESCALER = new_divisor; + tcc_enable(&self->tcc_instance); + } + } + if (t->is_tc) { + while (tc_is_syncing(&self->tc_instance)) { + /* Wait for sync */ + } + t->tc->COUNT16.CC[0].reg = new_top; + } else { + tcc_set_top_value(&self->tcc_instance, new_top); + } + + common_hal_pulseio_pwmout_set_duty_cycle(self, old_duty); +} + +uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { + uint32_t system_clock = system_cpu_clock_get_hz(); + const pin_timer_t* t = self->timer; + uint32_t top; + uint8_t divisor; + if (t->is_tc) { + top = t->tc->COUNT16.CC[0].reg; + divisor = t->tc->COUNT16.CTRLA.bit.PRESCALER; + } else { + top = t->tcc->PER.reg; + divisor = t->tcc->CTRLA.bit.PRESCALER; + } + return (system_clock / prescaler[divisor]) / (top + 1); +} + +bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { + return self->variable_frequency; +} diff --git a/atmel-samd/common-hal/pulseio/PWMOut.h b/atmel-samd/common-hal/pulseio/PWMOut.h new file mode 100644 index 000000000..b8e207f3e --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PWMOut.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "asf/sam0/drivers/tc/tc.h" +#include "asf/sam0/drivers/tcc/tcc.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t *pin; + const pin_timer_t* timer; + bool variable_frequency; + union { + struct tc_module tc_instance; + struct tcc_module tcc_instance; + }; +} pulseio_pwmout_obj_t; + +void pwmout_reset(void); + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PWMOUT_H__ diff --git a/atmel-samd/common-hal/pulseio/PulseIn.c b/atmel-samd/common-hal/pulseio/PulseIn.c new file mode 100644 index 000000000..69eff2a0b --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PulseIn.c @@ -0,0 +1,221 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/pulseio/PulseIn.h" + +#include + +#include "asf/common2/services/delay/delay.h" +#include "asf/sam0/drivers/extint/extint.h" +#include "asf/sam0/drivers/extint/extint_callback.h" +#include "asf/sam0/drivers/port/port.h" + +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "samd21_pins.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" + +#include "tick.h" + +static pulseio_pulsein_obj_t *active_pulseins[EIC_NUMBER_OF_INTERRUPTS]; +static uint64_t last_ms[EIC_NUMBER_OF_INTERRUPTS]; +static uint16_t last_us[EIC_NUMBER_OF_INTERRUPTS]; + +void pulsein_reset(void) { + for (int i = 0; i < EIC_NUMBER_OF_INTERRUPTS; i++) { + active_pulseins[i] = NULL; + last_ms[i] = 0; + last_us[i] = 0; + } +} + +static void pulsein_set_config(pulseio_pulsein_obj_t* self, bool first_edge) { + struct extint_chan_conf config; + extint_chan_get_config_defaults(&config); + config.gpio_pin = self->pin; + config.gpio_pin_pull = EXTINT_PULL_NONE; + config.filter_input_signal = true; + + if (!first_edge) { + config.detection_criteria = EXTINT_DETECT_BOTH; + } else if (self->idle_state) { + config.detection_criteria = EXTINT_DETECT_FALLING; + } else { + config.detection_criteria = EXTINT_DETECT_RISING; + } + extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); + extint_chan_set_config(self->channel, &config); + // Clear any interrupts that may have triggered without notifying the CPU. + EIC->INTFLAG.reg |= (1UL << self->channel); + extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); +} + +static void pulsein_callback(void) { + // Grab the current time first. + uint16_t current_us = tc_get_count_value(&ms_timer); + uint64_t current_ms = ticks_ms; + pulseio_pulsein_obj_t* self = active_pulseins[extint_get_current_channel()]; + current_us = current_us * 1000 / self->ticks_per_ms; + if (self->first_edge) { + self->first_edge = false; + pulsein_set_config(self, false); + } else { + uint32_t ms_diff = current_ms - last_ms[self->channel]; + uint16_t us_diff = current_us - last_us[self->channel]; + if (last_us[self->channel] > current_us) { + us_diff = 1000 + current_us - last_us[self->channel]; + } + uint32_t total_diff = us_diff; + if (ms_diff > 1) { + total_diff += (ms_diff - 1) * 1000; + } + uint16_t duration = 0xffff; + if (total_diff < duration) { + duration = total_diff; + } + + uint16_t i = (self->start + self->len) % self->maxlen; + self->buffer[i] = duration; + if (self->len < self->maxlen) { + self->len++; + } else { + self->start++; + } + } + last_ms[self->channel] = current_ms; + last_us[self->channel] = current_us; +} + +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + if (!pin->has_extint) { + mp_raise_RuntimeError("No hardware support on pin"); + } + // TODO(tannewt): Switch to checking actual extint peripheral state when other + // classes use extints. + if (active_pulseins[pin->extint_channel] != NULL) { + mp_raise_RuntimeError("EXTINT channel already in use"); + } + + self->buffer = (uint16_t *) gc_alloc(maxlen * sizeof(uint16_t), false); + if (self->buffer == NULL) { + mp_raise_msg_varg(&mp_type_MemoryError, "Failed to allocate RX buffer of %d bytes", maxlen * sizeof(uint16_t)); + } + self->channel = pin->extint_channel; + self->pin = pin->pin; + self->maxlen = maxlen; + self->idle_state = idle_state; + self->start = 0; + self->len = 0; + self->first_edge = true; + self->ticks_per_ms = (system_cpu_clock_get_hz() / 1000 - 1); + + active_pulseins[pin->extint_channel] = self; + + pulsein_set_config(self, true); + extint_register_callback( + pulsein_callback, + self->channel, + EXTINT_CALLBACK_TYPE_DETECT); + extint_chan_enable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); +} + +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); + active_pulseins[self->channel] = NULL; + reset_pin(self->pin); +} + +void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { + extint_chan_disable_callback(self->channel, EXTINT_CALLBACK_TYPE_DETECT); +} + +void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, + uint16_t trigger_duration) { + // Send the trigger pulse. + if (trigger_duration > 0) { + struct port_config pin_conf; + port_get_config_defaults(&pin_conf); + + pin_conf.direction = PORT_PIN_DIR_OUTPUT; + pin_conf.input_pull = PORT_PIN_PULL_NONE; + port_pin_set_config(self->pin, &pin_conf); + port_pin_set_output_level(self->pin, !self->idle_state); + delay_us(trigger_duration); + port_pin_set_output_level(self->pin, self->idle_state); + } + + // Reconfigure the pin and make sure its set to detect the first edge. + last_ms[self->channel] = 0; + last_us[self->channel] = 0; + self->first_edge = true; + pulsein_set_config(self, true); +} + +void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { + common_hal_mcu_disable_interrupts(); + self->start = 0; + self->len = 0; + common_hal_mcu_enable_interrupts(); +} + +uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { + if (self->len == 0) { + mp_raise_IndexError("pop from an empty PulseIn"); + } + common_hal_mcu_disable_interrupts(); + uint16_t value = self->buffer[self->start]; + self->start = (self->start + 1) % self->maxlen; + self->len--; + common_hal_mcu_enable_interrupts(); + + return value; +} + +uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { + return self->maxlen; +} + +uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { + return self->len; +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, + int16_t index) { + common_hal_mcu_disable_interrupts(); + if (index < 0) { + index += self->len; + } + if (index < 0 || index >= self->len) { + common_hal_mcu_enable_interrupts(); + mp_raise_IndexError("index out of range"); + } + uint16_t value = self->buffer[(self->start + index) % self->maxlen]; + common_hal_mcu_enable_interrupts(); + return value; +} diff --git a/atmel-samd/common-hal/pulseio/PulseIn.h b/atmel-samd/common-hal/pulseio/PulseIn.h new file mode 100644 index 000000000..717b7267a --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PulseIn.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H__ + +#include "common-hal/microcontroller/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + uint8_t channel; + uint8_t pin; + uint16_t* buffer; + uint16_t maxlen; + bool idle_state; + volatile uint16_t start; + volatile uint16_t len; + volatile bool first_edge; + uint16_t ticks_per_ms; +} pulseio_pulsein_obj_t; + +void pulsein_reset(void); + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEIN_H__ diff --git a/atmel-samd/common-hal/pulseio/PulseOut.c b/atmel-samd/common-hal/pulseio/PulseOut.c new file mode 100644 index 000000000..1df4e30db --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PulseOut.c @@ -0,0 +1,164 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/pulseio/PulseOut.h" + +#include + +#include "asf/sam0/drivers/tc/tc_interrupt.h" +#include "asf/sam0/drivers/port/port.h" + +#include "mpconfigport.h" +#include "py/runtime.h" +#include "shared-bindings/pulseio/PulseOut.h" + +#undef ENABLE + +// This timer is shared amongst all PulseOut objects under the assumption that +// the code is single threaded. +static struct tc_module tc_instance; +static uint8_t refcount = 0; + +static __IO PORT_PINCFG_Type *active_pincfg = NULL; +static uint16_t *pulse_buffer = NULL; +static volatile uint16_t pulse_index = 0; +static uint16_t pulse_length; +static volatile uint32_t current_compare = 0; + +static void turn_on(__IO PORT_PINCFG_Type * pincfg) { + pincfg->reg = PORT_PINCFG_PMUXEN; +} + +static void turn_off(__IO PORT_PINCFG_Type * pincfg) { + pincfg->reg = PORT_PINCFG_RESETVALUE; +} + +void pulse_finish(struct tc_module *const module) { + pulse_index++; + + if (active_pincfg == NULL) { + return; + } + // Always turn it off. + turn_off(active_pincfg); + if (pulse_index >= pulse_length) { + return; + } + current_compare = (current_compare + pulse_buffer[pulse_index] * 3 / 4) & 0xffff; + tc_set_compare_value(&tc_instance, TC_COMPARE_CAPTURE_CHANNEL_0, current_compare); + if (pulse_index % 2 == 0) { + turn_on(active_pincfg); + } +} + +void pulseout_reset() { + refcount = 0; + active_pincfg = NULL; +} + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + if (refcount == 0) { + // Find a spare timer. + Tc *t = NULL; + Tc *tcs[TC_INST_NUM] = TC_INSTS; + for (uint8_t i = TC_INST_NUM; i > 0; i--) { + if (tcs[i - 1]->COUNT16.CTRLA.bit.ENABLE == 0) { + t = tcs[i - 1]; + break; + } + } + if (t == NULL) { + mp_raise_RuntimeError("All timers in use"); + } + + struct tc_config config_tc; + tc_get_config_defaults(&config_tc); + + config_tc.counter_size = TC_COUNTER_SIZE_16BIT; + config_tc.clock_prescaler = TC_CTRLA_PRESCALER_DIV64; + config_tc.wave_generation = TC_WAVE_GENERATION_NORMAL_FREQ; + + tc_init(&tc_instance, t, &config_tc); + tc_register_callback(&tc_instance, pulse_finish, TC_CALLBACK_CC_CHANNEL0); + tc_enable(&tc_instance); + tc_stop_counter(&tc_instance); + } + refcount++; + + self->pin = carrier->pin->pin; + + PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin); + self->pincfg = &port_base->PINCFG[self->pin % 32]; + + // Set the port to output a zero. + port_base->OUTCLR.reg = 1 << (self->pin % 32); + port_base->DIRSET.reg = 1 << (self->pin % 32); + + // Turn off the pinmux which should connect the port output. + turn_off(self->pincfg); +} + +void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { + PortGroup *const port_base = port_get_group_from_gpio_pin(self->pin); + port_base->DIRCLR.reg = 1 << (self->pin % 32); + + turn_on(self->pincfg); + + refcount--; + if (refcount == 0) { + tc_reset(&tc_instance); + } +} + +void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { + if (active_pincfg != NULL) { + mp_raise_RuntimeError("Another send is already active"); + } + active_pincfg = self->pincfg; + pulse_buffer = pulses; + pulse_index = 0; + pulse_length = length; + + current_compare = pulses[0] * 3 / 4; + tc_set_compare_value(&tc_instance, TC_COMPARE_CAPTURE_CHANNEL_0, current_compare); + + tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0); + turn_on(active_pincfg); + tc_start_counter(&tc_instance); + + while(pulse_index < length) { + // Do other things while we wait. The interrupts will handle sending the + // signal. + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + + tc_stop_counter(&tc_instance); + tc_disable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0); + active_pincfg = NULL; +} diff --git a/atmel-samd/common-hal/pulseio/PulseOut.h b/atmel-samd/common-hal/pulseio/PulseOut.h new file mode 100644 index 000000000..f06dcc44f --- /dev/null +++ b/atmel-samd/common-hal/pulseio/PulseOut.h @@ -0,0 +1,44 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "asf/sam0/drivers/tc/tc.h" +#include "asf/sam0/drivers/tcc/tcc.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + __IO PORT_PINCFG_Type *pincfg; + uint8_t pin; +} pulseio_pulseout_obj_t; + +void pulseout_reset(void); + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_PULSEIO_PULSEOUT_H__ diff --git a/atmel-samd/common-hal/pulseio/__init__.c b/atmel-samd/common-hal/pulseio/__init__.c new file mode 100644 index 000000000..2bee925bc --- /dev/null +++ b/atmel-samd/common-hal/pulseio/__init__.c @@ -0,0 +1 @@ +// No pulseio module functions. diff --git a/atmel-samd/common-hal/touchio/TouchIn.c b/atmel-samd/common-hal/touchio/TouchIn.c new file mode 100644 index 000000000..a680294e2 --- /dev/null +++ b/atmel-samd/common-hal/touchio/TouchIn.c @@ -0,0 +1,306 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/nlr.h" +#include "py/mperrno.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "shared-bindings/touchio/TouchIn.h" + +#include "tick.h" + +#include "QTouch/touch_api_ptc.h" + +#define DEF_SELFCAP_CAL_SEQ1_COUNT 8 +#define DEF_SELFCAP_CAL_SEQ2_COUNT 4 +#define DEF_SELFCAP_CC_CAL_CLK_PRESCALE_PER_NODE DEF_SELFCAP_CLK_PRESCALE_PER_NODE +#define DEF_SELFCAP_CC_CAL_SENSE_RESISTOR_PER_NODE DEF_SELFCAP_SENSE_RESISTOR_PER_NODE +#define DEF_SELFCAP_QUICK_REBURST_ENABLE 1u + +/** + * Mutual Cap sensors measured data pointer. + * Note: This pointer is initialized by the QTouch library once the + * touch_mutlcap_sensors_init API is called. */ +touch_measure_data_t *p_mutlcap_measure_data = NULL; + +/** + * Self Cap sensors measured data pointer. + * Note: This pointer is initialized by the QTouch library once the + * touch_selfcap_sensors_init API is called. */ +touch_measure_data_t *p_selfcap_measure_data = NULL; + + +/** + * Self Cap sensors data block provided as input to Touch library. + */ +static uint8_t selfcap_data_blk[PRIV_SELFCAP_DATA_BLK_SIZE]; + +/** + * Self Cap sensors Pins Info. + */ + +uint32_t selfcap_y_nodes[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_LINES}; + +filter_level_t selfcap_filter_level_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_FILTER_LEVEL_PER_NODE}; + +uint8_t selfcap_auto_os_per_node[DEF_SELFCAP_NUM_CHANNELS]= {DEF_SELFCAP_AUTO_OS_PER_NODE}; + +gain_t selfcap_gain_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_GAIN_PER_NODE}; + +rsel_val_t selfcap_resistor_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_SENSE_RESISTOR_PER_NODE}; + +prsc_div_sel_t selfcap_prsc_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_CLK_PRESCALE_PER_NODE}; + +prsc_div_sel_t selfcap_boot_prsc_per_node[DEF_SELFCAP_NUM_CHANNELS] = {DEF_SELFCAP_CC_CAL_CLK_PRESCALE_PER_NODE}; + +rsel_val_t selfcap_boot_resistor_per_node[DEF_SELFCAP_NUM_CHANNELS] = { DEF_SELFCAP_CC_CAL_SENSE_RESISTOR_PER_NODE}; + +freq_hop_sel_t selfcap_freq_hops[3u] = {DEF_SELFCAP_HOP_FREQS}; + +/** + * Self Cap Configuration structure provided as input to Touch Library. + * + * Note: Use the touch.h configuration header file to fill in + * the elements of this structure. DO NOT modify any of the input values + * directly in this structure. + */ +touch_selfcap_config_t selfcap_config = { + 0, /* Self Cap number of channels. */ + 0, /* Self Cap number of sensors. */ + DEF_SELFCAP_NUM_ROTORS_SLIDERS, /* Self Cap number of rotors and + * sliders. */ + + /* Self Cap GLOBAL SENSOR CONFIGURATION INFO. */ + { + DEF_SELFCAP_DI, /* uint8_t di; Sensor detect + * integration (DI) limit. */ + + /* Interchanging Negative and Positive Drift rate, since Signal + * increases on Touch. */ + DEF_SELFCAP_ATCH_DRIFT_RATE, /* uint8_t neg_drift_rate; + * Sensor + * negative drift rate. */ + DEF_SELFCAP_TCH_DRIFT_RATE, /* uint8_t pos_drift_rate; + * Sensor + * positive drift rate. */ + DEF_SELFCAP_MAX_ON_DURATION, /* uint8_t max_on_duration; + * Sensor + * maximum on duration. */ + DEF_SELFCAP_DRIFT_HOLD_TIME, /* uint8_t drift_hold_time; + * Sensor + * drift hold time. */ + DEF_SELFCAP_ATCH_RECAL_DELAY, /* uint8_t pos_recal_delay; + * Sensor positive recalibration + * delay. */ + + DEF_SELFCAP_CAL_SEQ1_COUNT, + DEF_SELFCAP_CAL_SEQ2_COUNT, + DEF_SELFCAP_ATCH_RECAL_THRESHOLD, /* recal_threshold_t + * recal_threshold; Sensor + * recalibration threshold. */ + DEF_SELFCAP_TOUCH_POSTPROCESS_MODE, + DEF_SELFCAP_AUTO_OS_SIGNAL_STABILITY_LIMIT, + DEF_SELFCAP_FREQ_AUTO_TUNE_SIGNAL_STABILITY_LIMIT, + DEF_SELFCAP_FREQ_AUTO_TUNE_IN_CNT, + DEF_SELFCAP_NOISE_MEAS_SIGNAL_STABILITY_LIMIT, /* signal + *stability */ + DEF_SELFCAP_NOISE_LIMIT, + DEF_SELFCAP_LOCKOUT_SEL, + DEF_SELFCAP_LOCKOUT_CNTDOWN, + #if ((SAMC20) || (SAMC21) || (SAML22)) + DEF_SELF_CAP_CSD_VALUE, + #endif + }, + { + selfcap_gain_per_node, /* Self Cap channel gain setting. */ + DEF_SELFCAP_FREQ_MODE, /* Self Cap noise counter measure + * enable/disable. */ + selfcap_prsc_per_node, + selfcap_resistor_per_node, + selfcap_boot_prsc_per_node, + selfcap_boot_resistor_per_node, + selfcap_freq_hops, + selfcap_filter_level_per_node, /* Self Cap filter level setting. */ + selfcap_auto_os_per_node, /* Self Cap auto oversamples + *setting. */ + }, + selfcap_data_blk, /* Self Cap data block index. */ + PRIV_SELFCAP_DATA_BLK_SIZE, /* Self Cap data block size. */ + selfcap_y_nodes, /* Self Cap channel nodes. */ + DEF_SELFCAP_QUICK_REBURST_ENABLE, + DEF_SELFCAP_FILTER_CALLBACK, /* Self Cap filter callback + * function + * pointer. */ + DEF_SELFCAP_FREQ_AUTO_TUNE_ENABLE, + DEF_SELFCAP_NOISE_MEAS_ENABLE, + DEF_SELFCAP_NOISE_MEAS_BUFFER_CNT, + DEF_SELFCAP_MOIS_TOLERANCE_ENABLE, + DEF_SELFCAP_NUM_MOIS_GROUPS, + DEF_SELFCAP_MOIS_QUICK_REBURST_ENABLE, + DEF_SELFCAP_PTC_GPIO_STATE, + .tlib_feature_list ={ + .lk_chk = DEF_LOCKOUT_FUNC, + .auto_os_init = DEF_AUTO_OS_FUNC,//auto_os_resolve, + .auto_tune_init = DEF_SELF_AUTO_TUNE_FUNC,// self_auto_tuning + .enable_aks = DEF_AKS_FUNC, /*AKS grouping function */ + } +}; + +/** + * Touch Library input configuration structure. + */ +touch_config_t touch_config = { + NULL, + &selfcap_config, /* Pointer to Self Cap configuration + * structure. */ + DEF_TOUCH_PTC_ISR_LVL, /* PTC interrupt level. */ +}; + +touchio_touchin_obj_t *active_touchin_obj[DEF_SELFCAP_NUM_CHANNELS]; + +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, + const mcu_pin_obj_t *pin) { + if (!pin->has_touch) { + mp_raise_ValueError("Invalid pin"); + } + + if (selfcap_config.num_channels > 0) { + // Deinit the touch sensor, we're going to reinitialize it. + touch_selfcap_sensors_deinit(); + + // Remove holes in the active list from sensors that may have been + // disabled. + int first_hole = -1; + for (int i = 0; i < selfcap_config.num_channels; i++) { + if (active_touchin_obj[i] == NULL && first_hole == -1) { + first_hole = i; + } else if (active_touchin_obj[i] != NULL && first_hole != -1) { + active_touchin_obj[first_hole] = active_touchin_obj[i]; + first_hole = i; + } + } + if (first_hole > -1) { + selfcap_config.num_channels = first_hole; + selfcap_config.num_sensors = first_hole; + } + } + + // Add our sensor to the end of the list. + self->pin = pin; + selfcap_y_nodes[selfcap_config.num_channels++] = Y(pin->touch_y_line); + active_touchin_obj[selfcap_config.num_sensors++] = self; + + /* Setup and enable generic clock source for PTC module. */ + struct system_gclk_chan_config gclk_chan_conf; + system_gclk_chan_get_config_defaults(&gclk_chan_conf); + gclk_chan_conf.source_generator = GCLK_GENERATOR_3; + system_gclk_chan_set_config(PTC_GCLK_ID, &gclk_chan_conf); + system_gclk_chan_enable(PTC_GCLK_ID); + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_PTC); + + touch_ret_t status; + /* Initialize touch library for Self Cap operation. */ + status = touch_selfcap_sensors_init_with_rs_table(&touch_config, + PRIV_SELFCAP_RS_TABLE_INIT, PRIV_NM_TABLE_INIT, + PRIV_FREQ_AUTO_TUNE_CHK, PRIV_MOIS_TOLERANCE_CHK); + if (status != TOUCH_SUCCESS) { + mp_raise_OSError(MP_EIO); + } + for (int i = 0; i < selfcap_config.num_channels; i++) { + status = touch_selfcap_sensor_config(SENSOR_TYPE_KEY, i, i, + NO_AKS_GROUP, 10u, HYST_25, RES_8_BIT, &active_touchin_obj[i]->sensor_id); + if (status != TOUCH_SUCCESS) { + mp_raise_OSError(MP_EIO); + } + } + status = touch_selfcap_sensors_calibrate(AUTO_TUNE_RSEL); + if (status != TOUCH_SUCCESS) { + mp_raise_OSError(MP_EIO); + } + + // Run a measurement to get calibrated. + common_hal_touchio_touchin_get_value(self); +} + +// This may get called twice, once on exit or deinit and once from the finaliser +// (__del__). We need the finaliser to reduce the chance of us writing to memory +// we no longer own because we keep track of Python pointers in active_touchin_obj. +void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self) { + touch_selfcap_sensor_disable(self->sensor_id); + // Remove ourselves from the list of active objects. We don't change the + // selfcap settings at all because we don't want to reinit now. Instead, + // we'll collect blank spots later on reinit. + for (int i = 0; i < DEF_SELFCAP_NUM_CHANNELS; i++) { + if (active_touchin_obj[i] == self) { + active_touchin_obj[i] = NULL; + break; + } + } +} + +volatile bool touch_read_ready = false; +volatile touch_acq_status_t touch_acq_status; + +void touch_selfcap_measure_complete_callback(void) +{ + touch_read_ready = true; + touch_acq_status = p_selfcap_measure_data->acq_status; +} + +bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self) { + if (p_selfcap_measure_data->acq_status & TOUCH_CC_CALIB_ERROR) { + mp_raise_RuntimeError("Touch calibration error"); + } + touch_acq_status = TOUCH_BURST_AGAIN; + uint64_t start_ticks = ticks_ms; + while((touch_acq_status & TOUCH_BURST_AGAIN) && ticks_ms - start_ticks < 1000) { + touch_read_ready = false; + touch_ret_t touch_ret = touch_selfcap_sensors_measure( + ticks_ms, + NORMAL_ACQ_MODE, + touch_selfcap_measure_complete_callback); + + if (touch_ret != TOUCH_SUCCESS) { + mp_raise_OSError(MP_EIO); + } + + while(!touch_read_ready && ticks_ms - start_ticks < 1000) { + // wait + #ifdef MICROPY_VM_HOOK_LOOP + MICROPY_VM_HOOK_LOOP + #endif + } + } + + if (touch_acq_status & TOUCH_BURST_AGAIN) { + mp_raise_OSError(MP_EIO); + } + + return (p_selfcap_measure_data->p_sensor_states[self->sensor_id / 8] & (1 << (self->sensor_id % 8))) != 0; +} diff --git a/atmel-samd/common-hal/touchio/TouchIn.h b/atmel-samd/common-hal/touchio/TouchIn.h new file mode 100644 index 000000000..85799529e --- /dev/null +++ b/atmel-samd/common-hal/touchio/TouchIn.h @@ -0,0 +1,42 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H__ + +#include "common-hal/microcontroller/types.h" + +#include "QTouch/touch_api_ptc.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + sensor_id_t sensor_id; +} touchio_touchin_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_TOUCHIO_TOUCHIN_H__ diff --git a/atmel-samd/common-hal/touchio/__init__.c b/atmel-samd/common-hal/touchio/__init__.c new file mode 100644 index 000000000..d2290447c --- /dev/null +++ b/atmel-samd/common-hal/touchio/__init__.c @@ -0,0 +1 @@ +// No touchio module functions. diff --git a/atmel-samd/main.c b/atmel-samd/main.c index 8c22b6a6c..613abb5a3 100644 --- a/atmel-samd/main.c +++ b/atmel-samd/main.c @@ -24,13 +24,13 @@ #include "asf/sam0/drivers/system/system.h" #include -#include "common-hal/nativeio/AnalogIn.h" -#include "common-hal/nativeio/PulseOut.h" -#include "common-hal/nativeio/PWMOut.h" +#include "common-hal/analogio/AnalogIn.h" +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PWMOut.h" #include "common-hal/usb_hid/__init__.h" #ifdef EXPRESS_BOARD -#include "common-hal/nativeio/types.h" +#include "common-hal/touchio/TouchIn.h" #include "QTouch/touch_api_ptc.h" #define INTERNAL_CIRCUITPY_CONFIG_START_ADDR (0x00040000 - 0x100) #else @@ -138,7 +138,7 @@ void reset_mp(void) { } #ifdef EXPRESS_BOARD -extern nativeio_touchin_obj_t *active_touchin_obj[DEF_SELFCAP_NUM_CHANNELS]; +extern touchio_touchin_obj_t *active_touchin_obj[DEF_SELFCAP_NUM_CHANNELS]; extern touch_selfcap_config_t selfcap_config; #endif extern volatile bool mp_msc_enabled; diff --git a/atmel-samd/mpconfigport.h b/atmel-samd/mpconfigport.h index 1d1abe21e..b6b77d24f 100644 --- a/atmel-samd/mpconfigport.h +++ b/atmel-samd/mpconfigport.h @@ -126,7 +126,10 @@ typedef long mp_off_t; // extra built in modules to add to the list of known ones extern const struct _mp_obj_module_t microcontroller_module; extern const struct _mp_obj_module_t bitbangio_module; -extern const struct _mp_obj_module_t nativeio_module; +extern const struct _mp_obj_module_t analogio_module; +extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t pulseio_module; +extern const struct _mp_obj_module_t busio_module; extern const struct _mp_obj_module_t board_module; extern const struct _mp_obj_module_t uos_module; extern const struct _mp_obj_module_t time_module; @@ -137,8 +140,10 @@ extern const struct _mp_obj_module_t usb_hid_module; // Internal flash size dependent settings. #if BOARD_FLASH_SIZE > 192000 + extern const struct _mp_obj_module_t touchio_module; #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) #define EXTRA_BUILTIN_MODULES \ + { MP_OBJ_NEW_QSTR(MP_QSTR_touchio), (mp_obj_t)&touchio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module } #define EXPRESS_BOARD #else @@ -148,7 +153,10 @@ extern const struct _mp_obj_module_t usb_hid_module; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_nativeio), (mp_obj_t)&nativeio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_uos), (mp_obj_t)&uos_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ diff --git a/atmel-samd/rgb_led_status.c b/atmel-samd/rgb_led_status.c index 7d77fc1eb..e04f12339 100644 --- a/atmel-samd/rgb_led_status.c +++ b/atmel-samd/rgb_led_status.c @@ -4,7 +4,7 @@ #include "mphalport.h" #include "shared-bindings/bitbangio/SPI.h" -#include "shared-bindings/nativeio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/neopixel_write/__init__.h" #include "shared-module/bitbangio/types.h" #include "rgb_led_status.h" @@ -12,7 +12,7 @@ #ifdef MICROPY_HW_NEOPIXEL static uint8_t status_neopixel_color[3]; -static nativeio_digitalinout_obj_t status_neopixel; +static digitalio_digitalinout_obj_t status_neopixel; #endif #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) @@ -26,8 +26,8 @@ static uint32_t current_status_color = 0; void rgb_led_status_init() { #ifdef MICROPY_HW_NEOPIXEL - common_hal_nativeio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL); - common_hal_nativeio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL); + common_hal_digitalio_digitalinout_construct(&status_neopixel, MICROPY_HW_NEOPIXEL); + common_hal_digitalio_digitalinout_switch_to_output(&status_neopixel, false, DRIVE_MODE_PUSH_PULL); #endif #if defined(MICROPY_HW_APA102_MOSI) && defined(MICROPY_HW_APA102_SCK) shared_module_bitbangio_spi_construct(&status_apa102, diff --git a/docs/common_hal.md b/docs/common_hal.md index 9492699f4..22093c3ba 100644 --- a/docs/common_hal.md +++ b/docs/common_hal.md @@ -1,5 +1,7 @@ -# Adding `nativeio` support to other ports -`nativeio` provides a well-defined, cross-port hardware abstraction layer built to support different devices and their drivers. It's backed by the Common HAL, a C api suitable for supporting different hardware in a similar manner. By sharing this C api, developers can support new hardware easily and cross-port functionality to the new hardware. +# Adding `digitalio` support to other ports +`digitalio` provides a well-defined, cross-port hardware abstraction layer built to support different devices and their drivers. It's backed by the Common HAL, a C api suitable for supporting different hardware in a similar manner. By sharing this C api, developers can support new hardware easily and cross-port functionality to the new hardware. + +These instructions also apply to `analogio`, `busio`, `pulseio` and `touchio`. Most drivers depend on `analogio`, `digitalio` and `busio` so start with those. ## File layout Common HAL related files are found in these locations: @@ -20,15 +22,23 @@ SRC_BINDINGS = \ board/__init__.c \ microcontroller/__init__.c \ microcontroller/Pin.c \ - nativeio/__init__.c \ - nativeio/AnalogIn.c \ - nativeio/AnalogOut.c \ - nativeio/DigitalInOut.c \ - nativeio/I2C.c \ - nativeio/PWMOut.c \ - nativeio/SPI.c \ + analogio/__init__.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ + pulseio/__init__.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/PWMOut.c \ + busio/__init__.c \ + busio/I2C.c \ + busio/SPI.c \ + busio/UART.c \ neopixel_write/__init__.c \ - time/__init__.c + time/__init__.c \ + usb_hid/__init__.c \ + usb_hid/Device.c SRC_BINDINGS_EXPANDED = $(addprefix shared-bindings/, $(SRC_BINDINGS)) \ $(addprefix common-hal/, $(SRC_BINDINGS)) @@ -46,14 +56,20 @@ Built in modules are typically defined in `mpconfigport.h`. To add support you s ``` extern const struct _mp_obj_module_t microcontroller_module; -extern const struct _mp_obj_module_t nativeio_module; +extern const struct _mp_obj_module_t analogio_module; +extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t pulseio_module; +extern const struct _mp_obj_module_t busio_module; extern const struct _mp_obj_module_t board_module; extern const struct _mp_obj_module_t time_module; extern const struct _mp_obj_module_t neopixel_write_module; #define MICROPY_PORT_BUILTIN_MODULES \ { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_nativeio), (mp_obj_t)&nativeio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module } \ diff --git a/docs/design_guide.rst b/docs/design_guide.rst index 8f56697fd..69860b7dc 100644 --- a/docs/design_guide.rst +++ b/docs/design_guide.rst @@ -267,8 +267,8 @@ you can because you never know how much something will be called. Fewer allocations means less time spent cleaning up. So, where you can, prefer bytearray buffers that are created in ``__init__`` and used throughout the object with methods that read or write into the buffer instead of creating new -objects. `nativeio` classes are design to read and write to subsections of -buffers. +objects. Unified hardware API classes such as `busio.SPI` are design to read and +write to subsections of buffers. Its ok to allocate an object to return to the user. Just beware of causing more than one allocation per call due to internal logic. diff --git a/esp8266/Makefile b/esp8266/Makefile index eac6eddc5..93e424112 100644 --- a/esp8266/Makefile +++ b/esp8266/Makefile @@ -79,7 +79,7 @@ SRC_C = \ esp_init_data.c \ gccollect.c \ lexerstr32.c \ - uart.c \ + espuart.c \ esppwm.c \ esponewire.c \ espneopixel.c \ @@ -109,16 +109,18 @@ SRC_C = \ SRC_COMMON_HAL = \ microcontroller/__init__.c \ microcontroller/Pin.c \ - nativeio/__init__.c \ - nativeio/AnalogIn.c \ - nativeio/AnalogOut.c \ - nativeio/DigitalInOut.c \ - nativeio/PulseIn.c \ - nativeio/PulseOut.c \ - nativeio/PWMOut.c \ - nativeio/SPI.c \ - nativeio/TouchIn.c \ - nativeio/UART.c \ + analogio/__init__.c \ + analogio/AnalogIn.c \ + analogio/AnalogOut.c \ + digitalio/__init__.c \ + digitalio/DigitalInOut.c \ + pulseio/__init__.c \ + pulseio/PulseIn.c \ + pulseio/PulseOut.c \ + pulseio/PWMOut.c \ + busio/__init__.c \ + busio/SPI.c \ + busio/UART.c \ neopixel_write/__init__.c \ time/__init__.c \ board/__init__.c @@ -131,8 +133,8 @@ SRC_SHARED_MODULE = \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ - nativeio/I2C.c \ - nativeio/OneWire.c \ + busio/I2C.c \ + busio/OneWire.c \ SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \ $(addprefix shared-module/, $(SRC_SHARED_MODULE)) diff --git a/esp8266/common-hal/analogio/AnalogIn.c b/esp8266/common-hal/analogio/AnalogIn.c new file mode 100644 index 000000000..0f43a0879 --- /dev/null +++ b/esp8266/common-hal/analogio/AnalogIn.c @@ -0,0 +1,60 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/analogio/AnalogIn.h" + +#include "user_interface.h" + +volatile bool adc_in_use __attribute__((aligned(4))) = false; + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, + const mcu_pin_obj_t *pin) { + if (pin != &pin_TOUT) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q does not have ADC capabilities", pin->name)); + } + adc_in_use = true; +} + +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self) { + adc_in_use = false; +} + +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) { + // ADC is 10 bit so shift by 6 to make it 16-bit. + return system_adc_read() << 6; +} + +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) { + return 1.0f; +} diff --git a/esp8266/common-hal/analogio/AnalogIn.h b/esp8266/common-hal/analogio/AnalogIn.h new file mode 100644 index 000000000..a4edd233d --- /dev/null +++ b/esp8266/common-hal/analogio/AnalogIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H__ + +#include "common-hal/microcontroller/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; +} analogio_analogin_obj_t; + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H__ diff --git a/esp8266/common-hal/analogio/AnalogOut.c b/esp8266/common-hal/analogio/AnalogOut.c new file mode 100644 index 000000000..30dc44830 --- /dev/null +++ b/esp8266/common-hal/analogio/AnalogOut.c @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "py/runtime.h" + +#include "shared-bindings/analogio/AnalogOut.h" + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, + const mcu_pin_obj_t *pin) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "No hardware support for analog out.")); +} + +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) { +} + +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, + uint16_t value) { +} diff --git a/esp8266/common-hal/analogio/AnalogOut.h b/esp8266/common-hal/analogio/AnalogOut.h new file mode 100644 index 000000000..146a6571c --- /dev/null +++ b/esp8266/common-hal/analogio/AnalogOut.h @@ -0,0 +1,37 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ + +#include "py/obj.h" + +// Not supported, throws error on construction. +typedef struct { + mp_obj_base_t base; +} analogio_analogout_obj_t; + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H__ diff --git a/esp8266/common-hal/analogio/__init__.c b/esp8266/common-hal/analogio/__init__.c new file mode 100644 index 000000000..eea58c77d --- /dev/null +++ b/esp8266/common-hal/analogio/__init__.c @@ -0,0 +1 @@ +// No analogio module functions. diff --git a/esp8266/common-hal/busio/I2C.h b/esp8266/common-hal/busio/I2C.h new file mode 100644 index 000000000..5877e6c31 --- /dev/null +++ b/esp8266/common-hal/busio/I2C.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H__ + +// Use the bitbang wrapper for I2C +#include "shared-module/busio/I2C.h" + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H__ diff --git a/esp8266/common-hal/busio/OneWire.h b/esp8266/common-hal/busio/OneWire.h new file mode 100644 index 000000000..3c52ced38 --- /dev/null +++ b/esp8266/common-hal/busio/OneWire.h @@ -0,0 +1,33 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H__ + +// Use the bitbang wrapper for OneWire +#include "shared-module/busio/OneWire.h" + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H__ diff --git a/esp8266/common-hal/busio/SPI.c b/esp8266/common-hal/busio/SPI.c new file mode 100644 index 000000000..9ffb0294d --- /dev/null +++ b/esp8266/common-hal/busio/SPI.c @@ -0,0 +1,176 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "esp8266/ets_alt_task.h" +#include "esp8266/hspi.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "common-hal/busio/SPI.h" +#include "py/nlr.h" + +#include "eagle_soc.h" +#include "c_types.h" +#include "gpio.h" + +extern const mcu_pin_obj_t pin_MTMS; +extern const mcu_pin_obj_t pin_MTCK; +extern const mcu_pin_obj_t pin_MTDI; + +void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso) { + if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) || + (mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI))) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Pins not valid for SPI")); + } + + uint32_t clock_div_flag = 0; + if (SPI_CLK_USE_DIV) { + clock_div_flag = 0x0001; + } + + // Set bit 9 if 80MHz sysclock required + WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9)); + // GPIO12 is HSPI MISO pin (Master Data In) + if (miso == &pin_MTDI) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2); + } + // GPIO13 is HSPI MOSI pin (Master Data Out) + if (mosi == &pin_MTCK) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); + } + // GPIO14 is HSPI CLK pin (Clock) + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); + + spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV); + spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); + spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); + + SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD); + CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE); +} + +void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); + + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 0); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); + + // Turn off outputs 12 - 14. + gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12); +} + +bool common_hal_busio_spi_configure(busio_spi_obj_t *self, + uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { + if (bits != 8) { + return false; + } + if (baudrate == 80000000L) { + // Special case for full speed. + spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV); + spi_clock(HSPI, 0, 0); + } else if (baudrate > 40000000L) { + return false; + } else { + uint32_t divider = 40000000L / baudrate; + uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1); + uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even + if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) { + return false; + } + spi_init_gpio(HSPI, SPI_CLK_USE_DIV); + spi_clock(HSPI, prediv, cntdiv); + } + spi_mode(HSPI, phase, polarity); + return true; +} + +bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) { + bool success = false; + common_hal_mcu_disable_interrupts(); + if (!self->locked) { + self->locked = true; + success = true; + } + common_hal_mcu_enable_interrupts(); + return success; +} + +bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) { + return self->locked; +} + +void common_hal_busio_spi_unlock(busio_spi_obj_t *self) { + self->locked = false; +} + +bool common_hal_busio_spi_write(busio_spi_obj_t *self, + const uint8_t * data, size_t len) { + size_t chunk_size = 1024; + size_t count = len / chunk_size; + size_t i = 0; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + spi_tx8fast(HSPI, data[i]); + ++i; + } + ets_loop_iter(); + } + while (i < len) { + spi_tx8fast(HSPI, data[i]); + ++i; + } + while (spi_busy(HSPI)) {}; // Wait for SPI to finish the last byte. + return true; +} + +bool common_hal_busio_spi_read(busio_spi_obj_t *self, + uint8_t * data, size_t len, uint8_t write_value) { + // Process data in chunks, let the pending tasks run in between + size_t chunk_size = 1024; // TODO this should depend on baudrate + size_t count = len / chunk_size; + size_t i = 0; + uint32_t long_write_value = ((uint32_t) write_value) << 24 | + write_value << 16 | + write_value << 8 | + write_value; + for (size_t j = 0; j < count; ++j) { + for (size_t k = 0; k < chunk_size; ++k) { + data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 0, 0, 8, long_write_value); + ++i; + } + ets_loop_iter(); + } + while (i < len) { + data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 0, 0, 8, long_write_value); + ++i; + } + return true; +} diff --git a/esp8266/common-hal/busio/SPI.h b/esp8266/common-hal/busio/SPI.h new file mode 100644 index 000000000..baff10b70 --- /dev/null +++ b/esp8266/common-hal/busio/SPI.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H__ + +#include "common-hal/microcontroller/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bool locked; +} busio_spi_obj_t; + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H__ diff --git a/esp8266/common-hal/busio/UART.c b/esp8266/common-hal/busio/UART.c new file mode 100644 index 000000000..b2a1d69b8 --- /dev/null +++ b/esp8266/common-hal/busio/UART.c @@ -0,0 +1,120 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "common-hal/microcontroller/__init__.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/busio/UART.h" + +#include "ets_sys.h" +#include "espuart.h" + +#include "py/nlr.h" + +// UartDev is defined and initialized in rom code. +extern UartDevice UartDev; + +void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, + uint8_t receiver_buffer_size) { + if (rx != NULL || tx != &pin_GPIO2) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Only tx supported on UART1 (GPIO2).")); + } + // set baudrate + UartDev.baut_rate = baudrate; + + // set data bits + switch (bits) { + case 5: + UartDev.data_bits = UART_FIVE_BITS; + break; + case 6: + UartDev.data_bits = UART_SIX_BITS; + break; + case 7: + UartDev.data_bits = UART_SEVEN_BITS; + break; + case 8: + UartDev.data_bits = UART_EIGHT_BITS; + break; + default: + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid data bits")); + break; + } + + if (parity == PARITY_NONE) { + UartDev.parity = UART_NONE_BITS; + UartDev.exist_parity = UART_STICK_PARITY_DIS; + } else { + UartDev.exist_parity = UART_STICK_PARITY_EN; + if (parity == PARITY_ODD) { + UartDev.parity = UART_ODD_BITS; + } else { + UartDev.parity = UART_EVEN_BITS; + } + } + + switch (stop) { + case 1: + UartDev.stop_bits = UART_ONE_STOP_BIT; + break; + case 2: + UartDev.stop_bits = UART_TWO_STOP_BIT; + break; + default: + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid stop bits")); + break; + } + + uart_setup(UART1); +} + +void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { + PIN_FUNC_SELECT(FUNC_U1TXD_BK, 0); +} + +size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { + return 0; +} + +// Write characters. +size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { + // write the data + for (size_t i = 0; i < len; ++i) { + uart_tx_one_char(UART1, *data++); + } + + // return number of bytes written + return len; +} + +uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { + return 0; +} + +bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { + return true; +} diff --git a/esp8266/common-hal/busio/UART.h b/esp8266/common-hal/busio/UART.h new file mode 100644 index 000000000..a87e7c9b2 --- /dev/null +++ b/esp8266/common-hal/busio/UART.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H__ + +#include "common-hal/microcontroller/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} busio_uart_obj_t; + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H__ diff --git a/esp8266/common-hal/busio/__init__.c b/esp8266/common-hal/busio/__init__.c new file mode 100644 index 000000000..41761b674 --- /dev/null +++ b/esp8266/common-hal/busio/__init__.c @@ -0,0 +1 @@ +// No busio module functions. diff --git a/esp8266/common-hal/digitalio/DigitalInOut.c b/esp8266/common-hal/digitalio/DigitalInOut.c new file mode 100644 index 000000000..356d0f3b8 --- /dev/null +++ b/esp8266/common-hal/digitalio/DigitalInOut.c @@ -0,0 +1,176 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include +#include + +#include "py/nlr.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/digitalio/DigitalInOut.h" + +digitalinout_result_t common_hal_digitalio_digitalinout_construct( + digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { + self->pin = pin; + PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); + return DIGITALINOUT_OK; +} + +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) { + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } +} + +void common_hal_digitalio_digitalinout_switch_to_input( + digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { + self->output = false; + + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input + } else { + PIN_PULLUP_DIS(self->pin->peripheral); + gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); + } + common_hal_digitalio_digitalinout_set_pull(self, pull); +} + +void common_hal_digitalio_digitalinout_switch_to_output( + digitalio_digitalinout_obj_t* self, bool value, + enum digitalinout_drive_mode_t drive_mode) { + self->output = true; + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + if (self->pin->gpio_number == 16) { + WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); + WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); + WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output + } else if (!self->open_drain) { + gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } + common_hal_digitalio_digitalinout_set_value(self, value); +} + +enum digitalinout_direction_t common_hal_digitalio_digitalinout_get_direction( + digitalio_digitalinout_obj_t* self) { + return self->output? DIRECTION_OUT : DIRECTION_IN; +} + +void common_hal_digitalio_digitalinout_set_value( + digitalio_digitalinout_obj_t* self, bool value) { + if (value) { + if (self->open_drain) { + // Disable output. + gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); + } else { + // Set high + gpio_output_set(1 << self->pin->gpio_number, 0, 0, 0); + } + } else { + if (self->open_drain) { + // Enable the output + gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); + } + // Set low + gpio_output_set(0, 1 << self->pin->gpio_number, 0, 0); + } +} + +// Register addresses taken from: https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers +volatile uint32_t* PIN_DIR = (uint32_t *) 0x6000030C; +volatile uint32_t* PIN_OUT = (uint32_t *) 0x60000300; +bool common_hal_digitalio_digitalinout_get_value( + digitalio_digitalinout_obj_t* self) { + if (!self->output) { + if (self->pin->gpio_number == 16) { + return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1; + } + return GPIO_INPUT_GET(self->pin->gpio_number); + } else { + uint32_t pin_mask = 1 << self->pin->gpio_number; + if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { + return true; + } else { + return ((*PIN_OUT) & pin_mask) != 0; + } + } +} + +void common_hal_digitalio_digitalinout_set_drive_mode( + digitalio_digitalinout_obj_t* self, + enum digitalinout_drive_mode_t drive_mode) { + bool value = common_hal_digitalio_digitalinout_get_value(self); + self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; + // True is implemented differently between modes so reset the value to make + // sure its correct for the new mode. + if (value) { + common_hal_digitalio_digitalinout_set_value(self, value); + } +} + +enum digitalinout_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode( + digitalio_digitalinout_obj_t* self) { + if (self->open_drain) { + return DRIVE_MODE_OPEN_DRAIN; + } else { + return DRIVE_MODE_PUSH_PULL; + } +} + +void common_hal_digitalio_digitalinout_set_pull( + digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { + if (pull == PULL_DOWN) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "ESP8266 does not support pull down.")); + return; + } + if (self->pin->gpio_number == 16) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "Pin does not support pull.")); + return; + } + if (pull == PULL_NONE) { + PIN_PULLUP_DIS(self->pin->peripheral); + } else { + PIN_PULLUP_EN(self->pin->peripheral); + } +} + +enum digitalinout_pull_t common_hal_digitalio_digitalinout_get_pull( + digitalio_digitalinout_obj_t* self) { + if (self->pin->gpio_number < 16 && + (READ_PERI_REG(self->pin->peripheral) & PERIPHS_IO_MUX_PULLUP) != 0) { + return PULL_UP; + } + return PULL_NONE; +} diff --git a/esp8266/common-hal/digitalio/DigitalInOut.h b/esp8266/common-hal/digitalio/DigitalInOut.h new file mode 100644 index 000000000..94de1bca5 --- /dev/null +++ b/esp8266/common-hal/digitalio/DigitalInOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + const mcu_pin_obj_t * pin; + bool output; + bool open_drain; +} digitalio_digitalinout_obj_t; + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H__ diff --git a/esp8266/common-hal/digitalio/__init__.c b/esp8266/common-hal/digitalio/__init__.c new file mode 100644 index 000000000..20fad4595 --- /dev/null +++ b/esp8266/common-hal/digitalio/__init__.c @@ -0,0 +1 @@ +// No digitalio module functions. diff --git a/esp8266/common-hal/nativeio/AnalogIn.c b/esp8266/common-hal/nativeio/AnalogIn.c deleted file mode 100644 index 57ff607a3..000000000 --- a/esp8266/common-hal/nativeio/AnalogIn.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "common-hal/microcontroller/__init__.h" -#include "shared-bindings/nativeio/AnalogIn.h" - -#include "user_interface.h" - -volatile bool adc_in_use __attribute__((aligned(4))) = false; - -void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, - const mcu_pin_obj_t *pin) { - if (pin != &pin_TOUT) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Pin %q does not have ADC capabilities", pin->name)); - } - adc_in_use = true; -} - -void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t* self) { - adc_in_use = false; -} - -uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self) { - // ADC is 10 bit so shift by 6 to make it 16-bit. - return system_adc_read() << 6; -} - -float common_hal_nativeio_analogin_get_reference_voltage(nativeio_analogin_obj_t *self) { - return 1.0f; -} diff --git a/esp8266/common-hal/nativeio/AnalogOut.c b/esp8266/common-hal/nativeio/AnalogOut.c deleted file mode 100644 index 06b1880c3..000000000 --- a/esp8266/common-hal/nativeio/AnalogOut.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include "py/runtime.h" - -#include "shared-bindings/nativeio/AnalogOut.h" - - -void common_hal_nativeio_analogout_construct(nativeio_analogout_obj_t* self, - const mcu_pin_obj_t *pin) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "No hardware support for analog out.")); -} - -void common_hal_nativeio_analogout_deinit(nativeio_analogout_obj_t *self) { -} - -void common_hal_nativeio_analogout_set_value(nativeio_analogout_obj_t *self, - uint16_t value) { -} diff --git a/esp8266/common-hal/nativeio/DigitalInOut.c b/esp8266/common-hal/nativeio/DigitalInOut.c deleted file mode 100644 index e6a28ed75..000000000 --- a/esp8266/common-hal/nativeio/DigitalInOut.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include -#include - -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/mphal.h" - -#include "shared-bindings/nativeio/DigitalInOut.h" - -digitalinout_result_t common_hal_nativeio_digitalinout_construct( - nativeio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) { - self->pin = pin; - PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function); - return DIGITALINOUT_OK; -} - -void common_hal_nativeio_digitalinout_deinit(nativeio_digitalinout_obj_t* self) { - if (self->pin->gpio_number < 16) { - uint32_t pin_mask = 1 << self->pin->gpio_number; - gpio_output_set(0x0, 0x0, 0x0, pin_mask); - PIN_FUNC_SELECT(self->pin->peripheral, 0); - PIN_PULLUP_DIS(self->pin->peripheral); - } -} - -void common_hal_nativeio_digitalinout_switch_to_input( - nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { - self->output = false; - - if (self->pin->gpio_number == 16) { - WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); - WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); - WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input - } else { - PIN_PULLUP_DIS(self->pin->peripheral); - gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); - } - common_hal_nativeio_digitalinout_set_pull(self, pull); -} - -void common_hal_nativeio_digitalinout_switch_to_output( - nativeio_digitalinout_obj_t* self, bool value, - enum digitalinout_drive_mode_t drive_mode) { - self->output = true; - self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; - if (self->pin->gpio_number == 16) { - WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); - WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); - WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output - } else if (!self->open_drain) { - gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); - PIN_PULLUP_DIS(self->pin->peripheral); - } - common_hal_nativeio_digitalinout_set_value(self, value); -} - -enum digitalinout_direction_t common_hal_nativeio_digitalinout_get_direction( - nativeio_digitalinout_obj_t* self) { - return self->output? DIRECTION_OUT : DIRECTION_IN; -} - -void common_hal_nativeio_digitalinout_set_value( - nativeio_digitalinout_obj_t* self, bool value) { - if (value) { - if (self->open_drain) { - // Disable output. - gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number); - } else { - // Set high - gpio_output_set(1 << self->pin->gpio_number, 0, 0, 0); - } - } else { - if (self->open_drain) { - // Enable the output - gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0); - } - // Set low - gpio_output_set(0, 1 << self->pin->gpio_number, 0, 0); - } -} - -// Register addresses taken from: https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers -volatile uint32_t* PIN_DIR = (uint32_t *) 0x6000030C; -volatile uint32_t* PIN_OUT = (uint32_t *) 0x60000300; -bool common_hal_nativeio_digitalinout_get_value( - nativeio_digitalinout_obj_t* self) { - if (!self->output) { - if (self->pin->gpio_number == 16) { - return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1; - } - return GPIO_INPUT_GET(self->pin->gpio_number); - } else { - uint32_t pin_mask = 1 << self->pin->gpio_number; - if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) { - return true; - } else { - return ((*PIN_OUT) & pin_mask) != 0; - } - } -} - -void common_hal_nativeio_digitalinout_set_drive_mode( - nativeio_digitalinout_obj_t* self, - enum digitalinout_drive_mode_t drive_mode) { - bool value = common_hal_nativeio_digitalinout_get_value(self); - self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN; - // True is implemented differently between modes so reset the value to make - // sure its correct for the new mode. - if (value) { - common_hal_nativeio_digitalinout_set_value(self, value); - } -} - -enum digitalinout_drive_mode_t common_hal_nativeio_digitalinout_get_drive_mode( - nativeio_digitalinout_obj_t* self) { - if (self->open_drain) { - return DRIVE_MODE_OPEN_DRAIN; - } else { - return DRIVE_MODE_PUSH_PULL; - } -} - -void common_hal_nativeio_digitalinout_set_pull( - nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull) { - if (pull == PULL_DOWN) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "ESP8266 does not support pull down.")); - return; - } - if (self->pin->gpio_number == 16) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "Pin does not support pull.")); - return; - } - if (pull == PULL_NONE) { - PIN_PULLUP_DIS(self->pin->peripheral); - } else { - PIN_PULLUP_EN(self->pin->peripheral); - } -} - -enum digitalinout_pull_t common_hal_nativeio_digitalinout_get_pull( - nativeio_digitalinout_obj_t* self) { - if (self->pin->gpio_number < 16 && - (READ_PERI_REG(self->pin->peripheral) & PERIPHS_IO_MUX_PULLUP) != 0) { - return PULL_UP; - } - return PULL_NONE; -} diff --git a/esp8266/common-hal/nativeio/DigitalInOut.h b/esp8266/common-hal/nativeio/DigitalInOut.h deleted file mode 100644 index 6325b978b..000000000 --- a/esp8266/common-hal/nativeio/DigitalInOut.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ -#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - const mcu_pin_obj_t * pin; - bool output; - bool open_drain; -} nativeio_digitalinout_obj_t; - -#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_DIGITALINOUT_H__ diff --git a/esp8266/common-hal/nativeio/PWMOut.c b/esp8266/common-hal/nativeio/PWMOut.c deleted file mode 100644 index 234246d15..000000000 --- a/esp8266/common-hal/nativeio/PWMOut.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "esppwm.h" - -#include "py/runtime.h" -#include "shared-bindings/nativeio/PWMOut.h" - -#include "eagle_soc.h" -#include "c_types.h" -#include "gpio.h" - -#define PWM_FREQ_MAX 1000 - -// Shared with pybpwm -extern bool pwm_inited; -bool first_channel_variable; - -void pwmout_reset(void) { - first_channel_variable = false; -} - -void common_hal_nativeio_pwmout_construct(nativeio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, - bool variable_frequency) { - if (frequency > PWM_FREQ_MAX) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX)); - } else if (frequency < 1) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "Minimum PWM frequency is 1hz.")); - } - - // start the PWM subsystem if it's not already running - if (!pwm_inited) { - pwm_init(); - pwm_inited = true; - pwm_set_freq(frequency, 0); - first_channel_variable = variable_frequency; - } else if (first_channel_variable || pwm_get_freq(0) != frequency) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Multiple PWM frequencies not supported. PWM already set to %dhz.", pwm_get_freq(0))); - } - - self->channel = pwm_add(pin->gpio_number, - pin->peripheral, - pin->gpio_function); - self->pin = pin; - if (self->channel == -1) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "PWM not supported on pin %d", pin->gpio_number)); - } -} - -extern void common_hal_nativeio_pwmout_deinit(nativeio_pwmout_obj_t* self) { - pwm_delete(self->channel); - pwm_start(); - if (self->pin->gpio_number < 16) { - uint32_t pin_mask = 1 << self->pin->gpio_number; - gpio_output_set(0x0, 0x0, 0x0, pin_mask); - PIN_FUNC_SELECT(self->pin->peripheral, 0); - PIN_PULLUP_DIS(self->pin->peripheral); - } -} - -extern void common_hal_nativeio_pwmout_set_duty_cycle(nativeio_pwmout_obj_t* self, uint16_t duty) { - // We get 16 bits of duty in but the underlying code is only ten bit. - pwm_set_duty(duty >> 6, self->channel); - pwm_start(); -} - -uint16_t common_hal_nativeio_pwmout_get_duty_cycle(nativeio_pwmout_obj_t* self) { - return pwm_get_duty(self->channel) << 6; -} - -void common_hal_nativeio_pwmout_set_frequency(nativeio_pwmout_obj_t* self, uint32_t frequency) { - if (frequency > PWM_FREQ_MAX) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX)); - } else if (frequency < 1) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "Minimum PWM frequency is 1hz.")); - } - pwm_set_freq(frequency, 0); -} - -uint32_t common_hal_nativeio_pwmout_get_frequency(nativeio_pwmout_obj_t* self) { - return pwm_get_freq(0); -} - -bool common_hal_nativeio_pwmout_get_variable_frequency(nativeio_pwmout_obj_t* self) { - return first_channel_variable; -} diff --git a/esp8266/common-hal/nativeio/PWMOut.h b/esp8266/common-hal/nativeio/PWMOut.h deleted file mode 100644 index 9406b4953..000000000 --- a/esp8266/common-hal/nativeio/PWMOut.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_PWMOUT_H__ -#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_PWMOUT_H__ - -void pwmout_reset(void); - -#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_NATIVEIO_PWMOUT_H__ diff --git a/esp8266/common-hal/nativeio/PulseIn.c b/esp8266/common-hal/nativeio/PulseIn.c deleted file mode 100644 index c4bd5a77c..000000000 --- a/esp8266/common-hal/nativeio/PulseIn.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "mpconfigport.h" -#include "py/gc.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/PulseIn.h" - -void common_hal_nativeio_pulsein_construct(nativeio_pulsein_obj_t* self, - const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { - mp_raise_NotImplementedError(""); -} - -void common_hal_nativeio_pulsein_deinit(nativeio_pulsein_obj_t* self) { - -} - -void common_hal_nativeio_pulsein_pause(nativeio_pulsein_obj_t* self) { -} - -void common_hal_nativeio_pulsein_resume(nativeio_pulsein_obj_t* self, - uint16_t trigger_duration) { -} - -void common_hal_nativeio_pulsein_clear(nativeio_pulsein_obj_t* self) { -} - -uint16_t common_hal_nativeio_pulsein_popleft(nativeio_pulsein_obj_t* self) { - return 0; -} - -uint16_t common_hal_nativeio_pulsein_get_maxlen(nativeio_pulsein_obj_t* self) { - return 0; -} - -uint16_t common_hal_nativeio_pulsein_get_len(nativeio_pulsein_obj_t* self) { - return 0; -} - -uint16_t common_hal_nativeio_pulsein_get_item(nativeio_pulsein_obj_t* self, - int16_t index) { - return 0; -} diff --git a/esp8266/common-hal/nativeio/PulseOut.c b/esp8266/common-hal/nativeio/PulseOut.c deleted file mode 100644 index d5d1e6366..000000000 --- a/esp8266/common-hal/nativeio/PulseOut.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - - -#include - -#include "py/runtime.h" -#include "shared-bindings/nativeio/PulseOut.h" - -void common_hal_nativeio_pulseout_construct(nativeio_pulseout_obj_t* self, - const nativeio_pwmout_obj_t* carrier) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "No hardware support for PulseOut.")); -} - -void common_hal_nativeio_pulseout_deinit(nativeio_pulseout_obj_t* self) { -} - -void common_hal_nativeio_pulseout_send(nativeio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { -} diff --git a/esp8266/common-hal/nativeio/SPI.c b/esp8266/common-hal/nativeio/SPI.c deleted file mode 100644 index 427c0d33c..000000000 --- a/esp8266/common-hal/nativeio/SPI.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "esp8266/ets_alt_task.h" -#include "esp8266/hspi.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/SPI.h" -#include "py/nlr.h" - -#include "eagle_soc.h" -#include "c_types.h" -#include "gpio.h" - -extern const mcu_pin_obj_t pin_MTMS; -extern const mcu_pin_obj_t pin_MTCK; -extern const mcu_pin_obj_t pin_MTDI; - -void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, - const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, - const mcu_pin_obj_t * miso) { - if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) || - (mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI))) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, - "Pins not valid for SPI")); - } - - uint32_t clock_div_flag = 0; - if (SPI_CLK_USE_DIV) { - clock_div_flag = 0x0001; - } - - // Set bit 9 if 80MHz sysclock required - WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9)); - // GPIO12 is HSPI MISO pin (Master Data In) - if (miso == &pin_MTDI) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2); - } - // GPIO13 is HSPI MOSI pin (Master Data Out) - if (mosi == &pin_MTCK) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2); - } - // GPIO14 is HSPI CLK pin (Clock) - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2); - - spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV); - spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); - spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW); - - SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD); - CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE); -} - -void common_hal_nativeio_spi_deinit(nativeio_spi_obj_t *self) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U); - - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 0); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); - - PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 0); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U); - - // Turn off outputs 12 - 14. - gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12); -} - -bool common_hal_nativeio_spi_configure(nativeio_spi_obj_t *self, - uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) { - if (bits != 8) { - return false; - } - if (baudrate == 80000000L) { - // Special case for full speed. - spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV); - spi_clock(HSPI, 0, 0); - } else if (baudrate > 40000000L) { - return false; - } else { - uint32_t divider = 40000000L / baudrate; - uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1); - uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even - if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) { - return false; - } - spi_init_gpio(HSPI, SPI_CLK_USE_DIV); - spi_clock(HSPI, prediv, cntdiv); - } - spi_mode(HSPI, phase, polarity); - return true; -} - -bool common_hal_nativeio_spi_try_lock(nativeio_spi_obj_t *self) { - bool success = false; - common_hal_mcu_disable_interrupts(); - if (!self->locked) { - self->locked = true; - success = true; - } - common_hal_mcu_enable_interrupts(); - return success; -} - -bool common_hal_nativeio_spi_has_lock(nativeio_spi_obj_t *self) { - return self->locked; -} - -void common_hal_nativeio_spi_unlock(nativeio_spi_obj_t *self) { - self->locked = false; -} - -bool common_hal_nativeio_spi_write(nativeio_spi_obj_t *self, - const uint8_t * data, size_t len) { - size_t chunk_size = 1024; - size_t count = len / chunk_size; - size_t i = 0; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - spi_tx8fast(HSPI, data[i]); - ++i; - } - ets_loop_iter(); - } - while (i < len) { - spi_tx8fast(HSPI, data[i]); - ++i; - } - while (spi_busy(HSPI)) {}; // Wait for SPI to finish the last byte. - return true; -} - -bool common_hal_nativeio_spi_read(nativeio_spi_obj_t *self, - uint8_t * data, size_t len, uint8_t write_value) { - // Process data in chunks, let the pending tasks run in between - size_t chunk_size = 1024; // TODO this should depend on baudrate - size_t count = len / chunk_size; - size_t i = 0; - uint32_t long_write_value = ((uint32_t) write_value) << 24 | - write_value << 16 | - write_value << 8 | - write_value; - for (size_t j = 0; j < count; ++j) { - for (size_t k = 0; k < chunk_size; ++k) { - data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 0, 0, 8, long_write_value); - ++i; - } - ets_loop_iter(); - } - while (i < len) { - data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 0, 0, 8, long_write_value); - ++i; - } - return true; -} diff --git a/esp8266/common-hal/nativeio/TouchIn.c b/esp8266/common-hal/nativeio/TouchIn.c deleted file mode 100644 index 1501a7936..000000000 --- a/esp8266/common-hal/nativeio/TouchIn.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "py/nlr.h" -#include "py/runtime.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "shared-bindings/nativeio/TouchIn.h" - -void common_hal_nativeio_touchin_construct(nativeio_touchin_obj_t* self, - const mcu_pin_obj_t *pin) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, - "No hardware support for capacitive touch.")); -} - -void common_hal_nativeio_touchin_deinit(nativeio_touchin_obj_t* self) { -} - -bool common_hal_nativeio_touchin_get_value(nativeio_touchin_obj_t *self) { - return false; -} diff --git a/esp8266/common-hal/nativeio/UART.c b/esp8266/common-hal/nativeio/UART.c deleted file mode 100644 index 8509dec64..000000000 --- a/esp8266/common-hal/nativeio/UART.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "common-hal/microcontroller/__init__.h" -#include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/UART.h" - -#include "ets_sys.h" -#include "uart.h" - -#include "py/nlr.h" - -// UartDev is defined and initialized in rom code. -extern UartDevice UartDev; - -void common_hal_nativeio_uart_construct(nativeio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, - uint8_t receiver_buffer_size) { - if (rx != NULL || tx != &pin_GPIO2) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Only tx supported on UART1 (GPIO2).")); - } - // set baudrate - UartDev.baut_rate = baudrate; - - // set data bits - switch (bits) { - case 5: - UartDev.data_bits = UART_FIVE_BITS; - break; - case 6: - UartDev.data_bits = UART_SIX_BITS; - break; - case 7: - UartDev.data_bits = UART_SEVEN_BITS; - break; - case 8: - UartDev.data_bits = UART_EIGHT_BITS; - break; - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid data bits")); - break; - } - - if (parity == PARITY_NONE) { - UartDev.parity = UART_NONE_BITS; - UartDev.exist_parity = UART_STICK_PARITY_DIS; - } else { - UartDev.exist_parity = UART_STICK_PARITY_EN; - if (parity == PARITY_ODD) { - UartDev.parity = UART_ODD_BITS; - } else { - UartDev.parity = UART_EVEN_BITS; - } - } - - switch (stop) { - case 1: - UartDev.stop_bits = UART_ONE_STOP_BIT; - break; - case 2: - UartDev.stop_bits = UART_TWO_STOP_BIT; - break; - default: - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid stop bits")); - break; - } - - uart_setup(UART1); -} - -void common_hal_nativeio_uart_deinit(nativeio_uart_obj_t *self) { - PIN_FUNC_SELECT(FUNC_U1TXD_BK, 0); -} - -size_t common_hal_nativeio_uart_read(nativeio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) { - return 0; -} - -// Write characters. -size_t common_hal_nativeio_uart_write(nativeio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) { - // write the data - for (size_t i = 0; i < len; ++i) { - uart_tx_one_char(UART1, *data++); - } - - // return number of bytes written - return len; -} - -uint32_t common_hal_nativeio_uart_rx_characters_available(nativeio_uart_obj_t *self) { - return 0; -} - -bool common_hal_nativeio_uart_ready_to_tx(nativeio_uart_obj_t *self) { - return true; -} diff --git a/esp8266/common-hal/nativeio/__init__.c b/esp8266/common-hal/nativeio/__init__.c deleted file mode 100644 index e0ec8acfb..000000000 --- a/esp8266/common-hal/nativeio/__init__.c +++ /dev/null @@ -1 +0,0 @@ -// No nativeio module functions. diff --git a/esp8266/common-hal/nativeio/types.h b/esp8266/common-hal/nativeio/types.h deleted file mode 100644 index 05b7d28c2..000000000 --- a/esp8266/common-hal/nativeio/types.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This defines the types used to underly the standard nativeio Python objects. -// The shared API is defined in terms of these types. - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ - -#include "common-hal/microcontroller/types.h" - -#include "py/obj.h" - -// Use the bitbang wrapper for I2C and OneWire -#include "shared-module/nativeio/I2C.h" -#include "shared-module/nativeio/OneWire.h" - -typedef struct { - mp_obj_base_t base; - const mcu_pin_obj_t * pin; -} nativeio_analogin_obj_t; - -// Not supported, throws error on construction. -typedef struct { - mp_obj_base_t base; -} nativeio_analogout_obj_t; - -typedef struct { - mp_obj_base_t base; - bool locked; -} nativeio_spi_obj_t; - -typedef struct { - mp_obj_base_t base; -} nativeio_pulsein_obj_t; - -typedef struct { - mp_obj_base_t base; -} nativeio_pulseout_obj_t; - -typedef struct { - mp_obj_base_t base; - int channel; - const mcu_pin_obj_t* pin; -} nativeio_pwmout_obj_t; - -typedef struct { - mp_obj_base_t base; -} nativeio_touchin_obj_t; - -typedef struct { - mp_obj_base_t base; -} nativeio_uart_obj_t; - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_NATIVEIO_TYPES_H__ diff --git a/esp8266/common-hal/neopixel_write/__init__.c b/esp8266/common-hal/neopixel_write/__init__.c index daaeead43..84a743d11 100644 --- a/esp8266/common-hal/neopixel_write/__init__.c +++ b/esp8266/common-hal/neopixel_write/__init__.c @@ -28,6 +28,6 @@ #include "espneopixel.h" -void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { +void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) { esp_neopixel_write(digitalinout->pin->gpio_number, pixels, numBytes); } diff --git a/esp8266/common-hal/pulseio/PWMOut.c b/esp8266/common-hal/pulseio/PWMOut.c new file mode 100644 index 000000000..40a46e392 --- /dev/null +++ b/esp8266/common-hal/pulseio/PWMOut.c @@ -0,0 +1,118 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "esppwm.h" + +#include "py/runtime.h" +#include "shared-bindings/pulseio/PWMOut.h" + +#include "eagle_soc.h" +#include "c_types.h" +#include "gpio.h" + +#define PWM_FREQ_MAX 1000 + +// Shared with pybpwm +extern bool pwm_inited; +bool first_channel_variable; + +void pwmout_reset(void) { + first_channel_variable = false; +} + +void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, + bool variable_frequency) { + if (frequency > PWM_FREQ_MAX) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX)); + } else if (frequency < 1) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "Minimum PWM frequency is 1hz.")); + } + + // start the PWM subsystem if it's not already running + if (!pwm_inited) { + pwm_init(); + pwm_inited = true; + pwm_set_freq(frequency, 0); + first_channel_variable = variable_frequency; + } else if (first_channel_variable || pwm_get_freq(0) != frequency) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Multiple PWM frequencies not supported. PWM already set to %dhz.", pwm_get_freq(0))); + } + + self->channel = pwm_add(pin->gpio_number, + pin->peripheral, + pin->gpio_function); + self->pin = pin; + if (self->channel == -1) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "PWM not supported on pin %d", pin->gpio_number)); + } +} + +extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) { + pwm_delete(self->channel); + pwm_start(); + if (self->pin->gpio_number < 16) { + uint32_t pin_mask = 1 << self->pin->gpio_number; + gpio_output_set(0x0, 0x0, 0x0, pin_mask); + PIN_FUNC_SELECT(self->pin->peripheral, 0); + PIN_PULLUP_DIS(self->pin->peripheral); + } +} + +extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) { + // We get 16 bits of duty in but the underlying code is only ten bit. + pwm_set_duty(duty >> 6, self->channel); + pwm_start(); +} + +uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) { + return pwm_get_duty(self->channel) << 6; +} + +void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) { + if (frequency > PWM_FREQ_MAX) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError, + "Maximum PWM frequency is %dhz.", PWM_FREQ_MAX)); + } else if (frequency < 1) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, + "Minimum PWM frequency is 1hz.")); + } + pwm_set_freq(frequency, 0); +} + +uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) { + return pwm_get_freq(0); +} + +bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) { + return first_channel_variable; +} diff --git a/esp8266/common-hal/pulseio/PWMOut.h b/esp8266/common-hal/pulseio/PWMOut.h new file mode 100644 index 000000000..7eb22e6e1 --- /dev/null +++ b/esp8266/common-hal/pulseio/PWMOut.h @@ -0,0 +1,40 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H__ + +#include "common-hal/microcontroller/types.h" + +typedef struct { + mp_obj_base_t base; + int channel; + const mcu_pin_obj_t* pin; +} pulseio_pwmout_obj_t; + +void pwmout_reset(void); + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H__ diff --git a/esp8266/common-hal/pulseio/PulseIn.c b/esp8266/common-hal/pulseio/PulseIn.c new file mode 100644 index 000000000..784116bef --- /dev/null +++ b/esp8266/common-hal/pulseio/PulseIn.c @@ -0,0 +1,69 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "mpconfigport.h" +#include "py/gc.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" + +void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) { + mp_raise_NotImplementedError(""); +} + +void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) { + +} + +void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) { +} + +void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, + uint16_t trigger_duration) { +} + +void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) { +} + +uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) { + return 0; +} + +uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) { + return 0; +} + +uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) { + return 0; +} + +uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, + int16_t index) { + return 0; +} diff --git a/esp8266/common-hal/pulseio/PulseIn.h b/esp8266/common-hal/pulseio/PulseIn.h new file mode 100644 index 000000000..c3a27d929 --- /dev/null +++ b/esp8266/common-hal/pulseio/PulseIn.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H__ + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} pulseio_pulsein_obj_t; + +void pwmout_reset(void); + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H__ diff --git a/esp8266/common-hal/pulseio/PulseOut.c b/esp8266/common-hal/pulseio/PulseOut.c new file mode 100644 index 000000000..1301abbf3 --- /dev/null +++ b/esp8266/common-hal/pulseio/PulseOut.c @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + + +#include + +#include "py/runtime.h" +#include "shared-bindings/pulseio/PulseOut.h" + +void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "No hardware support for PulseOut.")); +} + +void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) { +} + +void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, uint16_t* pulses, uint16_t length) { +} diff --git a/esp8266/common-hal/pulseio/PulseOut.h b/esp8266/common-hal/pulseio/PulseOut.h new file mode 100644 index 000000000..c4c6ef616 --- /dev/null +++ b/esp8266/common-hal/pulseio/PulseOut.h @@ -0,0 +1,38 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H__ +#define __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H__ + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; +} pulseio_pulseout_obj_t; + +void pwmout_reset(void); + +#endif // __MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H__ diff --git a/esp8266/common-hal/pulseio/__init__.c b/esp8266/common-hal/pulseio/__init__.c new file mode 100644 index 000000000..2bee925bc --- /dev/null +++ b/esp8266/common-hal/pulseio/__init__.c @@ -0,0 +1 @@ +// No pulseio module functions. diff --git a/esp8266/esp_mphal.c b/esp8266/esp_mphal.c index f5e284fde..5db4f1968 100644 --- a/esp8266/esp_mphal.c +++ b/esp8266/esp_mphal.c @@ -27,7 +27,7 @@ #include #include "ets_sys.h" #include "etshal.h" -#include "uart.h" +#include "espuart.h" #include "esp_mphal.h" #include "user_interface.h" #include "ets_alt_task.h" diff --git a/esp8266/espuart.c b/esp8266/espuart.c new file mode 100644 index 000000000..ee893f4ec --- /dev/null +++ b/esp8266/espuart.c @@ -0,0 +1,281 @@ +/****************************************************************************** + * Copyright 2013-2014 Espressif Systems (Wuxi) + * + * FileName: uart.c + * + * Description: Two UART mode configration and interrupt handler. + * Check your hardware connection while use this mode. + * + * Modification history: + * 2014/3/12, v1.0 create this file. +*******************************************************************************/ +#include "ets_sys.h" +#include "osapi.h" +#include "espuart.h" +#include "osapi.h" +#include "uart_register.h" +#include "etshal.h" +#include "c_types.h" +#include "user_interface.h" +#include "esp_mphal.h" + +// seems that this is missing in the Espressif SDK +#define FUNC_U0RXD 0 + +#define UART_REPL UART0 + +// UartDev is defined and initialized in rom code. +extern UartDevice UartDev; + +// the uart to which OS messages go; -1 to disable +static int uart_os = UART_OS; + +#if MICROPY_REPL_EVENT_DRIVEN +static os_event_t uart_evt_queue[16]; +#endif + +static void uart0_rx_intr_handler(void *para); + +void soft_reset(void); +void mp_keyboard_interrupt(void); + +/****************************************************************************** + * FunctionName : uart_config + * Description : Internal used function + * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled + * UART1 just used for debug output + * Parameters : uart_no, use UART0 or UART1 defined ahead + * Returns : NONE +*******************************************************************************/ +static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no) { + if (uart_no == UART1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } else { + ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, NULL); + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); + } + + uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate)); + + WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity + | UartDev.parity + | (UartDev.stop_bits << UART_STOP_BIT_NUM_S) + | (UartDev.data_bits << UART_BIT_NUM_S)); + + // clear rx and tx fifo,not ready + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + + if (uart_no == UART0) { + // set rx fifo trigger + WRITE_PERI_REG(UART_CONF1(uart_no), + ((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | + ((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | + UART_RX_FLOW_EN | + (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | + UART_RX_TOUT_EN); + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA | + UART_FRM_ERR_INT_ENA); + } else { + WRITE_PERI_REG(UART_CONF1(uart_no), + ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); + } + + // clear all interrupt + WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); + // enable rx_interrupt + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); +} + +/****************************************************************************** + * FunctionName : uart1_tx_one_char + * Description : Internal used function + * Use uart1 interface to transfer one char + * Parameters : uint8 TxChar - character to tx + * Returns : OK +*******************************************************************************/ +void uart_tx_one_char(uint8 uart, uint8 TxChar) { + while (true) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { + break; + } + } + WRITE_PERI_REG(UART_FIFO(uart), TxChar); +} + +void uart_flush(uint8 uart) { + while (true) { + uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) { + break; + } + } +} + +/****************************************************************************** + * FunctionName : uart1_write_char + * Description : Internal used function + * Do some special deal while tx char is '\r' or '\n' + * Parameters : char c - character to tx + * Returns : NONE +*******************************************************************************/ +static void ICACHE_FLASH_ATTR +uart_os_write_char(char c) { + if (uart_os == -1) { + return; + } + if (c == '\n') { + uart_tx_one_char(uart_os, '\r'); + uart_tx_one_char(uart_os, '\n'); + } else if (c == '\r') { + } else { + uart_tx_one_char(uart_os, c); + } +} + +void ICACHE_FLASH_ATTR +uart_os_config(int uart) { + uart_os = uart; +} + +/****************************************************************************** + * FunctionName : uart0_rx_intr_handler + * Description : Internal used function + * UART0 interrupt handler, add self handle code inside + * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg + * Returns : NONE +*******************************************************************************/ + +static void uart0_rx_intr_handler(void *para) { + /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents + * uart1 and uart0 respectively + */ + + uint8 uart_no = UART_REPL; + + if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) { + // frame error + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); + } + + if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { + // fifo full + goto read_chars; + } else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) { + read_chars: + ETS_UART_INTR_DISABLE(); + + while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { + uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff; + if (RcvChar == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else { + ringbuf_put(&input_buf, RcvChar); + } + } + + mp_hal_signal_input(); + + // Clear pending FIFO interrupts + WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST); + ETS_UART_INTR_ENABLE(); + } +} + +// Waits at most timeout microseconds for at least 1 char to become ready for reading. +// Returns true if something available, false if not. +bool uart_rx_wait(uint32_t timeout_us) { + uint32_t start = system_get_time(); + for (;;) { + if (input_buf.iget != input_buf.iput) { + return true; // have at least 1 char ready for reading + } + if (system_get_time() - start >= timeout_us) { + return false; // timeout + } + ets_event_poll(); + } +} + +// Returns char from the input buffer, else -1 if buffer is empty. +int uart_rx_char(void) { + return ringbuf_get(&input_buf); +} + +int uart_rx_one_char(uint8 uart_no) { + if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { + return READ_PERI_REG(UART_FIFO(uart_no)) & 0xff; + } + return -1; +} + +/****************************************************************************** + * FunctionName : uart_init + * Description : user interface for init uart + * Parameters : UartBautRate uart0_br - uart0 bautrate + * UartBautRate uart1_br - uart1 bautrate + * Returns : NONE +*******************************************************************************/ +void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) { + // rom use 74880 baut_rate, here reinitialize + UartDev.baut_rate = uart0_br; + uart_config(UART0); + UartDev.baut_rate = uart1_br; + uart_config(UART1); + ETS_UART_INTR_ENABLE(); + + // install handler for "os" messages + os_install_putc1((void *)uart_os_write_char); +} + +void ICACHE_FLASH_ATTR uart_reattach() { + uart_init(UART_BIT_RATE_74880, UART_BIT_RATE_74880); +} + +void ICACHE_FLASH_ATTR uart_setup(uint8 uart) { + ETS_UART_INTR_DISABLE(); + uart_config(uart); + ETS_UART_INTR_ENABLE(); +} + +// Task-based UART interface + +#include "py/obj.h" +#include "lib/utils/pyexec.h" + +#if MICROPY_REPL_EVENT_DRIVEN +void uart_task_handler(os_event_t *evt) { + if (pyexec_repl_active) { + // TODO: Just returning here isn't exactly right. + // What really should be done is something like + // enquing delayed event to itself, for another + // chance to feed data to REPL. Otherwise, there + // can be situation when buffer has bunch of data, + // and sits unprocessed, because we consumed all + // processing signals like this. + return; + } + + int c, ret = 0; + while ((c = ringbuf_get(&input_buf)) >= 0) { + if (c == interrupt_char) { + mp_keyboard_interrupt(); + } + ret = pyexec_event_repl_process_char(c); + if (ret & PYEXEC_FORCED_EXIT) { + break; + } + } + + if (ret & PYEXEC_FORCED_EXIT) { + soft_reset(); + } +} + +void uart_task_init() { + system_os_task(uart_task_handler, UART_TASK_ID, uart_evt_queue, sizeof(uart_evt_queue) / sizeof(*uart_evt_queue)); +} +#endif diff --git a/esp8266/espuart.h b/esp8266/espuart.h new file mode 100644 index 000000000..2b97683ff --- /dev/null +++ b/esp8266/espuart.h @@ -0,0 +1,103 @@ +#ifndef _INCLUDED_UART_H_ +#define _INCLUDED_UART_H_ + +#include + +#define UART0 (0) +#define UART1 (1) + +typedef enum { + UART_FIVE_BITS = 0x0, + UART_SIX_BITS = 0x1, + UART_SEVEN_BITS = 0x2, + UART_EIGHT_BITS = 0x3 +} UartBitsNum4Char; + +typedef enum { + UART_ONE_STOP_BIT = 0, + UART_ONE_HALF_STOP_BIT = BIT2, + UART_TWO_STOP_BIT = BIT2 +} UartStopBitsNum; + +typedef enum { + UART_NONE_BITS = 0, + UART_ODD_BITS = BIT0, + UART_EVEN_BITS = 0 +} UartParityMode; + +typedef enum { + UART_STICK_PARITY_DIS = 0, + UART_STICK_PARITY_EN = BIT1 +} UartExistParity; + +typedef enum { + UART_BIT_RATE_9600 = 9600, + UART_BIT_RATE_19200 = 19200, + UART_BIT_RATE_38400 = 38400, + UART_BIT_RATE_57600 = 57600, + UART_BIT_RATE_74880 = 74880, + UART_BIT_RATE_115200 = 115200, + UART_BIT_RATE_230400 = 230400, + UART_BIT_RATE_256000 = 256000, + UART_BIT_RATE_460800 = 460800, + UART_BIT_RATE_921600 = 921600 +} UartBautRate; + +typedef enum { + UART_NONE_CTRL, + UART_HARDWARE_CTRL, + UART_XON_XOFF_CTRL +} UartFlowCtrl; + +typedef enum { + UART_EMPTY, + UART_UNDER_WRITE, + UART_WRITE_OVER +} RcvMsgBuffState; + +typedef struct { + uint32 RcvBuffSize; + uint8 *pRcvMsgBuff; + uint8 *pWritePos; + uint8 *pReadPos; + uint8 TrigLvl; //JLU: may need to pad + RcvMsgBuffState BuffState; +} RcvMsgBuff; + +typedef struct { + uint32 TrxBuffSize; + uint8 *pTrxBuff; +} TrxMsgBuff; + +typedef enum { + UART_BAUD_RATE_DET, + UART_WAIT_SYNC_FRM, + UART_SRCH_MSG_HEAD, + UART_RCV_MSG_BODY, + UART_RCV_ESC_CHAR, +} RcvMsgState; + +typedef struct { + UartBautRate baut_rate; + UartBitsNum4Char data_bits; + UartExistParity exist_parity; + UartParityMode parity; // chip size in byte + UartStopBitsNum stop_bits; + UartFlowCtrl flow_ctrl; + RcvMsgBuff rcv_buff; + TrxMsgBuff trx_buff; + RcvMsgState rcv_state; + int received; + int buff_uart_no; //indicate which uart use tx/rx buffer +} UartDevice; + +void uart_init(UartBautRate uart0_br, UartBautRate uart1_br); +int uart0_rx(void); +bool uart_rx_wait(uint32_t timeout_us); +int uart_rx_char(void); +void uart_tx_one_char(uint8 uart, uint8 TxChar); +void uart_flush(uint8 uart); +void uart_os_config(int uart); +void uart_setup(uint8 uart); + +#endif // _INCLUDED_UART_H_ diff --git a/esp8266/machine_uart.c b/esp8266/machine_uart.c index 9bc6422cc..0ae9c6e6c 100644 --- a/esp8266/machine_uart.c +++ b/esp8266/machine_uart.c @@ -29,7 +29,7 @@ #include #include "ets_sys.h" -#include "uart.h" +#include "espuart.h" #include "py/runtime.h" #include "py/stream.h" diff --git a/esp8266/main.c b/esp8266/main.c index 0c1ad1bab..9ac728e38 100644 --- a/esp8266/main.c +++ b/esp8266/main.c @@ -40,7 +40,7 @@ #include "gccollect.h" #include "user_interface.h" #include "common-hal/microcontroller/Pin.h" -#include "common-hal/nativeio/PWMOut.h" +#include "common-hal/pulseio/PWMOut.h" STATIC char heap[36 * 1024]; diff --git a/esp8266/modesp.c b/esp8266/modesp.c index f13d94b32..77f8d1332 100644 --- a/esp8266/modesp.c +++ b/esp8266/modesp.c @@ -38,7 +38,7 @@ #include "netutils.h" #include "queue.h" #include "ets_sys.h" -#include "uart.h" +#include "espuart.h" #include "user_interface.h" #include "espconn.h" #include "spi_flash.h" diff --git a/esp8266/mpconfigport.h b/esp8266/mpconfigport.h index fa2e8bc1b..c4a375200 100644 --- a/esp8266/mpconfigport.h +++ b/esp8266/mpconfigport.h @@ -156,7 +156,10 @@ extern const struct _mp_obj_module_t mp_module_machine; extern const struct _mp_obj_module_t onewire_module; extern const struct _mp_obj_module_t microcontroller_module; extern const struct _mp_obj_module_t board_module; -extern const struct _mp_obj_module_t nativeio_module; +extern const struct _mp_obj_module_t analogio_module; +extern const struct _mp_obj_module_t digitalio_module; +extern const struct _mp_obj_module_t pulseio_module; +extern const struct _mp_obj_module_t busio_module; extern const struct _mp_obj_module_t bitbangio_module; extern const struct _mp_obj_module_t time_module; @@ -172,7 +175,10 @@ extern const struct _mp_obj_module_t time_module; { MP_OBJ_NEW_QSTR(MP_QSTR__onewire), (mp_obj_t)&onewire_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \ - { MP_OBJ_NEW_QSTR(MP_QSTR_nativeio), (mp_obj_t)&nativeio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \ + { MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \ { MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \ diff --git a/esp8266/uart.c b/esp8266/uart.c deleted file mode 100644 index 001a9c673..000000000 --- a/esp8266/uart.c +++ /dev/null @@ -1,281 +0,0 @@ -/****************************************************************************** - * Copyright 2013-2014 Espressif Systems (Wuxi) - * - * FileName: uart.c - * - * Description: Two UART mode configration and interrupt handler. - * Check your hardware connection while use this mode. - * - * Modification history: - * 2014/3/12, v1.0 create this file. -*******************************************************************************/ -#include "ets_sys.h" -#include "osapi.h" -#include "uart.h" -#include "osapi.h" -#include "uart_register.h" -#include "etshal.h" -#include "c_types.h" -#include "user_interface.h" -#include "esp_mphal.h" - -// seems that this is missing in the Espressif SDK -#define FUNC_U0RXD 0 - -#define UART_REPL UART0 - -// UartDev is defined and initialized in rom code. -extern UartDevice UartDev; - -// the uart to which OS messages go; -1 to disable -static int uart_os = UART_OS; - -#if MICROPY_REPL_EVENT_DRIVEN -static os_event_t uart_evt_queue[16]; -#endif - -static void uart0_rx_intr_handler(void *para); - -void soft_reset(void); -void mp_keyboard_interrupt(void); - -/****************************************************************************** - * FunctionName : uart_config - * Description : Internal used function - * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled - * UART1 just used for debug output - * Parameters : uart_no, use UART0 or UART1 defined ahead - * Returns : NONE -*******************************************************************************/ -static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no) { - if (uart_no == UART1) { - PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); - } else { - ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, NULL); - PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); - PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); - } - - uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate)); - - WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity - | UartDev.parity - | (UartDev.stop_bits << UART_STOP_BIT_NUM_S) - | (UartDev.data_bits << UART_BIT_NUM_S)); - - // clear rx and tx fifo,not ready - SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); - CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); - - if (uart_no == UART0) { - // set rx fifo trigger - WRITE_PERI_REG(UART_CONF1(uart_no), - ((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | - ((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | - UART_RX_FLOW_EN | - (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | - UART_RX_TOUT_EN); - SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA | - UART_FRM_ERR_INT_ENA); - } else { - WRITE_PERI_REG(UART_CONF1(uart_no), - ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); - } - - // clear all interrupt - WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); - // enable rx_interrupt - SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); -} - -/****************************************************************************** - * FunctionName : uart1_tx_one_char - * Description : Internal used function - * Use uart1 interface to transfer one char - * Parameters : uint8 TxChar - character to tx - * Returns : OK -*******************************************************************************/ -void uart_tx_one_char(uint8 uart, uint8 TxChar) { - while (true) { - uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { - break; - } - } - WRITE_PERI_REG(UART_FIFO(uart), TxChar); -} - -void uart_flush(uint8 uart) { - while (true) { - uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) { - break; - } - } -} - -/****************************************************************************** - * FunctionName : uart1_write_char - * Description : Internal used function - * Do some special deal while tx char is '\r' or '\n' - * Parameters : char c - character to tx - * Returns : NONE -*******************************************************************************/ -static void ICACHE_FLASH_ATTR -uart_os_write_char(char c) { - if (uart_os == -1) { - return; - } - if (c == '\n') { - uart_tx_one_char(uart_os, '\r'); - uart_tx_one_char(uart_os, '\n'); - } else if (c == '\r') { - } else { - uart_tx_one_char(uart_os, c); - } -} - -void ICACHE_FLASH_ATTR -uart_os_config(int uart) { - uart_os = uart; -} - -/****************************************************************************** - * FunctionName : uart0_rx_intr_handler - * Description : Internal used function - * UART0 interrupt handler, add self handle code inside - * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg - * Returns : NONE -*******************************************************************************/ - -static void uart0_rx_intr_handler(void *para) { - /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents - * uart1 and uart0 respectively - */ - - uint8 uart_no = UART_REPL; - - if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) { - // frame error - WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); - } - - if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) { - // fifo full - goto read_chars; - } else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) { - read_chars: - ETS_UART_INTR_DISABLE(); - - while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { - uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff; - if (RcvChar == mp_interrupt_char) { - mp_keyboard_interrupt(); - } else { - ringbuf_put(&input_buf, RcvChar); - } - } - - mp_hal_signal_input(); - - // Clear pending FIFO interrupts - WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST); - ETS_UART_INTR_ENABLE(); - } -} - -// Waits at most timeout microseconds for at least 1 char to become ready for reading. -// Returns true if something available, false if not. -bool uart_rx_wait(uint32_t timeout_us) { - uint32_t start = system_get_time(); - for (;;) { - if (input_buf.iget != input_buf.iput) { - return true; // have at least 1 char ready for reading - } - if (system_get_time() - start >= timeout_us) { - return false; // timeout - } - ets_event_poll(); - } -} - -// Returns char from the input buffer, else -1 if buffer is empty. -int uart_rx_char(void) { - return ringbuf_get(&input_buf); -} - -int uart_rx_one_char(uint8 uart_no) { - if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) { - return READ_PERI_REG(UART_FIFO(uart_no)) & 0xff; - } - return -1; -} - -/****************************************************************************** - * FunctionName : uart_init - * Description : user interface for init uart - * Parameters : UartBautRate uart0_br - uart0 bautrate - * UartBautRate uart1_br - uart1 bautrate - * Returns : NONE -*******************************************************************************/ -void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) { - // rom use 74880 baut_rate, here reinitialize - UartDev.baut_rate = uart0_br; - uart_config(UART0); - UartDev.baut_rate = uart1_br; - uart_config(UART1); - ETS_UART_INTR_ENABLE(); - - // install handler for "os" messages - os_install_putc1((void *)uart_os_write_char); -} - -void ICACHE_FLASH_ATTR uart_reattach() { - uart_init(UART_BIT_RATE_74880, UART_BIT_RATE_74880); -} - -void ICACHE_FLASH_ATTR uart_setup(uint8 uart) { - ETS_UART_INTR_DISABLE(); - uart_config(uart); - ETS_UART_INTR_ENABLE(); -} - -// Task-based UART interface - -#include "py/obj.h" -#include "lib/utils/pyexec.h" - -#if MICROPY_REPL_EVENT_DRIVEN -void uart_task_handler(os_event_t *evt) { - if (pyexec_repl_active) { - // TODO: Just returning here isn't exactly right. - // What really should be done is something like - // enquing delayed event to itself, for another - // chance to feed data to REPL. Otherwise, there - // can be situation when buffer has bunch of data, - // and sits unprocessed, because we consumed all - // processing signals like this. - return; - } - - int c, ret = 0; - while ((c = ringbuf_get(&input_buf)) >= 0) { - if (c == interrupt_char) { - mp_keyboard_interrupt(); - } - ret = pyexec_event_repl_process_char(c); - if (ret & PYEXEC_FORCED_EXIT) { - break; - } - } - - if (ret & PYEXEC_FORCED_EXIT) { - soft_reset(); - } -} - -void uart_task_init() { - system_os_task(uart_task_handler, UART_TASK_ID, uart_evt_queue, sizeof(uart_evt_queue) / sizeof(*uart_evt_queue)); -} -#endif diff --git a/esp8266/uart.h b/esp8266/uart.h deleted file mode 100644 index 2b97683ff..000000000 --- a/esp8266/uart.h +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef _INCLUDED_UART_H_ -#define _INCLUDED_UART_H_ - -#include - -#define UART0 (0) -#define UART1 (1) - -typedef enum { - UART_FIVE_BITS = 0x0, - UART_SIX_BITS = 0x1, - UART_SEVEN_BITS = 0x2, - UART_EIGHT_BITS = 0x3 -} UartBitsNum4Char; - -typedef enum { - UART_ONE_STOP_BIT = 0, - UART_ONE_HALF_STOP_BIT = BIT2, - UART_TWO_STOP_BIT = BIT2 -} UartStopBitsNum; - -typedef enum { - UART_NONE_BITS = 0, - UART_ODD_BITS = BIT0, - UART_EVEN_BITS = 0 -} UartParityMode; - -typedef enum { - UART_STICK_PARITY_DIS = 0, - UART_STICK_PARITY_EN = BIT1 -} UartExistParity; - -typedef enum { - UART_BIT_RATE_9600 = 9600, - UART_BIT_RATE_19200 = 19200, - UART_BIT_RATE_38400 = 38400, - UART_BIT_RATE_57600 = 57600, - UART_BIT_RATE_74880 = 74880, - UART_BIT_RATE_115200 = 115200, - UART_BIT_RATE_230400 = 230400, - UART_BIT_RATE_256000 = 256000, - UART_BIT_RATE_460800 = 460800, - UART_BIT_RATE_921600 = 921600 -} UartBautRate; - -typedef enum { - UART_NONE_CTRL, - UART_HARDWARE_CTRL, - UART_XON_XOFF_CTRL -} UartFlowCtrl; - -typedef enum { - UART_EMPTY, - UART_UNDER_WRITE, - UART_WRITE_OVER -} RcvMsgBuffState; - -typedef struct { - uint32 RcvBuffSize; - uint8 *pRcvMsgBuff; - uint8 *pWritePos; - uint8 *pReadPos; - uint8 TrigLvl; //JLU: may need to pad - RcvMsgBuffState BuffState; -} RcvMsgBuff; - -typedef struct { - uint32 TrxBuffSize; - uint8 *pTrxBuff; -} TrxMsgBuff; - -typedef enum { - UART_BAUD_RATE_DET, - UART_WAIT_SYNC_FRM, - UART_SRCH_MSG_HEAD, - UART_RCV_MSG_BODY, - UART_RCV_ESC_CHAR, -} RcvMsgState; - -typedef struct { - UartBautRate baut_rate; - UartBitsNum4Char data_bits; - UartExistParity exist_parity; - UartParityMode parity; // chip size in byte - UartStopBitsNum stop_bits; - UartFlowCtrl flow_ctrl; - RcvMsgBuff rcv_buff; - TrxMsgBuff trx_buff; - RcvMsgState rcv_state; - int received; - int buff_uart_no; //indicate which uart use tx/rx buffer -} UartDevice; - -void uart_init(UartBautRate uart0_br, UartBautRate uart1_br); -int uart0_rx(void); -bool uart_rx_wait(uint32_t timeout_us); -int uart_rx_char(void); -void uart_tx_one_char(uint8 uart, uint8 TxChar); -void uart_flush(uint8 uart); -void uart_os_config(int uart); -void uart_setup(uint8 uart); - -#endif // _INCLUDED_UART_H_ diff --git a/shared-bindings/analogio/AnalogIn.c b/shared-bindings/analogio/AnalogIn.c new file mode 100644 index 000000000..f07302250 --- /dev/null +++ b/shared-bindings/analogio/AnalogIn.c @@ -0,0 +1,164 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/AnalogIn.h" + +//| .. currentmodule:: analogio +//| +//| :class:`AnalogIn` -- read analog voltage +//| ============================================ +//| +//| Usage:: +//| +//| import analogio +//| from board import * +//| +//| with analogio.AnalogIn(A1) as adc: +//| val = adc.value +//| + +//| .. class:: AnalogIn(pin) +//| +//| Use the AnalogIn on the given pin. The reference voltage varies by +//| platform so use ``reference_voltage`` to read the configured setting. +//| +//| :param ~microcontroller.Pin pin: the pin to read from +//| +STATIC mp_obj_t analogio_analogin_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + // check number of arguments + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + // 1st argument is the pin + mp_obj_t pin_obj = args[0]; + assert_pin(pin_obj, false); + + analogio_analogin_obj_t *self = m_new_obj(analogio_analogin_obj_t); + self->base.type = &analogio_analogin_type; + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + common_hal_analogio_analogin_construct(self, pin); + + return (mp_obj_t) self; +} + +//| .. method:: deinit() +//| +//| Turn off the AnalogIn and release the pin for other use. +//| +STATIC mp_obj_t analogio_analogin_deinit(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_analogio_analogin_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_deinit_obj, analogio_analogin_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t analogio_analogin___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_analogio_analogin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogin___exit___obj, 4, 4, analogio_analogin___exit__); + +//| .. attribute:: value +//| +//| Read the value on the analog pin and return it. The returned value +//| will be between 0 and 65535 inclusive (16-bit). Even if the underlying +//| analog to digital converter (ADC) is lower resolution, the result will +//| be scaled to be 16-bit. +//| +//| :return: the data read +//| :rtype: int +//| +STATIC mp_obj_t analogio_analogin_obj_get_value(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_analogio_analogin_get_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_value_obj, analogio_analogin_obj_get_value); + +const mp_obj_property_t analogio_analogin_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&analogio_analogin_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: reference_voltage +//| +//| The maximum voltage measurable. Also known as the reference voltage. +//| +//| :return: the reference voltage +//| :rtype: float +//| +STATIC mp_obj_t analogio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { + analogio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_float(common_hal_analogio_analogin_get_reference_voltage(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogin_get_reference_voltage_obj, + analogio_analogin_obj_get_reference_voltage); + +const mp_obj_property_t analogio_analogin_reference_voltage_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&analogio_analogin_get_reference_voltage_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t analogio_analogin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogin_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogin___exit___obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&analogio_analogin_value_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_reference_voltage), MP_ROM_PTR(&analogio_analogin_reference_voltage_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_analogin_locals_dict, analogio_analogin_locals_dict_table); + +const mp_obj_type_t analogio_analogin_type = { + { &mp_type_type }, + .name = MP_QSTR_AnalogIn, + .make_new = analogio_analogin_make_new, + .locals_dict = (mp_obj_t)&analogio_analogin_locals_dict, +}; diff --git a/shared-bindings/analogio/AnalogIn.h b/shared-bindings/analogio/AnalogIn.h new file mode 100644 index 000000000..64ddaab0f --- /dev/null +++ b/shared-bindings/analogio/AnalogIn.h @@ -0,0 +1,40 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/analogio/AnalogIn.h" + +extern const mp_obj_type_t analogio_analogin_type; + +void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self); +uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self); +float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGIN_H__ diff --git a/shared-bindings/analogio/AnalogOut.c b/shared-bindings/analogio/AnalogOut.c new file mode 100644 index 000000000..6b02f8c0a --- /dev/null +++ b/shared-bindings/analogio/AnalogOut.c @@ -0,0 +1,147 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/AnalogOut.h" + +//| .. currentmodule:: analogio +//| +//| :class:`AnalogOut` -- output analog voltage +//| ============================================ +//| +//| The AnalogOut is used to output analog values (a specific voltage). +//| +//| Example usage:: +//| +//| import analogio +//| from microcontroller import pin +//| +//| with analogio.AnalogOut(pin.PA02) as dac: # output on pin PA02 +//| dac.value = 32768 # makes PA02 1.65V +//| + +//| .. class:: AnalogOut(pin) +//| +//| Use the AnalogOut on the given pin. +//| +//| :param ~microcontroller.Pin pin: the pin to output to +//| +STATIC mp_obj_t analogio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + // check arguments + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + assert_pin(args[0], false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + + analogio_analogout_obj_t *self = m_new_obj(analogio_analogout_obj_t); + self->base.type = &analogio_analogout_type; + assert_pin_free(pin); + common_hal_analogio_analogout_construct(self, pin); + + return self; +} + +//| .. method:: deinit() +//| +//| Turn off the AnalogOut and release the pin for other use. +//| +STATIC mp_obj_t analogio_analogout_deinit(mp_obj_t self_in) { + analogio_analogout_obj_t *self = self_in; + + common_hal_analogio_analogout_deinit(self); + + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(analogio_analogout_deinit_obj, analogio_analogout_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t analogio_analogout___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_analogio_analogout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(analogio_analogout___exit___obj, 4, 4, analogio_analogout___exit__); + +//| .. attribute:: value +//| +//| The value on the analog pin. The value must be between 0 and 65535 +//| inclusive (16-bit). Even if the underlying digital to analog converter +//| is lower resolution, the input must be scaled to be 16-bit. +//| +//| :return: the last value written +//| :rtype: int +//| +STATIC mp_obj_t analogio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + analogio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint32_t v = mp_obj_get_int(value); + if (v >= (1 << 16)) { + mp_raise_ValueError("AnalogOut is only 16 bits. Value must be less than 65536."); + } + common_hal_analogio_analogout_set_value(self, v); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(analogio_analogout_set_value_obj, analogio_analogout_obj_set_value); + +const mp_obj_property_t analogio_analogout_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&analogio_analogout_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t analogio_analogout_locals_dict_table[] = { + // instance methods + { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&analogio_analogout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&analogio_analogout___exit___obj) }, + + // Properties + { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&analogio_analogout_value_obj }, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_analogout_locals_dict, analogio_analogout_locals_dict_table); + +const mp_obj_type_t analogio_analogout_type = { + { &mp_type_type }, + .name = MP_QSTR_AnalogOut, + .make_new = analogio_analogout_make_new, + .locals_dict = (mp_obj_t)&analogio_analogout_locals_dict, +}; diff --git a/shared-bindings/analogio/AnalogOut.h b/shared-bindings/analogio/AnalogOut.h new file mode 100644 index 000000000..3aa19ac29 --- /dev/null +++ b/shared-bindings/analogio/AnalogOut.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/analogio/AnalogOut.h" + +extern const mp_obj_type_t analogio_analogout_type; + +void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self); +void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self, uint16_t value); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO_ANALOGOUT_H__ diff --git a/shared-bindings/analogio/__init__.c b/shared-bindings/analogio/__init__.c new file mode 100644 index 000000000..39d6bdcda --- /dev/null +++ b/shared-bindings/analogio/__init__.c @@ -0,0 +1,84 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/analogio/__init__.h" +#include "shared-bindings/analogio/AnalogIn.h" +#include "shared-bindings/analogio/AnalogOut.h" + +//| :mod:`analogio` --- Analog hardware support +//| ================================================= +//| +//| .. module:: analogio +//| :synopsis: Analog hardware support +//| :platform: SAMD21, ESP8266 +//| +//| The `analogio` module contains classes to provide access to analog IO +//| typically implemented with digital-to-analog (DAC) and analog-to-digital +//| (ADC) converters. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| AnalogIn +//| AnalogOut +//| +//| All libraries change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| +//| For example:: +//| +//| import analogio +//| from board import * +//| +//| with analogio.AnalogIn(A0) as pin: +//| print(pin.value) +//| +//| This example will initialize the the device, read +//| :py:data:`~analogio.AnalogIn.value` and then +//| :py:meth:`~analogio.AnalogIn.deinit` the hardware. +//| + +STATIC const mp_rom_map_elem_t analogio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_analogio) }, + { MP_ROM_QSTR(MP_QSTR_AnalogIn), MP_ROM_PTR(&analogio_analogin_type) }, + { MP_ROM_QSTR(MP_QSTR_AnalogOut), MP_ROM_PTR(&analogio_analogout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(analogio_module_globals, analogio_module_globals_table); + +const mp_obj_module_t analogio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&analogio_module_globals, +}; diff --git a/shared-bindings/analogio/__init__.h b/shared-bindings/analogio/__init__.h new file mode 100644 index 000000000..9a0c77cb8 --- /dev/null +++ b/shared-bindings/analogio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H__ + +#include "py/obj.h" + +// Nothing now. + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_ANALOGIO___INIT___H__ diff --git a/shared-bindings/bitbangio/OneWire.h b/shared-bindings/bitbangio/OneWire.h index dcc0386d4..a888dae04 100644 --- a/shared-bindings/bitbangio/OneWire.h +++ b/shared-bindings/bitbangio/OneWire.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H__ #include "common-hal/microcontroller/types.h" #include "shared-module/bitbangio/types.h" @@ -39,4 +39,4 @@ extern bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) extern bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self); extern void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self, bool bit); -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BITBANGIO_ONEWIRE_H__ diff --git a/shared-bindings/bitbangio/__init__.c b/shared-bindings/bitbangio/__init__.c index 5fe469758..85acab0d3 100644 --- a/shared-bindings/bitbangio/__init__.c +++ b/shared-bindings/bitbangio/__init__.c @@ -25,7 +25,7 @@ */ // bitbangio implements some standard protocols in the processor. Its only -// dependency is nativeio.DigitalInOut. +// dependency is digitalio. #include @@ -45,12 +45,13 @@ //| //| .. module:: bitbangio //| :synopsis: Digital protocols implemented by the CPU -//| :platform: SAMD21 +//| :platform: SAMD21, ESP8266 //| -//| The `bitbangio` module contains classes to provide digital protocol support -//| regardless of whether the underlying hardware exists to use the protocol. +//| The `bitbangio` module contains classes to provide digital bus protocol +//| support regardless of whether the underlying hardware exists to use the +//| protocol. //| -//| First try to use `nativeio` module instead which may utilize peripheral +//| First try to use `busio` module instead which may utilize peripheral //| hardware to implement the protocols. Native implementations will be faster //| than bitbanged versions and have more capabilities. //| diff --git a/shared-bindings/busio/I2C.c b/shared-bindings/busio/I2C.c new file mode 100644 index 000000000..7383cb104 --- /dev/null +++ b/shared-bindings/busio/I2C.c @@ -0,0 +1,286 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// This file contains all of the Python API definitions for the +// busio.I2C class. + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/I2C.h" + +#include "lib/utils/context_manager_helpers.h" +#include "py/runtime.h" +//| .. currentmodule:: busio +//| +//| :class:`I2C` --- Two wire serial protocol +//| ------------------------------------------ +//| +//| .. class:: I2C(scl, sda, \*, frequency=400000) +//| +//| I2C is a two-wire protocol for communicating between devices. At the +//| physical level it consists of 2 wires: SCL and SDA, the clock and data +//| lines respectively. +//| +//| .. seealso:: Using this class directly requires careful lock management. +//| Instead, use :class:`~adafruit_bus_device.i2c_device.I2CDevice` to +//| manage locks. +//| +//| .. seealso:: Using this class to directly read registers requires manual +//| bit unpacking. Instead, use an existing driver or make one with +//| :ref:`Register ` data descriptors. +//| +//| :param ~microcontroller.Pin scl: The clock pin +//| :param ~microcontroller.Pin sda: The data pin +//| :param int frequency: The clock frequency in Hertz +//| +STATIC mp_obj_t busio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); + busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); + self->base.type = &busio_i2c_type; + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_scl, ARG_sda, ARG_frequency }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_scl].u_obj, false); + assert_pin(args[ARG_sda].u_obj, false); + const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); + assert_pin_free(scl); + const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); + assert_pin_free(sda); + common_hal_busio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int); + return (mp_obj_t)self; +} + +//| .. method:: I2C.deinit() +//| +//| Releases control of the underlying hardware so other classes can use it. +//| +STATIC mp_obj_t busio_i2c_obj_deinit(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_i2c_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_deinit_obj, busio_i2c_obj_deinit); + +//| .. method:: I2C.__enter__() +//| +//| No-op used in Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: I2C.__exit__() +//| +//| Automatically deinitializes the hardware on context exit. +//| +STATIC mp_obj_t busio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_i2c_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_i2c___exit___obj, 4, 4, busio_i2c_obj___exit__); + +static void check_lock(busio_i2c_obj_t *self) { + if (!common_hal_busio_i2c_has_lock(self)) { + mp_raise_RuntimeError("Function requires lock."); + } +} + +//| .. method:: I2C.scan() +//| +//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a +//| list of those that respond. +//| +//| :return: List of device ids on the I2C bus +//| :rtype: list +//| +STATIC mp_obj_t busio_i2c_scan(mp_obj_t self_in) { + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_lock(self); + mp_obj_t list = mp_obj_new_list(0, NULL); + // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved + for (int addr = 0x08; addr < 0x78; ++addr) { + bool success = common_hal_busio_i2c_probe(self, addr); + if (success) { + mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); + } + } + return list; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_scan_obj, busio_i2c_scan); + +//| .. method:: I2C.try_lock() +//| +//| Attempts to grab the I2C lock. Returns True on success. +//| +//| :return: True when lock has been grabbed +//| :rtype: bool +//| +STATIC mp_obj_t busio_i2c_obj_try_lock(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_busio_i2c_try_lock(MP_OBJ_TO_PTR(self_in))); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_try_lock_obj, busio_i2c_obj_try_lock); + +//| .. method:: I2C.unlock() +//| +//| Releases the I2C lock. +//| +STATIC mp_obj_t busio_i2c_obj_unlock(mp_obj_t self_in) { + common_hal_busio_i2c_unlock(MP_OBJ_TO_PTR(self_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_i2c_unlock_obj, busio_i2c_obj_unlock); + +//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer)) +//| +//| Read into ``buffer`` from the slave specified by ``address``. +//| The number of bytes read will be the length of ``buffer``. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buf[start:end]`` will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer to write into +//| :param int start: Index to start writing at +//| :param int end: Index to write up to but not include +//| +STATIC mp_obj_t busio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + int32_t end = args[ARG_end].u_int; + if (end < 0) { + end += bufinfo.len; + } + uint32_t start = args[ARG_start].u_int; + uint32_t len = end - start; + if ((uint32_t) end < start) { + len = 0; + } else if (len > bufinfo.len) { + len = bufinfo.len; + } + uint8_t status = common_hal_busio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, len); + if (status != 0) { + mp_raise_OSError(status); + } + + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_readfrom_into_obj, 3, busio_i2c_readfrom_into); + +//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True) +//| +//| Write the bytes from ``buffer`` to the slave specified by ``address``. +//| Transmits a stop bit if ``stop`` is set. +//| +//| If ``start`` or ``end`` is provided, then the buffer will be sliced +//| as if ``buffer[start:end]``. This will not cause an allocation like +//| ``buffer[start:end]`` will so it saves memory. +//| +//| :param int address: 7-bit device address +//| :param bytearray buffer: buffer containing the bytes to write +//| :param int start: Index to start writing from +//| :param int end: Index to read up to but not include +//| :param bool stop: If true, output an I2C stop condition after the +//| buffer is written +//| +STATIC mp_obj_t busio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_address, ARG_buffer, ARG_start, ARG_end, ARG_stop }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, + }; + busio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + // get the buffer to write the data from + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + + int32_t end = args[ARG_end].u_int; + if (end < 0) { + end += bufinfo.len; + } + uint32_t start = args[ARG_start].u_int; + uint32_t len = end - start; + if ((uint32_t) end < start) { + len = 0; + } else if (len > bufinfo.len) { + len = bufinfo.len; + } + + // do the transfer + uint8_t status = common_hal_busio_i2c_write(self, args[ARG_address].u_int, + ((uint8_t*) bufinfo.buf) + start, len, args[ARG_stop].u_bool); + if (status != 0) { + mp_raise_OSError(status); + } + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(busio_i2c_writeto_obj, 1, busio_i2c_writeto); + +STATIC const mp_rom_map_elem_t busio_i2c_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_i2c_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_i2c___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&busio_i2c_scan_obj) }, + + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_i2c_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&busio_i2c_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&busio_i2c_readfrom_into_obj) }, + { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&busio_i2c_writeto_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(busio_i2c_locals_dict, busio_i2c_locals_dict_table); + +const mp_obj_type_t busio_i2c_type = { + { &mp_type_type }, + .name = MP_QSTR_I2C, + .make_new = busio_i2c_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_i2c_locals_dict, +}; diff --git a/shared-bindings/busio/I2C.h b/shared-bindings/busio/I2C.h new file mode 100644 index 000000000..0d260a309 --- /dev/null +++ b/shared-bindings/busio/I2C.h @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Machine is the HAL for low-level, hardware accelerated functions. It is not +// meant to simplify APIs, its only meant to unify them so that other modules +// do not require port specific logic. +// +// This file includes externs for all functions a port should implement to +// support the machine module. + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H__ + +#include "py/obj.h" + +#include "common-hal/microcontroller/types.h" +#include "common-hal/busio/I2C.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t busio_i2c_type; + +// Initializes the hardware peripheral. +extern void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t * scl, + const mcu_pin_obj_t * sda, + uint32_t frequency); + +extern void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self); + +extern bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self); +extern bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self); +extern void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self); + +// Probe the bus to see if a device acknowledges the given address. +extern bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr); + +// Write to the device and return 0 on success or an appropriate error code from mperrno.h +extern uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t address, + const uint8_t * data, size_t len, + bool stop); + +// Reads memory of the i2c device picking up where it left off and return 0 on +// success or an appropriate error code from mperrno.h +extern uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t address, + uint8_t * data, size_t len); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_I2C_H__ diff --git a/shared-bindings/busio/OneWire.c b/shared-bindings/busio/OneWire.c new file mode 100644 index 000000000..52aed2135 --- /dev/null +++ b/shared-bindings/busio/OneWire.c @@ -0,0 +1,169 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/OneWire.h" + +//| .. currentmodule:: busio +//| +//| :class:`OneWire` -- Lowest-level of the Maxim OneWire protocol +//| ================================================================= +//| +//| :class:`~busio.OneWire` implements the timing-sensitive foundation of the Maxim +//| (formerly Dallas Semi) OneWire protocol. +//| +//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 +//| +//| .. class:: OneWire(pin) +//| +//| Create a OneWire object associated with the given pin. The object +//| implements the lowest level timing-sensitive bits of the protocol. +//| +//| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus +//| +//| Read a short series of pulses:: +//| +//| import busio +//| import board +//| +//| with busio.OneWire(board.D7) as onewire: +//| onewire.reset() +//| onewire.write_bit(True) +//| onewire.write_bit(False) +//| print(onewire.read_bit()) +//| +STATIC mp_obj_t busio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_pin }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_pin].u_obj, false); + const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + busio_onewire_obj_t *self = m_new_obj(busio_onewire_obj_t); + self->base.type = &busio_onewire_type; + + common_hal_busio_onewire_construct(self, pin); + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialize the OneWire bus and release any hardware resources for reuse. +//| +STATIC mp_obj_t busio_onewire_deinit(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_onewire_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_deinit_obj, busio_onewire_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t busio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_onewire_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_onewire___exit___obj, 4, 4, busio_onewire_obj___exit__); + +//| .. method:: reset() +//| +//| Reset the OneWire bus and read presence +//| +//| :returns: False when at least one device is present +//| :rtype: bool +//| +STATIC mp_obj_t busio_onewire_obj_reset(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_busio_onewire_reset(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_reset_obj, busio_onewire_obj_reset); + +//| .. method:: read_bit() +//| +//| Read in a bit +//| +//| :returns: bit state read +//| :rtype: bool +//| +STATIC mp_obj_t busio_onewire_obj_read_bit(mp_obj_t self_in) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_busio_onewire_read_bit(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_onewire_read_bit_obj, busio_onewire_obj_read_bit); + +//| .. method:: write_bit(value) +//| +//| Write out a bit based on value. +//| +STATIC mp_obj_t busio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { + busio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_busio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(busio_onewire_write_bit_obj, busio_onewire_obj_write_bit); + +STATIC const mp_rom_map_elem_t busio_onewire_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_onewire_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_onewire___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&busio_onewire_reset_obj) }, + { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&busio_onewire_read_bit_obj) }, + { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&busio_onewire_write_bit_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_onewire_locals_dict, busio_onewire_locals_dict_table); + +const mp_obj_type_t busio_onewire_type = { + { &mp_type_type }, + .name = MP_QSTR_OneWire, + .make_new = busio_onewire_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_onewire_locals_dict, +}; diff --git a/shared-bindings/busio/OneWire.h b/shared-bindings/busio/OneWire.h new file mode 100644 index 000000000..df5cecb7c --- /dev/null +++ b/shared-bindings/busio/OneWire.h @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/busio/OneWire.h" + +extern const mp_obj_type_t busio_onewire_type; + +extern void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, + const mcu_pin_obj_t* pin); +extern void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_reset(busio_onewire_obj_t* self); +extern bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t* self); +extern void common_hal_busio_onewire_write_bit(busio_onewire_obj_t* self, bool bit); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_ONEWIRE_H__ diff --git a/shared-bindings/busio/SPI.c b/shared-bindings/busio/SPI.c new file mode 100644 index 000000000..d4d9ec345 --- /dev/null +++ b/shared-bindings/busio/SPI.c @@ -0,0 +1,304 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// This file contains all of the Python API definitions for the +// busio.SPI class. + +#include + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/SPI.h" + +#include "lib/utils/context_manager_helpers.h" +#include "py/mperrno.h" +#include "py/nlr.h" +#include "py/runtime.h" + +//| .. currentmodule:: busio +//| +//| :class:`SPI` -- a 3-4 wire serial protocol +//| ----------------------------------------------- +//| +//| SPI is a serial protocol that has exclusive pins for data in and out of the +//| master. It is typically faster than :py:class:`~busio.I2C` because a +//| separate pin is used to control the active slave rather than a transitted +//| address. This class only manages three of the four SPI lines: `!clock`, +//| `!MOSI`, `!MISO`. Its up to the client to manage the appropriate slave +//| select line. (This is common because multiple slaves can share the `!clock`, +//| `!MOSI` and `!MISO` lines and therefore the hardware.) +//| +//| .. class:: SPI(clock, MOSI=None, MISO=None) +//| +//| Construct an SPI object on the given pins. +//| +//| .. seealso:: Using this class directly requires careful lock management. +//| Instead, use :class:`~adafruit_bus_device.spi_device.SPIDevice` to +//| manage locks. +//| +//| .. seealso:: Using this class to directly read registers requires manual +//| bit unpacking. Instead, use an existing driver or make one with +//| :ref:`Register ` data descriptors. +//| +//| :param ~microcontroller.Pin clock: the pin to use for the clock. +//| :param ~microcontroller.Pin MOSI: the Master Out Slave In pin. +//| :param ~microcontroller.Pin MISO: the Master In Slave Out pin. +//| + +// TODO(tannewt): Support LSB SPI. +STATIC mp_obj_t busio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); + busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); + self->base.type = &busio_spi_type; + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_clock, ARG_MOSI, ARG_MISO }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_clock].u_obj, false); + assert_pin(args[ARG_MOSI].u_obj, true); + assert_pin(args[ARG_MISO].u_obj, true); + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); + assert_pin_free(clock); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); + assert_pin_free(mosi); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); + assert_pin_free(miso); + common_hal_busio_spi_construct(self, clock, mosi, miso); + return (mp_obj_t)self; +} + +//| .. method:: SPI.deinit() +//| +//| Turn off the SPI bus. +//| +STATIC mp_obj_t busio_spi_obj_deinit(mp_obj_t self_in) { + busio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_spi_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_deinit_obj, busio_spi_obj_deinit); + +//| .. method:: SPI.__enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: SPI.__exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t busio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_spi_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_spi_obj___exit___obj, 4, 4, busio_spi_obj___exit__); + +static void check_lock(busio_spi_obj_t *self) { + if (!common_hal_busio_spi_has_lock(self)) { + mp_raise_RuntimeError("Function requires lock"); + } +} + +//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8) +//| +//| Configures the SPI bus. Only valid when locked. +//| +//| :param int baudrate: the clock rate in Hertz +//| :param int polarity: the base state of the clock line (0 or 1) +//| :param int phase: the edge of the clock that data is captured. First (0) +//| or second (1). Rising or falling depends on clock polarity. +//| :param int bits: the number of bits per word +//| +STATIC mp_obj_t busio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, + { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + uint8_t polarity = args[ARG_polarity].u_int; + if (polarity != 0 && polarity != 1) { + mp_raise_ValueError("Invalid polarity"); + } + uint8_t phase = args[ARG_phase].u_int; + if (phase != 0 && phase != 1) { + mp_raise_ValueError("Invalid phase"); + } + uint8_t bits = args[ARG_bits].u_int; + if (bits != 8 && bits != 9) { + mp_raise_ValueError("Invalid number of bits"); + } + + if (!common_hal_busio_spi_configure(self, args[ARG_baudrate].u_int, + polarity, phase, bits)) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_configure_obj, 1, busio_spi_configure); + +//| .. method:: SPI.try_lock() +//| +//| Attempts to grab the SPI lock. Returns True on success. +//| +//| :return: True when lock has been grabbed +//| :rtype: bool +//| +STATIC mp_obj_t busio_spi_obj_try_lock(mp_obj_t self_in) { + return mp_obj_new_bool(common_hal_busio_spi_try_lock(MP_OBJ_TO_PTR(self_in))); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_try_lock_obj, busio_spi_obj_try_lock); + +//| .. method:: SPI.unlock() +//| +//| Releases the SPI lock. +//| +STATIC mp_obj_t busio_spi_obj_unlock(mp_obj_t self_in) { + common_hal_busio_spi_unlock(MP_OBJ_TO_PTR(self_in)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_spi_unlock_obj, busio_spi_obj_unlock); + +//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer)) +//| +//| Write the data contained in ``buf``. Requires the SPI being locked. +//| +//| :param bytearray buffer: buffer containing the bytes to write +//| :param int start: Index to start writing from +//| :param int end: Index to read up to but not include +//| +STATIC mp_obj_t busio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); + int32_t end = args[ARG_end].u_int; + if (end < 0) { + end += bufinfo.len; + } + uint32_t start = args[ARG_start].u_int; + uint32_t len = end - start; + if ((uint32_t) end < start) { + len = 0; + } else if (len > bufinfo.len) { + len = bufinfo.len; + } + + bool ok = common_hal_busio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, len); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_write_obj, 2, busio_spi_write); + + +//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0) +//| +//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked. +//| +//| :param bytearray buffer: buffer to write into +//| :param int start: Index to start writing at +//| :param int end: Index to write up to but not include +//| :param int write_value: Value to write reading. (Usually ignored.) +//| +STATIC mp_obj_t busio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, + { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, + { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + }; + busio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_lock(self); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); + int32_t end = args[ARG_end].u_int; + if (end < 0) { + end += bufinfo.len; + } + uint32_t start = args[ARG_start].u_int; + uint32_t len = end - start; + if ((uint32_t) end < start) { + len = 0; + } else if (len > bufinfo.len) { + len = bufinfo.len; + } + + bool ok = common_hal_busio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, len, args[ARG_write_value].u_int); + if (!ok) { + mp_raise_OSError(MP_EIO); + } + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(busio_spi_readinto_obj, 2, busio_spi_readinto); + +STATIC const mp_rom_map_elem_t busio_spi_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_spi_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_spi_obj___exit___obj) }, + + { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&busio_spi_configure_obj) }, + { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&busio_spi_try_lock_obj) }, + { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&busio_spi_unlock_obj) }, + + { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&busio_spi_readinto_obj) }, + { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&busio_spi_write_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_spi_locals_dict, busio_spi_locals_dict_table); + +const mp_obj_type_t busio_spi_type = { + { &mp_type_type }, + .name = MP_QSTR_SPI, + .make_new = busio_spi_make_new, + .locals_dict = (mp_obj_dict_t*)&busio_spi_locals_dict, +}; diff --git a/shared-bindings/busio/SPI.h b/shared-bindings/busio/SPI.h new file mode 100644 index 000000000..e3deb0e72 --- /dev/null +++ b/shared-bindings/busio/SPI.h @@ -0,0 +1,57 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H__ + +#include "py/obj.h" + +#include "common-hal/microcontroller/types.h" +#include "common-hal/busio/SPI.h" + +// Type object used in Python. Should be shared between ports. +extern const mp_obj_type_t busio_spi_type; + +// Construct an underlying SPI object. +extern void common_hal_busio_spi_construct(busio_spi_obj_t *self, + const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, + const mcu_pin_obj_t * miso); + +extern void common_hal_busio_spi_deinit(busio_spi_obj_t *self); + +extern bool common_hal_busio_spi_configure(busio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); + +extern bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self); +extern bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self); +extern void common_hal_busio_spi_unlock(busio_spi_obj_t *self); + +// Writes out the given data. +extern bool common_hal_busio_spi_write(busio_spi_obj_t *self, const uint8_t *data, size_t len); + +// Reads in len bytes while outputting zeroes. +extern bool common_hal_busio_spi_read(busio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_SPI_H__ diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c new file mode 100644 index 000000000..11ee91355 --- /dev/null +++ b/shared-bindings/busio/UART.c @@ -0,0 +1,290 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "shared-bindings/busio/UART.h" + +#include "lib/utils/context_manager_helpers.h" + +#include "py/ioctl.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared-bindings/microcontroller/Pin.h" + +//| .. currentmodule:: busio +//| +//| :class:`UART` -- a bidirectional serial protocol +//| ================================================= +//| +//| +//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1000, receiver_buffer_size=64) +//| +//| A common bidirectional serial protocol that uses an an agreed upon speed +//| rather than a shared clock line. +//| +//| :param ~microcontroller.Pin tx: the pin to transmit with +//| :param ~microcontroller.Pin rx: the pin to receive on +//| :param int baudrate: the transmit and receive speed +/// :param int bits: the number of bits per byte, 7, 8 or 9. +/// :param Parity parity: the parity used for error checking +/// :param int stop: the number of stop bits, 1 or 2. +/// :param int timeout: the timeout in milliseconds to wait for the first character and between subsequent characters. +/// :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.) +//| +typedef struct { + mp_obj_base_t base; +} busio_uart_parity_obj_t; +extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; +extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; + +STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); + busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); + self->base.type = &busio_uart_type; + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9600} }, + { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, + { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, + { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, + { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, + { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + assert_pin(args[ARG_rx].u_obj, true); + const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); + assert_pin_free(rx); + + assert_pin(args[ARG_tx].u_obj, true); + const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj); + assert_pin_free(tx); + + uint8_t bits = args[ARG_bits].u_int; + if (bits < 7 || bits > 9) { + mp_raise_ValueError("bits must be 7, 8 or 9"); + } + + uart_parity_t parity = PARITY_NONE; + if (args[ARG_parity].u_obj == &busio_uart_parity_even_obj) { + parity = PARITY_EVEN; + } else if (args[ARG_parity].u_obj == &busio_uart_parity_odd_obj) { + parity = PARITY_ODD; + } + + uint8_t stop = args[ARG_stop].u_int; + if (stop != 1 && stop != 2) { + mp_raise_ValueError("stop must be 1 or 2"); + } + + common_hal_busio_uart_construct(self, tx, rx, + args[ARG_baudrate].u_int, bits, parity, stop, args[ARG_timeout].u_int, + args[ARG_receiver_buffer_size].u_int); + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Deinitialises the UART and releases any hardware resources for reuse. +//| +STATIC mp_obj_t busio_uart_obj_deinit(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_busio_uart_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_deinit_obj, busio_uart_obj_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t busio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_busio_uart_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(busio_uart___exit___obj, 4, 4, busio_uart_obj___exit__); + +// These are standard stream methods. Code is in py/stream.c. +// +//| .. method:: read(nbytes=None) +//| +//| Read characters. If ``nbytes`` is specified then read at most that many +//| bytes. Otherwise, read everything that has been buffered. +//| +//| :return: Data read +//| :rtype: bytes or None +//| +//| .. method:: readinto(buf, nbytes=None) +//| +//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most +//| that many bytes. Otherwise, read at most ``len(buf)`` bytes. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: bytes or None +//| +//| .. method:: readline() +//| +//| Read a line, ending in a newline character. +//| +//| :return: the line read +//| :rtype: int or None +//| +//| .. method:: write(buf) +//| +//| Write the buffer of bytes to the bus. +//| +//| :return: the number of bytes written +//| :rtype: int or None +//| + +// These three methods are used by the shared stream methods. +STATIC mp_uint_t busio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { + busio_uart_obj_t *self = self_in; + byte *buf = buf_in; + + // make sure we want at least 1 char + if (size == 0) { + return 0; + } + + return common_hal_busio_uart_read(self, buf, size, errcode); +} + +STATIC mp_uint_t busio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { + busio_uart_obj_t *self = self_in; + const byte *buf = buf_in; + + return common_hal_busio_uart_write(self, buf, size, errcode); +} + +STATIC mp_uint_t busio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { + busio_uart_obj_t *self = self_in; + mp_uint_t ret; + if (request == MP_IOCTL_POLL) { + mp_uint_t flags = arg; + ret = 0; + if ((flags & MP_IOCTL_POLL_RD) && common_hal_busio_uart_rx_characters_available(self) > 0) { + ret |= MP_IOCTL_POLL_RD; + } + if ((flags & MP_IOCTL_POLL_WR) && common_hal_busio_uart_ready_to_tx(self)) { + ret |= MP_IOCTL_POLL_WR; + } + } else { + *errcode = MP_EINVAL; + ret = MP_STREAM_ERROR; + } + return ret; +} + +//| .. class:: busio.UART.Parity +//| +//| Enum-like class to define the parity used to verify correct data transfer. +//| +//| .. data:: ODD +//| +//| Total number of ones should be odd. +//| +//| .. data:: EVEN +//| +//| Total number of ones should be even. +//| +const mp_obj_type_t busio_uart_parity_type; + +const busio_uart_parity_obj_t busio_uart_parity_odd_obj = { + { &busio_uart_parity_type }, +}; + +const busio_uart_parity_obj_t busio_uart_parity_even_obj = { + { &busio_uart_parity_type }, +}; + +STATIC const mp_rom_map_elem_t busio_uart_parity_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_ODD), MP_ROM_PTR(&busio_uart_parity_odd_obj) }, + { MP_ROM_QSTR(MP_QSTR_EVEN), MP_ROM_PTR(&busio_uart_parity_even_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_uart_parity_locals_dict, busio_uart_parity_locals_dict_table); + +STATIC void busio_uart_parity_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr parity = MP_QSTR_ODD; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&busio_uart_parity_even_obj)) { + parity = MP_QSTR_EVEN; + } + mp_printf(print, "%q.%q.%q.%q", MP_QSTR_busio, MP_QSTR_UART, MP_QSTR_Parity, parity); +} + +const mp_obj_type_t busio_uart_parity_type = { + { &mp_type_type }, + .name = MP_QSTR_Parity, + .print = busio_uart_parity_print, + .locals_dict = (mp_obj_t)&busio_uart_parity_locals_dict, +}; + +STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&busio_uart_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&busio_uart___exit___obj) }, + + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + + // Nested Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) }, +}; +STATIC MP_DEFINE_CONST_DICT(busio_uart_locals_dict, busio_uart_locals_dict_table); + +STATIC const mp_stream_p_t uart_stream_p = { + .read = busio_uart_read, + .write = busio_uart_write, + .ioctl = busio_uart_ioctl, + .is_text = false, +}; + +const mp_obj_type_t busio_uart_type = { + { &mp_type_type }, + .name = MP_QSTR_UART, + .make_new = busio_uart_make_new, + .getiter = mp_identity, + .iternext = mp_stream_unbuffered_iter, + .protocol = &uart_stream_p, + .locals_dict = (mp_obj_dict_t*)&busio_uart_locals_dict, +}; diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h new file mode 100644 index 000000000..e0a8a0b09 --- /dev/null +++ b/shared-bindings/busio/UART.h @@ -0,0 +1,60 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/busio/UART.h" + +extern const mp_obj_type_t busio_uart_type; + +typedef enum { + PARITY_NONE, + PARITY_EVEN, + PARITY_ODD +} uart_parity_t; + +// Construct an underlying UART object. +extern void common_hal_busio_uart_construct(busio_uart_obj_t *self, + const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, + uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, + uint8_t receiver_buffer_size); + +extern void common_hal_busio_uart_deinit(busio_uart_obj_t *self); + +// Read characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_read(busio_uart_obj_t *self, + uint8_t *data, size_t len, int *errcode); + +// Write characters. len is in characters NOT bytes! +extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self, + const uint8_t *data, size_t len, int *errcode); + +extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self); +extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H__ diff --git a/shared-bindings/busio/__init__.c b/shared-bindings/busio/__init__.c new file mode 100644 index 000000000..9e075752d --- /dev/null +++ b/shared-bindings/busio/__init__.c @@ -0,0 +1,98 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/busio/__init__.h" +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/busio/OneWire.h" +#include "shared-bindings/busio/SPI.h" +#include "shared-bindings/busio/UART.h" +#include "shared-bindings/busio/__init__.h" + +#include "py/runtime.h" + +//| :mod:`busio` --- Hardware accelerated behavior +//| ================================================= +//| +//| .. module:: busio +//| :synopsis: Hardware accelerated behavior +//| :platform: SAMD21 +//| +//| The `busio` module contains classes to support a variety of serial +//| protocols. +//| +//| When the microcontroller does not support the behavior in a hardware +//| accelerated fashion it may internally use a bitbang routine. However, if +//| hardware support is available on a subset of pins but not those provided, +//| then a RuntimeError will be raised. Use the `bitbangio` module to explicitly +//| bitbang a serial protocol on any general purpose pins. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| I2C +//| OneWire +//| SPI +//| UART +//| +//| All libraries change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| +//| For example:: +//| +//| import busio +//| from board import * +//| +//| with busio.I2C(SCL, SDA) as i2c: +//| i2c.scan() +//| +//| This example will initialize the the device, run +//| :py:meth:`~busio.I2C.scan` and then :py:meth:`~busio.I2C.deinit` the +//| hardware. +//| + +STATIC const mp_rom_map_elem_t busio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_busio) }, + { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&busio_i2c_type) }, + { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&busio_onewire_type) }, + { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&busio_spi_type) }, + { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&busio_uart_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(busio_module_globals, busio_module_globals_table); + +const mp_obj_module_t busio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&busio_module_globals, +}; diff --git a/shared-bindings/busio/__init__.h b/shared-bindings/busio/__init__.h new file mode 100644 index 000000000..214c2b144 --- /dev/null +++ b/shared-bindings/busio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H__ + +#include "py/obj.h" + +// Nothing now. + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO___INIT___H__ diff --git a/shared-bindings/digitalio/DigitalInOut.c b/shared-bindings/digitalio/DigitalInOut.c new file mode 100644 index 000000000..65ace8357 --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOut.c @@ -0,0 +1,486 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "lib/utils/context_manager_helpers.h" + +#include "py/nlr.h" +#include "py/objtype.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/mphal.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +//| .. currentmodule:: digitalio +//| +//| :class:`DigitalInOut` -- digital input and output +//| ========================================================= +//| +//| A DigitalInOut is used to digitally control I/O pins. For analog control of +//| a pin, see the :py:class:`~digitalio.AnalogIn` and +//| :py:class:`~digitalio.AnalogOut` classes. +//| + +//| .. class:: DigitalInOut(pin) +//| +//| Create a new DigitalInOut object associated with the pin. Defaults to input +//| with no pull. Use :py:meth:`switch_to_input` and +//| :py:meth:`switch_to_output` to change the direction. +//| +//| :param ~microcontroller.Pin pin: The pin to control +//| +STATIC mp_obj_t digitalio_digitalinout_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + + digitalio_digitalinout_obj_t *self = m_new_obj(digitalio_digitalinout_obj_t); + self->base.type = &digitalio_digitalinout_type; + + assert_pin(args[0], false); + mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); + assert_pin_free(pin); + common_hal_digitalio_digitalinout_construct(self, pin); + + return (mp_obj_t)self; +} + +//| .. method:: deinit() +//| +//| Turn off the DigitalInOut and release the pin for other use. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_deinit(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_digitalio_digitalinout_deinit(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_deinit_obj, digitalio_digitalinout_obj_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t digitalio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_digitalio_digitalinout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(digitalio_digitalinout_obj___exit___obj, 4, 4, digitalio_digitalinout_obj___exit__); + +//| +//| .. method:: switch_to_output(value=False, drive_mode=DriveMode.PUSH_PULL) +//| +//| Switch to writing out digital values. +//| +//| :param bool value: default value to set upon switching +//| :param DriveMode drive_mode: drive mode for the output +//| +typedef struct { + mp_obj_base_t base; +} digitalio_digitalinout_drive_mode_obj_t; +extern const digitalio_digitalinout_drive_mode_obj_t digitalio_digitalinout_drive_mode_push_pull_obj; +extern const digitalio_digitalinout_drive_mode_obj_t digitalio_digitalinout_drive_mode_open_drain_obj; + +STATIC mp_obj_t digitalio_digitalinout_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_value, ARG_drive_mode }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_value, MP_ARG_BOOL, {.u_bool = false} }, + { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &digitalio_digitalinout_drive_mode_push_pull_obj} }, + }; + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + enum digitalinout_drive_mode_t drive_mode = DRIVE_MODE_PUSH_PULL; + if (args[ARG_drive_mode].u_rom_obj == &digitalio_digitalinout_drive_mode_open_drain_obj) { + drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + // do the transfer + common_hal_digitalio_digitalinout_switch_to_output(self, args[ARG_value].u_bool, drive_mode); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_output_obj, 1, digitalio_digitalinout_switch_to_output); + +//| .. method:: switch_to_input(pull=None) +//| +//| Switch to read in digital values. +//| +//| :param Pull pull: pull configuration for the input +//| +//| Example usage:: +//| +//| import digitalio +//| import board +//| +//| with digitalio.DigitalInOut(board.SLIDE_SWITCH) as switch: +//| switch.switch_to_input(pull=digitalio.DigitalInOut.Pull.UP) +//| # Or, after switch_to_input +//| switch.pull = digitalio.DigitalInOut.Pull.UP +//| print(switch.value) +//| +typedef struct { + mp_obj_base_t base; +} digitalio_digitalinout_pull_obj_t; +extern const digitalio_digitalinout_pull_obj_t digitalio_digitalinout_pull_up_obj; +extern const digitalio_digitalinout_pull_obj_t digitalio_digitalinout_pull_down_obj; + +STATIC mp_obj_t digitalio_digitalinout_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_pull }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, + }; + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + enum digitalinout_pull_t pull = PULL_NONE; + if (args[ARG_pull].u_rom_obj == &digitalio_digitalinout_pull_up_obj) { + pull = PULL_UP; + }else if (args[ARG_pull].u_rom_obj == &digitalio_digitalinout_pull_down_obj) { + pull = PULL_DOWN; + } + // do the transfer + common_hal_digitalio_digitalinout_switch_to_input(self, pull); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_KW(digitalio_digitalinout_switch_to_input_obj, 1, digitalio_digitalinout_switch_to_input); + +//| .. attribute:: direction +//| +//| Get the direction of the pin. +//| +//| :raises AttributeError: when set. Use :py:meth:`switch_to_input` and :py:meth:`switch_to_output` to change the direction. +//| +typedef struct { + mp_obj_base_t base; +} digitalio_digitalinout_direction_obj_t; +extern const digitalio_digitalinout_direction_obj_t digitalio_digitalinout_direction_in_obj; +extern const digitalio_digitalinout_direction_obj_t digitalio_digitalinout_direction_out_obj; + +STATIC mp_obj_t digitalio_digitalinout_obj_get_direction(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + enum digitalinout_direction_t direction = common_hal_digitalio_digitalinout_get_direction(self); + if (direction == DIRECTION_IN) { + return (mp_obj_t)&digitalio_digitalinout_direction_in_obj; + } + return (mp_obj_t)&digitalio_digitalinout_direction_out_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_direction_obj, digitalio_digitalinout_obj_get_direction); + +const mp_obj_property_t digitalio_digitalinout_direction_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_direction_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: value +//| +//| The digital logic level of the pin. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_value(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + bool value = common_hal_digitalio_digitalinout_get_value(self); + return mp_obj_new_bool(value); +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_value_obj, digitalio_digitalinout_obj_get_value); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_IN) { + mp_raise_AttributeError("Cannot set value when direction is input."); + return mp_const_none; + } + common_hal_digitalio_digitalinout_set_value(self, mp_obj_is_true(value)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_value_obj, digitalio_digitalinout_obj_set_value); + +const mp_obj_property_t digitalio_digitalinout_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_value_obj, + (mp_obj_t)&digitalio_digitalinout_set_value_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: drive_mode +//| +//| Get or set the pin drive mode. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_IN) { + mp_raise_AttributeError("Drive mode not used when direction is input."); + return mp_const_none; + } + enum digitalinout_drive_mode_t drive_mode = common_hal_digitalio_digitalinout_get_drive_mode(self); + if (drive_mode == DRIVE_MODE_PUSH_PULL) { + return (mp_obj_t)&digitalio_digitalinout_drive_mode_push_pull_obj; + } + return (mp_obj_t)&digitalio_digitalinout_drive_mode_open_drain_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_drive_mode_obj, digitalio_digitalinout_obj_get_drive_mode); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_IN) { + mp_raise_AttributeError("Drive mode not used when direction is input."); + return mp_const_none; + } + enum digitalinout_drive_mode_t c_drive_mode = DRIVE_MODE_PUSH_PULL; + if (drive_mode == &digitalio_digitalinout_drive_mode_open_drain_obj) { + c_drive_mode = DRIVE_MODE_OPEN_DRAIN; + } + common_hal_digitalio_digitalinout_set_drive_mode(self, c_drive_mode); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_drive_mode_obj, digitalio_digitalinout_obj_set_drive_mode); + +const mp_obj_property_t digitalio_digitalinout_drive_mode_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_drive_mode_obj, + (mp_obj_t)&digitalio_digitalinout_set_drive_mode_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: pull +//| +//| Get or set the pin pull. +//| +//| :raises AttributeError: if the direction is ~`Direction.OUT`. +//| +STATIC mp_obj_t digitalio_digitalinout_obj_get_pull(mp_obj_t self_in) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUT) { + mp_raise_AttributeError("Pull not used when direction is output."); + return mp_const_none; + } + enum digitalinout_pull_t pull = common_hal_digitalio_digitalinout_get_pull(self); + if (pull == PULL_UP) { + return (mp_obj_t)&digitalio_digitalinout_pull_up_obj; + } else if (pull == PULL_DOWN) { + return (mp_obj_t)&digitalio_digitalinout_pull_down_obj; + } + return (mp_obj_t)&mp_const_none_obj; +} +MP_DEFINE_CONST_FUN_OBJ_1(digitalio_digitalinout_get_pull_obj, digitalio_digitalinout_obj_get_pull); + +STATIC mp_obj_t digitalio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { + digitalio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (common_hal_digitalio_digitalinout_get_direction(self) == DIRECTION_OUT) { + mp_raise_AttributeError("Pull not used when direction is output."); + return mp_const_none; + } + enum digitalinout_pull_t pull = PULL_NONE; + if (pull_obj == &digitalio_digitalinout_pull_up_obj) { + pull = PULL_UP; + } else if (pull_obj == &digitalio_digitalinout_pull_down_obj) { + pull = PULL_DOWN; + } + common_hal_digitalio_digitalinout_set_pull(self, pull); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(digitalio_digitalinout_set_pull_obj, digitalio_digitalinout_obj_set_pull); + +const mp_obj_property_t digitalio_digitalinout_pull_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&digitalio_digitalinout_get_pull_obj, + (mp_obj_t)&digitalio_digitalinout_set_pull_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. class:: digitalio.DigitalInOut.Direction +//| +//| Enum-like class to define which direction the digital values are +//| going. +//| +//| .. data:: IN +//| +//| Read digital data in +//| +//| .. data:: OUT +//| +//| Write digital data out +//| +const mp_obj_type_t digitalio_digitalinout_direction_type; + +const digitalio_digitalinout_direction_obj_t digitalio_digitalinout_direction_in_obj = { + { &digitalio_digitalinout_direction_type }, +}; + +const digitalio_digitalinout_direction_obj_t digitalio_digitalinout_direction_out_obj = { + { &digitalio_digitalinout_direction_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_digitalinout_direction_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_PTR(&digitalio_digitalinout_direction_in_obj) }, + { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_PTR(&digitalio_digitalinout_direction_out_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_digitalinout_direction_locals_dict, digitalio_digitalinout_direction_locals_dict_table); + +STATIC void digitalio_digitalinout_direction_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr direction = MP_QSTR_IN; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_digitalinout_direction_out_obj)) { + direction = MP_QSTR_OUT; + } + mp_printf(print, "%q.%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_DigitalInOut, MP_QSTR_Direction, direction); +} + +const mp_obj_type_t digitalio_digitalinout_direction_type = { + { &mp_type_type }, + .name = MP_QSTR_Direction, + .print = digitalio_digitalinout_direction_print, + .locals_dict = (mp_obj_t)&digitalio_digitalinout_direction_locals_dict, +}; + +//| .. class:: digitalio.DigitalInOut.DriveMode +//| +//| Enum-like class to define the drive mode used when outputting +//| digital values. +//| +//| .. data:: PUSH_PULL +//| +//| Output both high and low digital values +//| +//| .. data:: OPEN_DRAIN +//| +//| Output low digital values but go into high z for digital high. This is +//| useful for i2c and other protocols that share a digital line. +//| +const mp_obj_type_t digitalio_digitalinout_drive_mode_type; + +const digitalio_digitalinout_drive_mode_obj_t digitalio_digitalinout_drive_mode_push_pull_obj = { + { &digitalio_digitalinout_drive_mode_type }, +}; + +const digitalio_digitalinout_drive_mode_obj_t digitalio_digitalinout_drive_mode_open_drain_obj = { + { &digitalio_digitalinout_drive_mode_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_digitalinout_drive_mode_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_PUSH_PULL), MP_ROM_PTR(&digitalio_digitalinout_drive_mode_push_pull_obj) }, + { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_PTR(&digitalio_digitalinout_drive_mode_open_drain_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_digitalinout_drive_mode_locals_dict, digitalio_digitalinout_drive_mode_locals_dict_table); + +STATIC void digitalio_digitalinout_drive_mode_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr drive_mode = MP_QSTR_PUSH_PULL; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_digitalinout_drive_mode_open_drain_obj)) { + drive_mode = MP_QSTR_OPEN_DRAIN; + } + mp_printf(print, "%q.%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_DigitalInOut, MP_QSTR_DriveMode, drive_mode); +} + +const mp_obj_type_t digitalio_digitalinout_drive_mode_type = { + { &mp_type_type }, + .name = MP_QSTR_DriveMode, + .print = digitalio_digitalinout_drive_mode_print, + .locals_dict = (mp_obj_t)&digitalio_digitalinout_drive_mode_locals_dict, +}; + +//| .. class:: digitalio.DigitalInOut.Pull +//| +//| Enum-like class to define the pull value, if any, used while reading +//| digital values in. +//| +//| .. data:: UP +//| +//| When the input line isn't being driven the pull up can pull the state +//| of the line high so it reads as true. +//| +//| .. data:: DOWN +//| +//| When the input line isn't being driven the pull down can pull the +//| state of the line low so it reads as false. +//| +const mp_obj_type_t digitalio_digitalinout_pull_type; + +const digitalio_digitalinout_pull_obj_t digitalio_digitalinout_pull_up_obj = { + { &digitalio_digitalinout_pull_type }, +}; + +const digitalio_digitalinout_pull_obj_t digitalio_digitalinout_pull_down_obj = { + { &digitalio_digitalinout_pull_type }, +}; + +STATIC const mp_rom_map_elem_t digitalio_digitalinout_pull_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&digitalio_digitalinout_pull_up_obj) }, + { MP_ROM_QSTR(MP_QSTR_DOWN), MP_ROM_PTR(&digitalio_digitalinout_pull_down_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(digitalio_digitalinout_pull_locals_dict, digitalio_digitalinout_pull_locals_dict_table); + +STATIC void digitalio_digitalinout_pull_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { + qstr pull = MP_QSTR_UP; + if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&digitalio_digitalinout_pull_down_obj)) { + pull = MP_QSTR_DOWN; + } + mp_printf(print, "%q.%q.%q.%q", MP_QSTR_digitalio, MP_QSTR_DigitalInOut, MP_QSTR_Pull, pull); +} + +const mp_obj_type_t digitalio_digitalinout_pull_type = { + { &mp_type_type }, + .name = MP_QSTR_Pull, + .print = digitalio_digitalinout_pull_print, + .locals_dict = (mp_obj_t)&digitalio_digitalinout_pull_locals_dict, +}; + +STATIC const mp_rom_map_elem_t digitalio_digitalinout_locals_dict_table[] = { + // instance methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&digitalio_digitalinout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&digitalio_digitalinout_obj___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&digitalio_digitalinout_switch_to_output_obj) }, + { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&digitalio_digitalinout_switch_to_input_obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_direction), MP_ROM_PTR(&digitalio_digitalinout_direction_obj) }, + { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&digitalio_digitalinout_value_obj) }, + { MP_ROM_QSTR(MP_QSTR_drive_mode), MP_ROM_PTR(&digitalio_digitalinout_drive_mode_obj) }, + { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&digitalio_digitalinout_pull_obj) }, + + // Nested Enum-like Classes. + { MP_ROM_QSTR(MP_QSTR_Direction), MP_ROM_PTR(&digitalio_digitalinout_direction_type) }, + { MP_ROM_QSTR(MP_QSTR_DriveMode), MP_ROM_PTR(&digitalio_digitalinout_drive_mode_type) }, + { MP_ROM_QSTR(MP_QSTR_Pull), MP_ROM_PTR(&digitalio_digitalinout_pull_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(digitalio_digitalinout_locals_dict, digitalio_digitalinout_locals_dict_table); + +const mp_obj_type_t digitalio_digitalinout_type = { + { &mp_type_type }, + .name = MP_QSTR_DigitalInOut, + .make_new = digitalio_digitalinout_make_new, + .locals_dict = (mp_obj_t)&digitalio_digitalinout_locals_dict, +}; diff --git a/shared-bindings/digitalio/DigitalInOut.h b/shared-bindings/digitalio/DigitalInOut.h new file mode 100644 index 000000000..7fd6810f1 --- /dev/null +++ b/shared-bindings/digitalio/DigitalInOut.h @@ -0,0 +1,68 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/digitalio/DigitalInOut.h" + +extern const mp_obj_type_t digitalio_digitalinout_type; + +enum digitalinout_direction_t { + DIRECTION_IN, + DIRECTION_OUT +}; + +enum digitalinout_pull_t { + PULL_NONE, + PULL_UP, + PULL_DOWN +}; + +enum digitalinout_drive_mode_t { + DRIVE_MODE_PUSH_PULL, + DRIVE_MODE_OPEN_DRAIN +}; + +typedef enum { + DIGITALINOUT_OK, + DIGITALINOUT_PIN_BUSY +} digitalinout_result_t; + +digitalinout_result_t common_hal_digitalio_digitalinout_construct(digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin); +void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_switch_to_input(digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull); +void common_hal_digitalio_digitalinout_switch_to_output(digitalio_digitalinout_obj_t* self, bool value, enum digitalinout_drive_mode_t drive_mode); +enum digitalinout_direction_t common_hal_digitalio_digitalinout_get_direction(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_value(digitalio_digitalinout_obj_t* self, bool value); +bool common_hal_digitalio_digitalinout_get_value(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_drive_mode(digitalio_digitalinout_obj_t* self, enum digitalinout_drive_mode_t drive_mode); +enum digitalinout_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(digitalio_digitalinout_obj_t* self); +void common_hal_digitalio_digitalinout_set_pull(digitalio_digitalinout_obj_t* self, enum digitalinout_pull_t pull); +enum digitalinout_pull_t common_hal_digitalio_digitalinout_get_pull(digitalio_digitalinout_obj_t* self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO_DIGITALINOUT_H__ diff --git a/shared-bindings/digitalio/__init__.c b/shared-bindings/digitalio/__init__.c new file mode 100644 index 000000000..687110671 --- /dev/null +++ b/shared-bindings/digitalio/__init__.c @@ -0,0 +1,95 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/digitalio/__init__.h" +#include "shared-bindings/digitalio/DigitalInOut.h" + +#include "py/runtime.h" + +//| :mod:`digitalio` --- Basic digital pin support +//| ================================================= +//| +//| .. module:: digitalio +//| :synopsis: Basic digital pin support +//| :platform: SAMD21, ESP8266 +//| +//| The `digitalio` module contains classes to provide access to basic digital IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| DigitalInOut +//| +//| All classes change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| +//| For example:: +//| +//| import digitalio +//| from board import * +//| +//| with digitalio.DigitalInOut(D13) as pin: +//| print(pin.value) +//| +//| This example will initialize the the device, read +//| :py:data:`~digitalio.DigitalInOut.value` and then +//| :py:meth:`~digitalio.DigitalInOut.deinit` the hardware. +//| +//| Here is blinky:: +//| +//| import digitalio +//| from board import * +//| import time +//| +//| with digitalio.DigitalInOut(D13) as led: +//| led.switch_to_output() +//| while True: +//| led.value = True +//| time.sleep(0.1) +//| led.value = False +//| time.sleep(0.1) +//| + +STATIC const mp_rom_map_elem_t digitalio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_digitalio) }, + { MP_ROM_QSTR(MP_QSTR_DigitalInOut), MP_ROM_PTR(&digitalio_digitalinout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(digitalio_module_globals, digitalio_module_globals_table); + +const mp_obj_module_t digitalio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&digitalio_module_globals, +}; diff --git a/shared-bindings/digitalio/__init__.h b/shared-bindings/digitalio/__init__.h new file mode 100644 index 000000000..ed7cb5181 --- /dev/null +++ b/shared-bindings/digitalio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H__ + +#include "py/obj.h" + +// Nothing now. + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_DIGITALIO___INIT___H__ diff --git a/shared-bindings/nativeio/AnalogIn.c b/shared-bindings/nativeio/AnalogIn.c deleted file mode 100644 index 4513cd8af..000000000 --- a/shared-bindings/nativeio/AnalogIn.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "py/nlr.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/AnalogIn.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`AnalogIn` -- read analog voltage -//| ============================================ -//| -//| Usage:: -//| -//| import nativeio -//| from board import * -//| -//| with nativeio.AnalogIn(A1) as adc: -//| val = adc.value -//| - -//| .. class:: AnalogIn(pin) -//| -//| Use the AnalogIn on the given pin. The reference voltage varies by -//| platform so use ``reference_voltage`` to read the configured setting. -//| -//| :param ~microcontroller.Pin pin: the pin to read from -//| -STATIC mp_obj_t nativeio_analogin_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 1, false); - - // 1st argument is the pin - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); - - nativeio_analogin_obj_t *self = m_new_obj(nativeio_analogin_obj_t); - self->base.type = &nativeio_analogin_type; - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); - common_hal_nativeio_analogin_construct(self, pin); - - return (mp_obj_t) self; -} - -//| .. method:: deinit() -//| -//| Turn off the AnalogIn and release the pin for other use. -//| -STATIC mp_obj_t nativeio_analogin_deinit(mp_obj_t self_in) { - nativeio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_analogin_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogin_deinit_obj, nativeio_analogin_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_analogin___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_analogin_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_analogin___exit___obj, 4, 4, nativeio_analogin___exit__); - -//| .. attribute:: value -//| -//| Read the value on the analog pin and return it. The returned value -//| will be between 0 and 65535 inclusive (16-bit). Even if the underlying -//| analog to digital converter (ADC) is lower resolution, the result will -//| be scaled to be 16-bit. -//| -//| :return: the data read -//| :rtype: int -//| -STATIC mp_obj_t nativeio_analogin_obj_get_value(mp_obj_t self_in) { - nativeio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_analogin_get_value(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogin_get_value_obj, nativeio_analogin_obj_get_value); - -const mp_obj_property_t nativeio_analogin_value_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_analogin_get_value_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: reference_voltage -//| -//| The maximum voltage measurable. Also known as the reference voltage. -//| -//| :return: the reference voltage -//| :rtype: float -//| -STATIC mp_obj_t nativeio_analogin_obj_get_reference_voltage(mp_obj_t self_in) { - nativeio_analogin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_float(common_hal_nativeio_analogin_get_reference_voltage(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogin_get_reference_voltage_obj, - nativeio_analogin_obj_get_reference_voltage); - -const mp_obj_property_t nativeio_analogin_reference_voltage_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_analogin_get_reference_voltage_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t nativeio_analogin_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_analogin_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_analogin___exit___obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&nativeio_analogin_value_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_reference_voltage), MP_ROM_PTR(&nativeio_analogin_reference_voltage_obj)}, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_analogin_locals_dict, nativeio_analogin_locals_dict_table); - -const mp_obj_type_t nativeio_analogin_type = { - { &mp_type_type }, - .name = MP_QSTR_AnalogIn, - .make_new = nativeio_analogin_make_new, - .locals_dict = (mp_obj_t)&nativeio_analogin_locals_dict, -}; diff --git a/shared-bindings/nativeio/AnalogIn.h b/shared-bindings/nativeio/AnalogIn.h deleted file mode 100644 index ea5cfb84e..000000000 --- a/shared-bindings/nativeio/AnalogIn.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_analogin_type; - -void common_hal_nativeio_analogin_construct(nativeio_analogin_obj_t* self, const mcu_pin_obj_t *pin); -void common_hal_nativeio_analogin_deinit(nativeio_analogin_obj_t* self); -uint16_t common_hal_nativeio_analogin_get_value(nativeio_analogin_obj_t *self); -float common_hal_nativeio_analogin_get_reference_voltage(nativeio_analogin_obj_t *self); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ diff --git a/shared-bindings/nativeio/AnalogOut.c b/shared-bindings/nativeio/AnalogOut.c deleted file mode 100644 index c34fa48f3..000000000 --- a/shared-bindings/nativeio/AnalogOut.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/AnalogOut.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`AnalogOut` -- output analog voltage -//| ============================================ -//| -//| The AnalogOut is used to output analog values (a specific voltage). -//| -//| Example usage:: -//| -//| import nativeio -//| from microcontroller import pin -//| -//| with nativeio.AnalogOut(pin.PA02) as dac: # output on pin PA02 -//| dac.value = 32768 # makes PA02 1.65V -//| - -//| .. class:: AnalogOut(pin) -//| -//| Use the AnalogOut on the given pin. -//| -//| :param ~microcontroller.Pin pin: the pin to output to -//| -STATIC mp_obj_t nativeio_analogout_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - // check arguments - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - - assert_pin(args[0], false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); - - nativeio_analogout_obj_t *self = m_new_obj(nativeio_analogout_obj_t); - self->base.type = &nativeio_analogout_type; - assert_pin_free(pin); - common_hal_nativeio_analogout_construct(self, pin); - - return self; -} - -//| .. method:: deinit() -//| -//| Turn off the AnalogOut and release the pin for other use. -//| -STATIC mp_obj_t nativeio_analogout_deinit(mp_obj_t self_in) { - nativeio_analogout_obj_t *self = self_in; - - common_hal_nativeio_analogout_deinit(self); - - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_analogout_deinit_obj, nativeio_analogout_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_analogout___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_analogout_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_analogout___exit___obj, 4, 4, nativeio_analogout___exit__); - -//| .. attribute:: value -//| -//| The value on the analog pin. The value must be between 0 and 65535 -//| inclusive (16-bit). Even if the underlying digital to analog converter -//| is lower resolution, the input must be scaled to be 16-bit. -//| -//| :return: the last value written -//| :rtype: int -//| -STATIC mp_obj_t nativeio_analogout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { - nativeio_analogout_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint32_t v = mp_obj_get_int(value); - if (v >= (1 << 16)) { - mp_raise_ValueError("AnalogOut is only 16 bits. Value must be less than 65536."); - } - common_hal_nativeio_analogout_set_value(self, v); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_analogout_set_value_obj, nativeio_analogout_obj_set_value); - -const mp_obj_property_t nativeio_analogout_value_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&nativeio_analogout_set_value_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t nativeio_analogout_locals_dict_table[] = { - // instance methods - { MP_OBJ_NEW_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_analogout_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_analogout___exit___obj) }, - - // Properties - { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&nativeio_analogout_value_obj }, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_analogout_locals_dict, nativeio_analogout_locals_dict_table); - -const mp_obj_type_t nativeio_analogout_type = { - { &mp_type_type }, - .name = MP_QSTR_AnalogOut, - .make_new = nativeio_analogout_make_new, - .locals_dict = (mp_obj_t)&nativeio_analogout_locals_dict, -}; diff --git a/shared-bindings/nativeio/AnalogOut.h b/shared-bindings/nativeio/AnalogOut.h deleted file mode 100644 index 195e4c313..000000000 --- a/shared-bindings/nativeio/AnalogOut.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGOUT_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGOUT_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_analogout_type; - -void common_hal_nativeio_analogout_construct(nativeio_analogout_obj_t* self, const mcu_pin_obj_t *pin); -void common_hal_nativeio_analogout_deinit(nativeio_analogout_obj_t *self); -void common_hal_nativeio_analogout_set_value(nativeio_analogout_obj_t *self, uint16_t value); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGOUT_H__ diff --git a/shared-bindings/nativeio/DigitalInOut.c b/shared-bindings/nativeio/DigitalInOut.c deleted file mode 100644 index 421e14277..000000000 --- a/shared-bindings/nativeio/DigitalInOut.c +++ /dev/null @@ -1,486 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include -#include - -#include "lib/utils/context_manager_helpers.h" - -#include "py/nlr.h" -#include "py/objtype.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/mphal.h" - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/DigitalInOut.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`DigitalInOut` -- digital input and output -//| ========================================================= -//| -//| A DigitalInOut is used to digitally control I/O pins. For analog control of -//| a pin, see the :py:class:`~nativeio.AnalogIn` and -//| :py:class:`~nativeio.AnalogOut` classes. -//| - -//| .. class:: DigitalInOut(pin) -//| -//| Create a new DigitalInOut object associated with the pin. Defaults to input -//| with no pull. Use :py:meth:`switch_to_input` and -//| :py:meth:`switch_to_output` to change the direction. -//| -//| :param ~microcontroller.Pin pin: The pin to control -//| -STATIC mp_obj_t nativeio_digitalinout_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - - nativeio_digitalinout_obj_t *self = m_new_obj(nativeio_digitalinout_obj_t); - self->base.type = &nativeio_digitalinout_type; - - assert_pin(args[0], false); - mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(args[0]); - assert_pin_free(pin); - common_hal_nativeio_digitalinout_construct(self, pin); - - return (mp_obj_t)self; -} - -//| .. method:: deinit() -//| -//| Turn off the DigitalInOut and release the pin for other use. -//| -STATIC mp_obj_t nativeio_digitalinout_obj_deinit(mp_obj_t self_in) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_digitalinout_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_digitalinout_deinit_obj, nativeio_digitalinout_obj_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_digitalinout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_digitalinout_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_digitalinout_obj___exit___obj, 4, 4, nativeio_digitalinout_obj___exit__); - -//| -//| .. method:: switch_to_output(value=False, drive_mode=DriveMode.PUSH_PULL) -//| -//| Switch to writing out digital values. -//| -//| :param bool value: default value to set upon switching -//| :param DriveMode drive_mode: drive mode for the output -//| -typedef struct { - mp_obj_base_t base; -} nativeio_digitalinout_drive_mode_obj_t; -extern const nativeio_digitalinout_drive_mode_obj_t nativeio_digitalinout_drive_mode_push_pull_obj; -extern const nativeio_digitalinout_drive_mode_obj_t nativeio_digitalinout_drive_mode_open_drain_obj; - -STATIC mp_obj_t nativeio_digitalinout_switch_to_output(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_value, ARG_drive_mode }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_value, MP_ARG_BOOL, {.u_bool = false} }, - { MP_QSTR_drive_mode, MP_ARG_OBJ, {.u_rom_obj = &nativeio_digitalinout_drive_mode_push_pull_obj} }, - }; - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - enum digitalinout_drive_mode_t drive_mode = DRIVE_MODE_PUSH_PULL; - if (args[ARG_drive_mode].u_rom_obj == &nativeio_digitalinout_drive_mode_open_drain_obj) { - drive_mode = DRIVE_MODE_OPEN_DRAIN; - } - // do the transfer - common_hal_nativeio_digitalinout_switch_to_output(self, args[ARG_value].u_bool, drive_mode); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_digitalinout_switch_to_output_obj, 1, nativeio_digitalinout_switch_to_output); - -//| .. method:: switch_to_input(pull=None) -//| -//| Switch to read in digital values. -//| -//| :param Pull pull: pull configuration for the input -//| -//| Example usage:: -//| -//| import nativeio -//| import board -//| -//| with nativeio.DigitalInOut(board.SLIDE_SWITCH) as switch: -//| switch.switch_to_input(pull=nativeio.DigitalInOut.Pull.UP) -//| # Or, after switch_to_input -//| switch.pull = nativeio.DigitalInOut.Pull.UP -//| print(switch.value) -//| -typedef struct { - mp_obj_base_t base; -} nativeio_digitalinout_pull_obj_t; -extern const nativeio_digitalinout_pull_obj_t nativeio_digitalinout_pull_up_obj; -extern const nativeio_digitalinout_pull_obj_t nativeio_digitalinout_pull_down_obj; - -STATIC mp_obj_t nativeio_digitalinout_switch_to_input(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_pull }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_pull, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} }, - }; - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - enum digitalinout_pull_t pull = PULL_NONE; - if (args[ARG_pull].u_rom_obj == &nativeio_digitalinout_pull_up_obj) { - pull = PULL_UP; - }else if (args[ARG_pull].u_rom_obj == &nativeio_digitalinout_pull_down_obj) { - pull = PULL_DOWN; - } - // do the transfer - common_hal_nativeio_digitalinout_switch_to_input(self, pull); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_digitalinout_switch_to_input_obj, 1, nativeio_digitalinout_switch_to_input); - -//| .. attribute:: direction -//| -//| Get the direction of the pin. -//| -//| :raises AttributeError: when set. Use :py:meth:`switch_to_input` and :py:meth:`switch_to_output` to change the direction. -//| -typedef struct { - mp_obj_base_t base; -} nativeio_digitalinout_direction_obj_t; -extern const nativeio_digitalinout_direction_obj_t nativeio_digitalinout_direction_in_obj; -extern const nativeio_digitalinout_direction_obj_t nativeio_digitalinout_direction_out_obj; - -STATIC mp_obj_t nativeio_digitalinout_obj_get_direction(mp_obj_t self_in) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - enum digitalinout_direction_t direction = common_hal_nativeio_digitalinout_get_direction(self); - if (direction == DIRECTION_IN) { - return (mp_obj_t)&nativeio_digitalinout_direction_in_obj; - } - return (mp_obj_t)&nativeio_digitalinout_direction_out_obj; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_digitalinout_get_direction_obj, nativeio_digitalinout_obj_get_direction); - -const mp_obj_property_t nativeio_digitalinout_direction_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_digitalinout_get_direction_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: value -//| -//| The digital logic level of the pin. -//| -STATIC mp_obj_t nativeio_digitalinout_obj_get_value(mp_obj_t self_in) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - bool value = common_hal_nativeio_digitalinout_get_value(self); - return mp_obj_new_bool(value); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_digitalinout_get_value_obj, nativeio_digitalinout_obj_get_value); - -STATIC mp_obj_t nativeio_digitalinout_obj_set_value(mp_obj_t self_in, mp_obj_t value) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (common_hal_nativeio_digitalinout_get_direction(self) == DIRECTION_IN) { - mp_raise_AttributeError("Cannot set value when direction is input."); - return mp_const_none; - } - common_hal_nativeio_digitalinout_set_value(self, mp_obj_is_true(value)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_digitalinout_set_value_obj, nativeio_digitalinout_obj_set_value); - -const mp_obj_property_t nativeio_digitalinout_value_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_digitalinout_get_value_obj, - (mp_obj_t)&nativeio_digitalinout_set_value_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: drive_mode -//| -//| Get or set the pin drive mode. -//| -STATIC mp_obj_t nativeio_digitalinout_obj_get_drive_mode(mp_obj_t self_in) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (common_hal_nativeio_digitalinout_get_direction(self) == DIRECTION_IN) { - mp_raise_AttributeError("Drive mode not used when direction is input."); - return mp_const_none; - } - enum digitalinout_drive_mode_t drive_mode = common_hal_nativeio_digitalinout_get_drive_mode(self); - if (drive_mode == DRIVE_MODE_PUSH_PULL) { - return (mp_obj_t)&nativeio_digitalinout_drive_mode_push_pull_obj; - } - return (mp_obj_t)&nativeio_digitalinout_drive_mode_open_drain_obj; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_digitalinout_get_drive_mode_obj, nativeio_digitalinout_obj_get_drive_mode); - -STATIC mp_obj_t nativeio_digitalinout_obj_set_drive_mode(mp_obj_t self_in, mp_obj_t drive_mode) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (common_hal_nativeio_digitalinout_get_direction(self) == DIRECTION_IN) { - mp_raise_AttributeError("Drive mode not used when direction is input."); - return mp_const_none; - } - enum digitalinout_drive_mode_t c_drive_mode = DRIVE_MODE_PUSH_PULL; - if (drive_mode == &nativeio_digitalinout_drive_mode_open_drain_obj) { - c_drive_mode = DRIVE_MODE_OPEN_DRAIN; - } - common_hal_nativeio_digitalinout_set_drive_mode(self, c_drive_mode); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_digitalinout_set_drive_mode_obj, nativeio_digitalinout_obj_set_drive_mode); - -const mp_obj_property_t nativeio_digitalinout_drive_mode_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_digitalinout_get_drive_mode_obj, - (mp_obj_t)&nativeio_digitalinout_set_drive_mode_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: pull -//| -//| Get or set the pin pull. -//| -//| :raises AttributeError: if the direction is ~`Direction.OUT`. -//| -STATIC mp_obj_t nativeio_digitalinout_obj_get_pull(mp_obj_t self_in) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (common_hal_nativeio_digitalinout_get_direction(self) == DIRECTION_OUT) { - mp_raise_AttributeError("Pull not used when direction is output."); - return mp_const_none; - } - enum digitalinout_pull_t pull = common_hal_nativeio_digitalinout_get_pull(self); - if (pull == PULL_UP) { - return (mp_obj_t)&nativeio_digitalinout_pull_up_obj; - } else if (pull == PULL_DOWN) { - return (mp_obj_t)&nativeio_digitalinout_pull_down_obj; - } - return (mp_obj_t)&mp_const_none_obj; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_digitalinout_get_pull_obj, nativeio_digitalinout_obj_get_pull); - -STATIC mp_obj_t nativeio_digitalinout_obj_set_pull(mp_obj_t self_in, mp_obj_t pull_obj) { - nativeio_digitalinout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (common_hal_nativeio_digitalinout_get_direction(self) == DIRECTION_OUT) { - mp_raise_AttributeError("Pull not used when direction is output."); - return mp_const_none; - } - enum digitalinout_pull_t pull = PULL_NONE; - if (pull_obj == &nativeio_digitalinout_pull_up_obj) { - pull = PULL_UP; - } else if (pull_obj == &nativeio_digitalinout_pull_down_obj) { - pull = PULL_DOWN; - } - common_hal_nativeio_digitalinout_set_pull(self, pull); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_digitalinout_set_pull_obj, nativeio_digitalinout_obj_set_pull); - -const mp_obj_property_t nativeio_digitalinout_pull_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_digitalinout_get_pull_obj, - (mp_obj_t)&nativeio_digitalinout_set_pull_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. class:: microcontroller.DigitalInOut.Direction -//| -//| Enum-like class to define which direction the digital values are -//| going. -//| -//| .. data:: IN -//| -//| Read digital data in -//| -//| .. data:: OUT -//| -//| Write digital data out -//| -const mp_obj_type_t nativeio_digitalinout_direction_type; - -const nativeio_digitalinout_direction_obj_t nativeio_digitalinout_direction_in_obj = { - { &nativeio_digitalinout_direction_type }, -}; - -const nativeio_digitalinout_direction_obj_t nativeio_digitalinout_direction_out_obj = { - { &nativeio_digitalinout_direction_type }, -}; - -STATIC const mp_rom_map_elem_t nativeio_digitalinout_direction_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_PTR(&nativeio_digitalinout_direction_in_obj) }, - { MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_PTR(&nativeio_digitalinout_direction_out_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_digitalinout_direction_locals_dict, nativeio_digitalinout_direction_locals_dict_table); - -STATIC void nativeio_digitalinout_direction_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr direction = MP_QSTR_IN; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&nativeio_digitalinout_direction_out_obj)) { - direction = MP_QSTR_OUT; - } - mp_printf(print, "%q.%q.%q.%q", MP_QSTR_nativeio, MP_QSTR_DigitalInOut, MP_QSTR_Direction, direction); -} - -const mp_obj_type_t nativeio_digitalinout_direction_type = { - { &mp_type_type }, - .name = MP_QSTR_Direction, - .print = nativeio_digitalinout_direction_print, - .locals_dict = (mp_obj_t)&nativeio_digitalinout_direction_locals_dict, -}; - -//| .. class:: nativeio.DigitalInOut.DriveMode -//| -//| Enum-like class to define the drive mode used when outputting -//| digital values. -//| -//| .. data:: PUSH_PULL -//| -//| Output both high and low digital values -//| -//| .. data:: OPEN_DRAIN -//| -//| Output low digital values but go into high z for digital high. This is -//| useful for i2c and other protocols that share a digital line. -//| -const mp_obj_type_t nativeio_digitalinout_drive_mode_type; - -const nativeio_digitalinout_drive_mode_obj_t nativeio_digitalinout_drive_mode_push_pull_obj = { - { &nativeio_digitalinout_drive_mode_type }, -}; - -const nativeio_digitalinout_drive_mode_obj_t nativeio_digitalinout_drive_mode_open_drain_obj = { - { &nativeio_digitalinout_drive_mode_type }, -}; - -STATIC const mp_rom_map_elem_t nativeio_digitalinout_drive_mode_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_PUSH_PULL), MP_ROM_PTR(&nativeio_digitalinout_drive_mode_push_pull_obj) }, - { MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_PTR(&nativeio_digitalinout_drive_mode_open_drain_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_digitalinout_drive_mode_locals_dict, nativeio_digitalinout_drive_mode_locals_dict_table); - -STATIC void nativeio_digitalinout_drive_mode_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr drive_mode = MP_QSTR_PUSH_PULL; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&nativeio_digitalinout_drive_mode_open_drain_obj)) { - drive_mode = MP_QSTR_OPEN_DRAIN; - } - mp_printf(print, "%q.%q.%q.%q", MP_QSTR_nativeio, MP_QSTR_DigitalInOut, MP_QSTR_DriveMode, drive_mode); -} - -const mp_obj_type_t nativeio_digitalinout_drive_mode_type = { - { &mp_type_type }, - .name = MP_QSTR_DriveMode, - .print = nativeio_digitalinout_drive_mode_print, - .locals_dict = (mp_obj_t)&nativeio_digitalinout_drive_mode_locals_dict, -}; - -//| .. class:: nativeio.DigitalInOut.Pull -//| -//| Enum-like class to define the pull value, if any, used while reading -//| digital values in. -//| -//| .. data:: UP -//| -//| When the input line isn't being driven the pull up can pull the state -//| of the line high so it reads as true. -//| -//| .. data:: DOWN -//| -//| When the input line isn't being driven the pull down can pull the -//| state of the line low so it reads as false. -//| -const mp_obj_type_t nativeio_digitalinout_pull_type; - -const nativeio_digitalinout_pull_obj_t nativeio_digitalinout_pull_up_obj = { - { &nativeio_digitalinout_pull_type }, -}; - -const nativeio_digitalinout_pull_obj_t nativeio_digitalinout_pull_down_obj = { - { &nativeio_digitalinout_pull_type }, -}; - -STATIC const mp_rom_map_elem_t nativeio_digitalinout_pull_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_UP), MP_ROM_PTR(&nativeio_digitalinout_pull_up_obj) }, - { MP_ROM_QSTR(MP_QSTR_DOWN), MP_ROM_PTR(&nativeio_digitalinout_pull_down_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_digitalinout_pull_locals_dict, nativeio_digitalinout_pull_locals_dict_table); - -STATIC void nativeio_digitalinout_pull_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr pull = MP_QSTR_UP; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&nativeio_digitalinout_pull_down_obj)) { - pull = MP_QSTR_DOWN; - } - mp_printf(print, "%q.%q.%q.%q", MP_QSTR_nativeio, MP_QSTR_DigitalInOut, MP_QSTR_Pull, pull); -} - -const mp_obj_type_t nativeio_digitalinout_pull_type = { - { &mp_type_type }, - .name = MP_QSTR_Pull, - .print = nativeio_digitalinout_pull_print, - .locals_dict = (mp_obj_t)&nativeio_digitalinout_pull_locals_dict, -}; - -STATIC const mp_rom_map_elem_t nativeio_digitalinout_locals_dict_table[] = { - // instance methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_digitalinout_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_digitalinout_obj___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_switch_to_output), MP_ROM_PTR(&nativeio_digitalinout_switch_to_output_obj) }, - { MP_ROM_QSTR(MP_QSTR_switch_to_input), MP_ROM_PTR(&nativeio_digitalinout_switch_to_input_obj) }, - - // Properties - { MP_ROM_QSTR(MP_QSTR_direction), MP_ROM_PTR(&nativeio_digitalinout_direction_obj) }, - { MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&nativeio_digitalinout_value_obj) }, - { MP_ROM_QSTR(MP_QSTR_drive_mode), MP_ROM_PTR(&nativeio_digitalinout_drive_mode_obj) }, - { MP_ROM_QSTR(MP_QSTR_pull), MP_ROM_PTR(&nativeio_digitalinout_pull_obj) }, - - // Nested Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_Direction), MP_ROM_PTR(&nativeio_digitalinout_direction_type) }, - { MP_ROM_QSTR(MP_QSTR_DriveMode), MP_ROM_PTR(&nativeio_digitalinout_drive_mode_type) }, - { MP_ROM_QSTR(MP_QSTR_Pull), MP_ROM_PTR(&nativeio_digitalinout_pull_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_digitalinout_locals_dict, nativeio_digitalinout_locals_dict_table); - -const mp_obj_type_t nativeio_digitalinout_type = { - { &mp_type_type }, - .name = MP_QSTR_DigitalInOut, - .make_new = nativeio_digitalinout_make_new, - .locals_dict = (mp_obj_t)&nativeio_digitalinout_locals_dict, -}; diff --git a/shared-bindings/nativeio/DigitalInOut.h b/shared-bindings/nativeio/DigitalInOut.h deleted file mode 100644 index b712a811c..000000000 --- a/shared-bindings/nativeio/DigitalInOut.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_DIGITALINOUT_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_DIGITALINOUT_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_digitalinout_type; - -enum digitalinout_direction_t { - DIRECTION_IN, - DIRECTION_OUT -}; - -enum digitalinout_pull_t { - PULL_NONE, - PULL_UP, - PULL_DOWN -}; - -enum digitalinout_drive_mode_t { - DRIVE_MODE_PUSH_PULL, - DRIVE_MODE_OPEN_DRAIN -}; - -typedef enum { - DIGITALINOUT_OK, - DIGITALINOUT_PIN_BUSY -} digitalinout_result_t; - -digitalinout_result_t common_hal_nativeio_digitalinout_construct(nativeio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin); -void common_hal_nativeio_digitalinout_deinit(nativeio_digitalinout_obj_t* self); -void common_hal_nativeio_digitalinout_switch_to_input(nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull); -void common_hal_nativeio_digitalinout_switch_to_output(nativeio_digitalinout_obj_t* self, bool value, enum digitalinout_drive_mode_t drive_mode); -enum digitalinout_direction_t common_hal_nativeio_digitalinout_get_direction(nativeio_digitalinout_obj_t* self); -void common_hal_nativeio_digitalinout_set_value(nativeio_digitalinout_obj_t* self, bool value); -bool common_hal_nativeio_digitalinout_get_value(nativeio_digitalinout_obj_t* self); -void common_hal_nativeio_digitalinout_set_drive_mode(nativeio_digitalinout_obj_t* self, enum digitalinout_drive_mode_t drive_mode); -enum digitalinout_drive_mode_t common_hal_nativeio_digitalinout_get_drive_mode(nativeio_digitalinout_obj_t* self); -void common_hal_nativeio_digitalinout_set_pull(nativeio_digitalinout_obj_t* self, enum digitalinout_pull_t pull); -enum digitalinout_pull_t common_hal_nativeio_digitalinout_get_pull(nativeio_digitalinout_obj_t* self); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_DIGITALINOUT_H__ diff --git a/shared-bindings/nativeio/I2C.c b/shared-bindings/nativeio/I2C.c deleted file mode 100644 index fe3e206b2..000000000 --- a/shared-bindings/nativeio/I2C.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This file contains all of the Python API definitions for the -// nativeio.I2C class. - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/I2C.h" - -#include "lib/utils/context_manager_helpers.h" -#include "py/runtime.h" -//| .. currentmodule:: nativeio -//| -//| :class:`I2C` --- Two wire serial protocol -//| ------------------------------------------ -//| -//| .. class:: I2C(scl, sda, \*, frequency=400000) -//| -//| I2C is a two-wire protocol for communicating between devices. At the -//| physical level it consists of 2 wires: SCL and SDA, the clock and data -//| lines respectively. -//| -//| .. seealso:: Using this class directly requires careful lock management. -//| Instead, use :class:`~adafruit_bus_device.i2c_device.I2CDevice` to -//| manage locks. -//| -//| .. seealso:: Using this class to directly read registers requires manual -//| bit unpacking. Instead, use an existing driver or make one with -//| :ref:`Register ` data descriptors. -//| -//| :param ~microcontroller.Pin scl: The clock pin -//| :param ~microcontroller.Pin sda: The data pin -//| :param int frequency: The clock frequency in Hertz -//| -STATIC mp_obj_t nativeio_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - nativeio_i2c_obj_t *self = m_new_obj(nativeio_i2c_obj_t); - self->base.type = &nativeio_i2c_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_scl, ARG_sda, ARG_frequency }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_scl, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_sda, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 400000} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - assert_pin(args[ARG_scl].u_obj, false); - assert_pin(args[ARG_sda].u_obj, false); - const mcu_pin_obj_t* scl = MP_OBJ_TO_PTR(args[ARG_scl].u_obj); - assert_pin_free(scl); - const mcu_pin_obj_t* sda = MP_OBJ_TO_PTR(args[ARG_sda].u_obj); - assert_pin_free(sda); - common_hal_nativeio_i2c_construct(self, scl, sda, args[ARG_frequency].u_int); - return (mp_obj_t)self; -} - -//| .. method:: I2C.deinit() -//| -//| Releases control of the underlying hardware so other classes can use it. -//| -STATIC mp_obj_t nativeio_i2c_obj_deinit(mp_obj_t self_in) { - nativeio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_i2c_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_i2c_deinit_obj, nativeio_i2c_obj_deinit); - -//| .. method:: I2C.__enter__() -//| -//| No-op used in Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: I2C.__exit__() -//| -//| Automatically deinitializes the hardware on context exit. -//| -STATIC mp_obj_t nativeio_i2c_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_i2c_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_i2c___exit___obj, 4, 4, nativeio_i2c_obj___exit__); - -static void check_lock(nativeio_i2c_obj_t *self) { - if (!common_hal_nativeio_i2c_has_lock(self)) { - mp_raise_RuntimeError("Function requires lock."); - } -} - -//| .. method:: I2C.scan() -//| -//| Scan all I2C addresses between 0x08 and 0x77 inclusive and return a -//| list of those that respond. -//| -//| :return: List of device ids on the I2C bus -//| :rtype: list -//| -STATIC mp_obj_t nativeio_i2c_scan(mp_obj_t self_in) { - nativeio_i2c_obj_t *self = MP_OBJ_TO_PTR(self_in); - check_lock(self); - mp_obj_t list = mp_obj_new_list(0, NULL); - // 7-bit addresses 0b0000xxx and 0b1111xxx are reserved - for (int addr = 0x08; addr < 0x78; ++addr) { - bool success = common_hal_nativeio_i2c_probe(self, addr); - if (success) { - mp_obj_list_append(list, MP_OBJ_NEW_SMALL_INT(addr)); - } - } - return list; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_i2c_scan_obj, nativeio_i2c_scan); - -//| .. method:: I2C.try_lock() -//| -//| Attempts to grab the I2C lock. Returns True on success. -//| -//| :return: True when lock has been grabbed -//| :rtype: bool -//| -STATIC mp_obj_t nativeio_i2c_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(common_hal_nativeio_i2c_try_lock(MP_OBJ_TO_PTR(self_in))); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_i2c_try_lock_obj, nativeio_i2c_obj_try_lock); - -//| .. method:: I2C.unlock() -//| -//| Releases the I2C lock. -//| -STATIC mp_obj_t nativeio_i2c_obj_unlock(mp_obj_t self_in) { - common_hal_nativeio_i2c_unlock(MP_OBJ_TO_PTR(self_in)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_i2c_unlock_obj, nativeio_i2c_obj_unlock); - -//| .. method:: I2C.readfrom_into(address, buffer, \*, start=0, end=len(buffer)) -//| -//| Read into ``buffer`` from the slave specified by ``address``. -//| The number of bytes read will be the length of ``buffer``. -//| -//| If ``start`` or ``end`` is provided, then the buffer will be sliced -//| as if ``buffer[start:end]``. This will not cause an allocation like -//| ``buf[start:end]`` will so it saves memory. -//| -//| :param int address: 7-bit device address -//| :param bytearray buffer: buffer to write into -//| :param int start: Index to start writing at -//| :param int end: Index to write up to but not include -//| -STATIC mp_obj_t nativeio_i2c_readfrom_into(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_address, ARG_buffer, ARG_start, ARG_end }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - }; - nativeio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_lock(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } - uint8_t status = common_hal_nativeio_i2c_read(self, args[ARG_address].u_int, ((uint8_t*)bufinfo.buf) + start, len); - if (status != 0) { - mp_raise_OSError(status); - } - - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_i2c_readfrom_into_obj, 3, nativeio_i2c_readfrom_into); - -//| .. method:: I2C.writeto(address, buffer, \*, start=0, end=len(buffer), stop=True) -//| -//| Write the bytes from ``buffer`` to the slave specified by ``address``. -//| Transmits a stop bit if ``stop`` is set. -//| -//| If ``start`` or ``end`` is provided, then the buffer will be sliced -//| as if ``buffer[start:end]``. This will not cause an allocation like -//| ``buffer[start:end]`` will so it saves memory. -//| -//| :param int address: 7-bit device address -//| :param bytearray buffer: buffer containing the bytes to write -//| :param int start: Index to start writing from -//| :param int end: Index to read up to but not include -//| :param bool stop: If true, output an I2C stop condition after the -//| buffer is written -//| -STATIC mp_obj_t nativeio_i2c_writeto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_address, ARG_buffer, ARG_start, ARG_end, ARG_stop }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_address, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = true} }, - }; - nativeio_i2c_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_lock(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - // get the buffer to write the data from - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } - - // do the transfer - uint8_t status = common_hal_nativeio_i2c_write(self, args[ARG_address].u_int, - ((uint8_t*) bufinfo.buf) + start, len, args[ARG_stop].u_bool); - if (status != 0) { - mp_raise_OSError(status); - } - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_i2c_writeto_obj, 1, nativeio_i2c_writeto); - -STATIC const mp_rom_map_elem_t nativeio_i2c_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_i2c_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_i2c___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&nativeio_i2c_scan_obj) }, - - { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&nativeio_i2c_try_lock_obj) }, - { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&nativeio_i2c_unlock_obj) }, - - { MP_ROM_QSTR(MP_QSTR_readfrom_into), MP_ROM_PTR(&nativeio_i2c_readfrom_into_obj) }, - { MP_ROM_QSTR(MP_QSTR_writeto), MP_ROM_PTR(&nativeio_i2c_writeto_obj) }, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_i2c_locals_dict, nativeio_i2c_locals_dict_table); - -const mp_obj_type_t nativeio_i2c_type = { - { &mp_type_type }, - .name = MP_QSTR_I2C, - .make_new = nativeio_i2c_make_new, - .locals_dict = (mp_obj_dict_t*)&nativeio_i2c_locals_dict, -}; diff --git a/shared-bindings/nativeio/I2C.h b/shared-bindings/nativeio/I2C.h deleted file mode 100644 index 5f3c89a77..000000000 --- a/shared-bindings/nativeio/I2C.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Machine is the HAL for low-level, hardware accelerated functions. It is not -// meant to simplify APIs, its only meant to unify them so that other modules -// do not require port specific logic. -// -// This file includes externs for all functions a port should implement to -// support the machine module. - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_I2C_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_I2C_H__ - -#include "py/obj.h" - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -// Type object used in Python. Should be shared between ports. -extern const mp_obj_type_t nativeio_i2c_type; - -// Initializes the hardware peripheral. -extern void common_hal_nativeio_i2c_construct(nativeio_i2c_obj_t *self, - const mcu_pin_obj_t * scl, - const mcu_pin_obj_t * sda, - uint32_t frequency); - -extern void common_hal_nativeio_i2c_deinit(nativeio_i2c_obj_t *self); - -extern bool common_hal_nativeio_i2c_try_lock(nativeio_i2c_obj_t *self); -extern bool common_hal_nativeio_i2c_has_lock(nativeio_i2c_obj_t *self); -extern void common_hal_nativeio_i2c_unlock(nativeio_i2c_obj_t *self); - -// Probe the bus to see if a device acknowledges the given address. -extern bool common_hal_nativeio_i2c_probe(nativeio_i2c_obj_t *self, uint8_t addr); - -// Write to the device and return 0 on success or an appropriate error code from mperrno.h -extern uint8_t common_hal_nativeio_i2c_write(nativeio_i2c_obj_t *self, uint16_t address, - const uint8_t * data, size_t len, - bool stop); - -// Reads memory of the i2c device picking up where it left off and return 0 on -// success or an appropriate error code from mperrno.h -extern uint8_t common_hal_nativeio_i2c_read(nativeio_i2c_obj_t *self, uint16_t address, - uint8_t * data, size_t len); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_I2C_H__ diff --git a/shared-bindings/nativeio/OneWire.c b/shared-bindings/nativeio/OneWire.c deleted file mode 100644 index f9fbbe63c..000000000 --- a/shared-bindings/nativeio/OneWire.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/runtime0.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/OneWire.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`OneWire` -- Lowest-level of the Maxim OneWire protocol -//| ================================================================= -//| -//| :class:`~nativeio.OneWire` implements the timing-sensitive foundation of the Maxim -//| (formerly Dallas Semi) OneWire protocol. -//| -//| Protocol definition is here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 -//| -//| .. class:: OneWire(pin) -//| -//| Create a OneWire object associated with the given pin. The object -//| implements the lowest level timing-sensitive bits of the protocol. -//| -//| :param ~microcontroller.Pin pin: Pin connected to the OneWire bus -//| -//| Read a short series of pulses:: -//| -//| import nativeio -//| import board -//| -//| with nativeio.OneWire(board.D7) as onewire: -//| onewire.reset() -//| onewire.write_bit(True) -//| onewire.write_bit(False) -//| print(onewire.read_bit()) -//| -STATIC mp_obj_t nativeio_onewire_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_pin }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - assert_pin(args[ARG_pin].u_obj, false); - const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); - - nativeio_onewire_obj_t *self = m_new_obj(nativeio_onewire_obj_t); - self->base.type = &nativeio_onewire_type; - - common_hal_nativeio_onewire_construct(self, pin); - return MP_OBJ_FROM_PTR(self); -} - -//| .. method:: deinit() -//| -//| Deinitialize the OneWire bus and release any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_onewire_deinit(mp_obj_t self_in) { - nativeio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_onewire_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_onewire_deinit_obj, nativeio_onewire_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_onewire_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_onewire_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_onewire___exit___obj, 4, 4, nativeio_onewire_obj___exit__); - -//| .. method:: reset() -//| -//| Reset the OneWire bus and read presence -//| -//| :returns: False when at least one device is present -//| :rtype: bool -//| -STATIC mp_obj_t nativeio_onewire_obj_reset(mp_obj_t self_in) { - nativeio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_nativeio_onewire_reset(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_onewire_reset_obj, nativeio_onewire_obj_reset); - -//| .. method:: read_bit() -//| -//| Read in a bit -//| -//| :returns: bit state read -//| :rtype: bool -//| -STATIC mp_obj_t nativeio_onewire_obj_read_bit(mp_obj_t self_in) { - nativeio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - - return mp_obj_new_bool(common_hal_nativeio_onewire_read_bit(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_onewire_read_bit_obj, nativeio_onewire_obj_read_bit); - -//| .. method:: write_bit(value) -//| -//| Write out a bit based on value. -//| -STATIC mp_obj_t nativeio_onewire_obj_write_bit(mp_obj_t self_in, mp_obj_t bool_obj) { - nativeio_onewire_obj_t *self = MP_OBJ_TO_PTR(self_in); - - common_hal_nativeio_onewire_write_bit(self, mp_obj_is_true(bool_obj)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_onewire_write_bit_obj, nativeio_onewire_obj_write_bit); - -STATIC const mp_rom_map_elem_t nativeio_onewire_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_onewire_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_onewire___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&nativeio_onewire_reset_obj) }, - { MP_ROM_QSTR(MP_QSTR_read_bit), MP_ROM_PTR(&nativeio_onewire_read_bit_obj) }, - { MP_ROM_QSTR(MP_QSTR_write_bit), MP_ROM_PTR(&nativeio_onewire_write_bit_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_onewire_locals_dict, nativeio_onewire_locals_dict_table); - -const mp_obj_type_t nativeio_onewire_type = { - { &mp_type_type }, - .name = MP_QSTR_OneWire, - .make_new = nativeio_onewire_make_new, - .locals_dict = (mp_obj_dict_t*)&nativeio_onewire_locals_dict, -}; diff --git a/shared-bindings/nativeio/OneWire.h b/shared-bindings/nativeio/OneWire.h deleted file mode 100644 index 9d5c2c932..000000000 --- a/shared-bindings/nativeio/OneWire.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_onewire_type; - -extern void common_hal_nativeio_onewire_construct(nativeio_onewire_obj_t* self, - const mcu_pin_obj_t* pin); -extern void common_hal_nativeio_onewire_deinit(nativeio_onewire_obj_t* self); -extern bool common_hal_nativeio_onewire_reset(nativeio_onewire_obj_t* self); -extern bool common_hal_nativeio_onewire_read_bit(nativeio_onewire_obj_t* self); -extern void common_hal_nativeio_onewire_write_bit(nativeio_onewire_obj_t* self, bool bit); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ONEWIRE_H__ diff --git a/shared-bindings/nativeio/PWMOut.c b/shared-bindings/nativeio/PWMOut.c deleted file mode 100644 index 6d5710f8e..000000000 --- a/shared-bindings/nativeio/PWMOut.c +++ /dev/null @@ -1,221 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/PWMOut.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`PWMOut` -- Output a Pulse Width Modulated signal -//| ======================================================== -//| -//| PWMOut can be used to output a PWM signal on a given pin. -//| -//| .. class:: PWMOut(pin, \*, duty_cycle=0, frequency=500, variable_frequency=False) -//| -//| Create a PWM object associated with the given pin. This allows you to -//| write PWM signals out on the given pin. Frequency is fixed after init -//| unless ``variable_frequency`` is True. -//| -//| .. note:: When ``variable_frequency`` is True, further PWM outputs may be -//| limited because it may take more internal resources to be flexible. So, -//| when outputting both fixed and flexible frequency signals construct the -//| fixed outputs first. -//| -//| :param ~microcontroller.Pin pin: The pin to output to -//| :param int duty: The fraction of each pulse which is high. 16-bit -//| :param int frequency: The target frequency in Hertz (32-bit) -//| :param bool variable_frequency: True if the frequency will change over time -//| -//| Simple LED fade:: -//| -//| import nativeio -//| import board -//| -//| with nativeio.PWMOut(board.D13) as pwm: # output on D13 -//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at the default 500hz -//| -//| PWM at specific frequency (servos and motors):: -//| -//| import nativeio -//| import board -//| -//| with nativeio.PWMOut(board.D13, frequency=50) as pwm: -//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at 50hz -//| -//| Variable frequency (usually tones):: -//| -//| import nativeio -//| import board -//| import time -//| -//| with nativeio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True) as pwm: -//| time.sleep(0.2) -//| pwm.frequency = 880 -//| time.sleep(0.1) -//| -STATIC mp_obj_t nativeio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - assert_pin_free(pin); - - // create PWM object from the given pin - nativeio_pwmout_obj_t *self = m_new_obj(nativeio_pwmout_obj_t); - self->base.type = &nativeio_pwmout_type; - - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); - enum { ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500} }, - { MP_QSTR_variable_frequency, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, - }; - mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, args + 1, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); - uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; - uint32_t frequency = parsed_args[ARG_frequency].u_int; - bool variable_frequency = parsed_args[ARG_variable_frequency].u_int; - - common_hal_nativeio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); - - return MP_OBJ_FROM_PTR(self); -} - -//| .. method:: deinit() -//| -//| Deinitialises the PWMOut and releases any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_pwmout_deinit(mp_obj_t self_in) { - nativeio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_pwmout_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pwmout_deinit_obj, nativeio_pwmout_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_pwmout_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_pwmout___exit___obj, 4, 4, nativeio_pwmout_obj___exit__); - -//| .. attribute:: duty_cycle -//| -//| 16 bit value that dictates how much of one cycle is high (1) versus low -//| (0). 0xffff will always be high, 0 will always be low and 0x7fff will -//| be half high and then half low. -STATIC mp_obj_t nativeio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { - nativeio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_pwmout_get_duty_cycle(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pwmout_get_duty_cycle_obj, nativeio_pwmout_obj_get_duty_cycle); - -STATIC mp_obj_t nativeio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) { - nativeio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - mp_int_t duty = mp_obj_get_int(duty_cycle); - if (duty < 0 || duty > 0xffff) { - mp_raise_ValueError("PWM duty must be between 0 and 65536 (16 bit resolution)"); - } - common_hal_nativeio_pwmout_set_duty_cycle(self, duty); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_pwmout_set_duty_cycle_obj, nativeio_pwmout_obj_set_duty_cycle); - -const mp_obj_property_t nativeio_pwmout_duty_cycle_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_pwmout_get_duty_cycle_obj, - (mp_obj_t)&nativeio_pwmout_set_duty_cycle_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. attribute:: frequency -//| -//| 32 bit value that dictates the PWM frequency in Hertz (cycles per -//| second). Only writeable when constructed with ``variable_frequency=True``. -//| -STATIC mp_obj_t nativeio_pwmout_obj_get_frequency(mp_obj_t self_in) { - nativeio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_pwmout_get_frequency(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pwmout_get_frequency_obj, nativeio_pwmout_obj_get_frequency); - -STATIC mp_obj_t nativeio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { - nativeio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (!common_hal_nativeio_pwmout_get_variable_frequency(self)) { - mp_raise_AttributeError( - "PWM frequency not writeable when variable_frequency is False on " - "construction."); - } - common_hal_nativeio_pwmout_set_frequency(self, mp_obj_get_int(frequency)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_pwmout_set_frequency_obj, nativeio_pwmout_obj_set_frequency); - -const mp_obj_property_t nativeio_pwmout_frequency_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_pwmout_get_frequency_obj, - (mp_obj_t)&nativeio_pwmout_set_frequency_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t nativeio_pwmout_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_pwmout_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_pwmout___exit___obj) }, - - // Properties - { MP_ROM_QSTR(MP_QSTR_duty_cycle), MP_ROM_PTR(&nativeio_pwmout_duty_cycle_obj) }, - { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&nativeio_pwmout_frequency_obj) }, - // TODO(tannewt): Add enabled to determine whether the signal is output - // without giving up the resources. Useful for IR output. -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_pwmout_locals_dict, nativeio_pwmout_locals_dict_table); - -const mp_obj_type_t nativeio_pwmout_type = { - { &mp_type_type }, - .name = MP_QSTR_PWMOut, - .make_new = nativeio_pwmout_make_new, - .locals_dict = (mp_obj_dict_t*)&nativeio_pwmout_locals_dict, -}; diff --git a/shared-bindings/nativeio/PWMOut.h b/shared-bindings/nativeio/PWMOut.h deleted file mode 100644 index 588992ceb..000000000 --- a/shared-bindings/nativeio/PWMOut.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PWMOUT_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PWMOUT_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_pwmout_type; - -extern void common_hal_nativeio_pwmout_construct(nativeio_pwmout_obj_t* self, - const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, - bool variable_frequency); -extern void common_hal_nativeio_pwmout_deinit(nativeio_pwmout_obj_t* self); -extern void common_hal_nativeio_pwmout_set_duty_cycle(nativeio_pwmout_obj_t* self, uint16_t duty); -extern uint16_t common_hal_nativeio_pwmout_get_duty_cycle(nativeio_pwmout_obj_t* self); -extern void common_hal_nativeio_pwmout_set_frequency(nativeio_pwmout_obj_t* self, uint32_t frequency); -extern uint32_t common_hal_nativeio_pwmout_get_frequency(nativeio_pwmout_obj_t* self); -extern bool common_hal_nativeio_pwmout_get_variable_frequency(nativeio_pwmout_obj_t* self); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PWMOUT_H__ diff --git a/shared-bindings/nativeio/PulseIn.c b/shared-bindings/nativeio/PulseIn.c deleted file mode 100644 index 78e0c84e4..000000000 --- a/shared-bindings/nativeio/PulseIn.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "py/runtime0.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/PulseIn.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`PulseIn` -- Read a series of pulse durations -//| ======================================================== -//| -//| PulseIn is used to measure a series of active and idle pulses. This is -//| commonly used in infrared receivers and low cost temperature sensors (DHT). -//| The pulsed signal consists of timed active and idle periods. Unlike PWM, -//| there is no set duration for active and idle pairs. -//| -//| .. class:: PulseIn(pin, maxlen=2, \*, idle_state=False) -//| -//| Create a PulseIn object associated with the given pin. The object acts as -//| a read-only sequence of pulse lengths with a given max length. When it is -//| active, new pulse lengths are added to the end of the list. When there is -//| no more room (len() == `maxlen`) the oldest pulse length is removed to -//| make room. -//| -//| :param ~microcontroller.Pin pin: Pin to read pulses from. -//| :param int maxlen: Maximum number of pulse durations to store at once -//| :param bool idle_state: Idle state of the pin. At start and after `resume` -//| the first recorded pulse will the opposite state from idle. -//| -//| Read a short series of pulses:: -//| -//| import nativeio -//| import board -//| -//| with nativeio.PulseIn(board.D7) as pulses: -//| # Wait for an active pulse -//| while len(pulses) == 0: -//| pass -//| # Pause while we do something with the pulses -//| pulses.pause() -//| -//| # Print the pulses. pulses[0] is an active pulse unless the length -//| # reached max length and idle pulses are recorded. -//| print(pulses) -//| -//| # Clear the rest -//| pulse_in.clear() -//| -//| # Resume with an 80 microsecond active pulse -//| pulse_in.resume(80) -//| -STATIC mp_obj_t nativeio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_pin, ARG_maxlen, ARG_idle_state }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_maxlen, MP_ARG_INT, {.u_int = 2} }, - { MP_QSTR_idle_state, MP_ARG_BOOL, {.u_bool = false} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - assert_pin(args[ARG_pin].u_obj, false); - const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); - assert_pin_free(pin); - - nativeio_pulsein_obj_t *self = m_new_obj(nativeio_pulsein_obj_t); - self->base.type = &nativeio_pulsein_type; - - common_hal_nativeio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, - args[ARG_idle_state].u_bool); - - return MP_OBJ_FROM_PTR(self); -} - -//| .. method:: deinit() -//| -//| Deinitialises the PulseIn and releases any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_pulsein_deinit(mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_pulsein_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulsein_deinit_obj, nativeio_pulsein_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_pulsein_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_pulsein___exit___obj, 4, 4, nativeio_pulsein_obj___exit__); - -//| .. method:: pause() -//| -//| Pause pulse capture -//| -STATIC mp_obj_t nativeio_pulsein_obj_pause(mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - - common_hal_nativeio_pulsein_pause(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulsein_pause_obj, nativeio_pulsein_obj_pause); - -//| .. method:: resume(trigger_duration=0) -//| -//| Resumes pulse capture after an optional trigger pulse. -//| -//| .. warning:: Using trigger pulse with a device that drives both high and -//| low signals risks a short. Make sure your device is open drain (only -//| drives low) when using a trigger pulse. You most likely added a -//| "pull-up" resistor to your circuit to do this. -//| -//| :param int trigger_duration: trigger pulse duration in microseconds -//| -STATIC mp_obj_t nativeio_pulsein_obj_resume(mp_obj_t self_in, mp_obj_t duration_obj) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint16_t trigger_duration = 0; - if (MP_OBJ_IS_SMALL_INT(duration_obj)) { - trigger_duration = MP_OBJ_SMALL_INT_VALUE(duration_obj); - } else if (duration_obj != mp_const_none) { - mp_raise_TypeError("trigger_duration must be int"); - } - - common_hal_nativeio_pulsein_resume(self, trigger_duration); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_pulsein_resume_obj, nativeio_pulsein_obj_resume); - -//| .. method:: clear() -//| -//| Clears all captured pulses -//| -STATIC mp_obj_t nativeio_pulsein_obj_clear(mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - - common_hal_nativeio_pulsein_clear(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulsein_clear_obj, nativeio_pulsein_obj_clear); - -//| .. method:: popleft() -//| -//| Removes and returns the oldest read pulse. -//| -STATIC mp_obj_t nativeio_pulsein_obj_popleft(mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_pulsein_popleft(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulsein_popleft_obj, nativeio_pulsein_obj_popleft); - -//| .. attribute:: maxlen -//| -//| Returns the maximum length of the PulseIn. When len() is equal to maxlen, -//| it is unclear which pulses are active and which are idle. -//| -STATIC mp_obj_t nativeio_pulsein_obj_get_maxlen(mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_pulsein_get_maxlen(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulsein_get_maxlen_obj, nativeio_pulsein_obj_get_maxlen); - -const mp_obj_property_t nativeio_pulsein_maxlen_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_pulsein_get_maxlen_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -//| .. method:: __len__() -//| -//| Returns the current pulse length -//| -//| This allows you to:: -//| -//| pulses = nativeio.PulseIn(pin) -//| print(len(pulses)) -//| -STATIC mp_obj_t pulsein_unary_op(mp_uint_t op, mp_obj_t self_in) { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - uint16_t len = common_hal_nativeio_pulsein_get_len(self); - switch (op) { - case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); - case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); - default: return MP_OBJ_NULL; // op not supported - } -} - -//| .. method:: __get__(index) -//| -//| Returns the value at the given index or values in slice. -//| -//| This allows you to:: -//| -//| pulses = nativeio.PulseIn(pin) -//| print(pulses[0]) -//| -STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { - if (value == mp_const_none) { - // delete item - mp_raise_AttributeError("Cannot delete values"); - } else { - nativeio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); - if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { - mp_raise_NotImplementedError("Slices not supported"); - } else { - uint16_t index = 0; - if (MP_OBJ_IS_SMALL_INT(index_obj)) { - index = MP_OBJ_SMALL_INT_VALUE(index_obj); - } else { - mp_raise_TypeError("index must be int"); - } - if (value == MP_OBJ_SENTINEL) { - // load - return MP_OBJ_NEW_SMALL_INT(common_hal_nativeio_pulsein_get_item(self, index)); - } else { - mp_raise_AttributeError("Read-only"); - } - } - } - return mp_const_none; -} - -STATIC const mp_rom_map_elem_t nativeio_pulsein_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_pulsein_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_pulsein___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&nativeio_pulsein_pause_obj) }, - { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&nativeio_pulsein_resume_obj) }, - { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&nativeio_pulsein_clear_obj) }, - { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&nativeio_pulsein_popleft_obj) }, - { MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&nativeio_pulsein_maxlen_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_pulsein_locals_dict, nativeio_pulsein_locals_dict_table); - -const mp_obj_type_t nativeio_pulsein_type = { - { &mp_type_type }, - .name = MP_QSTR_PulseIn, - .make_new = nativeio_pulsein_make_new, - .subscr = pulsein_subscr, - .unary_op = pulsein_unary_op, - .locals_dict = (mp_obj_dict_t*)&nativeio_pulsein_locals_dict, -}; diff --git a/shared-bindings/nativeio/PulseIn.h b/shared-bindings/nativeio/PulseIn.h deleted file mode 100644 index cdb5e95c5..000000000 --- a/shared-bindings/nativeio/PulseIn.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEIN_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEIN_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_pulsein_type; - -extern void common_hal_nativeio_pulsein_construct(nativeio_pulsein_obj_t* self, - const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state); -extern void common_hal_nativeio_pulsein_deinit(nativeio_pulsein_obj_t* self); -extern void common_hal_nativeio_pulsein_pause(nativeio_pulsein_obj_t* self); -extern void common_hal_nativeio_pulsein_resume(nativeio_pulsein_obj_t* self, uint16_t trigger_duration); -extern void common_hal_nativeio_pulsein_clear(nativeio_pulsein_obj_t* self); -extern uint16_t common_hal_nativeio_pulsein_popleft(nativeio_pulsein_obj_t* self); -extern uint16_t common_hal_nativeio_pulsein_get_maxlen(nativeio_pulsein_obj_t* self); -extern uint16_t common_hal_nativeio_pulsein_get_len(nativeio_pulsein_obj_t* self); -extern uint16_t common_hal_nativeio_pulsein_get_item(nativeio_pulsein_obj_t* self, int16_t index); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEIN_H__ diff --git a/shared-bindings/nativeio/PulseOut.c b/shared-bindings/nativeio/PulseOut.c deleted file mode 100644 index 79f189293..000000000 --- a/shared-bindings/nativeio/PulseOut.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/PulseOut.h" -#include "shared-bindings/nativeio/PWMOut.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`PulseOut` -- Output a pulse train -//| ======================================================== -//| -//| PulseOut is used to pulse PWM "carrier" output on and off. This is commonly -//| used in infrared remotes. The pulsed signal consists of timed on and off -//| periods. Unlike PWM, there is no set duration for on and off pairs. -//| -//| .. class:: PulseOut(carrier) -//| -//| Create a PulseOut object associated with the given PWM out experience. -//| -//| :param ~nativeio.PWMOut carrier: PWMOut that is set to output on the desired pin. -//| -//| Send a short series of pulses:: -//| -//| import array -//| import nativeio -//| import board -//| -//| with nativeio.PWMOut(board.D13, duty_cycle=2 ** 15) as pwm: -//| pulse = nativeio.PulseOut(pwm) -//| # on off on off on -//| pulses = array.array('h', [65000, 1000, 65000, 65000, 1000]) -//| pulse.send(pulses) -//| -//| # Modify the array of pulses. -//| pulses[0] = 200 -//| pulse.send(pulses) -//| -STATIC mp_obj_t nativeio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { - mp_arg_check_num(n_args, n_kw, 1, 1, true); - mp_obj_t carrier_obj = args[0]; - - if (!MP_OBJ_IS_TYPE(carrier_obj, &nativeio_pwmout_type)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Expected a %q", nativeio_pwmout_type.name)); - } - - // create Pulse object from the given pin - nativeio_pulseout_obj_t *self = m_new_obj(nativeio_pulseout_obj_t); - self->base.type = &nativeio_pulseout_type; - - common_hal_nativeio_pulseout_construct(self, (nativeio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj)); - - return MP_OBJ_FROM_PTR(self); -} - -//| .. method:: deinit() -//| -//| Deinitialises the PulseOut and releases any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_pulseout_deinit(mp_obj_t self_in) { - nativeio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_pulseout_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_pulseout_deinit_obj, nativeio_pulseout_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_pulseout_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_pulseout___exit___obj, 4, 4, nativeio_pulseout_obj___exit__); - -//| .. method:: send(pulses) -//| -//| Pulse alternating on and off durations in microseconds starting with on. -//| ``pulses`` must be an `array.array` with data type 'H' for unsigned -//| halfword (two bytes). -//| -//| This method waits until the whole array of pulses has been sent and -//| ensures the signal is off afterwards. -//| -//| :param array.array pulses: pulse durations in microseconds -//| -STATIC mp_obj_t nativeio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { - nativeio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ); - if (bufinfo.typecode != 'H') { - mp_raise_TypeError("Array must contain halfwords (type 'H')"); - } - common_hal_nativeio_pulseout_send(self, (uint16_t *)bufinfo.buf, bufinfo.len / 2); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_2(nativeio_pulseout_send_obj, nativeio_pulseout_obj_send); - -STATIC const mp_rom_map_elem_t nativeio_pulseout_locals_dict_table[] = { - // Methods - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_pulseout_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_pulseout___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&nativeio_pulseout_send_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_pulseout_locals_dict, nativeio_pulseout_locals_dict_table); - -const mp_obj_type_t nativeio_pulseout_type = { - { &mp_type_type }, - .name = MP_QSTR_PulseOut, - .make_new = nativeio_pulseout_make_new, - .locals_dict = (mp_obj_dict_t*)&nativeio_pulseout_locals_dict, -}; diff --git a/shared-bindings/nativeio/PulseOut.h b/shared-bindings/nativeio/PulseOut.h deleted file mode 100644 index 23fb8efed..000000000 --- a/shared-bindings/nativeio/PulseOut.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEOUT_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEOUT_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_pulseout_type; - -extern void common_hal_nativeio_pulseout_construct(nativeio_pulseout_obj_t* self, - const nativeio_pwmout_obj_t* carrier); -extern void common_hal_nativeio_pulseout_deinit(nativeio_pulseout_obj_t* self); -extern void common_hal_nativeio_pulseout_send(nativeio_pulseout_obj_t* self, - uint16_t* pulses, uint16_t len); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_PULSEOUT_H__ diff --git a/shared-bindings/nativeio/SPI.c b/shared-bindings/nativeio/SPI.c deleted file mode 100644 index 8d545a127..000000000 --- a/shared-bindings/nativeio/SPI.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This file contains all of the Python API definitions for the -// nativeio.SPI class. - -#include - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/SPI.h" - -#include "lib/utils/context_manager_helpers.h" -#include "py/mperrno.h" -#include "py/nlr.h" -#include "py/runtime.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`SPI` -- a 3-4 wire serial protocol -//| ----------------------------------------------- -//| -//| SPI is a serial protocol that has exclusive pins for data in and out of the -//| master. It is typically faster than :py:class:`~nativeio.I2C` because a -//| separate pin is used to control the active slave rather than a transitted -//| address. This class only manages three of the four SPI lines: `!clock`, -//| `!MOSI`, `!MISO`. Its up to the client to manage the appropriate slave -//| select line. (This is common because multiple slaves can share the `!clock`, -//| `!MOSI` and `!MISO` lines and therefore the hardware.) -//| -//| .. class:: SPI(clock, MOSI=None, MISO=None) -//| -//| Construct an SPI object on the given pins. -//| -//| .. seealso:: Using this class directly requires careful lock management. -//| Instead, use :class:`~adafruit_bus_device.spi_device.SPIDevice` to -//| manage locks. -//| -//| .. seealso:: Using this class to directly read registers requires manual -//| bit unpacking. Instead, use an existing driver or make one with -//| :ref:`Register ` data descriptors. -//| -//| :param ~microcontroller.Pin clock: the pin to use for the clock. -//| :param ~microcontroller.Pin MOSI: the Master Out Slave In pin. -//| :param ~microcontroller.Pin MISO: the Master In Slave Out pin. -//| - -// TODO(tannewt): Support LSB SPI. -STATIC mp_obj_t nativeio_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - nativeio_spi_obj_t *self = m_new_obj(nativeio_spi_obj_t); - self->base.type = &nativeio_spi_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_clock, ARG_MOSI, ARG_MISO }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_clock, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_MOSI, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_MISO, MP_ARG_OBJ, {.u_obj = mp_const_none} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - assert_pin(args[ARG_clock].u_obj, false); - assert_pin(args[ARG_MOSI].u_obj, true); - assert_pin(args[ARG_MISO].u_obj, true); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(args[ARG_clock].u_obj); - assert_pin_free(clock); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(args[ARG_MOSI].u_obj); - assert_pin_free(mosi); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(args[ARG_MISO].u_obj); - assert_pin_free(miso); - common_hal_nativeio_spi_construct(self, clock, mosi, miso); - return (mp_obj_t)self; -} - -//| .. method:: SPI.deinit() -//| -//| Turn off the SPI bus. -//| -STATIC mp_obj_t nativeio_spi_obj_deinit(mp_obj_t self_in) { - nativeio_spi_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_spi_deinit(self); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_spi_deinit_obj, nativeio_spi_obj_deinit); - -//| .. method:: SPI.__enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: SPI.__exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_spi_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_spi_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_spi_obj___exit___obj, 4, 4, nativeio_spi_obj___exit__); - -static void check_lock(nativeio_spi_obj_t *self) { - if (!common_hal_nativeio_spi_has_lock(self)) { - mp_raise_RuntimeError("Function requires lock"); - } -} - -//| .. method:: SPI.configure(\*, baudrate=100000, polarity=0, phase=0, bits=8) -//| -//| Configures the SPI bus. Only valid when locked. -//| -//| :param int baudrate: the clock rate in Hertz -//| :param int polarity: the base state of the clock line (0 or 1) -//| :param int phase: the edge of the clock that data is captured. First (0) -//| or second (1). Rising or falling depends on clock polarity. -//| :param int bits: the number of bits per word -//| -STATIC mp_obj_t nativeio_spi_configure(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 100000} }, - { MP_QSTR_polarity, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_phase, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, - }; - nativeio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_lock(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - uint8_t polarity = args[ARG_polarity].u_int; - if (polarity != 0 && polarity != 1) { - mp_raise_ValueError("Invalid polarity"); - } - uint8_t phase = args[ARG_phase].u_int; - if (phase != 0 && phase != 1) { - mp_raise_ValueError("Invalid phase"); - } - uint8_t bits = args[ARG_bits].u_int; - if (bits != 8 && bits != 9) { - mp_raise_ValueError("Invalid number of bits"); - } - - if (!common_hal_nativeio_spi_configure(self, args[ARG_baudrate].u_int, - polarity, phase, bits)) { - mp_raise_OSError(MP_EIO); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_spi_configure_obj, 1, nativeio_spi_configure); - -//| .. method:: SPI.try_lock() -//| -//| Attempts to grab the SPI lock. Returns True on success. -//| -//| :return: True when lock has been grabbed -//| :rtype: bool -//| -STATIC mp_obj_t nativeio_spi_obj_try_lock(mp_obj_t self_in) { - return mp_obj_new_bool(common_hal_nativeio_spi_try_lock(MP_OBJ_TO_PTR(self_in))); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_spi_try_lock_obj, nativeio_spi_obj_try_lock); - -//| .. method:: SPI.unlock() -//| -//| Releases the SPI lock. -//| -STATIC mp_obj_t nativeio_spi_obj_unlock(mp_obj_t self_in) { - common_hal_nativeio_spi_unlock(MP_OBJ_TO_PTR(self_in)); - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_spi_unlock_obj, nativeio_spi_obj_unlock); - -//| .. method:: SPI.write(buffer, \*, start=0, end=len(buffer)) -//| -//| Write the data contained in ``buf``. Requires the SPI being locked. -//| -//| :param bytearray buffer: buffer containing the bytes to write -//| :param int start: Index to start writing from -//| :param int end: Index to read up to but not include -//| -STATIC mp_obj_t nativeio_spi_write(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_buffer, ARG_start, ARG_end }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - }; - nativeio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_lock(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_READ); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } - - bool ok = common_hal_nativeio_spi_write(self, ((uint8_t*)bufinfo.buf) + start, len); - if (!ok) { - mp_raise_OSError(MP_EIO); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_spi_write_obj, 2, nativeio_spi_write); - - -//| .. method:: SPI.readinto(buffer, \*, start=0, end=len(buffer), write_value=0) -//| -//| Read into the buffer specified by ``buf`` while writing zeroes. Requires the SPI being locked. -//| -//| :param bytearray buffer: buffer to write into -//| :param int start: Index to start writing at -//| :param int end: Index to write up to but not include -//| :param int write_value: Value to write reading. (Usually ignored.) -//| -STATIC mp_obj_t nativeio_spi_readinto(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { - enum { ARG_buffer, ARG_start, ARG_end, ARG_write_value }; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_buffer, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} }, - { MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - { MP_QSTR_end, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = INT_MAX} }, - { MP_QSTR_write_value,MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, - }; - nativeio_spi_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); - check_lock(self); - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - mp_buffer_info_t bufinfo; - mp_get_buffer_raise(args[ARG_buffer].u_obj, &bufinfo, MP_BUFFER_WRITE); - int32_t end = args[ARG_end].u_int; - if (end < 0) { - end += bufinfo.len; - } - uint32_t start = args[ARG_start].u_int; - uint32_t len = end - start; - if ((uint32_t) end < start) { - len = 0; - } else if (len > bufinfo.len) { - len = bufinfo.len; - } - - bool ok = common_hal_nativeio_spi_read(self, ((uint8_t*)bufinfo.buf) + start, len, args[ARG_write_value].u_int); - if (!ok) { - mp_raise_OSError(MP_EIO); - } - return mp_const_none; -} -MP_DEFINE_CONST_FUN_OBJ_KW(nativeio_spi_readinto_obj, 2, nativeio_spi_readinto); - -STATIC const mp_rom_map_elem_t nativeio_spi_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_spi_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_spi_obj___exit___obj) }, - - { MP_ROM_QSTR(MP_QSTR_configure), MP_ROM_PTR(&nativeio_spi_configure_obj) }, - { MP_ROM_QSTR(MP_QSTR_try_lock), MP_ROM_PTR(&nativeio_spi_try_lock_obj) }, - { MP_ROM_QSTR(MP_QSTR_unlock), MP_ROM_PTR(&nativeio_spi_unlock_obj) }, - - { MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&nativeio_spi_readinto_obj) }, - { MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&nativeio_spi_write_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_spi_locals_dict, nativeio_spi_locals_dict_table); - -const mp_obj_type_t nativeio_spi_type = { - { &mp_type_type }, - .name = MP_QSTR_SPI, - .make_new = nativeio_spi_make_new, - .locals_dict = (mp_obj_dict_t*)&nativeio_spi_locals_dict, -}; diff --git a/shared-bindings/nativeio/SPI.h b/shared-bindings/nativeio/SPI.h deleted file mode 100644 index b997ddf67..000000000 --- a/shared-bindings/nativeio/SPI.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_SPI_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_SPI_H__ - -#include "py/obj.h" - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -// Type object used in Python. Should be shared between ports. -extern const mp_obj_type_t nativeio_spi_type; - -// Construct an underlying SPI object. -extern void common_hal_nativeio_spi_construct(nativeio_spi_obj_t *self, - const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, - const mcu_pin_obj_t * miso); - -extern void common_hal_nativeio_spi_deinit(nativeio_spi_obj_t *self); - -extern bool common_hal_nativeio_spi_configure(nativeio_spi_obj_t *self, uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits); - -extern bool common_hal_nativeio_spi_try_lock(nativeio_spi_obj_t *self); -extern bool common_hal_nativeio_spi_has_lock(nativeio_spi_obj_t *self); -extern void common_hal_nativeio_spi_unlock(nativeio_spi_obj_t *self); - -// Writes out the given data. -extern bool common_hal_nativeio_spi_write(nativeio_spi_obj_t *self, const uint8_t *data, size_t len); - -// Reads in len bytes while outputting zeroes. -extern bool common_hal_nativeio_spi_read(nativeio_spi_obj_t *self, uint8_t *data, size_t len, uint8_t write_value); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_SPI_H__ diff --git a/shared-bindings/nativeio/TouchIn.c b/shared-bindings/nativeio/TouchIn.c deleted file mode 100644 index 7b391499c..000000000 --- a/shared-bindings/nativeio/TouchIn.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "lib/utils/context_manager_helpers.h" -#include "py/binary.h" -#include "py/mphal.h" -#include "py/nlr.h" -#include "py/objproperty.h" -#include "py/runtime.h" -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/TouchIn.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`TouchIn` -- Read the state of a capacitive touch sensor -//| =================================================================== -//| -//| Usage:: -//| -//| import nativeio -//| from board import * -//| -//| with nativeio.TouchIn(A1) as touch: -//| if touch.value: -//| print("touched!") -//| - -//| .. class:: TouchIn(pin) -//| -//| Use the TouchIn on the given pin. -//| -//| :param ~microcontroller.Pin pin: the pin to read from -//| -STATIC mp_obj_t nativeio_touchin_make_new(const mp_obj_type_t *type, - mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { - // check number of arguments - mp_arg_check_num(n_args, n_kw, 1, 1, false); - - // 1st argument is the pin - mp_obj_t pin_obj = args[0]; - assert_pin(pin_obj, false); - - nativeio_touchin_obj_t *self = m_new_obj(nativeio_touchin_obj_t); - self->base.type = &nativeio_touchin_type; - const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); - common_hal_nativeio_touchin_construct(self, pin); - - return (mp_obj_t) self; -} - -//| .. method:: deinit() -//| -//| Deinitialises the TouchIn and releases any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_touchin_deinit(mp_obj_t self_in) { - nativeio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_touchin_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_touchin_deinit_obj, nativeio_touchin_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_touchin_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_touchin___exit___obj, 4, 4, nativeio_touchin_obj___exit__); - -//| .. attribute:: value -//| -//| Whether the touch pad is being touched or not. -//| -//| :return: True when touched, False otherwise. -//| :rtype: bool -//| -STATIC mp_obj_t nativeio_touchin_obj_get_value(mp_obj_t self_in) { - nativeio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); - return mp_obj_new_bool(common_hal_nativeio_touchin_get_value(self)); -} -MP_DEFINE_CONST_FUN_OBJ_1(nativeio_touchin_get_value_obj, nativeio_touchin_obj_get_value); - -const mp_obj_property_t nativeio_touchin_value_obj = { - .base.type = &mp_type_property, - .proxy = {(mp_obj_t)&nativeio_touchin_get_value_obj, - (mp_obj_t)&mp_const_none_obj, - (mp_obj_t)&mp_const_none_obj}, -}; - -STATIC const mp_rom_map_elem_t nativeio_touchin_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_touchin___exit___obj) }, - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_touchin_deinit_obj) }, - - { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&nativeio_touchin_value_obj)}, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_touchin_locals_dict, nativeio_touchin_locals_dict_table); - -const mp_obj_type_t nativeio_touchin_type = { - { &mp_type_type }, - .name = MP_QSTR_TouchIn, - .make_new = nativeio_touchin_make_new, - .locals_dict = (mp_obj_t)&nativeio_touchin_locals_dict, -}; diff --git a/shared-bindings/nativeio/TouchIn.h b/shared-bindings/nativeio/TouchIn.h deleted file mode 100644 index b22f655e5..000000000 --- a/shared-bindings/nativeio/TouchIn.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2013, 2014 Damien P. George - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_TOUCHIN_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_TOUCHIN_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_touchin_type; - -void common_hal_nativeio_touchin_construct(nativeio_touchin_obj_t* self, const mcu_pin_obj_t *pin); -void common_hal_nativeio_touchin_deinit(nativeio_touchin_obj_t* self); -bool common_hal_nativeio_touchin_get_value(nativeio_touchin_obj_t *self); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_TOUCHIN_H__ diff --git a/shared-bindings/nativeio/UART.c b/shared-bindings/nativeio/UART.c deleted file mode 100644 index c56130593..000000000 --- a/shared-bindings/nativeio/UART.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include - -#include "shared-bindings/nativeio/UART.h" - -#include "lib/utils/context_manager_helpers.h" - -#include "py/ioctl.h" -#include "py/runtime.h" -#include "py/stream.h" - -#include "shared-bindings/microcontroller/Pin.h" - -//| .. currentmodule:: nativeio -//| -//| :class:`UART` -- a bidirectional serial protocol -//| ================================================= -//| -//| -//| .. class:: UART(tx, rx, \*, baudrate=9600, bits=8, parity=None, stop=1, timeout=1000, receiver_buffer_size=64) -//| -//| A common bidirectional serial protocol that uses an an agreed upon speed -//| rather than a shared clock line. -//| -//| :param ~microcontroller.Pin tx: the pin to transmit with -//| :param ~microcontroller.Pin rx: the pin to receive on -//| :param int baudrate: the transmit and receive speed -/// :param int bits: the number of bits per byte, 7, 8 or 9. -/// :param Parity parity: the parity used for error checking -/// :param int stop: the number of stop bits, 1 or 2. -/// :param int timeout: the timeout in milliseconds to wait for the first character and between subsequent characters. -/// :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.) -//| -typedef struct { - mp_obj_base_t base; -} nativeio_uart_parity_obj_t; -extern const nativeio_uart_parity_obj_t nativeio_uart_parity_even_obj; -extern const nativeio_uart_parity_obj_t nativeio_uart_parity_odd_obj; - -STATIC mp_obj_t nativeio_uart_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { - mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true); - nativeio_uart_obj_t *self = m_new_obj(nativeio_uart_obj_t); - self->base.type = &nativeio_uart_type; - mp_map_t kw_args; - mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); - enum { ARG_tx, ARG_rx, ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_receiver_buffer_size}; - static const mp_arg_t allowed_args[] = { - { MP_QSTR_tx, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_rx, MP_ARG_REQUIRED | MP_ARG_OBJ }, - { MP_QSTR_baudrate, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 9600} }, - { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} }, - { MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} }, - { MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, - { MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1000} }, - { MP_QSTR_receiver_buffer_size, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 64} }, - }; - mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; - mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); - - assert_pin(args[ARG_rx].u_obj, true); - const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(args[ARG_rx].u_obj); - assert_pin_free(rx); - - assert_pin(args[ARG_tx].u_obj, true); - const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(args[ARG_tx].u_obj); - assert_pin_free(tx); - - uint8_t bits = args[ARG_bits].u_int; - if (bits < 7 || bits > 9) { - mp_raise_ValueError("bits must be 7, 8 or 9"); - } - - uart_parity_t parity = PARITY_NONE; - if (args[ARG_parity].u_obj == &nativeio_uart_parity_even_obj) { - parity = PARITY_EVEN; - } else if (args[ARG_parity].u_obj == &nativeio_uart_parity_odd_obj) { - parity = PARITY_ODD; - } - - uint8_t stop = args[ARG_stop].u_int; - if (stop != 1 && stop != 2) { - mp_raise_ValueError("stop must be 1 or 2"); - } - - common_hal_nativeio_uart_construct(self, tx, rx, - args[ARG_baudrate].u_int, bits, parity, stop, args[ARG_timeout].u_int, - args[ARG_receiver_buffer_size].u_int); - return (mp_obj_t)self; -} - -//| .. method:: deinit() -//| -//| Deinitialises the UART and releases any hardware resources for reuse. -//| -STATIC mp_obj_t nativeio_uart_obj_deinit(mp_obj_t self_in) { - nativeio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); - common_hal_nativeio_uart_deinit(self); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_1(nativeio_uart_deinit_obj, nativeio_uart_obj_deinit); - -//| .. method:: __enter__() -//| -//| No-op used by Context Managers. -//| -// Provided by context manager helper. - -//| .. method:: __exit__() -//| -//| Automatically deinitializes the hardware when exiting a context. -//| -STATIC mp_obj_t nativeio_uart_obj___exit__(size_t n_args, const mp_obj_t *args) { - (void)n_args; - common_hal_nativeio_uart_deinit(args[0]); - return mp_const_none; -} -STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(nativeio_uart___exit___obj, 4, 4, nativeio_uart_obj___exit__); - -// These are standard stream methods. Code is in py/stream.c. -// -//| .. method:: read(nbytes=None) -//| -//| Read characters. If ``nbytes`` is specified then read at most that many -//| bytes. Otherwise, read everything that has been buffered. -//| -//| :return: Data read -//| :rtype: bytes or None -//| -//| .. method:: readinto(buf, nbytes=None) -//| -//| Read bytes into the ``buf``. If ``nbytes`` is specified then read at most -//| that many bytes. Otherwise, read at most ``len(buf)`` bytes. -//| -//| :return: number of bytes read and stored into ``buf`` -//| :rtype: bytes or None -//| -//| .. method:: readline() -//| -//| Read a line, ending in a newline character. -//| -//| :return: the line read -//| :rtype: int or None -//| -//| .. method:: write(buf) -//| -//| Write the buffer of bytes to the bus. -//| -//| :return: the number of bytes written -//| :rtype: int or None -//| - -// These three methods are used by the shared stream methods. -STATIC mp_uint_t nativeio_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) { - nativeio_uart_obj_t *self = self_in; - byte *buf = buf_in; - - // make sure we want at least 1 char - if (size == 0) { - return 0; - } - - return common_hal_nativeio_uart_read(self, buf, size, errcode); -} - -STATIC mp_uint_t nativeio_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) { - nativeio_uart_obj_t *self = self_in; - const byte *buf = buf_in; - - return common_hal_nativeio_uart_write(self, buf, size, errcode); -} - -STATIC mp_uint_t nativeio_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) { - nativeio_uart_obj_t *self = self_in; - mp_uint_t ret; - if (request == MP_IOCTL_POLL) { - mp_uint_t flags = arg; - ret = 0; - if ((flags & MP_IOCTL_POLL_RD) && common_hal_nativeio_uart_rx_characters_available(self) > 0) { - ret |= MP_IOCTL_POLL_RD; - } - if ((flags & MP_IOCTL_POLL_WR) && common_hal_nativeio_uart_ready_to_tx(self)) { - ret |= MP_IOCTL_POLL_WR; - } - } else { - *errcode = MP_EINVAL; - ret = MP_STREAM_ERROR; - } - return ret; -} - -//| .. class:: nativeio.UART.Parity -//| -//| Enum-like class to define the parity used to verify correct data transfer. -//| -//| .. data:: ODD -//| -//| Total number of ones should be odd. -//| -//| .. data:: EVEN -//| -//| Total number of ones should be even. -//| -const mp_obj_type_t nativeio_uart_parity_type; - -const nativeio_uart_parity_obj_t nativeio_uart_parity_odd_obj = { - { &nativeio_uart_parity_type }, -}; - -const nativeio_uart_parity_obj_t nativeio_uart_parity_even_obj = { - { &nativeio_uart_parity_type }, -}; - -STATIC const mp_rom_map_elem_t nativeio_uart_parity_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_ODD), MP_ROM_PTR(&nativeio_uart_parity_odd_obj) }, - { MP_ROM_QSTR(MP_QSTR_EVEN), MP_ROM_PTR(&nativeio_uart_parity_even_obj) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_uart_parity_locals_dict, nativeio_uart_parity_locals_dict_table); - -STATIC void nativeio_uart_parity_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) { - qstr parity = MP_QSTR_ODD; - if (MP_OBJ_TO_PTR(self_in) == MP_ROM_PTR(&nativeio_uart_parity_even_obj)) { - parity = MP_QSTR_EVEN; - } - mp_printf(print, "%q.%q.%q.%q", MP_QSTR_nativeio, MP_QSTR_UART, MP_QSTR_Parity, parity); -} - -const mp_obj_type_t nativeio_uart_parity_type = { - { &mp_type_type }, - .name = MP_QSTR_Parity, - .print = nativeio_uart_parity_print, - .locals_dict = (mp_obj_t)&nativeio_uart_parity_locals_dict, -}; - -STATIC const mp_rom_map_elem_t nativeio_uart_locals_dict_table[] = { - { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&nativeio_uart_deinit_obj) }, - { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, - { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&nativeio_uart___exit___obj) }, - - // Standard stream methods. - { MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj)}, - { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, - - // Nested Enum-like Classes. - { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&nativeio_uart_parity_type) }, -}; -STATIC MP_DEFINE_CONST_DICT(nativeio_uart_locals_dict, nativeio_uart_locals_dict_table); - -STATIC const mp_stream_p_t uart_stream_p = { - .read = nativeio_uart_read, - .write = nativeio_uart_write, - .ioctl = nativeio_uart_ioctl, - .is_text = false, -}; - -const mp_obj_type_t nativeio_uart_type = { - { &mp_type_type }, - .name = MP_QSTR_UART, - .make_new = nativeio_uart_make_new, - .getiter = mp_identity, - .iternext = mp_stream_unbuffered_iter, - .protocol = &uart_stream_p, - .locals_dict = (mp_obj_dict_t*)&nativeio_uart_locals_dict, -}; diff --git a/shared-bindings/nativeio/UART.h b/shared-bindings/nativeio/UART.h deleted file mode 100644 index bafc5b730..000000000 --- a/shared-bindings/nativeio/UART.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__ - -#include "common-hal/microcontroller/types.h" -#include "common-hal/nativeio/types.h" - -extern const mp_obj_type_t nativeio_uart_type; - -typedef enum { - PARITY_NONE, - PARITY_EVEN, - PARITY_ODD -} uart_parity_t; - -// Construct an underlying UART object. -extern void common_hal_nativeio_uart_construct(nativeio_uart_obj_t *self, - const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate, - uint8_t bits, uart_parity_t parity, uint8_t stop, uint32_t timeout, - uint8_t receiver_buffer_size); - -extern void common_hal_nativeio_uart_deinit(nativeio_uart_obj_t *self); - -// Read characters. len is in characters NOT bytes! -extern size_t common_hal_nativeio_uart_read(nativeio_uart_obj_t *self, - uint8_t *data, size_t len, int *errcode); - -// Write characters. len is in characters NOT bytes! -extern size_t common_hal_nativeio_uart_write(nativeio_uart_obj_t *self, - const uint8_t *data, size_t len, int *errcode); - -extern uint32_t common_hal_nativeio_uart_rx_characters_available(nativeio_uart_obj_t *self); -extern bool common_hal_nativeio_uart_ready_to_tx(nativeio_uart_obj_t *self); - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_UART_H__ diff --git a/shared-bindings/nativeio/__init__.c b/shared-bindings/nativeio/__init__.c deleted file mode 100644 index 3287a46cd..000000000 --- a/shared-bindings/nativeio/__init__.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// nativeio is the HAL for low-level, hardware accelerated classes. It -// is not meant to simplify APIs, its only meant to unify them so that other -// libraries do not require port specific logic. - -#include - -#include "py/obj.h" -#include "py/runtime.h" - -#include "shared-bindings/microcontroller/Pin.h" -#include "shared-bindings/nativeio/__init__.h" -#include "shared-bindings/nativeio/AnalogIn.h" -#include "shared-bindings/nativeio/AnalogOut.h" -#include "shared-bindings/nativeio/DigitalInOut.h" -#include "shared-bindings/nativeio/I2C.h" -#include "shared-bindings/nativeio/OneWire.h" -#include "shared-bindings/nativeio/PulseIn.h" -#include "shared-bindings/nativeio/PulseOut.h" -#include "shared-bindings/nativeio/PWMOut.h" -#include "shared-bindings/nativeio/SPI.h" -#include "shared-bindings/nativeio/TouchIn.h" -#include "shared-bindings/nativeio/UART.h" -#include "common-hal/nativeio/types.h" -#include "shared-bindings/nativeio/__init__.h" - -#include "py/runtime.h" - -//| :mod:`nativeio` --- Hardware accelerated behavior -//| ================================================= -//| -//| .. module:: nativeio -//| :synopsis: Hardware accelerated behavior -//| :platform: SAMD21 -//| -//| The `nativeio` module contains classes to provide access to IO typically -//| accelerated by hardware on the onboard microcontroller. The classes are -//| meant to align with commonly hardware accelerated IO and not necessarily -//| match up with microcontroller structure (because it varies). -//| -//| When the microcontroller does not support the behavior in a hardware -//| accelerated fashion it may internally use a bitbang routine. However, if -//| hardware support is available on a subset of pins but not those provided, -//| then a RuntimeError will be raised. Use the `bitbangio` module to explicitly -//| bitbang a protocol on any general purpose pins. -//| -//| Libraries -//| -//| .. toctree:: -//| :maxdepth: 3 -//| -//| AnalogIn -//| AnalogOut -//| DigitalInOut -//| I2C -//| OneWire -//| PulseIn -//| PulseOut -//| PWMOut -//| SPI -//| TouchIn -//| UART -//| -//| All libraries change hardware state and should be deinitialized when they -//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a -//| context manager. -//| -//| For example:: -//| -//| import nativeio -//| from board import * -//| -//| with nativeio.I2C(SCL, SDA) as i2c: -//| i2c.scan() -//| -//| This example will initialize the the device, run -//| :py:meth:`~nativeio.I2C.scan` and then :py:meth:`~nativeio.I2C.deinit` the -//| hardware. -//| -//| Here is blinky:: -//| -//| import nativeio -//| from board import * -//| import time -//| -//| with nativeio.DigitalInOut(D13) as led: -//| led.switch_to_output() -//| while True: -//| led.value = True -//| time.sleep(0.1) -//| led.value = False -//| time.sleep(0.1) -//| - -STATIC const mp_rom_map_elem_t nativeio_module_globals_table[] = { - { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_nativeio) }, - { MP_ROM_QSTR(MP_QSTR_AnalogIn), MP_ROM_PTR(&nativeio_analogin_type) }, - { MP_ROM_QSTR(MP_QSTR_AnalogOut), MP_ROM_PTR(&nativeio_analogout_type) }, - { MP_ROM_QSTR(MP_QSTR_DigitalInOut), MP_ROM_PTR(&nativeio_digitalinout_type) }, - { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&nativeio_i2c_type) }, - { MP_ROM_QSTR(MP_QSTR_OneWire), MP_ROM_PTR(&nativeio_onewire_type) }, - { MP_ROM_QSTR(MP_QSTR_PulseIn), MP_ROM_PTR(&nativeio_pulsein_type) }, - { MP_ROM_QSTR(MP_QSTR_PulseOut), MP_ROM_PTR(&nativeio_pulseout_type) }, - { MP_ROM_QSTR(MP_QSTR_PWMOut), MP_ROM_PTR(&nativeio_pwmout_type) }, - { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&nativeio_spi_type) }, - { MP_ROM_QSTR(MP_QSTR_TouchIn), MP_ROM_PTR(&nativeio_touchin_type) }, - { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&nativeio_uart_type) }, -}; - -STATIC MP_DEFINE_CONST_DICT(nativeio_module_globals, nativeio_module_globals_table); - -const mp_obj_module_t nativeio_module = { - .base = { &mp_type_module }, - .globals = (mp_obj_dict_t*)&nativeio_module_globals, -}; diff --git a/shared-bindings/nativeio/__init__.h b/shared-bindings/nativeio/__init__.h deleted file mode 100644 index 7f4c01e05..000000000 --- a/shared-bindings/nativeio/__init__.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2016 Scott Shawcroft - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO___INIT___H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO___INIT___H__ - -#include "py/obj.h" - -// Nothing now. - -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO___INIT___H__ diff --git a/shared-bindings/neopixel_write/__init__.c b/shared-bindings/neopixel_write/__init__.c index b0490e1ae..faf2433d0 100644 --- a/shared-bindings/neopixel_write/__init__.c +++ b/shared-bindings/neopixel_write/__init__.c @@ -28,9 +28,7 @@ #include "py/mphal.h" #include "py/runtime.h" -#include "common-hal/nativeio/types.h" - -#include "shared-bindings/nativeio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-bindings/neopixel_write/__init__.h" //| :mod:`neopixel_write` --- Low-level neopixel implementation @@ -47,15 +45,15 @@ //| //| Write buf out on the given DigitalInOut. //| -//| :param ~nativeio.DigitalInOut gpio: the DigitalInOut to output with +//| :param ~digitalio.DigitalInOut gpio: the DigitalInOut to output with //| :param bytearray buf: The bytes to clock out. No assumption is made about color order //| STATIC mp_obj_t neopixel_write_neopixel_write_(mp_obj_t digitalinout_obj, mp_obj_t buf) { - if (!MP_OBJ_IS_TYPE(digitalinout_obj, &nativeio_digitalinout_type)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Expected a %q", nativeio_digitalinout_type.name)); + if (!MP_OBJ_IS_TYPE(digitalinout_obj, &digitalio_digitalinout_type)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Expected a %q", digitalio_digitalinout_type.name)); } // Convert parameters into expected types. - const nativeio_digitalinout_obj_t *digitalinout = MP_OBJ_TO_PTR(digitalinout_obj); + const digitalio_digitalinout_obj_t *digitalinout = MP_OBJ_TO_PTR(digitalinout_obj); mp_buffer_info_t bufinfo; mp_get_buffer_raise(buf, &bufinfo, MP_BUFFER_READ); // Call platform's neopixel write function with provided buffer and options. diff --git a/shared-bindings/neopixel_write/__init__.h b/shared-bindings/neopixel_write/__init__.h index 87f85ee01..39b565ee2 100644 --- a/shared-bindings/neopixel_write/__init__.h +++ b/shared-bindings/neopixel_write/__init__.h @@ -30,8 +30,8 @@ #include #include -#include "common-hal/nativeio/types.h" +#include "common-hal/digitalio/DigitalInOut.h" -extern void common_hal_neopixel_write(const nativeio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); +extern void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* gpio, uint8_t *pixels, uint32_t numBytes); #endif diff --git a/shared-bindings/pulseio/PWMOut.c b/shared-bindings/pulseio/PWMOut.c new file mode 100644 index 000000000..73f3bfd3e --- /dev/null +++ b/shared-bindings/pulseio/PWMOut.c @@ -0,0 +1,221 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PWMOut.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PWMOut` -- Output a Pulse Width Modulated signal +//| ======================================================== +//| +//| PWMOut can be used to output a PWM signal on a given pin. +//| +//| .. class:: PWMOut(pin, \*, duty_cycle=0, frequency=500, variable_frequency=False) +//| +//| Create a PWM object associated with the given pin. This allows you to +//| write PWM signals out on the given pin. Frequency is fixed after init +//| unless ``variable_frequency`` is True. +//| +//| .. note:: When ``variable_frequency`` is True, further PWM outputs may be +//| limited because it may take more internal resources to be flexible. So, +//| when outputting both fixed and flexible frequency signals construct the +//| fixed outputs first. +//| +//| :param ~microcontroller.Pin pin: The pin to output to +//| :param int duty: The fraction of each pulse which is high. 16-bit +//| :param int frequency: The target frequency in Hertz (32-bit) +//| :param bool variable_frequency: True if the frequency will change over time +//| +//| Simple LED fade:: +//| +//| import pulseio +//| import board +//| +//| with pulseio.PWMOut(board.D13) as pwm: # output on D13 +//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at the default 500hz +//| +//| PWM at specific frequency (servos and motors):: +//| +//| import pulseio +//| import board +//| +//| with pulseio.PWMOut(board.D13, frequency=50) as pwm: +//| pwm.duty_cycle = 2 ** 15 # Cycles the pin with 50% duty cycle (half of 2 ** 16) at 50hz +//| +//| Variable frequency (usually tones):: +//| +//| import pulseio +//| import board +//| import time +//| +//| with pulseio.PWMOut(board.D13, duty_cycle=2 ** 15, frequency=440, variable_frequency=True) as pwm: +//| time.sleep(0.2) +//| pwm.frequency = 880 +//| time.sleep(0.1) +//| +STATIC mp_obj_t pulseio_pwmout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + mp_obj_t pin_obj = args[0]; + assert_pin(pin_obj, false); + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + assert_pin_free(pin); + + // create PWM object from the given pin + pulseio_pwmout_obj_t *self = m_new_obj(pulseio_pwmout_obj_t); + self->base.type = &pulseio_pwmout_type; + + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, args + n_args); + enum { ARG_duty_cycle, ARG_frequency, ARG_variable_frequency }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_duty_cycle, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} }, + { MP_QSTR_frequency, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 500} }, + { MP_QSTR_variable_frequency, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t parsed_args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, args + 1, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, parsed_args); + uint16_t duty_cycle = parsed_args[ARG_duty_cycle].u_int; + uint32_t frequency = parsed_args[ARG_frequency].u_int; + bool variable_frequency = parsed_args[ARG_variable_frequency].u_int; + + common_hal_pulseio_pwmout_construct(self, pin, duty_cycle, frequency, variable_frequency); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PWMOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pwmout_deinit(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pwmout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_deinit_obj, pulseio_pwmout_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t pulseio_pwmout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pwmout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pwmout___exit___obj, 4, 4, pulseio_pwmout_obj___exit__); + +//| .. attribute:: duty_cycle +//| +//| 16 bit value that dictates how much of one cycle is high (1) versus low +//| (0). 0xffff will always be high, 0 will always be low and 0x7fff will +//| be half high and then half low. +STATIC mp_obj_t pulseio_pwmout_obj_get_duty_cycle(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_duty_cycle(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_duty_cycle_obj, pulseio_pwmout_obj_get_duty_cycle); + +STATIC mp_obj_t pulseio_pwmout_obj_set_duty_cycle(mp_obj_t self_in, mp_obj_t duty_cycle) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + mp_int_t duty = mp_obj_get_int(duty_cycle); + if (duty < 0 || duty > 0xffff) { + mp_raise_ValueError("PWM duty must be between 0 and 65536 (16 bit resolution)"); + } + common_hal_pulseio_pwmout_set_duty_cycle(self, duty); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pwmout_set_duty_cycle_obj, pulseio_pwmout_obj_set_duty_cycle); + +const mp_obj_property_t pulseio_pwmout_duty_cycle_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pwmout_get_duty_cycle_obj, + (mp_obj_t)&pulseio_pwmout_set_duty_cycle_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. attribute:: frequency +//| +//| 32 bit value that dictates the PWM frequency in Hertz (cycles per +//| second). Only writeable when constructed with ``variable_frequency=True``. +//| +STATIC mp_obj_t pulseio_pwmout_obj_get_frequency(mp_obj_t self_in) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pwmout_get_frequency(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pwmout_get_frequency_obj, pulseio_pwmout_obj_get_frequency); + +STATIC mp_obj_t pulseio_pwmout_obj_set_frequency(mp_obj_t self_in, mp_obj_t frequency) { + pulseio_pwmout_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (!common_hal_pulseio_pwmout_get_variable_frequency(self)) { + mp_raise_AttributeError( + "PWM frequency not writeable when variable_frequency is False on " + "construction."); + } + common_hal_pulseio_pwmout_set_frequency(self, mp_obj_get_int(frequency)); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pwmout_set_frequency_obj, pulseio_pwmout_obj_set_frequency); + +const mp_obj_property_t pulseio_pwmout_frequency_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pwmout_get_frequency_obj, + (mp_obj_t)&pulseio_pwmout_set_frequency_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t pulseio_pwmout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pwmout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pwmout___exit___obj) }, + + // Properties + { MP_ROM_QSTR(MP_QSTR_duty_cycle), MP_ROM_PTR(&pulseio_pwmout_duty_cycle_obj) }, + { MP_ROM_QSTR(MP_QSTR_frequency), MP_ROM_PTR(&pulseio_pwmout_frequency_obj) }, + // TODO(tannewt): Add enabled to determine whether the signal is output + // without giving up the resources. Useful for IR output. +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pwmout_locals_dict, pulseio_pwmout_locals_dict_table); + +const mp_obj_type_t pulseio_pwmout_type = { + { &mp_type_type }, + .name = MP_QSTR_PWMOut, + .make_new = pulseio_pwmout_make_new, + .locals_dict = (mp_obj_dict_t*)&pulseio_pwmout_locals_dict, +}; diff --git a/shared-bindings/pulseio/PWMOut.h b/shared-bindings/pulseio/PWMOut.h new file mode 100644 index 000000000..f7a0bff22 --- /dev/null +++ b/shared-bindings/pulseio/PWMOut.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/pulseio/PWMOut.h" + +extern const mp_obj_type_t pulseio_pwmout_type; + +extern void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency, + bool variable_frequency); +extern void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self); +extern void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty); +extern uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self); +extern void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency); +extern uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self); +extern bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PWMOUT_H__ diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c new file mode 100644 index 000000000..e87020cd9 --- /dev/null +++ b/shared-bindings/pulseio/PulseIn.c @@ -0,0 +1,285 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/runtime0.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PulseIn.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PulseIn` -- Read a series of pulse durations +//| ======================================================== +//| +//| PulseIn is used to measure a series of active and idle pulses. This is +//| commonly used in infrared receivers and low cost temperature sensors (DHT). +//| The pulsed signal consists of timed active and idle periods. Unlike PWM, +//| there is no set duration for active and idle pairs. +//| +//| .. class:: PulseIn(pin, maxlen=2, \*, idle_state=False) +//| +//| Create a PulseIn object associated with the given pin. The object acts as +//| a read-only sequence of pulse lengths with a given max length. When it is +//| active, new pulse lengths are added to the end of the list. When there is +//| no more room (len() == `maxlen`) the oldest pulse length is removed to +//| make room. +//| +//| :param ~microcontroller.Pin pin: Pin to read pulses from. +//| :param int maxlen: Maximum number of pulse durations to store at once +//| :param bool idle_state: Idle state of the pin. At start and after `resume` +//| the first recorded pulse will the opposite state from idle. +//| +//| Read a short series of pulses:: +//| +//| import pulseio +//| import board +//| +//| with pulseio.PulseIn(board.D7) as pulses: +//| # Wait for an active pulse +//| while len(pulses) == 0: +//| pass +//| # Pause while we do something with the pulses +//| pulses.pause() +//| +//| # Print the pulses. pulses[0] is an active pulse unless the length +//| # reached max length and idle pulses are recorded. +//| print(pulses) +//| +//| # Clear the rest +//| pulse_in.clear() +//| +//| # Resume with an 80 microsecond active pulse +//| pulse_in.resume(80) +//| +STATIC mp_obj_t pulseio_pulsein_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *pos_args) { + mp_arg_check_num(n_args, n_kw, 1, MP_OBJ_FUN_ARGS_MAX, true); + mp_map_t kw_args; + mp_map_init_fixed_table(&kw_args, n_kw, pos_args + n_args); + enum { ARG_pin, ARG_maxlen, ARG_idle_state }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_pin, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_maxlen, MP_ARG_INT, {.u_int = 2} }, + { MP_QSTR_idle_state, MP_ARG_BOOL, {.u_bool = false} }, + }; + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, &kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + assert_pin(args[ARG_pin].u_obj, false); + const mcu_pin_obj_t* pin = MP_OBJ_TO_PTR(args[ARG_pin].u_obj); + assert_pin_free(pin); + + pulseio_pulsein_obj_t *self = m_new_obj(pulseio_pulsein_obj_t); + self->base.type = &pulseio_pulsein_type; + + common_hal_pulseio_pulsein_construct(self, pin, args[ARG_maxlen].u_int, + args[ARG_idle_state].u_bool); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PulseIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pulsein_deinit(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pulsein_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_deinit_obj, pulseio_pulsein_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t pulseio_pulsein_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pulsein_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulsein___exit___obj, 4, 4, pulseio_pulsein_obj___exit__); + +//| .. method:: pause() +//| +//| Pause pulse capture +//| +STATIC mp_obj_t pulseio_pulsein_obj_pause(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_pulseio_pulsein_pause(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_pause_obj, pulseio_pulsein_obj_pause); + +//| .. method:: resume(trigger_duration=0) +//| +//| Resumes pulse capture after an optional trigger pulse. +//| +//| .. warning:: Using trigger pulse with a device that drives both high and +//| low signals risks a short. Make sure your device is open drain (only +//| drives low) when using a trigger pulse. You most likely added a +//| "pull-up" resistor to your circuit to do this. +//| +//| :param int trigger_duration: trigger pulse duration in microseconds +//| +STATIC mp_obj_t pulseio_pulsein_obj_resume(mp_obj_t self_in, mp_obj_t duration_obj) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t trigger_duration = 0; + if (MP_OBJ_IS_SMALL_INT(duration_obj)) { + trigger_duration = MP_OBJ_SMALL_INT_VALUE(duration_obj); + } else if (duration_obj != mp_const_none) { + mp_raise_TypeError("trigger_duration must be int"); + } + + common_hal_pulseio_pulsein_resume(self, trigger_duration); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pulsein_resume_obj, pulseio_pulsein_obj_resume); + +//| .. method:: clear() +//| +//| Clears all captured pulses +//| +STATIC mp_obj_t pulseio_pulsein_obj_clear(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + + common_hal_pulseio_pulsein_clear(self); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_clear_obj, pulseio_pulsein_obj_clear); + +//| .. method:: popleft() +//| +//| Removes and returns the oldest read pulse. +//| +STATIC mp_obj_t pulseio_pulsein_obj_popleft(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_popleft(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_popleft_obj, pulseio_pulsein_obj_popleft); + +//| .. attribute:: maxlen +//| +//| Returns the maximum length of the PulseIn. When len() is equal to maxlen, +//| it is unclear which pulses are active and which are idle. +//| +STATIC mp_obj_t pulseio_pulsein_obj_get_maxlen(mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_maxlen(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulsein_get_maxlen_obj, pulseio_pulsein_obj_get_maxlen); + +const mp_obj_property_t pulseio_pulsein_maxlen_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&pulseio_pulsein_get_maxlen_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: __len__() +//| +//| Returns the current pulse length +//| +//| This allows you to:: +//| +//| pulses = pulseio.PulseIn(pin) +//| print(len(pulses)) +//| +STATIC mp_obj_t pulsein_unary_op(mp_uint_t op, mp_obj_t self_in) { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + uint16_t len = common_hal_pulseio_pulsein_get_len(self); + switch (op) { + case MP_UNARY_OP_BOOL: return mp_obj_new_bool(len != 0); + case MP_UNARY_OP_LEN: return MP_OBJ_NEW_SMALL_INT(len); + default: return MP_OBJ_NULL; // op not supported + } +} + +//| .. method:: __get__(index) +//| +//| Returns the value at the given index or values in slice. +//| +//| This allows you to:: +//| +//| pulses = pulseio.PulseIn(pin) +//| print(pulses[0]) +//| +STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { + if (value == mp_const_none) { + // delete item + mp_raise_AttributeError("Cannot delete values"); + } else { + pulseio_pulsein_obj_t *self = MP_OBJ_TO_PTR(self_in); + if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { + mp_raise_NotImplementedError("Slices not supported"); + } else { + uint16_t index = 0; + if (MP_OBJ_IS_SMALL_INT(index_obj)) { + index = MP_OBJ_SMALL_INT_VALUE(index_obj); + } else { + mp_raise_TypeError("index must be int"); + } + if (value == MP_OBJ_SENTINEL) { + // load + return MP_OBJ_NEW_SMALL_INT(common_hal_pulseio_pulsein_get_item(self, index)); + } else { + mp_raise_AttributeError("Read-only"); + } + } + } + return mp_const_none; +} + +STATIC const mp_rom_map_elem_t pulseio_pulsein_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulsein_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulsein___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_pause), MP_ROM_PTR(&pulseio_pulsein_pause_obj) }, + { MP_ROM_QSTR(MP_QSTR_resume), MP_ROM_PTR(&pulseio_pulsein_resume_obj) }, + { MP_ROM_QSTR(MP_QSTR_clear), MP_ROM_PTR(&pulseio_pulsein_clear_obj) }, + { MP_ROM_QSTR(MP_QSTR_popleft), MP_ROM_PTR(&pulseio_pulsein_popleft_obj) }, + { MP_ROM_QSTR(MP_QSTR_maxlen), MP_ROM_PTR(&pulseio_pulsein_maxlen_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pulsein_locals_dict, pulseio_pulsein_locals_dict_table); + +const mp_obj_type_t pulseio_pulsein_type = { + { &mp_type_type }, + .name = MP_QSTR_PulseIn, + .make_new = pulseio_pulsein_make_new, + .subscr = pulsein_subscr, + .unary_op = pulsein_unary_op, + .locals_dict = (mp_obj_dict_t*)&pulseio_pulsein_locals_dict, +}; diff --git a/shared-bindings/pulseio/PulseIn.h b/shared-bindings/pulseio/PulseIn.h new file mode 100644 index 000000000..5ffab1d67 --- /dev/null +++ b/shared-bindings/pulseio/PulseIn.h @@ -0,0 +1,46 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/pulseio/PulseIn.h" + +extern const mp_obj_type_t pulseio_pulsein_type; + +extern void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self, + const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state); +extern void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self); +extern void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self); +extern void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self, uint16_t trigger_duration); +extern void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self); +extern uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self, int16_t index); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEIN_H__ diff --git a/shared-bindings/pulseio/PulseOut.c b/shared-bindings/pulseio/PulseOut.c new file mode 100644 index 000000000..20e04e8fb --- /dev/null +++ b/shared-bindings/pulseio/PulseOut.c @@ -0,0 +1,150 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" + +//| .. currentmodule:: pulseio +//| +//| :class:`PulseOut` -- Output a pulse train +//| ======================================================== +//| +//| PulseOut is used to pulse PWM "carrier" output on and off. This is commonly +//| used in infrared remotes. The pulsed signal consists of timed on and off +//| periods. Unlike PWM, there is no set duration for on and off pairs. +//| +//| .. class:: PulseOut(carrier) +//| +//| Create a PulseOut object associated with the given PWM out experience. +//| +//| :param ~pulseio.PWMOut carrier: PWMOut that is set to output on the desired pin. +//| +//| Send a short series of pulses:: +//| +//| import array +//| import pulseio +//| import board +//| +//| with pulseio.PWMOut(board.D13, duty_cycle=2 ** 15) as pwm: +//| pulse = pulseio.PulseOut(pwm) +//| # on off on off on +//| pulses = array.array('h', [65000, 1000, 65000, 65000, 1000]) +//| pulse.send(pulses) +//| +//| # Modify the array of pulses. +//| pulses[0] = 200 +//| pulse.send(pulses) +//| +STATIC mp_obj_t pulseio_pulseout_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { + mp_arg_check_num(n_args, n_kw, 1, 1, true); + mp_obj_t carrier_obj = args[0]; + + if (!MP_OBJ_IS_TYPE(carrier_obj, &pulseio_pwmout_type)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Expected a %q", pulseio_pwmout_type.name)); + } + + // create Pulse object from the given pin + pulseio_pulseout_obj_t *self = m_new_obj(pulseio_pulseout_obj_t); + self->base.type = &pulseio_pulseout_type; + + common_hal_pulseio_pulseout_construct(self, (pulseio_pwmout_obj_t *)MP_OBJ_TO_PTR(carrier_obj)); + + return MP_OBJ_FROM_PTR(self); +} + +//| .. method:: deinit() +//| +//| Deinitialises the PulseOut and releases any hardware resources for reuse. +//| +STATIC mp_obj_t pulseio_pulseout_deinit(mp_obj_t self_in) { + pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_pulseio_pulseout_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pulseio_pulseout_deinit_obj, pulseio_pulseout_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t pulseio_pulseout_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_pulseio_pulseout_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pulseio_pulseout___exit___obj, 4, 4, pulseio_pulseout_obj___exit__); + +//| .. method:: send(pulses) +//| +//| Pulse alternating on and off durations in microseconds starting with on. +//| ``pulses`` must be an `array.array` with data type 'H' for unsigned +//| halfword (two bytes). +//| +//| This method waits until the whole array of pulses has been sent and +//| ensures the signal is off afterwards. +//| +//| :param array.array pulses: pulse durations in microseconds +//| +STATIC mp_obj_t pulseio_pulseout_obj_send(mp_obj_t self_in, mp_obj_t pulses) { + pulseio_pulseout_obj_t *self = MP_OBJ_TO_PTR(self_in); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(pulses, &bufinfo, MP_BUFFER_READ); + if (bufinfo.typecode != 'H') { + mp_raise_TypeError("Array must contain halfwords (type 'H')"); + } + common_hal_pulseio_pulseout_send(self, (uint16_t *)bufinfo.buf, bufinfo.len / 2); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(pulseio_pulseout_send_obj, pulseio_pulseout_obj_send); + +STATIC const mp_rom_map_elem_t pulseio_pulseout_locals_dict_table[] = { + // Methods + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pulseio_pulseout_deinit_obj) }, + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&pulseio_pulseout___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&pulseio_pulseout_send_obj) }, +}; +STATIC MP_DEFINE_CONST_DICT(pulseio_pulseout_locals_dict, pulseio_pulseout_locals_dict_table); + +const mp_obj_type_t pulseio_pulseout_type = { + { &mp_type_type }, + .name = MP_QSTR_PulseOut, + .make_new = pulseio_pulseout_make_new, + .locals_dict = (mp_obj_dict_t*)&pulseio_pulseout_locals_dict, +}; diff --git a/shared-bindings/pulseio/PulseOut.h b/shared-bindings/pulseio/PulseOut.h new file mode 100644 index 000000000..5365fd1f5 --- /dev/null +++ b/shared-bindings/pulseio/PulseOut.h @@ -0,0 +1,42 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/pulseio/PulseOut.h" +#include "common-hal/pulseio/PWMOut.h" + +extern const mp_obj_type_t pulseio_pulseout_type; + +extern void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self, + const pulseio_pwmout_obj_t* carrier); +extern void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self); +extern void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self, + uint16_t* pulses, uint16_t len); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO_PULSEOUT_H__ diff --git a/shared-bindings/pulseio/__init__.c b/shared-bindings/pulseio/__init__.c new file mode 100644 index 000000000..27d978ec5 --- /dev/null +++ b/shared-bindings/pulseio/__init__.c @@ -0,0 +1,87 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/pulseio/__init__.h" +#include "shared-bindings/pulseio/PulseIn.h" +#include "shared-bindings/pulseio/PulseOut.h" +#include "shared-bindings/pulseio/PWMOut.h" + +//| :mod:`pulseio` --- Support for pulse based protocols +//| ================================================= +//| +//| .. module:: pulseio +//| :synopsis: Support for pulse based protocols +//| :platform: SAMD21, ESP8266 +//| +//| The `pulseio` module contains classes to provide access to basic pulse IO. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| PulseIn +//| PulseOut +//| PWMOut +//| +//| All libraries change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| +//| For example:: +//| +//| import pulseio +//| import time +//| from board import * +//| +//| with pulseio.PWMOut(D13) as pin: +//| pin.duty_cycle = 2 ** 15 +//| time.sleep(0.1) +//| +//| This example will initialize the the device, set +//| :py:data:`~pulseio.PWMOut.duty_cycle`, sleep 0.1 seconds and then +//| :py:meth:`~pulseio.PWMOut.deinit` the hardware. +//| + +STATIC const mp_rom_map_elem_t pulseio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_pulseio) }, + { MP_ROM_QSTR(MP_QSTR_PulseIn), MP_ROM_PTR(&pulseio_pulsein_type) }, + { MP_ROM_QSTR(MP_QSTR_PulseOut), MP_ROM_PTR(&pulseio_pulseout_type) }, + { MP_ROM_QSTR(MP_QSTR_PWMOut), MP_ROM_PTR(&pulseio_pwmout_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(pulseio_module_globals, pulseio_module_globals_table); + +const mp_obj_module_t pulseio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&pulseio_module_globals, +}; diff --git a/shared-bindings/pulseio/__init__.h b/shared-bindings/pulseio/__init__.h new file mode 100644 index 000000000..26bb9f7b4 --- /dev/null +++ b/shared-bindings/pulseio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H__ + +#include "py/obj.h" + +// Nothing now. + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_PULSEIO___INIT___H__ diff --git a/shared-bindings/touchio/TouchIn.c b/shared-bindings/touchio/TouchIn.c new file mode 100644 index 000000000..f4e82994c --- /dev/null +++ b/shared-bindings/touchio/TouchIn.c @@ -0,0 +1,139 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "lib/utils/context_manager_helpers.h" +#include "py/binary.h" +#include "py/mphal.h" +#include "py/nlr.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/touchio/TouchIn.h" + +//| .. currentmodule:: touchio +//| +//| :class:`TouchIn` -- Read the state of a capacitive touch sensor +//| =================================================================== +//| +//| Usage:: +//| +//| import touchio +//| from board import * +//| +//| with touchio.TouchIn(A1) as touch: +//| if touch.value: +//| print("touched!") +//| + +//| .. class:: TouchIn(pin) +//| +//| Use the TouchIn on the given pin. +//| +//| :param ~microcontroller.Pin pin: the pin to read from +//| +STATIC mp_obj_t touchio_touchin_make_new(const mp_obj_type_t *type, + mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { + // check number of arguments + mp_arg_check_num(n_args, n_kw, 1, 1, false); + + // 1st argument is the pin + mp_obj_t pin_obj = args[0]; + assert_pin(pin_obj, false); + + touchio_touchin_obj_t *self = m_new_obj(touchio_touchin_obj_t); + self->base.type = &touchio_touchin_type; + const mcu_pin_obj_t *pin = MP_OBJ_TO_PTR(pin_obj); + common_hal_touchio_touchin_construct(self, pin); + + return (mp_obj_t) self; +} + +//| .. method:: deinit() +//| +//| Deinitialises the TouchIn and releases any hardware resources for reuse. +//| +STATIC mp_obj_t touchio_touchin_deinit(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_touchio_touchin_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_deinit_obj, touchio_touchin_deinit); + +//| .. method:: __enter__() +//| +//| No-op used by Context Managers. +//| +// Provided by context manager helper. + +//| .. method:: __exit__() +//| +//| Automatically deinitializes the hardware when exiting a context. +//| +STATIC mp_obj_t touchio_touchin_obj___exit__(size_t n_args, const mp_obj_t *args) { + (void)n_args; + common_hal_touchio_touchin_deinit(args[0]); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(touchio_touchin___exit___obj, 4, 4, touchio_touchin_obj___exit__); + +//| .. attribute:: value +//| +//| Whether the touch pad is being touched or not. +//| +//| :return: True when touched, False otherwise. +//| :rtype: bool +//| +STATIC mp_obj_t touchio_touchin_obj_get_value(mp_obj_t self_in) { + touchio_touchin_obj_t *self = MP_OBJ_TO_PTR(self_in); + return mp_obj_new_bool(common_hal_touchio_touchin_get_value(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(touchio_touchin_get_value_obj, touchio_touchin_obj_get_value); + +const mp_obj_property_t touchio_touchin_value_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&touchio_touchin_get_value_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +STATIC const mp_rom_map_elem_t touchio_touchin_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) }, + { MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&touchio_touchin___exit___obj) }, + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&touchio_touchin_deinit_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_value), MP_ROM_PTR(&touchio_touchin_value_obj)}, +}; + +STATIC MP_DEFINE_CONST_DICT(touchio_touchin_locals_dict, touchio_touchin_locals_dict_table); + +const mp_obj_type_t touchio_touchin_type = { + { &mp_type_type }, + .name = MP_QSTR_TouchIn, + .make_new = touchio_touchin_make_new, + .locals_dict = (mp_obj_t)&touchio_touchin_locals_dict, +}; diff --git a/shared-bindings/touchio/TouchIn.h b/shared-bindings/touchio/TouchIn.h new file mode 100644 index 000000000..04a72835e --- /dev/null +++ b/shared-bindings/touchio/TouchIn.h @@ -0,0 +1,39 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2013, 2014 Damien P. George + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H__ + +#include "common-hal/microcontroller/types.h" +#include "common-hal/touchio/TouchIn.h" + +extern const mp_obj_type_t touchio_touchin_type; + +void common_hal_touchio_touchin_construct(touchio_touchin_obj_t* self, const mcu_pin_obj_t *pin); +void common_hal_touchio_touchin_deinit(touchio_touchin_obj_t* self); +bool common_hal_touchio_touchin_get_value(touchio_touchin_obj_t *self); + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO_TOUCHIN_H__ diff --git a/shared-bindings/touchio/__init__.c b/shared-bindings/touchio/__init__.c new file mode 100644 index 000000000..a930c1af7 --- /dev/null +++ b/shared-bindings/touchio/__init__.c @@ -0,0 +1,82 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#include "py/obj.h" +#include "py/runtime.h" + +#include "shared-bindings/microcontroller/Pin.h" +#include "shared-bindings/touchio/__init__.h" +#include "shared-bindings/touchio/TouchIn.h" + +#include "py/runtime.h" + +//| :mod:`touchio` --- Touch related IO +//| ================================================= +//| +//| .. module:: touchio +//| :synopsis: Hardware accelerated behavior +//| :platform: SAMD21 +//| +//| The `touchio` module contains classes to provide access to touch IO typically +//| accelerated by hardware on the onboard microcontroller. +//| +//| Libraries +//| +//| .. toctree:: +//| :maxdepth: 3 +//| +//| TouchIn +//| +//| All libraries change hardware state and should be deinitialized when they +//| are no longer needed. To do so, either call :py:meth:`!deinit` or use a +//| context manager. +//| +//| For example:: +//| +//| import touchio +//| from board import * +//| +//| with touchio.TouchIn(D6) as touch_pin: +//| print(touch_pin.value) +//| +//| This example will initialize the the device, run +//| :py:data:`~touchio.TouchIn.value` and then :py:meth:`~touchio.TouchIn.deinit` +//| the hardware. +//| + +STATIC const mp_rom_map_elem_t touchio_module_globals_table[] = { + { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_touchio) }, + { MP_ROM_QSTR(MP_QSTR_TouchIn), MP_ROM_PTR(&touchio_touchin_type) }, +}; + +STATIC MP_DEFINE_CONST_DICT(touchio_module_globals, touchio_module_globals_table); + +const mp_obj_module_t touchio_module = { + .base = { &mp_type_module }, + .globals = (mp_obj_dict_t*)&touchio_module_globals, +}; diff --git a/shared-bindings/touchio/__init__.h b/shared-bindings/touchio/__init__.h new file mode 100644 index 000000000..fc40e462b --- /dev/null +++ b/shared-bindings/touchio/__init__.h @@ -0,0 +1,34 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2016 Scott Shawcroft + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H__ + +#include "py/obj.h" + +// Nothing now. + +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_TOUCHIO___INIT___H__ diff --git a/shared-bindings/usb_hid/Device.h b/shared-bindings/usb_hid/Device.h index 08713874e..234d7ebc2 100644 --- a/shared-bindings/usb_hid/Device.h +++ b/shared-bindings/usb_hid/Device.h @@ -24,8 +24,8 @@ * THE SOFTWARE. */ -#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ -#define __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ +#ifndef __MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H__ +#define __MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H__ #include "common-hal/usb_hid/types.h" @@ -35,4 +35,4 @@ void common_hal_usb_hid_device_send_report(usb_hid_device_obj_t *self, uint8_t* uint8_t common_hal_usb_hid_device_get_usage_page(usb_hid_device_obj_t *self); uint8_t common_hal_usb_hid_device_get_usage(usb_hid_device_obj_t *self); -#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_NATIVEIO_ANALOGIN_H__ +#endif // __MICROPY_INCLUDED_SHARED_BINDINGS_USB_HID_DEVICE_H__ diff --git a/shared-bindings/usb_hid/__init__.h b/shared-bindings/usb_hid/__init__.h index 576a3301b..ff478d083 100644 --- a/shared-bindings/usb_hid/__init__.h +++ b/shared-bindings/usb_hid/__init__.h @@ -30,8 +30,6 @@ #include #include -#include "common-hal/nativeio/types.h" - // TODO(tannewt): Make this a mp_obj_tuple_t when it is dynamically allocated. // until then we hard code it to two entries so LTO is happy. extern mp_obj_tuple2_t common_hal_usb_hid_devices; diff --git a/shared-module/bitbangio/I2C.c b/shared-module/bitbangio/I2C.c index 422f7778d..4c47629c7 100644 --- a/shared-module/bitbangio/I2C.c +++ b/shared-module/bitbangio/I2C.c @@ -31,7 +31,7 @@ #include "common-hal/microcontroller/types.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-module/bitbangio/types.h" #define I2C_STRETCH_LIMIT 255 @@ -43,30 +43,30 @@ STATIC void delay(bitbangio_i2c_obj_t *self) { } STATIC void scl_low(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_set_value(&self->scl, false); + common_hal_digitalio_digitalinout_set_value(&self->scl, false); } STATIC void scl_release(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_set_value(&self->scl, true); + common_hal_digitalio_digitalinout_set_value(&self->scl, true); delay(self); // For clock stretching, wait for the SCL pin to be released, with timeout. - for (int count = I2C_STRETCH_LIMIT; !common_hal_nativeio_digitalinout_get_value(&self->scl) && count; --count) { + for (int count = I2C_STRETCH_LIMIT; !common_hal_digitalio_digitalinout_get_value(&self->scl) && count; --count) { common_hal_mcu_delay_us(1); } } STATIC void sda_low(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_set_value(&self->sda, false); + common_hal_digitalio_digitalinout_set_value(&self->sda, false); } STATIC void sda_release(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_set_value(&self->sda, true); + common_hal_digitalio_digitalinout_set_value(&self->sda, true); } STATIC bool sda_read(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_switch_to_input(&self->sda, PULL_UP); - bool value = common_hal_nativeio_digitalinout_get_value(&self->sda); - common_hal_nativeio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_input(&self->sda, PULL_UP); + bool value = common_hal_digitalio_digitalinout_get_value(&self->sda); + common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); return value; } @@ -147,24 +147,24 @@ void shared_module_bitbangio_i2c_construct(bitbangio_i2c_obj_t *self, if (self->us_delay == 0) { self->us_delay = 1; } - digitalinout_result_t result = common_hal_nativeio_digitalinout_construct(&self->scl, scl); + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->scl, scl); if (result != DIGITALINOUT_OK) { return; } - result = common_hal_nativeio_digitalinout_construct(&self->sda, sda); + result = common_hal_digitalio_digitalinout_construct(&self->sda, sda); if (result != DIGITALINOUT_OK) { - common_hal_nativeio_digitalinout_deinit(&self->scl); + common_hal_digitalio_digitalinout_deinit(&self->scl); return; } - common_hal_nativeio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); - common_hal_nativeio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->scl, true, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->sda, true, DRIVE_MODE_OPEN_DRAIN); stop(self); } void shared_module_bitbangio_i2c_deinit(bitbangio_i2c_obj_t *self) { - common_hal_nativeio_digitalinout_deinit(&self->scl); - common_hal_nativeio_digitalinout_deinit(&self->sda); + common_hal_digitalio_digitalinout_deinit(&self->scl); + common_hal_digitalio_digitalinout_deinit(&self->sda); } bool shared_module_bitbangio_i2c_try_lock(bitbangio_i2c_obj_t *self) { diff --git a/shared-module/bitbangio/OneWire.c b/shared-module/bitbangio/OneWire.c index 5f45b3baf..b78acc8ec 100644 --- a/shared-module/bitbangio/OneWire.c +++ b/shared-module/bitbangio/OneWire.c @@ -27,28 +27,28 @@ #include "common-hal/microcontroller/types.h" #include "shared-bindings/bitbangio/OneWire.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-module/bitbangio/types.h" // Durations are taken from here: https://www.maximintegrated.com/en/app-notes/index.mvp/id/126 void shared_module_bitbangio_onewire_construct(bitbangio_onewire_obj_t* self, const mcu_pin_obj_t* pin) { - self->pin.base.type = &nativeio_digitalinout_type; - common_hal_nativeio_digitalinout_construct(&self->pin, pin); + self->pin.base.type = &digitalio_digitalinout_type; + common_hal_digitalio_digitalinout_construct(&self->pin, pin); } void shared_module_bitbangio_onewire_deinit(bitbangio_onewire_obj_t* self) { - common_hal_nativeio_digitalinout_deinit(&self->pin); + common_hal_digitalio_digitalinout_deinit(&self->pin); } bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) { common_hal_mcu_disable_interrupts(); - common_hal_nativeio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); common_hal_mcu_delay_us(480); - common_hal_nativeio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); common_hal_mcu_delay_us(70); - bool value = common_hal_nativeio_digitalinout_get_value(&self->pin); + bool value = common_hal_digitalio_digitalinout_get_value(&self->pin); common_hal_mcu_delay_us(410); common_hal_mcu_enable_interrupts(); return value; @@ -56,14 +56,14 @@ bool shared_module_bitbangio_onewire_reset(bitbangio_onewire_obj_t* self) { bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self) { common_hal_mcu_disable_interrupts(); - common_hal_nativeio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); common_hal_mcu_delay_us(6); - common_hal_nativeio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); // TODO(tannewt): Test with more devices and maybe make the delays // configurable. This should be 9 by the datasheet but all bits read as 1 // then. common_hal_mcu_delay_us(6); - bool value = common_hal_nativeio_digitalinout_get_value(&self->pin); + bool value = common_hal_digitalio_digitalinout_get_value(&self->pin); common_hal_mcu_delay_us(55); common_hal_mcu_enable_interrupts(); return value; @@ -72,9 +72,9 @@ bool shared_module_bitbangio_onewire_read_bit(bitbangio_onewire_obj_t* self) { void shared_module_bitbangio_onewire_write_bit(bitbangio_onewire_obj_t* self, bool bit) { common_hal_mcu_disable_interrupts(); - common_hal_nativeio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); + common_hal_digitalio_digitalinout_switch_to_output(&self->pin, false, DRIVE_MODE_OPEN_DRAIN); common_hal_mcu_delay_us(bit? 6 : 60); - common_hal_nativeio_digitalinout_switch_to_input(&self->pin, PULL_NONE); + common_hal_digitalio_digitalinout_switch_to_input(&self->pin, PULL_NONE); common_hal_mcu_delay_us(bit? 64 : 10); common_hal_mcu_enable_interrupts(); } diff --git a/shared-module/bitbangio/SPI.c b/shared-module/bitbangio/SPI.c index 5e8d73122..be0deda8f 100644 --- a/shared-module/bitbangio/SPI.c +++ b/shared-module/bitbangio/SPI.c @@ -31,7 +31,7 @@ #include "common-hal/microcontroller/types.h" #include "shared-bindings/microcontroller/__init__.h" -#include "shared-bindings/nativeio/DigitalInOut.h" +#include "shared-bindings/digitalio/DigitalInOut.h" #include "shared-module/bitbangio/types.h" #define MAX_BAUDRATE (common_hal_mcu_get_clock_frequency() / 48) @@ -39,26 +39,26 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) { - digitalinout_result_t result = common_hal_nativeio_digitalinout_construct(&self->clock, clock); + digitalinout_result_t result = common_hal_digitalio_digitalinout_construct(&self->clock, clock); if (result != DIGITALINOUT_OK) { nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Clock pin init failed.")); } if (mosi != mp_const_none) { - result = common_hal_nativeio_digitalinout_construct(&self->mosi, mosi); + result = common_hal_digitalio_digitalinout_construct(&self->mosi, mosi); if (result != DIGITALINOUT_OK) { - common_hal_nativeio_digitalinout_deinit(&self->clock); + common_hal_digitalio_digitalinout_deinit(&self->clock); nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "MOSI pin init failed.")); } self->has_mosi = true; } if (miso != mp_const_none) { - result = common_hal_nativeio_digitalinout_construct(&self->miso, miso); + result = common_hal_digitalio_digitalinout_construct(&self->miso, miso); if (result != DIGITALINOUT_OK) { - common_hal_nativeio_digitalinout_deinit(&self->clock); + common_hal_digitalio_digitalinout_deinit(&self->clock); if (mosi != mp_const_none) { - common_hal_nativeio_digitalinout_deinit(&self->mosi); + common_hal_digitalio_digitalinout_deinit(&self->mosi); } nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "MISO pin init failed.")); @@ -71,12 +71,12 @@ void shared_module_bitbangio_spi_construct(bitbangio_spi_obj_t *self, } void shared_module_bitbangio_spi_deinit(bitbangio_spi_obj_t *self) { - common_hal_nativeio_digitalinout_deinit(&self->clock); + common_hal_digitalio_digitalinout_deinit(&self->clock); if (self->has_mosi) { - common_hal_nativeio_digitalinout_deinit(&self->mosi); + common_hal_digitalio_digitalinout_deinit(&self->mosi); } if (self->has_miso) { - common_hal_nativeio_digitalinout_deinit(&self->miso); + common_hal_digitalio_digitalinout_deinit(&self->miso); } } @@ -129,9 +129,9 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_nativeio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); } if (dest != NULL) { dest[i] = data_in; @@ -144,16 +144,16 @@ bool shared_module_bitbangio_spi_write(bitbangio_spi_obj_t *self, const uint8_t for (size_t i = 0; i < len; ++i) { uint8_t data_out = data[i]; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_nativeio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); + common_hal_digitalio_digitalinout_set_value(&self->mosi, (data_out >> 7) & 1); if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); } else { - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } @@ -185,14 +185,14 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, if (delay_half <= MICROPY_PY_MACHINE_SPI_MIN_DELAY) { // Clock out zeroes while we read. if (self->has_mosi) { - common_hal_nativeio_digitalinout_set_value(&self->mosi, false); + common_hal_digitalio_digitalinout_set_value(&self->mosi, false); } for (size_t i = 0; i < len; ++i) { uint8_t data_in = 0; for (int j = 0; j < 8; ++j, data_out <<= 1) { - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); - data_in = (data_in << 1) | common_hal_nativeio_digitalinout_get_value(&self->miso); - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); } data[i] = data_in; } @@ -200,24 +200,24 @@ bool shared_module_bitbangio_spi_read(bitbangio_spi_obj_t *self, uint8_t *data, } #endif if (self->has_mosi) { - common_hal_nativeio_digitalinout_set_value(&self->mosi, false); + common_hal_digitalio_digitalinout_set_value(&self->mosi, false); } for (size_t i = 0; i < len; ++i) { uint8_t data_in = 0; for (int j = 0; j < 8; ++j) { if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); } else { - common_hal_nativeio_digitalinout_set_value(&self->clock, 1 - self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, 1 - self->polarity); common_hal_mcu_delay_us(delay_half); } - data_in = (data_in << 1) | common_hal_nativeio_digitalinout_get_value(&self->miso); + data_in = (data_in << 1) | common_hal_digitalio_digitalinout_get_value(&self->miso); if (self->phase == 0) { common_hal_mcu_delay_us(delay_half); - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); } else { - common_hal_nativeio_digitalinout_set_value(&self->clock, self->polarity); + common_hal_digitalio_digitalinout_set_value(&self->clock, self->polarity); common_hal_mcu_delay_us(delay_half); } } diff --git a/shared-module/bitbangio/types.h b/shared-module/bitbangio/types.h index 8fd4a48c4..46723a958 100644 --- a/shared-module/bitbangio/types.h +++ b/shared-module/bitbangio/types.h @@ -27,28 +27,28 @@ #ifndef __MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_TYPES_H__ #define __MICROPY_INCLUDED_SHARED_MODULE_BITBANGIO_TYPES_H__ -#include "common-hal/nativeio/DigitalInOut.h" +#include "common-hal/digitalio/DigitalInOut.h" #include "py/obj.h" typedef struct { mp_obj_base_t base; - nativeio_digitalinout_obj_t scl; - nativeio_digitalinout_obj_t sda; + digitalio_digitalinout_obj_t scl; + digitalio_digitalinout_obj_t sda; uint32_t us_delay; volatile bool locked; } bitbangio_i2c_obj_t; typedef struct { mp_obj_base_t base; - nativeio_digitalinout_obj_t pin; + digitalio_digitalinout_obj_t pin; } bitbangio_onewire_obj_t; typedef struct { mp_obj_base_t base; - nativeio_digitalinout_obj_t clock; - nativeio_digitalinout_obj_t mosi; - nativeio_digitalinout_obj_t miso; + digitalio_digitalinout_obj_t clock; + digitalio_digitalinout_obj_t mosi; + digitalio_digitalinout_obj_t miso; uint32_t delay_half; bool has_miso:1; bool has_mosi:1; diff --git a/shared-module/busio/I2C.c b/shared-module/busio/I2C.c new file mode 100644 index 000000000..f8f154e7f --- /dev/null +++ b/shared-module/busio/I2C.c @@ -0,0 +1,66 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "shared-bindings/busio/I2C.h" +#include "shared-bindings/bitbangio/I2C.h" +#include "py/mperrno.h" +#include "py/nlr.h" + +void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, + const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t freq) { + shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq); +} + +void common_hal_busio_i2c_deinit(busio_i2c_obj_t *self) { + shared_module_bitbangio_i2c_deinit(&self->bitbang); +} + +bool common_hal_busio_i2c_probe(busio_i2c_obj_t *self, uint8_t addr) { + return shared_module_bitbangio_i2c_probe(&self->bitbang, addr); +} + +bool common_hal_busio_i2c_try_lock(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_try_lock(&self->bitbang); +} + +bool common_hal_busio_i2c_has_lock(busio_i2c_obj_t *self) { + return shared_module_bitbangio_i2c_has_lock(&self->bitbang); +} + +void common_hal_busio_i2c_unlock(busio_i2c_obj_t *self) { + shared_module_bitbangio_i2c_unlock(&self->bitbang); +} + +uint8_t common_hal_busio_i2c_write(busio_i2c_obj_t *self, uint16_t addr, + const uint8_t * data, size_t len, bool transmit_stop_bit) { + return shared_module_bitbangio_i2c_write(&self->bitbang, addr, data, len, + transmit_stop_bit); +} + +uint8_t common_hal_busio_i2c_read(busio_i2c_obj_t *self, uint16_t addr, + uint8_t * data, size_t len) { + return shared_module_bitbangio_i2c_read(&self->bitbang, addr, data, len); +} diff --git a/shared-module/busio/I2C.h b/shared-module/busio/I2C.h new file mode 100644 index 000000000..9706124c2 --- /dev/null +++ b/shared-module/busio/I2C.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H__ + +#include "shared-module/bitbangio/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bitbangio_i2c_obj_t bitbang; +} busio_i2c_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_I2C_H__ diff --git a/shared-module/busio/OneWire.c b/shared-module/busio/OneWire.c new file mode 100644 index 000000000..0e3c2c384 --- /dev/null +++ b/shared-module/busio/OneWire.c @@ -0,0 +1,52 @@ +/* + * This file is part of the Micro Python project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// Wraps the bitbangio implementation of OneWire for use in busio. +#include "common-hal/microcontroller/types.h" +#include "shared-bindings/bitbangio/OneWire.h" +#include "shared-module/busio/OneWire.h" + +void common_hal_busio_onewire_construct(busio_onewire_obj_t* self, + const mcu_pin_obj_t* pin) { + shared_module_bitbangio_onewire_construct(&self->bitbang, pin); +} + +void common_hal_busio_onewire_deinit(busio_onewire_obj_t* self) { + shared_module_bitbangio_onewire_deinit(&self->bitbang); +} + +bool common_hal_busio_onewire_reset(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_reset(&self->bitbang); +} + +bool common_hal_busio_onewire_read_bit(busio_onewire_obj_t* self) { + return shared_module_bitbangio_onewire_read_bit(&self->bitbang); +} + +void common_hal_busio_onewire_write_bit(busio_onewire_obj_t* self, + bool bit) { + shared_module_bitbangio_onewire_write_bit(&self->bitbang, bit); +} diff --git a/shared-module/busio/OneWire.h b/shared-module/busio/OneWire.h new file mode 100644 index 000000000..9404a7206 --- /dev/null +++ b/shared-module/busio/OneWire.h @@ -0,0 +1,39 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H__ +#define __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H__ + +#include "shared-module/bitbangio/types.h" + +#include "py/obj.h" + +typedef struct { + mp_obj_base_t base; + bitbangio_onewire_obj_t bitbang; +} busio_onewire_obj_t; + +#endif // __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_BUSIO_ONEWIRE_H__ diff --git a/shared-module/nativeio/I2C.c b/shared-module/nativeio/I2C.c deleted file mode 100644 index 345a3825a..000000000 --- a/shared-module/nativeio/I2C.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "shared-bindings/nativeio/I2C.h" -#include "shared-bindings/bitbangio/I2C.h" -#include "py/mperrno.h" -#include "py/nlr.h" - -void common_hal_nativeio_i2c_construct(nativeio_i2c_obj_t *self, - const mcu_pin_obj_t* scl, const mcu_pin_obj_t* sda, uint32_t freq) { - shared_module_bitbangio_i2c_construct(&self->bitbang, scl, sda, freq); -} - -void common_hal_nativeio_i2c_deinit(nativeio_i2c_obj_t *self) { - shared_module_bitbangio_i2c_deinit(&self->bitbang); -} - -bool common_hal_nativeio_i2c_probe(nativeio_i2c_obj_t *self, uint8_t addr) { - return shared_module_bitbangio_i2c_probe(&self->bitbang, addr); -} - -bool common_hal_nativeio_i2c_try_lock(nativeio_i2c_obj_t *self) { - return shared_module_bitbangio_i2c_try_lock(&self->bitbang); -} - -bool common_hal_nativeio_i2c_has_lock(nativeio_i2c_obj_t *self) { - return shared_module_bitbangio_i2c_has_lock(&self->bitbang); -} - -void common_hal_nativeio_i2c_unlock(nativeio_i2c_obj_t *self) { - shared_module_bitbangio_i2c_unlock(&self->bitbang); -} - -uint8_t common_hal_nativeio_i2c_write(nativeio_i2c_obj_t *self, uint16_t addr, - const uint8_t * data, size_t len, bool transmit_stop_bit) { - return shared_module_bitbangio_i2c_write(&self->bitbang, addr, data, len, - transmit_stop_bit); -} - -uint8_t common_hal_nativeio_i2c_read(nativeio_i2c_obj_t *self, uint16_t addr, - uint8_t * data, size_t len) { - return shared_module_bitbangio_i2c_read(&self->bitbang, addr, data, len); -} diff --git a/shared-module/nativeio/I2C.h b/shared-module/nativeio/I2C.h deleted file mode 100644 index b26ba4642..000000000 --- a/shared-module/nativeio/I2C.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This defines the types used to underly the standard nativeio Python objects. -// The shared API is defined in terms of these types. - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_I2C_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_I2C_H__ - -#include "shared-module/bitbangio/types.h" - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - bitbangio_i2c_obj_t bitbang; -} nativeio_i2c_obj_t; - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_I2C_H__ diff --git a/shared-module/nativeio/OneWire.c b/shared-module/nativeio/OneWire.c deleted file mode 100644 index 490f9b109..000000000 --- a/shared-module/nativeio/OneWire.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * This file is part of the Micro Python project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// Wraps the bitbangio implementation of OneWire for use in nativeio. -#include "common-hal/microcontroller/types.h" -#include "shared-bindings/bitbangio/OneWire.h" -#include "common-hal/nativeio/types.h" - -void common_hal_nativeio_onewire_construct(nativeio_onewire_obj_t* self, - const mcu_pin_obj_t* pin) { - shared_module_bitbangio_onewire_construct(&self->bitbang, pin); -} - -void common_hal_nativeio_onewire_deinit(nativeio_onewire_obj_t* self) { - shared_module_bitbangio_onewire_deinit(&self->bitbang); -} - -bool common_hal_nativeio_onewire_reset(nativeio_onewire_obj_t* self) { - return shared_module_bitbangio_onewire_reset(&self->bitbang); -} - -bool common_hal_nativeio_onewire_read_bit(nativeio_onewire_obj_t* self) { - return shared_module_bitbangio_onewire_read_bit(&self->bitbang); -} - -void common_hal_nativeio_onewire_write_bit(nativeio_onewire_obj_t* self, - bool bit) { - shared_module_bitbangio_onewire_write_bit(&self->bitbang, bit); -} diff --git a/shared-module/nativeio/OneWire.h b/shared-module/nativeio/OneWire.h deleted file mode 100644 index 3704c55a3..000000000 --- a/shared-module/nativeio/OneWire.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of the MicroPython project, http://micropython.org/ - * - * The MIT License (MIT) - * - * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -// This defines the types used to underly the standard nativeio Python objects. -// The shared API is defined in terms of these types. - -#ifndef __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_ONEWIRE_H__ -#define __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_ONEWIRE_H__ - -#include "shared-module/bitbangio/types.h" - -#include "py/obj.h" - -typedef struct { - mp_obj_base_t base; - bitbangio_onewire_obj_t bitbang; -} nativeio_onewire_obj_t; - -#endif // __MICROPY_INCLUDED_ATMEL_SAMD_SHARED_MODULE_NATIVEIO_ONEWIRE_H__ -- cgit v1.2.3