mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-04 15:07:46 +00:00
Compare commits
68 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| dbff576c9e | |||
| f0a260be66 | |||
| 06e298c514 | |||
| f2f470973d | |||
| 448598cbf8 | |||
| ec98f2dc2c | |||
| 2476cd7bd8 | |||
| 01fed475e1 | |||
| edfdd4e09e | |||
| 5e54f08605 | |||
| 880b958d64 | |||
| 24db8b4e2c | |||
| 6df9247f92 | |||
| 56fb346438 | |||
| 3d279d4d25 | |||
| 4a336f674c | |||
| 2d32995f6a | |||
| 9a98d1be55 | |||
| 02e4548966 | |||
| 45dce188f5 | |||
| b3c0315a09 | |||
| 0ced12683c | |||
| b4eb406a43 | |||
| 10bd48c39d | |||
| ad3ef92cfe | |||
| f7dce6ae22 | |||
| a15f2167cc | |||
| 5d5378a47c | |||
| 3ceb688663 | |||
| 941c1c9057 | |||
| d8c813d515 | |||
| 905fc6fce3 | |||
| 80913d5fe7 | |||
| b6c750ccd1 | |||
| 43899e1330 | |||
| 45c68ef0fc | |||
| 025a66655f | |||
| 121e8147f7 | |||
| b48bc5ac5d | |||
| 0d40c99d1f | |||
| bee7422c3a | |||
| 43099c5d5f | |||
| 0f9b9d873b | |||
| 114e24870e | |||
| b33c84ff78 | |||
| 966210f1b0 | |||
| 90a13a697b | |||
| d632eb888f | |||
| f6761a9079 | |||
| 51c3aa271b | |||
| 520234e9f8 | |||
| 334ed57373 | |||
| 3637033fec | |||
| 233866443c | |||
| 65fd7aa1a1 | |||
| 82e9e4a7f3 | |||
| 76ff632134 | |||
| cd2694e85f | |||
| 734adb6df8 | |||
| 2492fcb322 | |||
| 4f82c231cb | |||
| 2c9a05a413 | |||
| a89a26112e | |||
| bd42656644 | |||
| 94729a4f7d | |||
| 050cf4dbbc | |||
| 49c8810432 | |||
| 4b38841f71 |
+100
@@ -1,3 +1,103 @@
|
|||||||
|
0.20.0
|
||||||
|
---
|
||||||
|
- **new devices**
|
||||||
|
- irremote: Add basic infra-red driver
|
||||||
|
- IS31FL3731: add driver for IS31FL3731 matrix LED driver (#370)
|
||||||
|
- l3gd20: add gyro driver
|
||||||
|
- SSD1289: Driver for SSD1289 LCD
|
||||||
|
|
||||||
|
- **enhancements**
|
||||||
|
- **ili9341**
|
||||||
|
- add support for atsame5x
|
||||||
|
- added Feather board support to InitDisplay()
|
||||||
|
- avoid heap allocations
|
||||||
|
- **lps22hb**
|
||||||
|
- pin rename, sync with main repo
|
||||||
|
- **lsmXXX**
|
||||||
|
- unified, error handling, memory management
|
||||||
|
- **max7xx**
|
||||||
|
- Add a SetIntensity() function to max7xx driver and example
|
||||||
|
- **vl53l1x**
|
||||||
|
- Add functions for setting 'region of interest'
|
||||||
|
- Fix switch-case semantics
|
||||||
|
- **ws2812**
|
||||||
|
- add support for m5stamp-c3
|
||||||
|
- convert AVR assembly to C inline assembly
|
||||||
|
- support high-MHz ARMv6M chips like the RP2040
|
||||||
|
- write inline assembly using C instead of Go
|
||||||
|
|
||||||
|
- **bugfixes**
|
||||||
|
- **dht**
|
||||||
|
- fix error check in example
|
||||||
|
- fix humidity and temperature extraction for DHT22 (#358)
|
||||||
|
- **esp8266**
|
||||||
|
- fix ConnectToAccessPoint timeout args
|
||||||
|
- **image**
|
||||||
|
- fix interface
|
||||||
|
- **pca9685**
|
||||||
|
- add buffered one shot write
|
||||||
|
- fix on=0 bug
|
||||||
|
- **wifinina**
|
||||||
|
- correct sendParamStr to handle empty strings, such as when connecting to an unsecured access point
|
||||||
|
|
||||||
|
0.19.0
|
||||||
|
---
|
||||||
|
- **new devices**
|
||||||
|
- ft6336: add support for ft6336
|
||||||
|
- pca9685: PCA9685 driver
|
||||||
|
- shtc3: Sensirion SHTC3 Relative Humidity / Temperature i2c sensor
|
||||||
|
- sx126x: Driver for Semtech sx126x radio modules
|
||||||
|
- xpt2046: XPT2046 Touch driver (#350)
|
||||||
|
- **enhancements**
|
||||||
|
- **hd44780i2c**
|
||||||
|
- clean up for go fmt
|
||||||
|
- Needed fixes and update hd44780i2c.go
|
||||||
|
- **ili9341, ili9342**
|
||||||
|
- add support for m5stack
|
||||||
|
- add support for m5stack-core2
|
||||||
|
- **wifi**
|
||||||
|
- modify to use shared net.Adapter interface for all supported wifi devices
|
||||||
|
- wifinina: remove busy wait
|
||||||
|
- **bugfixes**
|
||||||
|
- **hd44780**
|
||||||
|
- fix 4-bit data length flag
|
||||||
|
- Reset data pins to output mode after reading
|
||||||
|
- Nano 33 BLE drivers (#351)
|
||||||
|
- **docs**
|
||||||
|
- examples/wifi: add unified example for tcpclient that compiles for all supported wifi adaptors
|
||||||
|
|
||||||
|
0.18.0
|
||||||
|
---
|
||||||
|
- **new devices**
|
||||||
|
- apds9960: add support for APDS-9960 Digital Proximity sensor
|
||||||
|
- axp192: add support for AXP192 single Cell Li-Battery and power system management IC
|
||||||
|
- hts221: add support for HTS221 capacitive digital sensor for relative humidity and temperature
|
||||||
|
- i2csoft: add support for software I2C
|
||||||
|
- image: add support for image/jpeg and image/png
|
||||||
|
- lps22hb: add support for LPS22HB MEMS nano pressure sensor
|
||||||
|
- lsm6dox: add support for lsm6dox accelerometer
|
||||||
|
- lsm9ds1: add support for lsm9ds1 accelerometer
|
||||||
|
- **enhancements**
|
||||||
|
- ili9341: change to use drivers.SPI interface
|
||||||
|
- **ws2812**
|
||||||
|
- generate assembly instead of handwriting it
|
||||||
|
- improve timings to be compatible with the WS2811
|
||||||
|
- add support for 168MHz (e.g. Adafruit Feather STM32F405)
|
||||||
|
- add support for RISC-V
|
||||||
|
- wifinina: control nina pins, for example leds
|
||||||
|
- **docs**
|
||||||
|
- rtl8720dn: examples for tcpclient, udpstation, mqtt, and webserver
|
||||||
|
- **wifinina**
|
||||||
|
- nina-fw update docs
|
||||||
|
- examples/wifinina/http-get
|
||||||
|
- ili9341: refactor examples
|
||||||
|
- Fix broken link for SHT3x datasheet
|
||||||
|
- **core**
|
||||||
|
- all: use build directives for both Go1.17 and earlier versions
|
||||||
|
- **bugfixes**
|
||||||
|
- net: fix raddr of tcp conn
|
||||||
|
- mcp3008: fix bitshift bug
|
||||||
|
|
||||||
0.17.1
|
0.17.1
|
||||||
---
|
---
|
||||||
- To correct an error in the release process. Same as 0.17.0.
|
- To correct an error in the release process. Same as 0.17.0.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2018-2021 The TinyGo Authors. All rights reserved.
|
Copyright (c) 2018-2022 The TinyGo Authors. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
|
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/apds9960/proximity/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
|
tinygo build -size short -o ./build/test.hex -target=itsybitsy-m0 ./examples/apa102/itsybitsy-m0/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/at24cx/main.go
|
||||||
@@ -63,6 +65,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
|
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/hd44780i2c/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/hts221/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/hub75/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
|
tinygo build -size short -o ./build/test.hex -target=pyportal ./examples/ili9341/basic
|
||||||
@@ -79,6 +83,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
|
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/lis3dh/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=nano-33-ble ./examples/lps22hb/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/lsm303agr/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
|
tinygo build -size short -o ./build/test.hex -target=arduino-nano33 ./examples/lsm6ds3/main.go
|
||||||
@@ -101,6 +107,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
|
tinygo build -size short -o ./build/test.hex -target=p1am-100 ./examples/p1am/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=pico ./examples/pca9685/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setbuffer/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/pcd8544/setpixel/main.go
|
||||||
@@ -111,6 +119,8 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/sht3x/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/shtc3/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/i2c_128x32/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
|
tinygo build -size short -o ./build/test.hex -target=microbit ./examples/ssd1306/spi_128x64/main.go
|
||||||
@@ -149,6 +159,10 @@ smoke-test:
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
|
tinygo build -size short -o ./build/test.hex -target=circuitplay-express ./examples/ws2812
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.bin -target=m5stamp-c3 ./examples/ws2812
|
||||||
|
@md5sum ./build/test.bin
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=feather-nrf52840 ./examples/is31fl3731/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
ifneq ($(AVR), 0)
|
ifneq ($(AVR), 0)
|
||||||
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/ws2812
|
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/ws2812
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
@@ -181,8 +195,8 @@ endif
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
|
tinygo build -size short -o ./build/test.hex -target=feather-m0 ./examples/dht/main.go
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=arduino ./examples/keypad4x4/main.go
|
# tinygo build -size short -o ./build/test.hex -target=arduino ./examples/keypad4x4/main.go
|
||||||
@md5sum ./build/test.hex
|
# @md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
|
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/alarm/
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
|
tinygo build -size short -o ./build/test.hex -target=xiao ./examples/pcf8563/clkout/
|
||||||
@@ -205,15 +219,32 @@ endif
|
|||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/mqttsub/
|
tinygo build -size short -o ./build/test.hex -target=wioterminal ./examples/rtl8720dn/mqttsub/
|
||||||
@md5sum ./build/test.hex
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=feather-m4 ./examples/i2csoft/adt7410/
|
||||||
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.elf -target=wioterminal ./examples/axp192/m5stack-core2-blinky/
|
||||||
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/xpt2046/main.go
|
||||||
|
@md5sum ./build/test.uf2
|
||||||
|
tinygo build -size short -o ./build/test.elf -target=m5stack-core2 ./examples/ft6336/basic/
|
||||||
|
@md5sum ./build/test.elf
|
||||||
|
tinygo build -size short -o ./build/test.elf -target=m5stack-core2 ./examples/ft6336/touchpaint/
|
||||||
|
@md5sum ./build/test.elf
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=nucleo-wl55jc ./examples/sx126x/lora_rxtx/
|
||||||
|
@md5sum ./build/test.hex
|
||||||
|
tinygo build -size short -o ./build/test.uf2 -target=pico ./examples/ssd1289/main.go
|
||||||
|
@md5sum ./build/test.uf2
|
||||||
|
tinygo build -size short -o ./build/test.hex -target=pico ./examples/irremote/main.go
|
||||||
|
@md5sum ./build/test.hex
|
||||||
|
|
||||||
DRIVERS = $(wildcard */)
|
DRIVERS = $(wildcard */)
|
||||||
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
|
NOTESTS = build examples flash semihosting pcd8544 shiftregister st7789 microphone mcp3008 gps microbitmatrix \
|
||||||
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
|
hcsr04 ssd1331 ws2812 thermistor apa102 easystepper ssd1351 ili9341 wifinina shifter hub75 \
|
||||||
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x dht keypad4x4 max72xx p1am tone tm1637 \
|
hd44780 buzzer ssd1306 espat l9110x st7735 bmi160 l293x keypad4x4 max72xx p1am tone tm1637 \
|
||||||
pcf8563 mcp2515 servo sdcard rtl8720dn image cmd
|
pcf8563 mcp2515 servo sdcard rtl8720dn image cmd i2csoft hts221 lps22hb apds9960 axp192 xpt2046 \
|
||||||
|
ft6336 sx126x ssd1289 irremote
|
||||||
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
|
TESTS = $(filter-out $(addsuffix /%,$(NOTESTS)),$(DRIVERS))
|
||||||
|
|
||||||
unit-test:
|
unit-test:
|
||||||
@go test -v $(addprefix ./,$(TESTS))
|
@go test -v $(addprefix ./,$(TESTS))
|
||||||
|
|
||||||
test: clean fmt-check unit-test smoke-test
|
test: clean fmt-check unit-test smoke-test
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ func main() {
|
|||||||
|
|
||||||
## Currently supported devices
|
## Currently supported devices
|
||||||
|
|
||||||
The following 67 devices are supported.
|
The following 78 devices are supported.
|
||||||
|
|
||||||
| Device Name | Interface Type |
|
| Device Name | Interface Type |
|
||||||
|----------|-------------|
|
|----------|-------------|
|
||||||
@@ -61,7 +61,9 @@ The following 67 devices are supported.
|
|||||||
| [AHT20 I2C Temperature and Humidity Sensor](http://www.aosong.com/userfiles/files/media/AHT20%20%E8%8B%B1%E6%96%87%E7%89%88%E8%AF%B4%E6%98%8E%E4%B9%A6%20A0%2020201222.pdf) | I2C |
|
| [AHT20 I2C Temperature and Humidity Sensor](http://www.aosong.com/userfiles/files/media/AHT20%20%E8%8B%B1%E6%96%87%E7%89%88%E8%AF%B4%E6%98%8E%E4%B9%A6%20A0%2020201222.pdf) | I2C |
|
||||||
| [AMG88xx 8x8 Thermal camera sensor](https://cdn-learn.adafruit.com/assets/assets/000/043/261/original/Grid-EYE_SPECIFICATIONS%28Reference%29.pdf) | I2C |
|
| [AMG88xx 8x8 Thermal camera sensor](https://cdn-learn.adafruit.com/assets/assets/000/043/261/original/Grid-EYE_SPECIFICATIONS%28Reference%29.pdf) | I2C |
|
||||||
| [APA102 RGB LED](https://cdn-shop.adafruit.com/product-files/2343/APA102C.pdf) | SPI |
|
| [APA102 RGB LED](https://cdn-shop.adafruit.com/product-files/2343/APA102C.pdf) | SPI |
|
||||||
|
| [APDS9960 Digital proximity, ambient light, RGB and gesture sensor](https://cdn.sparkfun.com/assets/learn_tutorials/3/2/1/Avago-APDS-9960-datasheet.pdf) | I2C |
|
||||||
| [AT24CX 2-wire serial EEPROM](https://www.openimpulse.com/blog/wp-content/uploads/wpsc/downloadables/24C32-Datasheet.pdf) | I2C |
|
| [AT24CX 2-wire serial EEPROM](https://www.openimpulse.com/blog/wp-content/uploads/wpsc/downloadables/24C32-Datasheet.pdf) | I2C |
|
||||||
|
| [AXP192 single Cell Li-Battery and Power System Management](https://github.com/m5stack/M5-Schematic/blob/master/Core/AXP192%20Datasheet_v1.1_en_draft_2211.pdf) | I2C |
|
||||||
| [BBC micro:bit LED matrix](https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf) | GPIO |
|
| [BBC micro:bit LED matrix](https://github.com/bbcmicrobit/hardware/blob/master/SCH_BBC-Microbit_V1.3B.pdf) | GPIO |
|
||||||
| [BH1750 ambient light sensor](https://www.mouser.com/ds/2/348/bh1750fvi-e-186247.pdf) | I2C |
|
| [BH1750 ambient light sensor](https://www.mouser.com/ds/2/348/bh1750fvi-e-186247.pdf) | I2C |
|
||||||
| [BlinkM RGB LED](http://thingm.com/fileadmin/thingm/downloads/BlinkM_datasheet.pdf) | I2C |
|
| [BlinkM RGB LED](http://thingm.com/fileadmin/thingm/downloads/BlinkM_datasheet.pdf) | I2C |
|
||||||
@@ -76,23 +78,32 @@ The following 67 devices are supported.
|
|||||||
| [DS3231 real time clock](https://datasheets.maximintegrated.com/en/ds/DS3231.pdf) | I2C |
|
| [DS3231 real time clock](https://datasheets.maximintegrated.com/en/ds/DS3231.pdf) | I2C |
|
||||||
| [ESP32 as WiFi Coprocessor with Arduino nina-fw](https://github.com/arduino/nina-fw) | SPI |
|
| [ESP32 as WiFi Coprocessor with Arduino nina-fw](https://github.com/arduino/nina-fw) | SPI |
|
||||||
| [ESP8266/ESP32 AT Command set for WiFi/TCP/UDP](https://github.com/espressif/esp32-at) | UART |
|
| [ESP8266/ESP32 AT Command set for WiFi/TCP/UDP](https://github.com/espressif/esp32-at) | UART |
|
||||||
|
| [FT6336 touch controller](https://focuslcds.com/content/FT6236.pdf) | I2C |
|
||||||
| [GPS module](https://www.u-blox.com/en/product/neo-6-series) | I2C/UART |
|
| [GPS module](https://www.u-blox.com/en/product/neo-6-series) | I2C/UART |
|
||||||
| [HC-SR04 Ultrasonic distance sensor](https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf) | GPIO |
|
| [HC-SR04 Ultrasonic distance sensor](https://cdn.sparkfun.com/datasheets/Sensors/Proximity/HCSR04.pdf) | GPIO |
|
||||||
| [HD44780 LCD controller](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | GPIO/I2C |
|
| [HD44780 LCD controller](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) | GPIO/I2C |
|
||||||
|
| [HTS221 digital humidity and temperature sensor](https://www.st.com/resource/en/datasheet/hts221.pdf) | I2C |
|
||||||
| [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI |
|
| [HUB75 RGB led matrix](https://cdn-learn.adafruit.com/downloads/pdf/32x16-32x32-rgb-led-matrix.pdf) | SPI |
|
||||||
|
| [software I2C driver](https://www.ti.com/lit/an/slva704/slva704.pdf) | GPIO |
|
||||||
| [ILI9341 TFT color display](https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf) | SPI |
|
| [ILI9341 TFT color display](https://cdn-shop.adafruit.com/datasheets/ILI9341.pdf) | SPI |
|
||||||
| [INA260 Volt/Amp/Power meter](https://www.ti.com/lit/ds/symlink/ina260.pdf) | I2C |
|
| [INA260 Volt/Amp/Power meter](https://www.ti.com/lit/ds/symlink/ina260.pdf) | I2C |
|
||||||
|
| [Infrared remote control](https://en.wikipedia.org/wiki/Consumer_IR) | GPIO |
|
||||||
|
| [IS31FL3731 matrix LED driver](https://www.lumissil.com/assets/pdf/core/IS31FL3731_DS.pdf) | I2C |
|
||||||
| [4x4 Membrane Keypad](https://cdn.sparkfun.com/assets/f/f/a/5/0/DS-16038.pdf) | GPIO |
|
| [4x4 Membrane Keypad](https://cdn.sparkfun.com/assets/f/f/a/5/0/DS-16038.pdf) | GPIO |
|
||||||
| [L293x motor driver](https://www.ti.com/lit/ds/symlink/l293d.pdf) | GPIO/PWM |
|
| [L293x motor driver](https://www.ti.com/lit/ds/symlink/l293d.pdf) | GPIO/PWM |
|
||||||
| [L9110x motor driver](https://www.elecrow.com/download/datasheet-l9110.pdf) | GPIO/PWM |
|
| [L9110x motor driver](https://www.elecrow.com/download/datasheet-l9110.pdf) | GPIO/PWM |
|
||||||
| [LIS2MDL magnetometer](https://www.st.com/resource/en/datasheet/lis2mdl.pdf) | I2C |
|
| [LIS2MDL magnetometer](https://www.st.com/resource/en/datasheet/lis2mdl.pdf) | I2C |
|
||||||
| [LIS3DH accelerometer](https://www.st.com/resource/en/datasheet/lis3dh.pdf) | I2C |
|
| [LIS3DH accelerometer](https://www.st.com/resource/en/datasheet/lis3dh.pdf) | I2C |
|
||||||
|
| [LPS22HB MEMS nano pressure sensor](https://www.st.com/resource/en/datasheet/dm00140895.pdf) | I2C |
|
||||||
| [LSM6DS3 accelerometer](https://www.st.com/resource/en/datasheet/lsm6ds3.pdf) | I2C |
|
| [LSM6DS3 accelerometer](https://www.st.com/resource/en/datasheet/lsm6ds3.pdf) | I2C |
|
||||||
|
| [LSM6DSOX accelerometer](https://www.st.com/resource/en/datasheet/lsm6dsox.pdf) | I2C |
|
||||||
|
| [LSM303AGR accelerometer](https://www.st.com/resource/en/datasheet/lsm303agr.pdf) | I2C |
|
||||||
|
| [LSM9DS1 accelerometer](https://www.st.com/resource/en/datasheet/lsm9ds1.pdf) | I2C |
|
||||||
| [MAG3110 magnetometer](https://www.nxp.com/docs/en/data-sheet/MAG3110.pdf) | I2C |
|
| [MAG3110 magnetometer](https://www.nxp.com/docs/en/data-sheet/MAG3110.pdf) | I2C |
|
||||||
| [MAX7219 & MAX7221 display driver](https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf) | SPI |
|
| [MAX7219 & MAX7221 display driver](https://datasheets.maximintegrated.com/en/ds/MAX7219-MAX7221.pdf) | SPI |
|
||||||
| [MCP23017 port expander](https://ww1.microchip.com/downloads/en/DeviceDoc/20001952C.pdf) | I2C |
|
|
||||||
| [MCP3008 analog to digital converter (ADC)](http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf) | SPI |
|
|
||||||
| [MCP2515 Stand-Alone CAN Controller with SPI Interface](https://ww1.microchip.com/downloads/en/DeviceDoc/MCP2515-Family-Data-Sheet-DS20001801K.pdf) | SPI |
|
| [MCP2515 Stand-Alone CAN Controller with SPI Interface](https://ww1.microchip.com/downloads/en/DeviceDoc/MCP2515-Family-Data-Sheet-DS20001801K.pdf) | SPI |
|
||||||
|
| [MCP3008 analog to digital converter (ADC)](http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf) | SPI |
|
||||||
|
| [MCP23017 port expander](https://ww1.microchip.com/downloads/en/DeviceDoc/20001952C.pdf) | I2C |
|
||||||
| [Microphone - PDM](https://cdn-learn.adafruit.com/assets/assets/000/049/977/original/MP34DT01-M.pdf) | I2S/PDM |
|
| [Microphone - PDM](https://cdn-learn.adafruit.com/assets/assets/000/049/977/original/MP34DT01-M.pdf) | I2S/PDM |
|
||||||
| [MMA8653 accelerometer](https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf) | I2C |
|
| [MMA8653 accelerometer](https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf) | I2C |
|
||||||
| [MPU6050 accelerometer/gyroscope](https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf) | I2C |
|
| [MPU6050 accelerometer/gyroscope](https://store.invensense.com/datasheets/invensense/MPU-6050_DataSheet_V3%204.pdf) | I2C |
|
||||||
@@ -105,7 +116,8 @@ The following 67 devices are supported.
|
|||||||
| [Servo](https://learn.sparkfun.com/tutorials/hobby-servo-tutorial/all) | PWM |
|
| [Servo](https://learn.sparkfun.com/tutorials/hobby-servo-tutorial/all) | PWM |
|
||||||
| [Shift register (PISO)](https://en.wikipedia.org/wiki/Shift_register#Parallel-in_serial-out_\(PISO\)) | GPIO |
|
| [Shift register (PISO)](https://en.wikipedia.org/wiki/Shift_register#Parallel-in_serial-out_\(PISO\)) | GPIO |
|
||||||
| [Shift registers (SIPO)](https://en.wikipedia.org/wiki/Shift_register#Serial-in_parallel-out_(SIPO)) | GPIO |
|
| [Shift registers (SIPO)](https://en.wikipedia.org/wiki/Shift_register#Serial-in_parallel-out_(SIPO)) | GPIO |
|
||||||
| [SHT3x Digital Humidity Sensor](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/0_Datasheets/Humidity/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf) | I2C |
|
| [SHT3x Digital Humidity Sensor](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Datasheets/Sensirion_Humidity_Sensors_SHT3x_Datasheet_digital.pdf) | I2C |
|
||||||
|
| [SHTC3 Digital Humidity Sensor (RH/T)](https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/2_Humidity_Sensors/Datasheets/Sensirion_Humidity_Sensors_SHTC3_Datasheet.pdf) | I2C |
|
||||||
| [SPI NOR Flash Memory](https://en.wikipedia.org/wiki/Flash_memory#NOR_flash) | SPI/QSPI |
|
| [SPI NOR Flash Memory](https://en.wikipedia.org/wiki/Flash_memory#NOR_flash) | SPI/QSPI |
|
||||||
| [SPI SDCARD/MMC](https://en.wikipedia.org/wiki/SD_card) | SPI |
|
| [SPI SDCARD/MMC](https://en.wikipedia.org/wiki/SD_card) | SPI |
|
||||||
| [SSD1306 OLED display](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) | I2C / SPI |
|
| [SSD1306 OLED display](https://cdn-shop.adafruit.com/datasheets/SSD1306.pdf) | I2C / SPI |
|
||||||
@@ -123,6 +135,9 @@ The following 67 devices are supported.
|
|||||||
| [Waveshare 2.13" e-paper display](https://www.waveshare.com/w/upload/e/e6/2.13inch_e-Paper_Datasheet.pdf) | SPI |
|
| [Waveshare 2.13" e-paper display](https://www.waveshare.com/w/upload/e/e6/2.13inch_e-Paper_Datasheet.pdf) | SPI |
|
||||||
| [Waveshare 4.2" e-paper B/W display](https://www.waveshare.com/w/upload/6/6a/4.2inch-e-paper-specification.pdf) | SPI |
|
| [Waveshare 4.2" e-paper B/W display](https://www.waveshare.com/w/upload/6/6a/4.2inch-e-paper-specification.pdf) | SPI |
|
||||||
| [WS2812 RGB LED](https://cdn-shop.adafruit.com/datasheets/WS2812.pdf) | GPIO |
|
| [WS2812 RGB LED](https://cdn-shop.adafruit.com/datasheets/WS2812.pdf) | GPIO |
|
||||||
|
| [XPT2046 touch controller](http://grobotronics.com/images/datasheets/xpt2046-datasheet.pdf) | GPIO |
|
||||||
|
| [Semtech SX126x Lora](https://www.semtech.com/products/wireless-rf/lora-transceiv-ers/sx1261) | SPI |
|
||||||
|
| [SSD1289 TFT color display](http://aitendo3.sakura.ne.jp/aitendo_data/product_img/lcd/tft2/M032C1289TP/3.2-SSD1289.pdf) | GPIO |
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,468 @@
|
|||||||
|
// Package apds9960 implements a driver for APDS-9960,
|
||||||
|
// a digital proximity, ambient light, RGB and gesture sensor.
|
||||||
|
//
|
||||||
|
// Datasheet: https://cdn.sparkfun.com/assets/learn_tutorials/3/2/1/Avago-APDS-9960-datasheet.pdf
|
||||||
|
//
|
||||||
|
package apds9960
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device wraps an I2C connection to a APDS-9960 device.
|
||||||
|
type Device struct {
|
||||||
|
bus drivers.I2C
|
||||||
|
Address uint8
|
||||||
|
mode uint8
|
||||||
|
gesture gestureData
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration for APDS-9960 device.
|
||||||
|
type Configuration struct {
|
||||||
|
ProximityPulseLength uint8
|
||||||
|
ProximityPulseCount uint8
|
||||||
|
GesturePulseLength uint8
|
||||||
|
GesturePulseCount uint8
|
||||||
|
ProximityGain uint8
|
||||||
|
GestureGain uint8
|
||||||
|
ColorGain uint8
|
||||||
|
ADCIntegrationCycles uint16
|
||||||
|
LEDBoost uint16
|
||||||
|
threshold uint8
|
||||||
|
sensitivity uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// for gesture-related data
|
||||||
|
type gestureData struct {
|
||||||
|
detected uint8
|
||||||
|
threshold uint8
|
||||||
|
sensitivity uint8
|
||||||
|
gXDelta int16
|
||||||
|
gYDelta int16
|
||||||
|
gXPrevDelta int16
|
||||||
|
gYPrevDelta int16
|
||||||
|
received bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// for enabling various device function
|
||||||
|
type enableConfig struct {
|
||||||
|
GEN bool
|
||||||
|
PIEN bool
|
||||||
|
AIEN bool
|
||||||
|
WEN bool
|
||||||
|
PEN bool
|
||||||
|
AEN bool
|
||||||
|
PON bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new APDS-9960 connection. The I2C bus must already be
|
||||||
|
// configured.
|
||||||
|
//
|
||||||
|
// This function only creates the Device object, it does not touch the device.
|
||||||
|
func New(bus drivers.I2C) Device {
|
||||||
|
return Device{bus: bus, Address: ADPS9960_ADDRESS, mode: MODE_NONE}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connected returns whether APDS-9960 has been found.
|
||||||
|
// It does a "who am I" request and checks the response.
|
||||||
|
func (d *Device) Connected() bool {
|
||||||
|
data := []byte{0}
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_ID_REG, data)
|
||||||
|
return data[0] == 0xAB
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetMode returns current engine mode
|
||||||
|
func (d *Device) GetMode() uint8 {
|
||||||
|
return d.mode
|
||||||
|
}
|
||||||
|
|
||||||
|
// DisableAll turns off the device and all functions
|
||||||
|
func (d *Device) DisableAll() {
|
||||||
|
d.enable(enableConfig{})
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_GCONF4_REG, []byte{0x00})
|
||||||
|
d.mode = MODE_NONE
|
||||||
|
d.gesture.detected = GESTURE_NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetProximityPulse sets proximity pulse length (4, 8, 16, 32) and count (1~64)
|
||||||
|
// default: 16, 64
|
||||||
|
func (d *Device) SetProximityPulse(length, count uint8) {
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_PPULSE_REG, []byte{getPulseLength(length)<<6 | getPulseCount(count)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGesturePulse sets gesture pulse length (4, 8, 16, 32) and count (1~64)
|
||||||
|
// default: 16, 64
|
||||||
|
func (d *Device) SetGesturePulse(length, count uint8) {
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_GPULSE_REG, []byte{getPulseLength(length)<<6 | getPulseCount(count)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetADCIntegrationCycles sets ALS/color ADC internal integration cycles (1~256, 1 cycle = 2.78 ms)
|
||||||
|
// default: 4 (~10 ms)
|
||||||
|
func (d *Device) SetADCIntegrationCycles(cycles uint16) {
|
||||||
|
if cycles > 256 {
|
||||||
|
cycles = 256
|
||||||
|
}
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_ATIME_REG, []byte{uint8(256 - cycles)})
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGains sets proximity/gesture gain (1, 2, 4, 8x) and ALS/color gain (1, 4, 16, 64x)
|
||||||
|
// default: 1, 1, 4
|
||||||
|
func (d *Device) SetGains(proximityGain, gestureGain, colorGain uint8) {
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_CONTROL_REG, []byte{getProximityGain(proximityGain)<<2 | getALSGain(colorGain)})
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_GCONF2_REG, []byte{getProximityGain(gestureGain) << 5})
|
||||||
|
}
|
||||||
|
|
||||||
|
// LEDBoost sets proximity and gesture LED current level (100, 150, 200, 300 (%))
|
||||||
|
// default: 100
|
||||||
|
func (d *Device) LEDBoost(percent uint16) {
|
||||||
|
var v uint8
|
||||||
|
switch percent {
|
||||||
|
case 100:
|
||||||
|
v = 0
|
||||||
|
case 150:
|
||||||
|
v = 1
|
||||||
|
case 200:
|
||||||
|
v = 2
|
||||||
|
case 300:
|
||||||
|
v = 3
|
||||||
|
}
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_CONFIG2_REG, []byte{0x01 | v<<4})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setthreshold sets threshold (0~255) for detecting gestures
|
||||||
|
// default: 30
|
||||||
|
func (d *Device) Setthreshold(t uint8) {
|
||||||
|
d.gesture.threshold = t
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setsensitivity sets sensivity (0~100) for detecting gestures
|
||||||
|
// default: 20
|
||||||
|
func (d *Device) Setsensitivity(s uint8) {
|
||||||
|
if s > 100 {
|
||||||
|
s = 100
|
||||||
|
}
|
||||||
|
d.gesture.sensitivity = 100 - s
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableProximity starts the proximity engine
|
||||||
|
func (d *Device) EnableProximity() {
|
||||||
|
if d.mode != MODE_NONE {
|
||||||
|
d.DisableAll()
|
||||||
|
}
|
||||||
|
d.enable(enableConfig{PON: true, PEN: true, WEN: true})
|
||||||
|
d.mode = MODE_PROXIMITY
|
||||||
|
}
|
||||||
|
|
||||||
|
// ProximityAvailable reports if proximity data is available
|
||||||
|
func (d *Device) ProximityAvailable() bool {
|
||||||
|
if d.mode == MODE_PROXIMITY && d.readStatus("PVALID") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadProximity reads proximity data (0~255)
|
||||||
|
func (d *Device) ReadProximity() (proximity int32) {
|
||||||
|
if d.mode != MODE_PROXIMITY {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
data := []byte{0}
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_PDATA_REG, data)
|
||||||
|
return 255 - int32(data[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableColor starts the color engine
|
||||||
|
func (d *Device) EnableColor() {
|
||||||
|
if d.mode != MODE_NONE {
|
||||||
|
d.DisableAll()
|
||||||
|
}
|
||||||
|
d.enable(enableConfig{PON: true, AEN: true, WEN: true})
|
||||||
|
d.mode = MODE_COLOR
|
||||||
|
}
|
||||||
|
|
||||||
|
// ColorAvailable reports if color data is available
|
||||||
|
func (d *Device) ColorAvailable() bool {
|
||||||
|
if d.mode == MODE_COLOR && d.readStatus("AVALID") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadColor reads color data (red, green, blue, clear color/brightness)
|
||||||
|
func (d *Device) ReadColor() (r int32, g int32, b int32, clear int32) {
|
||||||
|
if d.mode != MODE_COLOR {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data := []byte{0, 0, 0, 0, 0, 0, 0, 0}
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_CDATAL_REG, data[:1])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_CDATAH_REG, data[1:2])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_RDATAL_REG, data[2:3])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_RDATAH_REG, data[3:4])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GDATAL_REG, data[4:5])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GDATAH_REG, data[5:6])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_BDATAL_REG, data[6:7])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_BDATAH_REG, data[7:])
|
||||||
|
clear = int32(uint16(data[1])<<8 | uint16(data[0]))
|
||||||
|
r = int32(uint16(data[3])<<8 | uint16(data[2]))
|
||||||
|
g = int32(uint16(data[5])<<8 | uint16(data[4]))
|
||||||
|
b = int32(uint16(data[7])<<8 | uint16(data[6]))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnableGesture starts the gesture engine
|
||||||
|
func (d *Device) EnableGesture() {
|
||||||
|
if d.mode != MODE_NONE {
|
||||||
|
d.DisableAll()
|
||||||
|
}
|
||||||
|
d.enable(enableConfig{PON: true, PEN: true, GEN: true, WEN: true})
|
||||||
|
d.mode = MODE_GESTURE
|
||||||
|
d.gesture.detected = GESTURE_NONE
|
||||||
|
d.gesture.gXDelta = 0
|
||||||
|
d.gesture.gYDelta = 0
|
||||||
|
d.gesture.gXPrevDelta = 0
|
||||||
|
d.gesture.gYPrevDelta = 0
|
||||||
|
d.gesture.received = false
|
||||||
|
}
|
||||||
|
|
||||||
|
// GestureAvailable reports if gesture data is available
|
||||||
|
func (d *Device) GestureAvailable() bool {
|
||||||
|
if d.mode != MODE_GESTURE {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
data := []byte{0, 0, 0, 0}
|
||||||
|
|
||||||
|
// check GVALID
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GSTATUS_REG, data[:1])
|
||||||
|
if data[0]&0x01 == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// get number of data sets available in FIFO
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GFLVL_REG, data[:1])
|
||||||
|
availableDataSets := data[0]
|
||||||
|
if availableDataSets == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// read up, down, left and right proximity data from FIFO
|
||||||
|
var dataSets [32][4]uint8
|
||||||
|
for i := uint8(0); i < availableDataSets; i++ {
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GFIFO_U_REG, data[:1])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GFIFO_D_REG, data[1:2])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GFIFO_L_REG, data[2:3])
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_GFIFO_R_REG, data[3:4])
|
||||||
|
for j := uint8(0); j < 4; j++ {
|
||||||
|
dataSets[i][j] = data[j]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// gesture detection process
|
||||||
|
d.gesture.detected = GESTURE_NONE
|
||||||
|
for i := uint8(0); i < availableDataSets; i++ {
|
||||||
|
U := dataSets[i][0]
|
||||||
|
D := dataSets[i][1]
|
||||||
|
L := dataSets[i][2]
|
||||||
|
R := dataSets[i][3]
|
||||||
|
|
||||||
|
// if all readings fall below threshold, it's possible that
|
||||||
|
// a movement's just been made
|
||||||
|
if U < d.gesture.threshold && D < d.gesture.threshold && L < d.gesture.threshold && R < d.gesture.threshold {
|
||||||
|
d.gesture.received = true
|
||||||
|
// if there were movement in the previous step (including the last data sets)
|
||||||
|
if d.gesture.gXPrevDelta != 0 && d.gesture.gYPrevDelta != 0 {
|
||||||
|
totalX := d.gesture.gXPrevDelta - d.gesture.gXDelta
|
||||||
|
totalY := d.gesture.gYPrevDelta - d.gesture.gYDelta
|
||||||
|
// if previous and current movement are in opposite directions (pass through one led then next)
|
||||||
|
// and the difference is big enough, the gesture is recorded
|
||||||
|
switch {
|
||||||
|
case totalX < -int16(d.gesture.sensitivity):
|
||||||
|
d.gesture.detected = GESTURE_LEFT
|
||||||
|
case totalX > int16(d.gesture.sensitivity):
|
||||||
|
d.gesture.detected = GESTURE_RIGHT
|
||||||
|
case totalY > int16(d.gesture.sensitivity):
|
||||||
|
d.gesture.detected = GESTURE_DOWN
|
||||||
|
case totalY < -int16(d.gesture.sensitivity):
|
||||||
|
d.gesture.detected = GESTURE_UP
|
||||||
|
}
|
||||||
|
d.gesture.gXDelta = 0
|
||||||
|
d.gesture.gYDelta = 0
|
||||||
|
d.gesture.gXPrevDelta = 0
|
||||||
|
d.gesture.gYPrevDelta = 0
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// recording current movement
|
||||||
|
d.gesture.gXDelta = int16(R) - int16(L)
|
||||||
|
d.gesture.gYDelta = int16(D) - int16(U)
|
||||||
|
if d.gesture.received {
|
||||||
|
d.gesture.received = false
|
||||||
|
d.gesture.gXPrevDelta = d.gesture.gXDelta
|
||||||
|
d.gesture.gYPrevDelta = d.gesture.gYDelta
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return d.gesture.detected != GESTURE_NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadGesture reads last gesture data
|
||||||
|
func (d *Device) ReadGesture() (gesture int32) {
|
||||||
|
return int32(d.gesture.detected)
|
||||||
|
}
|
||||||
|
|
||||||
|
// private functions
|
||||||
|
|
||||||
|
func (d *Device) configureDevice(cfg Configuration) {
|
||||||
|
d.DisableAll() // turn off everything
|
||||||
|
|
||||||
|
// "default" settings
|
||||||
|
if cfg.ProximityPulseLength == 0 {
|
||||||
|
cfg.ProximityPulseLength = 16
|
||||||
|
}
|
||||||
|
if cfg.ProximityPulseCount == 0 {
|
||||||
|
cfg.ProximityPulseCount = 64
|
||||||
|
}
|
||||||
|
if cfg.GesturePulseLength == 0 {
|
||||||
|
cfg.GesturePulseLength = 16
|
||||||
|
}
|
||||||
|
if cfg.GesturePulseCount == 0 {
|
||||||
|
cfg.GesturePulseCount = 64
|
||||||
|
}
|
||||||
|
if cfg.ProximityGain == 0 {
|
||||||
|
cfg.ProximityGain = 1
|
||||||
|
}
|
||||||
|
if cfg.GestureGain == 0 {
|
||||||
|
cfg.GestureGain = 1
|
||||||
|
}
|
||||||
|
if cfg.ColorGain == 0 {
|
||||||
|
cfg.ColorGain = 4
|
||||||
|
}
|
||||||
|
if cfg.ADCIntegrationCycles == 0 {
|
||||||
|
cfg.ADCIntegrationCycles = 4
|
||||||
|
}
|
||||||
|
if cfg.threshold == 0 {
|
||||||
|
d.gesture.threshold = 30
|
||||||
|
}
|
||||||
|
if cfg.sensitivity == 0 {
|
||||||
|
d.gesture.sensitivity = 20
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetProximityPulse(cfg.ProximityPulseLength, cfg.ProximityPulseCount)
|
||||||
|
d.SetGesturePulse(cfg.GesturePulseLength, cfg.GesturePulseCount)
|
||||||
|
d.SetGains(cfg.ProximityGain, cfg.GestureGain, cfg.ColorGain)
|
||||||
|
d.SetADCIntegrationCycles(cfg.ADCIntegrationCycles)
|
||||||
|
|
||||||
|
if cfg.LEDBoost > 0 {
|
||||||
|
d.LEDBoost(cfg.LEDBoost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) enable(cfg enableConfig) {
|
||||||
|
var gen, pien, aien, wen, pen, aen, pon uint8
|
||||||
|
|
||||||
|
if cfg.GEN {
|
||||||
|
gen = 1
|
||||||
|
}
|
||||||
|
if cfg.PIEN {
|
||||||
|
pien = 1
|
||||||
|
}
|
||||||
|
if cfg.AIEN {
|
||||||
|
aien = 1
|
||||||
|
}
|
||||||
|
if cfg.WEN {
|
||||||
|
wen = 1
|
||||||
|
}
|
||||||
|
if cfg.PEN {
|
||||||
|
pen = 1
|
||||||
|
}
|
||||||
|
if cfg.AEN {
|
||||||
|
aen = 1
|
||||||
|
}
|
||||||
|
if cfg.PON {
|
||||||
|
pon = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
data := []byte{gen<<6 | pien<<5 | aien<<4 | wen<<3 | pen<<2 | aen<<1 | pon}
|
||||||
|
d.bus.WriteRegister(d.Address, APDS9960_ENABLE_REG, data)
|
||||||
|
|
||||||
|
if cfg.PON {
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) readStatus(param string) bool {
|
||||||
|
data := []byte{0}
|
||||||
|
d.bus.ReadRegister(d.Address, APDS9960_STATUS_REG, data)
|
||||||
|
|
||||||
|
switch param {
|
||||||
|
case "CPSAT":
|
||||||
|
return data[0]>>7&0x01 == 1
|
||||||
|
case "PGSAT":
|
||||||
|
return data[0]>>6&0x01 == 1
|
||||||
|
case "PINT":
|
||||||
|
return data[0]>>5&0x01 == 1
|
||||||
|
case "AINT":
|
||||||
|
return data[0]>>4&0x01 == 1
|
||||||
|
case "PVALID":
|
||||||
|
return data[0]>>1&0x01 == 1
|
||||||
|
case "AVALID":
|
||||||
|
return data[0]&0x01 == 1
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPulseLength(l uint8) uint8 {
|
||||||
|
switch l {
|
||||||
|
case 4:
|
||||||
|
return 0
|
||||||
|
case 8:
|
||||||
|
return 1
|
||||||
|
case 16:
|
||||||
|
return 2
|
||||||
|
case 32:
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getPulseCount(c uint8) uint8 {
|
||||||
|
if c < 1 && c > 64 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return c - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func getProximityGain(g uint8) uint8 {
|
||||||
|
switch g {
|
||||||
|
case 1:
|
||||||
|
return 0
|
||||||
|
case 2:
|
||||||
|
return 1
|
||||||
|
case 4:
|
||||||
|
return 2
|
||||||
|
case 8:
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getALSGain(g uint8) uint8 {
|
||||||
|
switch g {
|
||||||
|
case 1:
|
||||||
|
return 0
|
||||||
|
case 4:
|
||||||
|
return 1
|
||||||
|
case 16:
|
||||||
|
return 2
|
||||||
|
case 64:
|
||||||
|
return 3
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
//go:build !nano_33_ble
|
||||||
|
// +build !nano_33_ble
|
||||||
|
|
||||||
|
package apds9960
|
||||||
|
|
||||||
|
import "tinygo.org/x/drivers"
|
||||||
|
|
||||||
|
// Configure sets up the APDS-9960 device.
|
||||||
|
func (d *Device) Configure(cfg Configuration) {
|
||||||
|
// configure device
|
||||||
|
d.configureDevice(cfg)
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//go:build nano_33_ble
|
||||||
|
// +build nano_33_ble
|
||||||
|
|
||||||
|
package apds9960
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Configure sets up the APDS-9960 device.
|
||||||
|
func (d *Device) Configure(cfg Configuration) {
|
||||||
|
|
||||||
|
// Following lines are Nano 33 BLE specific, they have nothing to do with sensor per se
|
||||||
|
machine.LSM_PWR.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.LSM_PWR.High()
|
||||||
|
machine.I2C_PULLUP.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.I2C_PULLUP.High()
|
||||||
|
// Wait a moment
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
|
|
||||||
|
// configure device
|
||||||
|
d.configureDevice(cfg)
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package apds9960
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// I2C address
|
||||||
|
ADPS9960_ADDRESS = 0x39
|
||||||
|
|
||||||
|
// control/status registers
|
||||||
|
APDS9960_RAM_REG = 0x00
|
||||||
|
APDS9960_ENABLE_REG = 0x80
|
||||||
|
APDS9960_ATIME_REG = 0x81
|
||||||
|
APDS9960_WTIME_REG = 0x83
|
||||||
|
APDS9960_AILTIL_REG = 0x84
|
||||||
|
APDS9960_AILTH_REG = 0x85
|
||||||
|
APDS9960_AIHTL_REG = 0x86
|
||||||
|
APDS9960_AIHTH_REG = 0x87
|
||||||
|
APDS9960_PILT_REG = 0x89
|
||||||
|
APDS9960_PIHT_REG = 0x8B
|
||||||
|
APDS9960_PERS_REG = 0x8C
|
||||||
|
APDS9960_CONFIG1_REG = 0x8D
|
||||||
|
APDS9960_PPULSE_REG = 0x8E
|
||||||
|
APDS9960_CONTROL_REG = 0x8F
|
||||||
|
APDS9960_CONFIG2_REG = 0x90
|
||||||
|
APDS9960_ID_REG = 0x92
|
||||||
|
APDS9960_STATUS_REG = 0x93
|
||||||
|
APDS9960_CDATAL_REG = 0x94
|
||||||
|
APDS9960_CDATAH_REG = 0x95
|
||||||
|
APDS9960_RDATAL_REG = 0x96
|
||||||
|
APDS9960_RDATAH_REG = 0x97
|
||||||
|
APDS9960_GDATAL_REG = 0x98
|
||||||
|
APDS9960_GDATAH_REG = 0x99
|
||||||
|
APDS9960_BDATAL_REG = 0x9A
|
||||||
|
APDS9960_BDATAH_REG = 0x9B
|
||||||
|
APDS9960_PDATA_REG = 0x9C
|
||||||
|
APDS9960_POFFSET_UR_REG = 0x9D
|
||||||
|
APDS9960_POFFSET_DL_REG = 0x9E
|
||||||
|
APDS9960_CONFIG3_REG = 0x9F
|
||||||
|
APDS9960_GPENTH_REG = 0xA0
|
||||||
|
APDS9960_GEXTH_REG = 0xA1
|
||||||
|
APDS9960_GCONF1_REG = 0xA2
|
||||||
|
APDS9960_GCONF2_REG = 0xA3
|
||||||
|
APDS9960_GOFFSET_U_REG = 0xA4
|
||||||
|
APDS9960_GOFFSET_D_REG = 0xA5
|
||||||
|
APDS9960_GOFFSET_L_REG = 0xA7
|
||||||
|
APDS9960_GOFFSET_R_REG = 0xA9
|
||||||
|
APDS9960_GPULSE_REG = 0xA6
|
||||||
|
APDS9960_GCONF3_REG = 0xAA
|
||||||
|
APDS9960_GCONF4_REG = 0xAB
|
||||||
|
APDS9960_GFLVL_REG = 0xAE
|
||||||
|
APDS9960_GSTATUS_REG = 0xAF
|
||||||
|
APDS9960_IFORCE_REG = 0xE4
|
||||||
|
APDS9960_PICLEAR_REG = 0xE5
|
||||||
|
APDS9960_CICLEAR_REG = 0xE6
|
||||||
|
APDS9960_AICLEAR_REG = 0xE7
|
||||||
|
APDS9960_GFIFO_U_REG = 0xFC
|
||||||
|
APDS9960_GFIFO_D_REG = 0xFD
|
||||||
|
APDS9960_GFIFO_L_REG = 0xFE
|
||||||
|
APDS9960_GFIFO_R_REG = 0xFF
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// sensor modes
|
||||||
|
MODE_NONE = iota
|
||||||
|
MODE_PROXIMITY
|
||||||
|
MODE_COLOR
|
||||||
|
MODE_GESTURE
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
|
||||||
|
// detected gestures
|
||||||
|
GESTURE_NONE = iota
|
||||||
|
GESTURE_UP
|
||||||
|
GESTURE_DOWN
|
||||||
|
GESTURE_LEFT
|
||||||
|
GESTURE_RIGHT
|
||||||
|
)
|
||||||
@@ -0,0 +1,258 @@
|
|||||||
|
// Package axp192 provides a driver for the axp192 I2C Enhanced single Cell
|
||||||
|
// Li-Battery and Power System Management IC.
|
||||||
|
//
|
||||||
|
// http://www.x-powers.com/en.php/Info/product_detail/article_id/29
|
||||||
|
// Datasheet: https://github.com/m5stack/M5-Schematic/blob/master/Core/AXP192%20Datasheet_v1.1_en_draft_2211.pdf
|
||||||
|
//
|
||||||
|
package axp192 // import "tinygo.org/x/drivers/axp192"
|
||||||
|
|
||||||
|
import (
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
ErrInvalidID Error = 0x1
|
||||||
|
)
|
||||||
|
|
||||||
|
func (e Error) Error() string {
|
||||||
|
switch e {
|
||||||
|
case ErrInvalidID:
|
||||||
|
return "Invalid chip ID"
|
||||||
|
default:
|
||||||
|
return "Unknown error"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Device struct {
|
||||||
|
bus drivers.I2C
|
||||||
|
buf []byte
|
||||||
|
Address uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns AXP192 device for the provided I2C bus using default address.
|
||||||
|
func New(i2c drivers.I2C) *Device {
|
||||||
|
return &Device{
|
||||||
|
bus: i2c,
|
||||||
|
buf: make([]byte, 2),
|
||||||
|
Address: Address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the AXP192 device.
|
||||||
|
func (d *Device) Configure(config Config) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadPowerSupplyStatus reads power supply status.
|
||||||
|
func (d *Device) ReadPowerSupplyStatus() uint8 {
|
||||||
|
return d.read8bit(RegPowerSupplyStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetVbusIPSOutAccessManagement sets VBUS-IPSOUT access management.
|
||||||
|
func (d *Device) SetVbusIPSOutAccessManagement(a uint8) {
|
||||||
|
d.write1Byte(RegVbusIPSOutAccessManagement, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetVbusIPSOutAccessManagement gets VBUS-IPSOUT access management.
|
||||||
|
func (d *Device) GetVbusIPSOutAccessManagement() uint8 {
|
||||||
|
return d.read8bit(RegVbusIPSOutAccessManagement)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGPIO1Control sets GPIO1 function.
|
||||||
|
func (d *Device) SetGPIO1Control(a uint8) {
|
||||||
|
d.write1Byte(RegGPIO1Control, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGPIO1Control gets GPIO1 function.
|
||||||
|
func (d *Device) GetGPIO1Control() uint8 {
|
||||||
|
return d.read8bit(RegGPIO1Control)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGPIO2Control sets GPIO2 function.
|
||||||
|
func (d *Device) SetGPIO2Control(a uint8) {
|
||||||
|
d.write1Byte(RegGPIO2Control, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGPIO2Control gets GPIO2 function.
|
||||||
|
func (d *Device) GetGPIO2Control() uint8 {
|
||||||
|
return d.read8bit(RegGPIO2Control)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGPIO20SignalStatus sets GPIO[2:0] signal status.
|
||||||
|
func (d *Device) SetGPIO20SignalStatus(a uint8) {
|
||||||
|
d.write1Byte(RegGPIO20SignalStatus, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGPIO20SignalStatus gets GPIO[2:0] signal status.
|
||||||
|
func (d *Device) GetGPIO20SignalStatus() uint8 {
|
||||||
|
return d.read8bit(RegGPIO20SignalStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBackupBatteryChargingControl sets backup battery charge control.
|
||||||
|
func (d *Device) SetBackupBatteryChargingControl(a uint8) {
|
||||||
|
d.write1Byte(RegBackupBatteryChargingControl, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetBackupBatteryChargingControl gets backup battery charge control.
|
||||||
|
func (d *Device) GetBackupBatteryChargingControl() uint8 {
|
||||||
|
return d.read8bit(RegBackupBatteryChargingControl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCDC1VoltageSet sets DC-DC1 output voltage.
|
||||||
|
func (d *Device) SetDCDC1VoltageSet(a uint8) {
|
||||||
|
d.write1Byte(RegDCDC1VoltageSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDCDC1VoltageSet gets DC-DC1 output voltage.
|
||||||
|
func (d *Device) GetDCDC1VoltageSet() uint8 {
|
||||||
|
return d.read8bit(RegDCDC1VoltageSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCDC2VoltageSet sets DC-DC2 dynamic voltage parameter.
|
||||||
|
func (d *Device) SetDCDC2VoltageSet(a uint8) {
|
||||||
|
d.write1Byte(RegDCDC2VoltageSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDCDC2VoltageSet gets DC-DC2 dynamic voltage parameter.
|
||||||
|
func (d *Device) GetDCDC2VoltageSet() uint8 {
|
||||||
|
return d.read8bit(RegDCDC2VoltageSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCDC3VoltageSet sets DC-DC3 output voltage.
|
||||||
|
func (d *Device) SetDCDC3VoltageSet(a uint8) {
|
||||||
|
d.write1Byte(RegDCDC3VoltageSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDCDC3VoltageSet gets DC-DC3 output voltage.
|
||||||
|
func (d *Device) GetDCDC3VoltageSet() uint8 {
|
||||||
|
return d.read8bit(RegDCDC3VoltageSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLDO23VoltageSet sets LDO2/3 output voltage.
|
||||||
|
func (d *Device) SetLDO23VoltageSet(a uint8) {
|
||||||
|
d.write1Byte(RegLDO23VoltageSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetLDO23VoltageSet gets LDO2/3 output voltage.
|
||||||
|
func (d *Device) GetLDO23VoltageSet() uint8 {
|
||||||
|
return d.read8bit(RegLDO23VoltageSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCDC13LDO23Switch sets DC-DC1/3 & LOD2/3 output control.
|
||||||
|
func (d *Device) SetDCDC13LDO23Switch(a uint8) {
|
||||||
|
d.write1Byte(RegDCDC13LDO23Switch, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDCDC13LDO23Switch gets DC-DC1/3 & LOD2/3 output control.
|
||||||
|
func (d *Device) GetDCDC13LDO23Switch() uint8 {
|
||||||
|
return d.read8bit(RegDCDC13LDO23Switch)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGPIO43FunctionControl sets GPIO[4:3] pin function.
|
||||||
|
func (d *Device) SetGPIO43FunctionControl(a uint8) {
|
||||||
|
d.write1Byte(RegGPIO43FunctionControl, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGPIO43FunctionControl gets GPIO[4:3] pin function.
|
||||||
|
func (d *Device) GetGPIO43FunctionControl() uint8 {
|
||||||
|
return d.read8bit(RegGPIO43FunctionControl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPEKParameterSet sets PEK press key parameter.
|
||||||
|
func (d *Device) SetPEKParameterSet(a uint8) {
|
||||||
|
d.write1Byte(RegPEKParameterSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPEKParameterSet gets PEK press key parameter.
|
||||||
|
func (d *Device) GetPEKParameterSet() uint8 {
|
||||||
|
return d.read8bit(RegPEKParameterSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetADCEnableSet sets ADC enable 1.
|
||||||
|
func (d *Device) SetADCEnableSet(a uint8) {
|
||||||
|
d.write1Byte(RegADCEnableSet, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetADCEnableSet gets ADC enable 1.
|
||||||
|
func (d *Device) GetADCEnableSet() uint8 {
|
||||||
|
return d.read8bit(RegADCEnableSet)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGPIO43SignalStatus sets GPIO[4:3] signal status.
|
||||||
|
func (d *Device) SetGPIO43SignalStatus(a uint8) {
|
||||||
|
d.write1Byte(RegGPIO43SignalStatus, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGPIO43SignalStatus gets GPIO[4:3] signal status.
|
||||||
|
func (d *Device) GetGPIO43SignalStatus() uint8 {
|
||||||
|
return d.read8bit(RegGPIO43SignalStatus)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCVoltage sets DC voltage.
|
||||||
|
func (d *Device) SetDCVoltage(number uint8, voltage uint16) {
|
||||||
|
if voltage < 700 {
|
||||||
|
voltage = 0
|
||||||
|
} else {
|
||||||
|
voltage = (voltage - 700) / 25
|
||||||
|
}
|
||||||
|
|
||||||
|
switch number {
|
||||||
|
case 0:
|
||||||
|
v := d.GetDCDC1VoltageSet()
|
||||||
|
d.SetDCDC1VoltageSet((v & 0x80) | (uint8(voltage) & 0x7F))
|
||||||
|
case 1:
|
||||||
|
v := d.GetDCDC2VoltageSet()
|
||||||
|
d.SetDCDC2VoltageSet((v & 0x80) | (uint8(voltage) & 0x7F))
|
||||||
|
case 2:
|
||||||
|
v := d.GetDCDC3VoltageSet()
|
||||||
|
d.SetDCDC3VoltageSet((v & 0x80) | (uint8(voltage) & 0x7F))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLDOVoltage sets LDO voltage.
|
||||||
|
func (d *Device) SetLDOVoltage(number uint8, voltage uint16) {
|
||||||
|
if voltage > 3300 {
|
||||||
|
voltage = 15
|
||||||
|
} else {
|
||||||
|
voltage = (voltage / 100) - 18
|
||||||
|
}
|
||||||
|
|
||||||
|
switch number {
|
||||||
|
case 2:
|
||||||
|
v := d.GetLDO23VoltageSet()
|
||||||
|
d.SetLDO23VoltageSet((v & 0x0F) | (uint8(voltage) << 4))
|
||||||
|
break
|
||||||
|
case 3:
|
||||||
|
v := d.GetLDO23VoltageSet()
|
||||||
|
d.SetLDO23VoltageSet((v & 0xF0) | uint8(voltage))
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLDOEnable enable LDO.
|
||||||
|
func (d *Device) SetLDOEnable(number uint8, state bool) {
|
||||||
|
mark := uint8(0x01)
|
||||||
|
mark <<= number
|
||||||
|
switch number {
|
||||||
|
case 2:
|
||||||
|
v := d.GetDCDC13LDO23Switch()
|
||||||
|
d.SetDCDC13LDO23Switch(v | mark)
|
||||||
|
case 3:
|
||||||
|
v := d.GetDCDC13LDO23Switch()
|
||||||
|
d.SetDCDC13LDO23Switch(v & (^mark))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) write1Byte(reg, data uint8) {
|
||||||
|
d.bus.WriteRegister(d.Address, reg, []byte{data})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) read8bit(reg uint8) uint8 {
|
||||||
|
d.bus.ReadRegister(d.Address, reg, d.buf[:1])
|
||||||
|
return d.buf[0]
|
||||||
|
}
|
||||||
@@ -0,0 +1,158 @@
|
|||||||
|
package axp192
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
axp192orig "tinygo.org/x/drivers/axp192"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device wraps an I2C connection to a AXP192 device.
|
||||||
|
type Device struct {
|
||||||
|
*axp192orig.Device
|
||||||
|
LED Pin
|
||||||
|
RST Pin
|
||||||
|
SPK_EN Pin
|
||||||
|
}
|
||||||
|
|
||||||
|
// New creates a new AXP192 connection. The I2C bus must already be
|
||||||
|
// configured.
|
||||||
|
//
|
||||||
|
// This function only creates the Device object, it does not touch the device.
|
||||||
|
func New(i2c drivers.I2C) *Device {
|
||||||
|
d := axp192orig.New(i2c)
|
||||||
|
|
||||||
|
axp := &Device{
|
||||||
|
Device: d,
|
||||||
|
}
|
||||||
|
axp.LED = Pin{pin: 1, axp: axp}
|
||||||
|
axp.SPK_EN = Pin{pin: 2, axp: axp}
|
||||||
|
axp.RST = Pin{pin: 4, axp: axp}
|
||||||
|
|
||||||
|
axp.begin()
|
||||||
|
|
||||||
|
return axp
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure sets up the device for communication
|
||||||
|
func (d *Device) Configure(config Config) error {
|
||||||
|
return d.Device.Configure(axp192orig.Config{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) begin() {
|
||||||
|
d.SetVbusIPSOutAccessManagement((d.GetVbusIPSOutAccessManagement() & 0x04) | 0x02)
|
||||||
|
d.SetGPIO1Control(d.GetGPIO1Control() & 0xF8)
|
||||||
|
d.SetGPIO2Control(d.GetGPIO2Control() & 0xF8)
|
||||||
|
d.SetBackupBatteryChargingControl((d.GetBackupBatteryChargingControl() & 0x1C) | 0xA2)
|
||||||
|
d.SetESPVoltage(3350)
|
||||||
|
d.SetLcdVoltage(3300)
|
||||||
|
d.SetLDOVoltage(2, 3300) //Periph power voltage preset (LCD_logic, SD card)
|
||||||
|
d.SetLDOVoltage(3, 2000) //Vibrator power voltage preset
|
||||||
|
|
||||||
|
d.SetLDOEnable(2, true)
|
||||||
|
d.SetDCDC3(true) // LCD Backlight
|
||||||
|
// GPIO4 : LCD Reset
|
||||||
|
d.SetGPIO43FunctionControl((d.GetGPIO43FunctionControl() & 0x72) | 0x84)
|
||||||
|
// Power On/Off Setting
|
||||||
|
d.SetPEKParameterSet(0x4C)
|
||||||
|
d.SetADCEnableSet(0xFF)
|
||||||
|
|
||||||
|
d.RST.Low()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
d.RST.High()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToggleLED toggles LED connected to AXP192.
|
||||||
|
func (d *Device) ToggleLED() {
|
||||||
|
v := d.GetGPIO20SignalStatus()
|
||||||
|
if (v & 0x02) > 0 {
|
||||||
|
d.SetGPIO20SignalStatus(v & 0xFD)
|
||||||
|
} else {
|
||||||
|
d.SetGPIO20SignalStatus(v | 0x02)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetESPVoltage sets voltage of ESP32.
|
||||||
|
func (d *Device) SetESPVoltage(voltage uint16) {
|
||||||
|
if voltage >= 3000 && voltage <= 3400 {
|
||||||
|
d.SetDCVoltage(0, voltage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetLcdVoltage sets voltage of LCD.
|
||||||
|
func (d *Device) SetLcdVoltage(voltage uint16) {
|
||||||
|
if voltage >= 2500 && voltage <= 3300 {
|
||||||
|
d.SetDCVoltage(2, voltage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDCDC3 enables or disables DCDC3.
|
||||||
|
func (d *Device) SetDCDC3(State bool) {
|
||||||
|
v := d.GetDCDC13LDO23Switch()
|
||||||
|
if State == true {
|
||||||
|
v = (1 << 1) | v
|
||||||
|
} else {
|
||||||
|
v = ^(uint8(1) << 1) & v
|
||||||
|
}
|
||||||
|
d.SetDCDC13LDO23Switch(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pin is a single pin on AXP192.
|
||||||
|
type Pin struct {
|
||||||
|
pin uint8
|
||||||
|
axp *Device
|
||||||
|
}
|
||||||
|
|
||||||
|
// High sets this GPIO pin to high.
|
||||||
|
func (p Pin) High() {
|
||||||
|
switch p.pin {
|
||||||
|
case 1: // LED
|
||||||
|
v := p.axp.GetGPIO20SignalStatus()
|
||||||
|
p.axp.SetGPIO20SignalStatus(v | 0x02)
|
||||||
|
case 2: // SPK_EN
|
||||||
|
case 4: // RST
|
||||||
|
v := p.axp.GetGPIO43SignalStatus()
|
||||||
|
v |= uint8(0x02)
|
||||||
|
p.axp.SetGPIO43SignalStatus(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Low sets this GPIO pin to low.
|
||||||
|
func (p Pin) Low() {
|
||||||
|
switch p.pin {
|
||||||
|
case 1: // LED
|
||||||
|
v := p.axp.GetGPIO20SignalStatus()
|
||||||
|
p.axp.SetGPIO20SignalStatus(v & 0xFD)
|
||||||
|
case 2: // SPK_EN
|
||||||
|
case 4: // RST
|
||||||
|
v := p.axp.GetGPIO43SignalStatus()
|
||||||
|
v &= ^uint8(0x02)
|
||||||
|
p.axp.SetGPIO43SignalStatus(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Toggle switches an output pin from low to high or from high to low.
|
||||||
|
func (p Pin) Toggle() {
|
||||||
|
switch p.pin {
|
||||||
|
case 1: // LED
|
||||||
|
v := p.axp.GetGPIO20SignalStatus()
|
||||||
|
if (v & 0x02) == 0 {
|
||||||
|
p.axp.SetGPIO20SignalStatus(v | 0x02)
|
||||||
|
} else {
|
||||||
|
p.axp.SetGPIO20SignalStatus(v & 0xFD)
|
||||||
|
}
|
||||||
|
case 2: // SPK_EN
|
||||||
|
case 4: // RST
|
||||||
|
v := p.axp.GetGPIO43SignalStatus()
|
||||||
|
if (v & 0x02) == 0 {
|
||||||
|
v |= uint8(0x02)
|
||||||
|
} else {
|
||||||
|
v &= ^uint8(0x02)
|
||||||
|
}
|
||||||
|
p.axp.SetGPIO43SignalStatus(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,127 @@
|
|||||||
|
package axp192
|
||||||
|
|
||||||
|
// power supply control class
|
||||||
|
// 0x00 Power supply status register
|
||||||
|
// 0x01 Power supply mode/charging status register
|
||||||
|
// 0x04 OTG VBUS status register
|
||||||
|
// 0x06‐09 Data buffer register
|
||||||
|
// 0x10 EXTEN & DC‐DC2 switch register
|
||||||
|
// 0x12 DC‐DC1/3 & LDO2/3switch register
|
||||||
|
// 0x23 DC‐DC2 voltage set register
|
||||||
|
// 0x25 DC‐DC2 voltage slope set register
|
||||||
|
// 0x26 DC‐DC1voltage set register
|
||||||
|
// 0x27 DC‐DC3 voltage set register
|
||||||
|
// 0x28 LDO2/3 voltage set register
|
||||||
|
// 0x30 VBUS‐IPSOUT access set register
|
||||||
|
// 0x31 VOFF power off voltage set register
|
||||||
|
// 0x32 Power off、battery detect、CHGLED control register
|
||||||
|
// 0x33 Charging control register1
|
||||||
|
// 0x34 Charging control register2
|
||||||
|
// 0x35 Backup battery charging control register
|
||||||
|
// 0x36 PEK parameter set register
|
||||||
|
// 0x37 DCDC switch frequency set register
|
||||||
|
// 0x38 Battery charging under temperature warning set register
|
||||||
|
// 0x39 Battery charging over temperature warning set register
|
||||||
|
// 0x3A APS under voltage Level1 set register
|
||||||
|
// 0x3B APS under voltage Level2 set register
|
||||||
|
// 0x3C Battery discharging under temperature warning set register
|
||||||
|
// 0x3D Battery discharging over temperature warning set register
|
||||||
|
// 0x80 DCDC mode set register
|
||||||
|
// 0x82 ADC enable set register 1
|
||||||
|
// 0x83 ADC enable set register 2
|
||||||
|
// 0x84 ADC sample frequency set, TS pin control register
|
||||||
|
// 0x85 GPIO [3:0] input range set register
|
||||||
|
// 0x8A Timer control register
|
||||||
|
// 0x8B VBUS monitor set register
|
||||||
|
// 0x8F Over temperature power off control register
|
||||||
|
|
||||||
|
// GPIO control class
|
||||||
|
// 0x90 GPIO0 control register
|
||||||
|
// 0x91 GPIO0 LDO mode output voltage set register
|
||||||
|
// 0x92 GPIO1 control register
|
||||||
|
// 0x93 GPIO2 control register
|
||||||
|
// 0x94 GPIO[2:0] signal status register
|
||||||
|
// 0x95 GPIO[4:3] function control register
|
||||||
|
// 0x96 GPIO[4:3] signal status register
|
||||||
|
// 0x97 GPIO[2:0] pull down control register
|
||||||
|
// 0x98 PWM1 frequency set register
|
||||||
|
// 0x99 PWM1 duty ratio set register 1
|
||||||
|
// 0x9A PWM1 duty ratio set register 2
|
||||||
|
// 0x9B PWM2 frequency set register
|
||||||
|
// 0x9C PWM2 duty ratio set register 1
|
||||||
|
// 0x9D PWM2 duty ratio set register 2
|
||||||
|
// 0x9E GPIO5 control register
|
||||||
|
|
||||||
|
// IRQ control class
|
||||||
|
// 0x40 IRQ enable control register 1
|
||||||
|
// 0x41 IRQ enable control register 2
|
||||||
|
// 0x42 IRQ enable control register 3
|
||||||
|
// 0x43 IRQ enable control register 4
|
||||||
|
// 0x44 IRQ status register 1
|
||||||
|
// 0x45 IRQ status register 2
|
||||||
|
// 0x46 IRQ status register 3
|
||||||
|
// 0x47 IRQ status register 4
|
||||||
|
|
||||||
|
// ADC data class
|
||||||
|
// 0x56 ACIN voltage ADC data high 8 bit
|
||||||
|
// 0x57 ACIN voltage ADC data low 4 bit
|
||||||
|
// 0x58 ACIN current ADC data high 8 bit
|
||||||
|
// 0x59 ACIN current ADC data low 4 bit
|
||||||
|
// 0x5A VBUS voltage ADC data high 8 bit
|
||||||
|
// 0x5B VBUS voltage ADC data low 4 bit
|
||||||
|
// 0x5C VBUS current ADC data high 8 bit
|
||||||
|
// 0x5D VBUS current ADC data low 4 bit
|
||||||
|
// 0x5E AXP192 internal temperature monitor ADC data High 8 bit
|
||||||
|
// 0x5F AXP192 internal temperature monitor ADC data low 4 bit
|
||||||
|
// 0x62 TS input ADC data High 8 bit,monitor battery temperature by default
|
||||||
|
// 0x63 TS input ADC data low 4 bit,monitor battery temperature by default
|
||||||
|
// 0x64 GPIO0 voltage ADC data high 8 bit
|
||||||
|
// 0x65 GPIO0 voltage ADC data low 4 bit
|
||||||
|
// 0x66 GPIO1 voltage ADC data high 8 bit
|
||||||
|
// 0x67 GPIO1 voltage ADC data low 4 bit
|
||||||
|
// 0x68 GPIO2 voltage ADC data high 8 bit
|
||||||
|
// 0x69 GPIO2 voltage ADC data low 4 bit
|
||||||
|
// 0x6A GPIO[3] voltage ADC data high 8 bit
|
||||||
|
// 0x6B GPIO[3] voltage ADC data low 4 bit
|
||||||
|
// 0x70 Battery instantaneous power high 8 bit
|
||||||
|
// 0x71 Battery instantaneous power middle 8 bit
|
||||||
|
// 0x72 Battery instantaneous power low 8 bit
|
||||||
|
// 0x78 Battery voltage high 8 bit
|
||||||
|
// 0x79 Battery voltage low 4 bit
|
||||||
|
// 0x7A Battery charging current high 8 bit
|
||||||
|
// 0x7B Battery charging current low 5 bit
|
||||||
|
// 0x7C Battery discharging current high 8 bit
|
||||||
|
// 0x7D Battery discharging current low 5 bit
|
||||||
|
// 0x7E APS voltage high 8 bit
|
||||||
|
// 0x7F APS voltage low 4 bit
|
||||||
|
// 0xB0 Battery charging coulomb counter data register 3
|
||||||
|
// 0xB1 Battery charging coulomb counter data register 2
|
||||||
|
// 0xB2 Battery charging coulomb counter data register 1
|
||||||
|
// 0xB3 Battery charging coulomb counter data register 0
|
||||||
|
// 0xB4 Battery discharging coulomb counter data register 3
|
||||||
|
// 0xB5 Battery discharging coulomb counter data register 2
|
||||||
|
// 0xB6 Battery discharging coulomb counter data register 1
|
||||||
|
// 0xB7 Battery discharging coulomb counter data register 0
|
||||||
|
// 0xB8 Coulomb counter control register
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Address is default I2C address.
|
||||||
|
Address = 0x34
|
||||||
|
|
||||||
|
RegPowerSupplyStatus = 0x00
|
||||||
|
RegDCDC13LDO23Switch = 0x12
|
||||||
|
RegVbusIPSOutAccessManagement = 0x30
|
||||||
|
RegBackupBatteryChargingControl = 0x35
|
||||||
|
RegDCDC2VoltageSet = 0x25
|
||||||
|
RegDCDC1VoltageSet = 0x26
|
||||||
|
RegDCDC3VoltageSet = 0x27
|
||||||
|
RegLDO23VoltageSet = 0x28
|
||||||
|
RegPEKParameterSet = 0x36
|
||||||
|
RegADCEnableSet = 0x82
|
||||||
|
|
||||||
|
RegGPIO1Control = 0x92
|
||||||
|
RegGPIO2Control = 0x93
|
||||||
|
RegGPIO20SignalStatus = 0x94
|
||||||
|
RegGPIO43FunctionControl = 0x95
|
||||||
|
RegGPIO43SignalStatus = 0x96
|
||||||
|
)
|
||||||
+3
-27
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
||||||
//
|
//
|
||||||
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
||||||
@@ -7,34 +10,10 @@
|
|||||||
package dht // import "tinygo.org/x/drivers/dht"
|
package dht // import "tinygo.org/x/drivers/dht"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"machine"
|
"machine"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// enum type for device type
|
|
||||||
type DeviceType uint8
|
|
||||||
|
|
||||||
// DeviceType specific parsing of information received from the sensor
|
|
||||||
func (d DeviceType) extractData(buf []byte) (temp int16, hum uint16) {
|
|
||||||
if d == DHT11 {
|
|
||||||
temp = int16(buf[2])
|
|
||||||
if buf[3]&0x80 > 0 {
|
|
||||||
temp = -1 - temp
|
|
||||||
}
|
|
||||||
temp *= 10
|
|
||||||
temp += int16(buf[3] & 0x0f)
|
|
||||||
hum = 10*uint16(buf[0]) + uint16(buf[1])
|
|
||||||
} else {
|
|
||||||
hum = binary.LittleEndian.Uint16(buf[0:2])
|
|
||||||
temp = int16(buf[3])<<8 + int16(buf[2]&0x7f)
|
|
||||||
if buf[2]&0x80 > 0 {
|
|
||||||
temp = -temp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Celsius and Fahrenheit temperature scales
|
// Celsius and Fahrenheit temperature scales
|
||||||
type TemperatureScale uint8
|
type TemperatureScale uint8
|
||||||
|
|
||||||
@@ -54,9 +33,6 @@ const (
|
|||||||
startTimeout = time.Millisecond * 200
|
startTimeout = time.Millisecond * 200
|
||||||
startingLow = time.Millisecond * 20
|
startingLow = time.Millisecond * 20
|
||||||
|
|
||||||
DHT11 DeviceType = iota
|
|
||||||
DHT22
|
|
||||||
|
|
||||||
C TemperatureScale = iota
|
C TemperatureScale = iota
|
||||||
F
|
F
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package dht
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeviceType is the enum type for device type
|
||||||
|
type DeviceType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
DHT11 DeviceType = iota
|
||||||
|
DHT22
|
||||||
|
)
|
||||||
|
|
||||||
|
// extractData parses information received from the sensor.
|
||||||
|
// The 2 first buffers are for the humidity and
|
||||||
|
// the 2 following corresponds to the temperature.
|
||||||
|
func (d DeviceType) extractData(buf []byte) (temp int16, hum uint16) {
|
||||||
|
switch d {
|
||||||
|
case DHT11:
|
||||||
|
hum = 10*uint16(buf[0]) + uint16(buf[1])
|
||||||
|
temp = int16(buf[2])
|
||||||
|
if buf[3]&0x80 > 0 {
|
||||||
|
temp = -1 - temp
|
||||||
|
}
|
||||||
|
temp *= 10
|
||||||
|
temp += int16(buf[3] & 0x0f)
|
||||||
|
case DHT22:
|
||||||
|
hum = binary.BigEndian.Uint16(buf[0:2])
|
||||||
|
temp = int16(buf[2]&0x7f)<<8 + int16(buf[3])
|
||||||
|
// the first bit corresponds to the sign bit
|
||||||
|
if buf[2]&0x80 > 0 {
|
||||||
|
temp = -temp
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// keeping this for retro-compatibility but not tested
|
||||||
|
hum = binary.LittleEndian.Uint16(buf[0:2])
|
||||||
|
temp = int16(buf[3])<<8 + int16(buf[2]&0x7f)
|
||||||
|
if buf[2]&0x80 > 0 {
|
||||||
|
temp = -temp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package dht
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDeviceType_extractData(t *testing.T) {
|
||||||
|
bitStr := "0000001010001100000000010101111111101110"
|
||||||
|
buf := bitStringToBytes(bitStr)
|
||||||
|
|
||||||
|
tt := []struct {
|
||||||
|
name string
|
||||||
|
d DeviceType
|
||||||
|
buf []byte
|
||||||
|
wantTemp int16
|
||||||
|
wantHum uint16
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
// temp = 35.1C hum = 65.2%
|
||||||
|
name: "DHT22", d: DHT22, buf: buf, wantTemp: 351, wantHum: 652,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tt {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
gotTemp, gotHum := tc.d.extractData(tc.buf)
|
||||||
|
if gotTemp != tc.wantTemp {
|
||||||
|
t.Errorf("extractData() gotTemp = %v, want %v", gotTemp, tc.wantTemp)
|
||||||
|
}
|
||||||
|
if gotHum != tc.wantHum {
|
||||||
|
t.Errorf("extractData() gotHum = %v, want %v", gotHum, tc.wantHum)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func bitStringToBytes(s string) []byte {
|
||||||
|
b := make([]byte, (len(s)+(8-1))/8)
|
||||||
|
for i, r := range s {
|
||||||
|
if r < '0' || r > '1' {
|
||||||
|
panic("not in range")
|
||||||
|
}
|
||||||
|
b[i>>3] |= byte(r-'0') << uint(7-i&7)
|
||||||
|
}
|
||||||
|
return b
|
||||||
|
}
|
||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
||||||
//
|
//
|
||||||
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
// Package dht provides a driver for DHTXX family temperature and humidity sensors.
|
||||||
//
|
//
|
||||||
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
// [1] Datasheet DHT11: https://www.mouser.com/datasheet/2/758/DHT11-Technical-Data-Sheet-Translated-Version-1143054.pdf
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
package dht // import "tinygo.org/x/drivers/dht"
|
package dht // import "tinygo.org/x/drivers/dht"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package espat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (d *Device) ConnectToAccessPoint(ssid, pass string, timeout time.Duration) error {
|
||||||
|
if len(ssid) == 0 {
|
||||||
|
return net.ErrWiFiMissingSSID
|
||||||
|
}
|
||||||
|
|
||||||
|
d.SetWifiMode(WifiModeClient)
|
||||||
|
return d.ConnectToAP(ssid, pass, int(timeout.Seconds()))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) Disconnect() error {
|
||||||
|
return d.DisconnectFromAP()
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/apds9960"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
|
machine.I2C1.Configure(machine.I2CConfig{
|
||||||
|
SCL: machine.SCL1_PIN,
|
||||||
|
SDA: machine.SDA1_PIN,
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := apds9960.New(machine.I2C1)
|
||||||
|
|
||||||
|
sensor.Configure(apds9960.Configuration{}) // use default settings
|
||||||
|
|
||||||
|
if !sensor.Connected() {
|
||||||
|
println("APDS-9960 not connected!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor.EnableColor() // enable color engine
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
if sensor.ColorAvailable() {
|
||||||
|
r, g, b, c := sensor.ReadColor()
|
||||||
|
println("Red =", r, "\tGreen =", g, "\tBlue =", b, "\tClear =", c)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/apds9960"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
|
machine.I2C1.Configure(machine.I2CConfig{
|
||||||
|
SCL: machine.SCL1_PIN,
|
||||||
|
SDA: machine.SDA1_PIN,
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := apds9960.New(machine.I2C1)
|
||||||
|
|
||||||
|
sensor.Configure(apds9960.Configuration{}) // use default settings
|
||||||
|
|
||||||
|
if !sensor.Connected() {
|
||||||
|
println("APDS-9960 not connected!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor.EnableGesture() // enable gesture engine
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
// wave your hand (not too slow) about 10 cm above the sensor
|
||||||
|
if sensor.GestureAvailable() {
|
||||||
|
|
||||||
|
gesture := sensor.ReadGesture()
|
||||||
|
print("Detected gesture: ")
|
||||||
|
switch gesture {
|
||||||
|
case apds9960.GESTURE_UP: // the nRF52 chip is "up"
|
||||||
|
println("Up")
|
||||||
|
case apds9960.GESTURE_DOWN:
|
||||||
|
println("Down")
|
||||||
|
case apds9960.GESTURE_LEFT:
|
||||||
|
println("Left")
|
||||||
|
case apds9960.GESTURE_RIGHT:
|
||||||
|
println("Right")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// note: the delay shouldn't be too long, otherwise new gesture data might be lost
|
||||||
|
time.Sleep(time.Millisecond * 250)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/apds9960"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
|
machine.I2C1.Configure(machine.I2CConfig{
|
||||||
|
SCL: machine.SCL1_PIN,
|
||||||
|
SDA: machine.SDA1_PIN,
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := apds9960.New(machine.I2C1)
|
||||||
|
|
||||||
|
// use default settings
|
||||||
|
sensor.Configure(apds9960.Configuration{})
|
||||||
|
|
||||||
|
if !sensor.Connected() {
|
||||||
|
println("APDS-9960 not connected!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor.EnableProximity() // enable proximity engine
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
if sensor.ProximityAvailable() {
|
||||||
|
p := sensor.ReadProximity()
|
||||||
|
println("Proximity:", p)
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
axp192 "tinygo.org/x/drivers/axp192/m5stack-core2-axp192"
|
||||||
|
"tinygo.org/x/drivers/i2csoft"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i2c := i2csoft.New(machine.SCL0_PIN, machine.SDA0_PIN)
|
||||||
|
i2c.Configure(i2csoft.I2CConfig{Frequency: 100e3})
|
||||||
|
|
||||||
|
axp := axp192.New(i2c)
|
||||||
|
led := axp.LED
|
||||||
|
|
||||||
|
for {
|
||||||
|
led.Low()
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
|
||||||
|
led.High()
|
||||||
|
time.Sleep(time.Millisecond * 500)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ func main() {
|
|||||||
dhtSensor := dht.New(pin, dht.DHT11)
|
dhtSensor := dht.New(pin, dht.DHT11)
|
||||||
for {
|
for {
|
||||||
temp, hum, err := dhtSensor.Measurements()
|
temp, hum, err := dhtSensor.Measurements()
|
||||||
if err != nil {
|
if err == nil {
|
||||||
fmt.Printf("Temperature: %02d.%d°C, Humidity: %02d.%d%%\n", temp/10, temp%10, hum/10, hum%10)
|
fmt.Printf("Temperature: %02d.%d°C, Humidity: %02d.%d%%\n", temp/10, temp%10, hum/10, hum%10)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Could not take measurements from the sensor: %s\n", err.Error())
|
fmt.Printf("Could not take measurements from the sensor: %s\n", err.Error())
|
||||||
|
|||||||
@@ -113,8 +113,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -99,8 +99,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -88,8 +88,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -108,8 +108,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -129,8 +129,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -91,8 +91,9 @@ func connectToESP() bool {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
println("Connecting to wifi network '" + ssid + "'")
|
println("Connecting to wifi network '" + ssid + "'")
|
||||||
|
|
||||||
adaptor.SetWifiMode(espat.WifiModeClient)
|
if err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second); err != nil {
|
||||||
adaptor.ConnectToAP(ssid, pass, 10)
|
failMessage(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
ip, err := adaptor.GetClientIP()
|
ip, err := adaptor.GetClientIP()
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ft6336"
|
||||||
|
"tinygo.org/x/drivers/i2csoft"
|
||||||
|
"tinygo.org/x/drivers/touch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitDisplay initializes the display of each board.
|
||||||
|
func initDevices() (touch.Pointer, error) {
|
||||||
|
i2c := i2csoft.New(machine.SCL0_PIN, machine.SDA0_PIN)
|
||||||
|
i2c.Configure(i2csoft.I2CConfig{Frequency: 100e3})
|
||||||
|
|
||||||
|
resistiveTouch := ft6336.New(i2c, machine.Pin(39))
|
||||||
|
resistiveTouch.Configure(ft6336.Config{})
|
||||||
|
resistiveTouch.SetPeriodActive(0x00)
|
||||||
|
|
||||||
|
return resistiveTouch, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
touchScreen, _ := initDevices()
|
||||||
|
|
||||||
|
for {
|
||||||
|
touch := touchScreen.ReadTouchPoint()
|
||||||
|
if touch.Z > 0 {
|
||||||
|
//X and Y are 16 bit with 12 bit resolution and need to be scaled for the display size
|
||||||
|
//Z is 24 bit and is typically > 2000 for a touch
|
||||||
|
println("touch:", touch.X, touch.Y, touch.Z)
|
||||||
|
//Example of scaling for m5stack-core2's 320x240 display with 320x270 touch area
|
||||||
|
println("screen:", (touch.X*320)>>16, (touch.Y*270)>>16)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
axp192 "tinygo.org/x/drivers/axp192/m5stack-core2-axp192"
|
||||||
|
"tinygo.org/x/drivers/ft6336"
|
||||||
|
"tinygo.org/x/drivers/i2csoft"
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
"tinygo.org/x/drivers/touch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitDisplay initializes the display of each board.
|
||||||
|
func initDevices() (touchPaintDisplay, touch.Pointer, error) {
|
||||||
|
machine.SPI2.Configure(machine.SPIConfig{
|
||||||
|
SCK: machine.LCD_SCK_PIN,
|
||||||
|
SDO: machine.LCD_SDO_PIN,
|
||||||
|
SDI: machine.LCD_SDI_PIN,
|
||||||
|
Frequency: 40e6,
|
||||||
|
})
|
||||||
|
|
||||||
|
i2c := i2csoft.New(machine.SCL0_PIN, machine.SDA0_PIN)
|
||||||
|
i2c.Configure(i2csoft.I2CConfig{Frequency: 100e3})
|
||||||
|
|
||||||
|
axp := axp192.New(i2c)
|
||||||
|
led := axp.LED
|
||||||
|
led.Low()
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI2,
|
||||||
|
machine.LCD_DC_PIN,
|
||||||
|
machine.LCD_SS_PIN,
|
||||||
|
machine.NoPin,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{
|
||||||
|
Width: 320,
|
||||||
|
Height: 240,
|
||||||
|
DisplayInversion: true,
|
||||||
|
})
|
||||||
|
display.FillScreen(color.RGBA{255, 255, 255, 255})
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation0Mirror)
|
||||||
|
|
||||||
|
resistiveTouch := ft6336.New(i2c, machine.Pin(39))
|
||||||
|
resistiveTouch.Configure(ft6336.Config{})
|
||||||
|
resistiveTouch.SetPeriodActive(0x00)
|
||||||
|
|
||||||
|
return display, resistiveTouch, nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,163 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/touch"
|
||||||
|
)
|
||||||
|
|
||||||
|
type touchPaintDisplay interface {
|
||||||
|
drivers.Displayer
|
||||||
|
FillRectangle(x, y, width, height int16, c color.RGBA) error
|
||||||
|
DrawRectangle(x, y, w, h int16, c color.RGBA) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
white = color.RGBA{255, 255, 255, 255}
|
||||||
|
black = color.RGBA{0, 0, 0, 255}
|
||||||
|
red = color.RGBA{255, 0, 0, 255}
|
||||||
|
green = color.RGBA{0, 255, 0, 255}
|
||||||
|
blue = color.RGBA{0, 0, 255, 255}
|
||||||
|
magenta = color.RGBA{255, 0, 255, 255}
|
||||||
|
yellow = color.RGBA{255, 255, 0, 255}
|
||||||
|
cyan = color.RGBA{0, 255, 255, 255}
|
||||||
|
|
||||||
|
oldColor color.RGBA
|
||||||
|
currentColor color.RGBA
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
penRadius = 3
|
||||||
|
boxSize = 30
|
||||||
|
|
||||||
|
Xmin = 0
|
||||||
|
Xmax = 0xFFFF
|
||||||
|
Ymin = 0
|
||||||
|
Ymax = 0xFFFF
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
display, resistiveTouch, _ := initDevices()
|
||||||
|
|
||||||
|
// fill the background and activate the backlight
|
||||||
|
width, height := display.Size()
|
||||||
|
display.FillRectangle(0, 0, width, height, black)
|
||||||
|
|
||||||
|
// make color selection boxes
|
||||||
|
display.FillRectangle(0, 0, boxSize, boxSize, red)
|
||||||
|
display.FillRectangle(boxSize, 0, boxSize, boxSize, yellow)
|
||||||
|
display.FillRectangle(boxSize*2, 0, boxSize, boxSize, green)
|
||||||
|
display.FillRectangle(boxSize*3, 0, boxSize, boxSize, cyan)
|
||||||
|
display.FillRectangle(boxSize*4, 0, boxSize, boxSize, blue)
|
||||||
|
display.FillRectangle(boxSize*5, 0, boxSize, boxSize, magenta)
|
||||||
|
display.FillRectangle(boxSize*6, 0, boxSize, boxSize, black)
|
||||||
|
display.FillRectangle(boxSize*7, 0, boxSize, boxSize, white)
|
||||||
|
|
||||||
|
// set the initial color to red and draw a box to highlight it
|
||||||
|
oldColor = red
|
||||||
|
currentColor = red
|
||||||
|
display.DrawRectangle(0, 0, boxSize, boxSize, white)
|
||||||
|
|
||||||
|
last := touch.Point{}
|
||||||
|
|
||||||
|
// loop and poll for touches, including performing debouncing
|
||||||
|
debounce := 0
|
||||||
|
for {
|
||||||
|
|
||||||
|
point := resistiveTouch.ReadTouchPoint()
|
||||||
|
touch := touch.Point{}
|
||||||
|
if point.Z>>6 > 100 {
|
||||||
|
rawX := mapval(point.X, Xmin, Xmax, 0, int(width))
|
||||||
|
rawY := mapval(point.Y, Ymin, Ymax, 0, int(height))
|
||||||
|
touch.X = rawX
|
||||||
|
touch.Y = rawY
|
||||||
|
touch.Z = 1
|
||||||
|
} else {
|
||||||
|
touch.X = 0
|
||||||
|
touch.Y = 0
|
||||||
|
touch.Z = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if last.Z != touch.Z {
|
||||||
|
debounce = 0
|
||||||
|
last = touch
|
||||||
|
} else if math.Abs(float64(touch.X-last.X)) > 4 ||
|
||||||
|
math.Abs(float64(touch.Y-last.Y)) > 4 {
|
||||||
|
debounce = 0
|
||||||
|
last = touch
|
||||||
|
} else if debounce > 1 {
|
||||||
|
debounce = 0
|
||||||
|
HandleTouch(display, last)
|
||||||
|
} else if touch.Z > 0 {
|
||||||
|
debounce++
|
||||||
|
} else {
|
||||||
|
last = touch
|
||||||
|
debounce = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on Arduino's "map" function
|
||||||
|
func mapval(x int, inMin int, inMax int, outMin int, outMax int) int {
|
||||||
|
return (x-inMin)*(outMax-outMin)/(inMax-inMin) + outMin
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleTouch(display touchPaintDisplay, touch touch.Point) {
|
||||||
|
|
||||||
|
if int16(touch.Y) < boxSize {
|
||||||
|
oldColor = currentColor
|
||||||
|
x := int16(touch.X)
|
||||||
|
switch {
|
||||||
|
case x < boxSize:
|
||||||
|
currentColor = red
|
||||||
|
case x < boxSize*2:
|
||||||
|
currentColor = yellow
|
||||||
|
case x < boxSize*3:
|
||||||
|
currentColor = green
|
||||||
|
case x < boxSize*4:
|
||||||
|
currentColor = cyan
|
||||||
|
case x < boxSize*5:
|
||||||
|
currentColor = blue
|
||||||
|
case x < boxSize*6:
|
||||||
|
currentColor = magenta
|
||||||
|
case x < boxSize*7:
|
||||||
|
currentColor = black
|
||||||
|
case x < boxSize*8:
|
||||||
|
currentColor = white
|
||||||
|
}
|
||||||
|
|
||||||
|
if oldColor == currentColor {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
display.DrawRectangle((x/boxSize)*boxSize, 0, boxSize, boxSize, white)
|
||||||
|
switch oldColor {
|
||||||
|
case red:
|
||||||
|
x = 0
|
||||||
|
case yellow:
|
||||||
|
x = boxSize
|
||||||
|
case green:
|
||||||
|
x = boxSize * 2
|
||||||
|
case cyan:
|
||||||
|
x = boxSize * 3
|
||||||
|
case blue:
|
||||||
|
x = boxSize * 4
|
||||||
|
case magenta:
|
||||||
|
x = boxSize * 5
|
||||||
|
case black:
|
||||||
|
x = boxSize * 6
|
||||||
|
case white:
|
||||||
|
x = boxSize * 7
|
||||||
|
}
|
||||||
|
display.FillRectangle(int16(x), 0, boxSize, boxSize, oldColor)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (int16(touch.Y) - penRadius) > boxSize {
|
||||||
|
display.FillRectangle(
|
||||||
|
int16(touch.X), int16(touch.Y), penRadius*2, penRadius*2, currentColor)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/hts221"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
|
machine.I2C1.Configure(machine.I2CConfig{
|
||||||
|
SCL: machine.SCL1_PIN,
|
||||||
|
SDA: machine.SDA1_PIN,
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := hts221.New(machine.I2C1)
|
||||||
|
|
||||||
|
sensor.Configure() // power on and calibrate
|
||||||
|
|
||||||
|
if !sensor.Connected() {
|
||||||
|
println("HTS221 not connected!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
h, _ := sensor.ReadHumidity()
|
||||||
|
t, _ := sensor.ReadTemperature()
|
||||||
|
println("h =", float32(h)/100.0, "% / t =", float32(t)/1000.0, "*C")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/adt7410"
|
||||||
|
"tinygo.org/x/drivers/i2csoft"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
i2c := i2csoft.New(machine.SCL_PIN, machine.SDA_PIN)
|
||||||
|
i2c.Configure(i2csoft.I2CConfig{
|
||||||
|
Frequency: 400e3,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := adt7410.New(i2c)
|
||||||
|
sensor.Configure()
|
||||||
|
|
||||||
|
for {
|
||||||
|
temp := sensor.ReadTempF()
|
||||||
|
fmt.Printf("temperature: %f\r\n", temp)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build atsamd21
|
|
||||||
// +build atsamd21
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI0,
|
|
||||||
machine.D0,
|
|
||||||
machine.D1,
|
|
||||||
machine.D2,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.D3
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI0.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.SPI0_SCK_PIN,
|
|
||||||
SDO: machine.SPI0_SDO_PIN,
|
|
||||||
SDI: machine.SPI0_SDI_PIN,
|
|
||||||
Frequency: 24000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/examples/ili9341/initdisplay"
|
||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,16 +16,15 @@ var (
|
|||||||
green = color.RGBA{0, 255, 0, 255}
|
green = color.RGBA{0, 255, 0, 255}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
display *ili9341.Device
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
display = initdisplay.InitDisplay()
|
||||||
|
|
||||||
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
|
||||||
|
|
||||||
display.Configure(ili9341.Config{})
|
|
||||||
width, height := display.Size()
|
width, height := display.Size()
|
||||||
|
|
||||||
display.FillScreen(black)
|
|
||||||
backlight.High()
|
|
||||||
|
|
||||||
display.FillRectangle(0, 0, width/2, height/2, white)
|
display.FillRectangle(0, 0, width/2, height/2, white)
|
||||||
display.FillRectangle(width/2, 0, width/2, height/2, red)
|
display.FillRectangle(width/2, 0, width/2, height/2, red)
|
||||||
display.FillRectangle(0, height/2, width/2, height/2, green)
|
display.FillRectangle(0, height/2, width/2, height/2, green)
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
//go:build pyportal
|
|
||||||
// +build pyportal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewParallel(
|
|
||||||
machine.LCD_DATA0,
|
|
||||||
machine.TFT_WR,
|
|
||||||
machine.TFT_DC,
|
|
||||||
machine.TFT_CS,
|
|
||||||
machine.TFT_RESET,
|
|
||||||
machine.TFT_RD,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.TFT_BACKLIGHT
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build wioterminal
|
|
||||||
// +build wioterminal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI3,
|
|
||||||
machine.LCD_DC,
|
|
||||||
machine.LCD_SS_PIN,
|
|
||||||
machine.LCD_RESET,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.LCD_BACKLIGHT
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI3.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.LCD_SCK_PIN,
|
|
||||||
SDO: machine.LCD_SDO_PIN,
|
|
||||||
SDI: machine.LCD_SDI_PIN,
|
|
||||||
Frequency: 40000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
//go:build atsamd21
|
||||||
|
// +build atsamd21
|
||||||
|
|
||||||
|
package initdisplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ()
|
||||||
|
|
||||||
|
func InitDisplay() *ili9341.Device {
|
||||||
|
machine.SPI0.Configure(machine.SPIConfig{
|
||||||
|
SCK: machine.SPI0_SCK_PIN,
|
||||||
|
SDO: machine.SPI0_SDO_PIN,
|
||||||
|
SDI: machine.SPI0_SDI_PIN,
|
||||||
|
Frequency: 24000000,
|
||||||
|
})
|
||||||
|
|
||||||
|
// configure backlight
|
||||||
|
backlight := machine.D3
|
||||||
|
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI0,
|
||||||
|
machine.D0,
|
||||||
|
machine.D1,
|
||||||
|
machine.D2,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{})
|
||||||
|
|
||||||
|
backlight.High()
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation270)
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
//go:build feather_m0 || feather_m4 || feather_m4_can || feather_nrf52840 || feather_nrf52840_sense || feather_stm32f405 || feather_rp2040
|
||||||
|
// +build feather_m0 feather_m4 feather_m4_can feather_nrf52840 feather_nrf52840_sense feather_stm32f405 feather_rp2040
|
||||||
|
|
||||||
|
package initdisplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitDisplay() *ili9341.Device {
|
||||||
|
machine.D5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.D6.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|
||||||
|
machine.SPI0.Configure(machine.SPIConfig{
|
||||||
|
SCK: machine.SPI0_SCK_PIN,
|
||||||
|
SDO: machine.SPI0_SDO_PIN,
|
||||||
|
SDI: machine.SPI0_SDI_PIN,
|
||||||
|
Frequency: 40000000,
|
||||||
|
})
|
||||||
|
|
||||||
|
// configure backlight
|
||||||
|
backlight := machine.D9
|
||||||
|
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI0,
|
||||||
|
machine.D10, // LCD_DC,
|
||||||
|
machine.D11, // LCD_SS_PIN,
|
||||||
|
machine.D12, // LCD_RESET,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{})
|
||||||
|
|
||||||
|
backlight.High()
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation270)
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
//go:build m5stack
|
||||||
|
// +build m5stack
|
||||||
|
|
||||||
|
package initdisplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitDisplay() *ili9341.Device {
|
||||||
|
machine.SPI2.Configure(machine.SPIConfig{
|
||||||
|
SCK: machine.SPI0_SCK_PIN,
|
||||||
|
SDO: machine.SPI0_SDO_PIN,
|
||||||
|
SDI: machine.SPI0_SDI_PIN,
|
||||||
|
Frequency: 40e6,
|
||||||
|
})
|
||||||
|
|
||||||
|
// configure backlight
|
||||||
|
backlight := machine.LCD_BL_PIN
|
||||||
|
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI2,
|
||||||
|
machine.LCD_DC_PIN,
|
||||||
|
machine.LCD_SS_PIN,
|
||||||
|
machine.LCD_RST_PIN,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{
|
||||||
|
Width: 320,
|
||||||
|
Height: 240,
|
||||||
|
DisplayInversion: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
backlight.High()
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation0Mirror)
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
|
package initdisplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
axp192 "tinygo.org/x/drivers/axp192/m5stack-core2-axp192"
|
||||||
|
"tinygo.org/x/drivers/i2csoft"
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
)
|
||||||
|
|
||||||
|
// InitDisplay initializes the display of each board.
|
||||||
|
func InitDisplay() *ili9341.Device {
|
||||||
|
machine.SPI2.Configure(machine.SPIConfig{
|
||||||
|
SCK: machine.LCD_SCK_PIN,
|
||||||
|
SDO: machine.LCD_SDO_PIN,
|
||||||
|
SDI: machine.LCD_SDI_PIN,
|
||||||
|
Frequency: 40e6,
|
||||||
|
})
|
||||||
|
|
||||||
|
i2c := i2csoft.New(machine.SCL0_PIN, machine.SDA0_PIN)
|
||||||
|
i2c.Configure(i2csoft.I2CConfig{Frequency: 100e3})
|
||||||
|
|
||||||
|
axp := axp192.New(i2c)
|
||||||
|
led := axp.LED
|
||||||
|
led.Low()
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI2,
|
||||||
|
machine.LCD_DC_PIN,
|
||||||
|
machine.LCD_SS_PIN,
|
||||||
|
machine.NoPin,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{
|
||||||
|
Width: 320,
|
||||||
|
Height: 240,
|
||||||
|
DisplayInversion: true,
|
||||||
|
})
|
||||||
|
display.FillScreen(color.RGBA{255, 255, 255, 255})
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation0Mirror)
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
//go:build pyportal
|
||||||
|
// +build pyportal
|
||||||
|
|
||||||
|
package initdisplay
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ili9341"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitDisplay() *ili9341.Device {
|
||||||
|
display := ili9341.NewParallel(
|
||||||
|
machine.LCD_DATA0,
|
||||||
|
machine.TFT_WR,
|
||||||
|
machine.TFT_DC,
|
||||||
|
machine.TFT_CS,
|
||||||
|
machine.TFT_RESET,
|
||||||
|
machine.TFT_RD,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure backlight
|
||||||
|
backlight := machine.TFT_BACKLIGHT
|
||||||
|
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{})
|
||||||
|
|
||||||
|
backlight.High()
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation270)
|
||||||
|
|
||||||
|
return display
|
||||||
|
}
|
||||||
+22
-13
@@ -1,7 +1,7 @@
|
|||||||
//go:build wioterminal
|
//go:build wioterminal
|
||||||
// +build wioterminal
|
// +build wioterminal
|
||||||
|
|
||||||
package main
|
package initdisplay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
"machine"
|
||||||
@@ -9,22 +9,31 @@ import (
|
|||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func InitDisplay() *ili9341.Device {
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI3,
|
|
||||||
machine.LCD_DC,
|
|
||||||
machine.LCD_SS_PIN,
|
|
||||||
machine.LCD_RESET,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.LCD_BACKLIGHT
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI3.Configure(machine.SPIConfig{
|
machine.SPI3.Configure(machine.SPIConfig{
|
||||||
SCK: machine.LCD_SCK_PIN,
|
SCK: machine.LCD_SCK_PIN,
|
||||||
SDO: machine.LCD_SDO_PIN,
|
SDO: machine.LCD_SDO_PIN,
|
||||||
SDI: machine.LCD_SDI_PIN,
|
SDI: machine.LCD_SDI_PIN,
|
||||||
Frequency: 40000000,
|
Frequency: 40000000,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// configure backlight
|
||||||
|
backlight := machine.LCD_BACKLIGHT
|
||||||
|
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
||||||
|
|
||||||
|
display := ili9341.NewSPI(
|
||||||
|
machine.SPI3,
|
||||||
|
machine.LCD_DC,
|
||||||
|
machine.LCD_SS_PIN,
|
||||||
|
machine.LCD_RESET,
|
||||||
|
)
|
||||||
|
|
||||||
|
// configure display
|
||||||
|
display.Configure(ili9341.Config{})
|
||||||
|
|
||||||
|
backlight.High()
|
||||||
|
|
||||||
|
display.SetRotation(ili9341.Rotation270)
|
||||||
|
|
||||||
|
return display
|
||||||
}
|
}
|
||||||
@@ -3,9 +3,9 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/examples/ili9341/initdisplay"
|
||||||
"tinygo.org/x/drivers/examples/ili9341/pyportal_boing/graphics"
|
"tinygo.org/x/drivers/examples/ili9341/pyportal_boing/graphics"
|
||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
)
|
)
|
||||||
@@ -44,20 +44,17 @@ var (
|
|||||||
palette [16]uint16
|
palette [16]uint16
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
display *ili9341.Device
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
display = initdisplay.InitDisplay()
|
||||||
|
|
||||||
// configure backlight
|
|
||||||
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
|
||||||
|
|
||||||
// configure display
|
|
||||||
display.Configure(ili9341.Config{})
|
|
||||||
print("width, height == ")
|
print("width, height == ")
|
||||||
width, height := display.Size()
|
width, height := display.Size()
|
||||||
println(width, height)
|
println(width, height)
|
||||||
|
|
||||||
backlight.High()
|
|
||||||
|
|
||||||
display.SetRotation(ili9341.Rotation270)
|
|
||||||
DrawBackground()
|
DrawBackground()
|
||||||
|
|
||||||
startTime = time.Now().UnixNano()
|
startTime = time.Now().UnixNano()
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
//go:build pyportal
|
|
||||||
// +build pyportal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewParallel(
|
|
||||||
machine.LCD_DATA0,
|
|
||||||
machine.TFT_WR,
|
|
||||||
machine.TFT_DC,
|
|
||||||
machine.TFT_CS,
|
|
||||||
machine.TFT_RESET,
|
|
||||||
machine.TFT_RD,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.TFT_BACKLIGHT
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build wioterminal
|
|
||||||
// +build wioterminal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI3,
|
|
||||||
machine.LCD_DC,
|
|
||||||
machine.LCD_SS_PIN,
|
|
||||||
machine.LCD_RESET,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.LCD_BACKLIGHT
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI3.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.LCD_SCK_PIN,
|
|
||||||
SDO: machine.LCD_SDO_PIN,
|
|
||||||
SDI: machine.LCD_SDI_PIN,
|
|
||||||
Frequency: 40000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build atsamd21
|
|
||||||
// +build atsamd21
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI0,
|
|
||||||
machine.D0,
|
|
||||||
machine.D1,
|
|
||||||
machine.D2,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.D3
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI0.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.SPI0_SCK_PIN,
|
|
||||||
SDO: machine.SPI0_SDO_PIN,
|
|
||||||
SDI: machine.SPI0_SDI_PIN,
|
|
||||||
Frequency: 24000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -2,9 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/examples/ili9341/initdisplay"
|
||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -16,16 +16,15 @@ var (
|
|||||||
white = color.RGBA{255, 255, 255, 255}
|
white = color.RGBA{255, 255, 255, 255}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
display *ili9341.Device
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
display := initdisplay.InitDisplay()
|
||||||
|
|
||||||
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
|
||||||
|
|
||||||
display.Configure(ili9341.Config{})
|
|
||||||
width, height := display.Size()
|
width, height := display.Size()
|
||||||
|
|
||||||
display.FillScreen(black)
|
|
||||||
backlight.High()
|
|
||||||
|
|
||||||
display.FillRectangle(0, 0, width/2, height/2, white)
|
display.FillRectangle(0, 0, width/2, height/2, white)
|
||||||
display.FillRectangle(width/2, 0, width/2, height/2, red)
|
display.FillRectangle(width/2, 0, width/2, height/2, red)
|
||||||
display.FillRectangle(0, height/2, width/2, height/2, green)
|
display.FillRectangle(0, height/2, width/2, height/2, green)
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
//go:build pyportal
|
|
||||||
// +build pyportal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewParallel(
|
|
||||||
machine.LCD_DATA0,
|
|
||||||
machine.TFT_WR,
|
|
||||||
machine.TFT_DC,
|
|
||||||
machine.TFT_CS,
|
|
||||||
machine.TFT_RESET,
|
|
||||||
machine.TFT_RD,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.TFT_BACKLIGHT
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build atsamd21
|
|
||||||
// +build atsamd21
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI0,
|
|
||||||
machine.D0,
|
|
||||||
machine.D1,
|
|
||||||
machine.D2,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.D3
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI0.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.SPI0_SCK_PIN,
|
|
||||||
SDO: machine.SPI0_SDO_PIN,
|
|
||||||
SDI: machine.SPI0_SDI_PIN,
|
|
||||||
Frequency: 24000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -3,10 +3,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"image/color"
|
"image/color"
|
||||||
"machine"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/examples/ili9341/initdisplay"
|
||||||
"tinygo.org/x/drivers/ili9341"
|
"tinygo.org/x/drivers/ili9341"
|
||||||
"tinygo.org/x/drivers/image/jpeg"
|
"tinygo.org/x/drivers/image/jpeg"
|
||||||
"tinygo.org/x/drivers/image/png"
|
"tinygo.org/x/drivers/image/png"
|
||||||
@@ -20,6 +20,10 @@ var (
|
|||||||
green = color.RGBA{0, 255, 0, 255}
|
green = color.RGBA{0, 255, 0, 255}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
display *ili9341.Device
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
err := run()
|
err := run()
|
||||||
for err != nil {
|
for err != nil {
|
||||||
@@ -28,9 +32,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func run() error {
|
func run() error {
|
||||||
backlight.Configure(machine.PinConfig{machine.PinOutput})
|
display = initdisplay.InitDisplay()
|
||||||
|
|
||||||
display.Configure(ili9341.Config{})
|
|
||||||
|
|
||||||
width, height := display.Size()
|
width, height := display.Size()
|
||||||
if width < 320 || height < 240 {
|
if width < 320 || height < 240 {
|
||||||
@@ -38,7 +40,6 @@ func run() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
display.FillScreen(black)
|
display.FillScreen(black)
|
||||||
backlight.High()
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
err := drawJpeg(display)
|
err := drawJpeg(display)
|
||||||
@@ -71,7 +72,8 @@ func drawPng(display *ili9341.Device) error {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return png.Decode(p)
|
_, err := png.Decode(p)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawJpeg(display *ili9341.Device) error {
|
func drawJpeg(display *ili9341.Device) error {
|
||||||
@@ -83,7 +85,8 @@ func drawJpeg(display *ili9341.Device) error {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return jpeg.Decode(p)
|
_, err := jpeg.Decode(p)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func errorMessage(err error) {
|
func errorMessage(err error) {
|
||||||
|
|||||||
@@ -1,23 +0,0 @@
|
|||||||
//go:build pyportal
|
|
||||||
// +build pyportal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewParallel(
|
|
||||||
machine.LCD_DATA0,
|
|
||||||
machine.TFT_WR,
|
|
||||||
machine.TFT_DC,
|
|
||||||
machine.TFT_CS,
|
|
||||||
machine.TFT_RESET,
|
|
||||||
machine.TFT_RD,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.TFT_BACKLIGHT
|
|
||||||
)
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
//go:build wioterminal
|
|
||||||
// +build wioterminal
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"machine"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/ili9341"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
display = ili9341.NewSPI(
|
|
||||||
machine.SPI3,
|
|
||||||
machine.LCD_DC,
|
|
||||||
machine.LCD_SS_PIN,
|
|
||||||
machine.LCD_RESET,
|
|
||||||
)
|
|
||||||
|
|
||||||
backlight = machine.LCD_BACKLIGHT
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
machine.SPI3.Configure(machine.SPIConfig{
|
|
||||||
SCK: machine.LCD_SCK_PIN,
|
|
||||||
SDO: machine.LCD_SDO_PIN,
|
|
||||||
SDI: machine.LCD_SDI_PIN,
|
|
||||||
Frequency: 40000000,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/irremote"
|
||||||
|
)
|
||||||
|
|
||||||
|
var irCmdButtons = map[uint16]string{
|
||||||
|
0xA2: "POWER",
|
||||||
|
0xE2: "FUNC/STOP",
|
||||||
|
0x62: "VOL+",
|
||||||
|
0x22: "FAST BACK",
|
||||||
|
0x02: "PAUSE",
|
||||||
|
0xC2: "FAST FORWARD",
|
||||||
|
0xE0: "DOWN",
|
||||||
|
0xA8: "VOL-",
|
||||||
|
0x90: "UP",
|
||||||
|
0x98: "EQ",
|
||||||
|
0xB0: "ST/REPT",
|
||||||
|
0x68: "0",
|
||||||
|
0x30: "1",
|
||||||
|
0x18: "2",
|
||||||
|
0x7A: "3",
|
||||||
|
0x10: "4",
|
||||||
|
0x38: "5",
|
||||||
|
0x5A: "6",
|
||||||
|
0x42: "7",
|
||||||
|
0x4A: "8",
|
||||||
|
0x52: "9",
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
pinIRIn = machine.GP26
|
||||||
|
ir irremote.ReceiverDevice
|
||||||
|
)
|
||||||
|
|
||||||
|
func setupPins() {
|
||||||
|
ir = irremote.NewReceiver(pinIRIn)
|
||||||
|
ir.Configure()
|
||||||
|
}
|
||||||
|
|
||||||
|
func irCallback(data irremote.Data) {
|
||||||
|
msg := "Command: " + irCmdButtons[data.Command]
|
||||||
|
if data.Flags&irremote.DataFlagIsRepeat != 0 {
|
||||||
|
msg = msg + " (REPEAT)"
|
||||||
|
}
|
||||||
|
println(msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
setupPins()
|
||||||
|
ir.SetCommandHandler(irCallback)
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Millisecond * 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/is31fl3731"
|
||||||
|
)
|
||||||
|
|
||||||
|
// I2CAddress -- address of led matrix
|
||||||
|
var I2CAddress uint8 = is31fl3731.I2C_ADDRESS_74
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
bus := machine.I2C0
|
||||||
|
err := bus.Configure(machine.I2CConfig{})
|
||||||
|
if err != nil {
|
||||||
|
println("could not configure I2C:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create driver for Adafruit 15x7 CharliePlex LED Matrix FeatherWing
|
||||||
|
// (CharlieWing): https://www.adafruit.com/product/3163
|
||||||
|
ledMatrix := is31fl3731.NewAdafruitCharlieWing15x7(bus, I2CAddress)
|
||||||
|
|
||||||
|
err = ledMatrix.Configure()
|
||||||
|
if err != nil {
|
||||||
|
println("could not configure is31fl3731 driver:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill the whole matrix on the frame #0 (visible by default)
|
||||||
|
ledMatrix.Fill(is31fl3731.FRAME_0, uint8(3))
|
||||||
|
|
||||||
|
// Draw couple pixels on the frame #1 (not visible yet)
|
||||||
|
ledMatrix.DrawPixelXY(is31fl3731.FRAME_1, uint8(0), uint8(0), uint8(10))
|
||||||
|
ledMatrix.DrawPixelXY(is31fl3731.FRAME_1, uint8(14), uint8(6), uint8(10))
|
||||||
|
|
||||||
|
// There are 8 frames available, it's a good idea to draw on an invisible
|
||||||
|
// frame and then switch to that frame to reduce flickering. Switch between
|
||||||
|
// frame #0 and #1 in a loop to show animation:
|
||||||
|
for {
|
||||||
|
println("show frame #0...")
|
||||||
|
ledMatrix.SetActiveFrame(is31fl3731.FRAME_0)
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
|
||||||
|
println("show frame #1...")
|
||||||
|
ledMatrix.SetActiveFrame(is31fl3731.FRAME_1)
|
||||||
|
time.Sleep(time.Second * 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/l3gd20"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
// Default address on most breakout boards.
|
||||||
|
pcaAddr = 0x40
|
||||||
|
)
|
||||||
|
|
||||||
|
bus := machine.I2C0
|
||||||
|
|
||||||
|
err := bus.Configure(machine.I2CConfig{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
gyro := l3gd20.NewI2C(bus, 105)
|
||||||
|
err = gyro.Configure(l3gd20.Config{Range: l3gd20.Range_250})
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var x, y, z int32
|
||||||
|
for {
|
||||||
|
err = gyro.Update()
|
||||||
|
if err != nil {
|
||||||
|
println(err.Error())
|
||||||
|
}
|
||||||
|
x, y, z = gyro.AngularVelocity()
|
||||||
|
println(x, y, z)
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/lps22hb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// use Nano 33 BLE Sense's internal I2C bus
|
||||||
|
machine.I2C1.Configure(machine.I2CConfig{
|
||||||
|
SCL: machine.SCL1_PIN,
|
||||||
|
SDA: machine.SDA1_PIN,
|
||||||
|
Frequency: machine.TWI_FREQ_400KHZ,
|
||||||
|
})
|
||||||
|
|
||||||
|
sensor := lps22hb.New(machine.I2C1)
|
||||||
|
sensor.Configure()
|
||||||
|
|
||||||
|
if !sensor.Connected() {
|
||||||
|
println("LPS22HB not connected!")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
p, _ := sensor.ReadPressure()
|
||||||
|
t, _ := sensor.ReadTemperature()
|
||||||
|
println("p =", float32(p)/1000.0, "hPa / t =", float32(t)/1000.0, "*C")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
// note: the device would power down itself after each query
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+42
-17
@@ -3,37 +3,62 @@ package main
|
|||||||
import (
|
import (
|
||||||
"machine"
|
"machine"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"tinygo.org/x/drivers/lsm303agr"
|
"tinygo.org/x/drivers/lsm303agr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
||||||
|
// LSM303AGR/MAG is connected to the I2C0 bus on micro:bit v1 (the same as P19/P20) and v2 (internal)
|
||||||
machine.I2C0.Configure(machine.I2CConfig{})
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
accel_mag := lsm303agr.New(machine.I2C0)
|
|
||||||
|
|
||||||
if !accel_mag.Connected() {
|
sensor := lsm303agr.New(machine.I2C0)
|
||||||
println("LSM303AGR/MAG not connected!")
|
err := sensor.Configure(lsm303agr.Configuration{}) //default settings
|
||||||
return
|
if err != nil {
|
||||||
|
for {
|
||||||
|
println("Failed to configure", err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
accel_mag.Configure(lsm303agr.Configuration{}) //default settings
|
// you can specify the following options to adjust accuracy, sensor range or save power.
|
||||||
|
// see https://github.com/tinygo-org/drivers/blob/release/lsm303agr/registers.go for details:
|
||||||
|
/*
|
||||||
|
sensor.Configure(lsm303agr.Configuration{
|
||||||
|
AccelPowerMode: lsm303agr.ACCEL_POWER_NORMAL,
|
||||||
|
AccelRange: lsm303agr.ACCEL_RANGE_2G,
|
||||||
|
AccelDataRate: lsm303agr.ACCEL_DATARATE_100HZ,
|
||||||
|
MagPowerMode: lsm303agr.MAG_POWER_NORMAL,
|
||||||
|
MagSystemMode: lsm303agr.MAG_SYSTEM_CONTINUOUS,
|
||||||
|
MagDataRate: lsm303agr.MAG_DATARATE_10HZ,
|
||||||
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
accel_x, accel_y, accel_z := accel_mag.ReadAcceleration()
|
if !sensor.Connected() {
|
||||||
pitch, roll := accel_mag.ReadPitchRoll()
|
println("LSM303AGR/MAG not connected!")
|
||||||
mag_x, mag_y, mag_z := accel_mag.ReadMagneticField()
|
time.Sleep(time.Second)
|
||||||
heading := accel_mag.ReadCompass()
|
continue
|
||||||
temp, _ := accel_mag.ReadTemperature()
|
}
|
||||||
|
|
||||||
|
// accel_x, accel_y, accel_z := sensor.ReadAcceleration()
|
||||||
|
// println("ACCEL_X:", accel_x/100000, " ACCEL_Y:", accel_y/100000, " ACCEL_Z:", accel_z/100000)
|
||||||
|
|
||||||
|
// mag_x, mag_y, mag_z := sensor.ReadMagneticField()
|
||||||
|
// println("MAG_X:", mag_x/100000, " MAG_Y:", mag_y/100000, " MAG_Z:", mag_z/100000)
|
||||||
|
|
||||||
|
pitch, roll, _ := sensor.ReadPitchRoll()
|
||||||
|
println("Pitch:", float32(pitch)/100000, " Roll:", float32(roll)/100000)
|
||||||
|
|
||||||
|
heading, _ := sensor.ReadCompass()
|
||||||
|
println("Heading:", float32(heading)/100000, "degrees")
|
||||||
|
|
||||||
|
temp, _ := sensor.ReadTemperature()
|
||||||
|
println("Temperature:", float32(temp)/1000, "*C")
|
||||||
|
|
||||||
println("ACCEL_X:", accel_x, " ACCEL_Y:", accel_y, " ACCEL_Z:", accel_z)
|
|
||||||
println("MAG_X:", mag_x, " MAG_Y:", mag_y, " MAG_Z:", mag_z)
|
|
||||||
println("Pitch:", pitch, " Roll:", roll)
|
|
||||||
println("Heading:", heading)
|
|
||||||
println("Temperature:", temp/1000)
|
|
||||||
println("\n")
|
println("\n")
|
||||||
|
time.Sleep(time.Millisecond * 250)
|
||||||
time.Sleep(time.Millisecond * 100)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,16 +12,23 @@ func main() {
|
|||||||
machine.I2C0.Configure(machine.I2CConfig{})
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
|
|
||||||
accel := lsm6ds3.New(machine.I2C0)
|
accel := lsm6ds3.New(machine.I2C0)
|
||||||
accel.Configure(lsm6ds3.Configuration{})
|
err := accel.Configure(lsm6ds3.Configuration{})
|
||||||
if !accel.Connected() {
|
if err != nil {
|
||||||
println("LSM6DS3 not connected")
|
for {
|
||||||
return
|
println("Failed to configure", err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
x, y, z := accel.ReadAcceleration()
|
if !accel.Connected() {
|
||||||
|
println("LSM6DS3 not connected")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
x, y, z, _ := accel.ReadAcceleration()
|
||||||
println("Acceleration:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
|
println("Acceleration:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
|
||||||
x, y, z = accel.ReadRotation()
|
x, y, z, _ = accel.ReadRotation()
|
||||||
println("Gyroscope:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
|
println("Gyroscope:", float32(x)/1000000, float32(y)/1000000, float32(z)/1000000)
|
||||||
x, _ = accel.ReadTemperature()
|
x, _ = accel.ReadTemperature()
|
||||||
println("Degrees C", float32(x)/1000, "\n\n")
|
println("Degrees C", float32(x)/1000, "\n\n")
|
||||||
|
|||||||
@@ -26,12 +26,18 @@ func main() {
|
|||||||
machine.I2C0.Configure(machine.I2CConfig{})
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
|
|
||||||
device := lsm6dsox.New(machine.I2C0)
|
device := lsm6dsox.New(machine.I2C0)
|
||||||
device.Configure(lsm6dsox.Configuration{
|
err := device.Configure(lsm6dsox.Configuration{
|
||||||
AccelRange: lsm6dsox.ACCEL_2G,
|
AccelRange: lsm6dsox.ACCEL_2G,
|
||||||
AccelSampleRate: lsm6dsox.ACCEL_SR_104,
|
AccelSampleRate: lsm6dsox.ACCEL_SR_104,
|
||||||
GyroRange: lsm6dsox.GYRO_250DPS,
|
GyroRange: lsm6dsox.GYRO_250DPS,
|
||||||
GyroSampleRate: lsm6dsox.GYRO_SR_104,
|
GyroSampleRate: lsm6dsox.GYRO_SR_104,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
for {
|
||||||
|
println("Failed to configure", err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|
||||||
@@ -46,8 +52,8 @@ func main() {
|
|||||||
calibrateGyro(device)
|
calibrateGyro(device)
|
||||||
}
|
}
|
||||||
|
|
||||||
ax, ay, az := device.ReadAcceleration()
|
ax, ay, az, _ := device.ReadAcceleration()
|
||||||
gx, gy, gz := device.ReadRotation()
|
gx, gy, gz, _ := device.ReadRotation()
|
||||||
t, _ := device.ReadTemperature()
|
t, _ := device.ReadTemperature()
|
||||||
|
|
||||||
if PLOTTER {
|
if PLOTTER {
|
||||||
@@ -64,7 +70,7 @@ func main() {
|
|||||||
|
|
||||||
func calibrateGyro(device *lsm6dsox.Device) {
|
func calibrateGyro(device *lsm6dsox.Device) {
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
gx, gy, gz := device.ReadRotation()
|
gx, gy, gz, _ := device.ReadRotation()
|
||||||
cal[0] += float32(gx) / 1000000
|
cal[0] += float32(gx) / 1000000
|
||||||
cal[1] += float32(gy) / 1000000
|
cal[1] += float32(gy) / 1000000
|
||||||
cal[2] += float32(gz) / 1000000
|
cal[2] += float32(gz) / 1000000
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
// LSM9DS1, 9 axis Inertial Measurement Unit (IMU)
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/lsm9ds1"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
PLOTTER = false
|
||||||
|
SHOW_ACCELERATION = true
|
||||||
|
SHOW_ROTATION = true
|
||||||
|
SHOW_MAGNETIC_FIELD = true
|
||||||
|
SHOW_TEMPERATURE = true
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
// I2C configure
|
||||||
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
|
|
||||||
|
// LSM9DS1 setup
|
||||||
|
device := lsm9ds1.New(machine.I2C0)
|
||||||
|
err := device.Configure(lsm9ds1.Configuration{
|
||||||
|
AccelRange: lsm9ds1.ACCEL_2G,
|
||||||
|
AccelSampleRate: lsm9ds1.ACCEL_SR_119,
|
||||||
|
GyroRange: lsm9ds1.GYRO_250DPS,
|
||||||
|
GyroSampleRate: lsm9ds1.GYRO_SR_119,
|
||||||
|
MagRange: lsm9ds1.MAG_4G,
|
||||||
|
MagSampleRate: lsm9ds1.MAG_SR_40,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
for {
|
||||||
|
println("Failed to configure", err.Error())
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
if !device.Connected() {
|
||||||
|
println("LSM9DS1 not connected")
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ax, ay, az, _ := device.ReadAcceleration()
|
||||||
|
gx, gy, gz, _ := device.ReadRotation()
|
||||||
|
mx, my, mz, _ := device.ReadMagneticField()
|
||||||
|
t, _ := device.ReadTemperature()
|
||||||
|
|
||||||
|
if PLOTTER {
|
||||||
|
printPlotter(ax, ay, az, gx, gy, gz, mx, my, mz, t)
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
} else {
|
||||||
|
printMonitor(ax, ay, az, gx, gy, gz, mx, my, mz, t)
|
||||||
|
time.Sleep(time.Millisecond * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arduino IDE's Serial Plotter
|
||||||
|
func printPlotter(ax, ay, az, gx, gy, gz, mx, my, mz, t int32) {
|
||||||
|
if SHOW_ACCELERATION {
|
||||||
|
fmt.Printf("AX:%f, AY:%f, AZ:%f,", axis(ax), axis(ay), axis(az))
|
||||||
|
}
|
||||||
|
if SHOW_ROTATION {
|
||||||
|
fmt.Printf("GX:%f, GY:%f, GZ:%f,", axis(gx), axis(gy), axis(gz))
|
||||||
|
}
|
||||||
|
if SHOW_MAGNETIC_FIELD {
|
||||||
|
fmt.Printf("MX:%d, MY:%d, MZ:%d,", mx, my, mz)
|
||||||
|
}
|
||||||
|
if SHOW_TEMPERATURE {
|
||||||
|
fmt.Printf("T:%f", float32(t)/1000)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Any Serial Monitor
|
||||||
|
func printMonitor(ax, ay, az, gx, gy, gz, mx, my, mz, t int32) {
|
||||||
|
if SHOW_ACCELERATION {
|
||||||
|
fmt.Printf("Acceleration (g): %f, %f, %f\r\n", axis(ax), axis(ay), axis(az))
|
||||||
|
}
|
||||||
|
if SHOW_ROTATION {
|
||||||
|
fmt.Printf("Rotation (dps): %f, %f, %f\r\n", axis(gx), axis(gy), axis(gz))
|
||||||
|
}
|
||||||
|
if SHOW_MAGNETIC_FIELD {
|
||||||
|
fmt.Printf("Magnetic field (nT): %d, %d, %d\r\n", mx, my, mz)
|
||||||
|
}
|
||||||
|
if SHOW_TEMPERATURE {
|
||||||
|
fmt.Printf("Temperature C: %f\r\n", float32(t)/1000)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
|
||||||
|
func axis(raw int32) float32 {
|
||||||
|
return float32(raw) / 1000000
|
||||||
|
}
|
||||||
@@ -29,6 +29,7 @@ func main() {
|
|||||||
driver.StopDisplayTest()
|
driver.StopDisplayTest()
|
||||||
driver.SetDecodeMode(4)
|
driver.SetDecodeMode(4)
|
||||||
driver.SetScanLimit(4)
|
driver.SetScanLimit(4)
|
||||||
|
driver.SetIntensity(8)
|
||||||
driver.StopShutdownMode()
|
driver.StopShutdownMode()
|
||||||
|
|
||||||
for i := 1; i < int(digitNumber); i++ {
|
for i := 1; i < int(digitNumber); i++ {
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/pca9685"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
const (
|
||||||
|
// Default address on most breakout boards.
|
||||||
|
pcaAddr = 0x40
|
||||||
|
)
|
||||||
|
err := machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
d := pca9685.New(machine.I2C0, 0x40)
|
||||||
|
err = d.IsConnected()
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
err = d.Configure(pca9685.PWMConfig{Period: 1e9 / 200}) // 200Hz PWM
|
||||||
|
if err != nil {
|
||||||
|
panic(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
var value uint32
|
||||||
|
step := d.Top() / 5
|
||||||
|
for {
|
||||||
|
for value = 0; value <= d.Top(); value += step {
|
||||||
|
d.SetAll(value)
|
||||||
|
dc := 100 * value / d.Top()
|
||||||
|
println("set dc @", dc, "%")
|
||||||
|
time.Sleep(800 * time.Millisecond)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ScanI2CDev finds I2C devices on the bus and rreturns them inside
|
||||||
|
// a slice. If slice is nil then no devices were found.
|
||||||
|
func ScanI2CDev(bus machine.I2C) (addrs []uint8) {
|
||||||
|
var addr, count uint8
|
||||||
|
var err error
|
||||||
|
w := []byte{1}
|
||||||
|
// Count devices in first scan
|
||||||
|
for addr = 1; addr < 127; addr++ {
|
||||||
|
err = bus.Tx(uint16(addr), w, nil)
|
||||||
|
if err == nil {
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
// Allocate slice and populate slice with addresses
|
||||||
|
addrs = make([]uint8, count)
|
||||||
|
count = 0
|
||||||
|
for addr = 1; addr < 127; addr++ {
|
||||||
|
err = bus.Tx(uint16(addr), w, nil)
|
||||||
|
if err == nil && count < uint8(len(addrs)) {
|
||||||
|
addrs[count] = addr
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return addrs
|
||||||
|
}
|
||||||
@@ -65,7 +65,7 @@ func run() error {
|
|||||||
}
|
}
|
||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func run() error {
|
|||||||
}
|
}
|
||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func run() error {
|
|||||||
}
|
}
|
||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ func run() error {
|
|||||||
}
|
}
|
||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ func run() error {
|
|||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
http.SetBuf(buf[:])
|
http.SetBuf(buf[:])
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func run() error {
|
|||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
http.SetBuf(buf[:])
|
http.SetBuf(buf[:])
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ func run() error {
|
|||||||
http.SetBuf(buf[:])
|
http.SetBuf(buf[:])
|
||||||
|
|
||||||
fmt.Fprintf(terminal, "ConnectToAP()\r\n")
|
fmt.Fprintf(terminal, "ConnectToAP()\r\n")
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func run() error {
|
|||||||
net.UseDriver(rtl)
|
net.UseDriver(rtl)
|
||||||
http.SetBuf(buf[:])
|
http.SetBuf(buf[:])
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func run() error {
|
|||||||
}
|
}
|
||||||
http.UseDriver(rtl)
|
http.UseDriver(rtl)
|
||||||
|
|
||||||
err = rtl.ConnectToAP(ssid, password)
|
err = rtl.ConnectToAccessPoint(ssid, password, 10*time.Second)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/shtc3"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
machine.I2C0.Configure(machine.I2CConfig{})
|
||||||
|
sensor := shtc3.New(machine.I2C0)
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
sensor.WakeUp()
|
||||||
|
|
||||||
|
temp, humidity, _ := sensor.ReadTemperatureHumidity()
|
||||||
|
t := fmt.Sprintf("%.2f", float32(temp)/1000)
|
||||||
|
h := fmt.Sprintf("%.2f", float32(humidity)/100)
|
||||||
|
println("Temperature:", t, "°C")
|
||||||
|
println("Humidity", h, "%")
|
||||||
|
|
||||||
|
sensor.Sleep()
|
||||||
|
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"machine"
|
||||||
|
"math/rand"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/ssd1289"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
//The SSD1289 is configured in 16 bit parallel mode and requires 16 GPIOs
|
||||||
|
//The Pin bus is the most flexible but ineffecient method it switches
|
||||||
|
//individual pins on and off. If you are able to use consecutive pins
|
||||||
|
//consider creating a more efficient bus implementation that uses
|
||||||
|
//your microcontrollers built in "ports"
|
||||||
|
//see rp2040bus.go for an example for the rapsberry pi pico
|
||||||
|
bus := ssd1289.NewPinBus([16]machine.Pin{
|
||||||
|
machine.GP4, //DB0
|
||||||
|
machine.GP5, //DB1
|
||||||
|
machine.GP6, //DB2
|
||||||
|
machine.GP7, //DB3
|
||||||
|
machine.GP8, //DB4
|
||||||
|
machine.GP9, //DB5
|
||||||
|
machine.GP10, //DB6
|
||||||
|
machine.GP11, //DB7
|
||||||
|
machine.GP12, //DB8
|
||||||
|
machine.GP13, //DB9
|
||||||
|
machine.GP14, //DB10
|
||||||
|
machine.GP15, //DB11
|
||||||
|
machine.GP16, //DB12
|
||||||
|
machine.GP17, //DB13
|
||||||
|
machine.GP18, //DB14
|
||||||
|
machine.GP19, //DB15
|
||||||
|
})
|
||||||
|
|
||||||
|
//Control pins for the SSD1289
|
||||||
|
rs := machine.GP0
|
||||||
|
wr := machine.GP1
|
||||||
|
cs := machine.GP2
|
||||||
|
rst := machine.GP3
|
||||||
|
|
||||||
|
display := ssd1289.New(rs, wr, cs, rst, bus)
|
||||||
|
|
||||||
|
display.Configure() //Sends intialization sequence to SSD1289.
|
||||||
|
//!! After configure the display will contain random data and needs to be cleared
|
||||||
|
|
||||||
|
background := color.RGBA{0, 0, 0, 255} //Black
|
||||||
|
display.FillDisplay(background) //Clears the display to the given color
|
||||||
|
|
||||||
|
for {
|
||||||
|
//Draw random filled coloured rectangles
|
||||||
|
x := int16(rand.Intn(120))
|
||||||
|
w := int16(rand.Intn(120))
|
||||||
|
|
||||||
|
y := int16(rand.Intn(160))
|
||||||
|
h := int16(rand.Intn(160))
|
||||||
|
|
||||||
|
r := uint8(rand.Intn(255))
|
||||||
|
g := uint8(rand.Intn(255))
|
||||||
|
b := uint8(rand.Intn(255))
|
||||||
|
|
||||||
|
c := color.RGBA{r, g, b, 255}
|
||||||
|
|
||||||
|
display.FillRect(x, y, w, h, c) //Fills the given rectangle the rest of the display is unaffected.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// This example will periodically enable Continuous "Preamble" and "Wave" modes on 868.1 Mhz
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
rfswitch "tinygo.org/x/drivers/examples/sx126x/rfswitch"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/sx126x"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FREQ = 868100000
|
||||||
|
|
||||||
|
var (
|
||||||
|
loraRadio *sx126x.Device
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("\n# TinyGo Lora continuous Wave/Preamble test")
|
||||||
|
println("# -----------------------------------------")
|
||||||
|
|
||||||
|
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|
||||||
|
// Create the driver
|
||||||
|
loraRadio = sx126x.New(machine.SPI3)
|
||||||
|
loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262)
|
||||||
|
|
||||||
|
// Create RF Switch
|
||||||
|
var radioSwitch rfswitch.CustomSwitch
|
||||||
|
loraRadio.SetRfSwitch(radioSwitch)
|
||||||
|
|
||||||
|
state := loraRadio.DetectDevice()
|
||||||
|
if !state {
|
||||||
|
panic("sx126x not detected. ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare for Lora operation
|
||||||
|
loraConf := sx126x.LoraConfig{
|
||||||
|
Freq: FREQ,
|
||||||
|
Bw: sx126x.SX126X_LORA_BW_500_0,
|
||||||
|
Sf: sx126x.SX126X_LORA_SF9,
|
||||||
|
Cr: sx126x.SX126X_LORA_CR_4_7,
|
||||||
|
HeaderType: sx126x.SX126X_LORA_HEADER_EXPLICIT,
|
||||||
|
Preamble: 12,
|
||||||
|
Ldr: sx126x.SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF,
|
||||||
|
Iq: sx126x.SX126X_LORA_IQ_STANDARD,
|
||||||
|
Crc: sx126x.SX126X_LORA_CRC_ON,
|
||||||
|
SyncWord: sx126x.SX126X_LORA_MAC_PRIVATE_SYNCWORD,
|
||||||
|
LoraTxPowerDBm: 14,
|
||||||
|
}
|
||||||
|
loraRadio.LoraConfig(loraConf)
|
||||||
|
|
||||||
|
// Although LoraConfig has already configured most of Lora settings,
|
||||||
|
// the following lines are still required to enable Continuous Preamble/Wave
|
||||||
|
loraRadio.SetPacketType(sx126x.SX126X_PACKET_TYPE_LORA)
|
||||||
|
loraRadio.SetRfFrequency(loraConf.Freq)
|
||||||
|
loraRadio.SetModulationParams(loraConf.Sf, loraConf.Bw, loraConf.Cr, loraConf.Ldr)
|
||||||
|
loraRadio.SetTxParams(loraConf.LoraTxPowerDBm, sx126x.SX126X_PA_RAMP_200U)
|
||||||
|
|
||||||
|
for {
|
||||||
|
println("2 seconds in Continuous Preamble")
|
||||||
|
loraRadio.SetStandby()
|
||||||
|
loraRadio.SetTxContinuousPreamble()
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Continuous Preamble Stopped")
|
||||||
|
|
||||||
|
loraRadio.SetStandby()
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
|
||||||
|
println("2 seconds in Continuous Wave")
|
||||||
|
loraRadio.SetTxContinuousWave()
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
println(" Continuous Wave Stopped")
|
||||||
|
|
||||||
|
loraRadio.SetStandby()
|
||||||
|
time.Sleep(60 * time.Second)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
// In this example, a Lora packet will be sent every 10s
|
||||||
|
// module will be in RX mode between two transmissions
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/stm32"
|
||||||
|
"machine"
|
||||||
|
"runtime/interrupt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
rfswitch "tinygo.org/x/drivers/examples/sx126x/rfswitch"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/sx126x"
|
||||||
|
)
|
||||||
|
|
||||||
|
const FREQ = 868100000
|
||||||
|
|
||||||
|
const (
|
||||||
|
LORA_DEFAULT_RXTIMEOUT_MS = 1000
|
||||||
|
LORA_DEFAULT_TXTIMEOUT_MS = 5000
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
loraRadio *sx126x.Device
|
||||||
|
txmsg = []byte("Hello TinyGO")
|
||||||
|
)
|
||||||
|
|
||||||
|
// radioIntHandler will take care of radio interrupts
|
||||||
|
func radioIntHandler(intr interrupt.Interrupt) {
|
||||||
|
loraRadio.HandleInterrupt()
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
println("\n# TinyGo Lora RX/TX test")
|
||||||
|
println("# ----------------------")
|
||||||
|
machine.LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|
||||||
|
// Create the driver
|
||||||
|
loraRadio = sx126x.New(machine.SPI3)
|
||||||
|
loraRadio.SetDeviceType(sx126x.DEVICE_TYPE_SX1262)
|
||||||
|
|
||||||
|
// Create RF Switch
|
||||||
|
var radioSwitch rfswitch.CustomSwitch
|
||||||
|
loraRadio.SetRfSwitch(radioSwitch)
|
||||||
|
|
||||||
|
// Detect the device
|
||||||
|
state := loraRadio.DetectDevice()
|
||||||
|
if !state {
|
||||||
|
panic("sx126x not detected.")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add interrupt handler for Radio IRQs
|
||||||
|
intr := interrupt.New(stm32.IRQ_Radio_IRQ_Busy, radioIntHandler)
|
||||||
|
intr.Enable()
|
||||||
|
|
||||||
|
loraConf := sx126x.LoraConfig{
|
||||||
|
Freq: FREQ,
|
||||||
|
Bw: sx126x.SX126X_LORA_BW_500_0,
|
||||||
|
Sf: sx126x.SX126X_LORA_SF9,
|
||||||
|
Cr: sx126x.SX126X_LORA_CR_4_7,
|
||||||
|
HeaderType: sx126x.SX126X_LORA_HEADER_EXPLICIT,
|
||||||
|
Preamble: 12,
|
||||||
|
Ldr: sx126x.SX126X_LORA_LOW_DATA_RATE_OPTIMIZE_OFF,
|
||||||
|
Iq: sx126x.SX126X_LORA_IQ_STANDARD,
|
||||||
|
Crc: sx126x.SX126X_LORA_CRC_ON,
|
||||||
|
SyncWord: sx126x.SX126X_LORA_MAC_PRIVATE_SYNCWORD,
|
||||||
|
LoraTxPowerDBm: 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
loraRadio.LoraConfig(loraConf)
|
||||||
|
|
||||||
|
var count uint
|
||||||
|
for {
|
||||||
|
tStart := time.Now()
|
||||||
|
|
||||||
|
// Blocking RX for LORA_DEFAULT_RXTIMEOUT_MS
|
||||||
|
println("Start Lora RX for 10 sec")
|
||||||
|
for int(time.Now().Sub(tStart).Seconds()) < 10 {
|
||||||
|
buf, err := loraRadio.LoraRx(LORA_DEFAULT_RXTIMEOUT_MS)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
println("RX Error: ", err)
|
||||||
|
} else if buf != nil {
|
||||||
|
println("Packet Received: len=", len(buf), string(buf))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println("END Lora RX")
|
||||||
|
|
||||||
|
println("LORA TX size=", len(txmsg))
|
||||||
|
err := loraRadio.LoraTx(txmsg, LORA_DEFAULT_TXTIMEOUT_MS)
|
||||||
|
if err != nil {
|
||||||
|
println("TX Error:", err)
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
//go:build gnse
|
||||||
|
// +build gnse
|
||||||
|
|
||||||
|
/*
|
||||||
|
Generic Node Sensor Edition
|
||||||
|
RFSwitch
|
||||||
|
|
||||||
|
Disable Switch : PB8=OFF PA0=OFF PA1=OFF
|
||||||
|
Enable RX : PB8=ON PA0=ON PA1=OFF
|
||||||
|
Enable TX RFO LP : PB8=ON PA0=ON PA1=ON
|
||||||
|
Enable TX RFO HP : PB8=ON PA0=OFF PA1=ON
|
||||||
|
*/
|
||||||
|
package rfswitch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/sx126x"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomSwitch struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
rfstate int
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s CustomSwitch) InitRFSwitch() {
|
||||||
|
machine.RF_FE_CTRL1.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.RF_FE_CTRL2.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.RF_FE_CTRL3.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
rfstate = -1 //Unknown
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||||
|
if mode == rfstate {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
switch mode {
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_TX_HP:
|
||||||
|
machine.RF_FE_CTRL1.Set(false)
|
||||||
|
machine.RF_FE_CTRL2.Set(true)
|
||||||
|
machine.RF_FE_CTRL3.Set(true)
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_TX_LP:
|
||||||
|
machine.RF_FE_CTRL1.Set(true)
|
||||||
|
machine.RF_FE_CTRL2.Set(true)
|
||||||
|
machine.RF_FE_CTRL3.Set(true)
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_RX:
|
||||||
|
machine.RF_FE_CTRL1.Set(true)
|
||||||
|
machine.RF_FE_CTRL2.Set(false)
|
||||||
|
machine.RF_FE_CTRL3.Set(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
rfstate = mode
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
//go:build lorae5
|
||||||
|
// +build lorae5
|
||||||
|
|
||||||
|
package radio
|
||||||
|
|
||||||
|
/*
|
||||||
|
/!\ LoRa-E5 module ONLY transmits through RFO_HP:
|
||||||
|
|
||||||
|
Receive: PA4=1, PA5=0
|
||||||
|
Transmit(high output power, SMPS mode): PA4=0, PA5=1
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/sx126x"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomSwitch struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CustomSwitch) InitRFSwitch() {
|
||||||
|
machine.PA4.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.PB5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||||
|
switch mode {
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_RX:
|
||||||
|
machine.PA4.Set(true)
|
||||||
|
machine.PB5.Set(false)
|
||||||
|
case sx126x.RFSWITCH_TX_LP:
|
||||||
|
errors.New("RFSWITCH_TX_LP not supported ")
|
||||||
|
case sx126x.RFSWITCH_TX_HP:
|
||||||
|
machine.PA4.Set(false)
|
||||||
|
machine.PB5.Set(true)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
//go:build nucleowl55jc
|
||||||
|
// +build nucleowl55jc
|
||||||
|
|
||||||
|
/*
|
||||||
|
Nucleo WL55JC1
|
||||||
|
RFSwitch
|
||||||
|
|
||||||
|
+-----------+---------+------------+------------+
|
||||||
|
| | FE_CTRL1 | FE_CTRL2 | FE_CTRL3 |
|
||||||
|
| | (PC4) | (PC5) | (PC3) |
|
||||||
|
+-----------+----------+-----------+------------+
|
||||||
|
| TX_HP | LOW | HIGH | HIGH |
|
||||||
|
| TX_LP | HIGH | HIGH | HIGH |
|
||||||
|
| RX | HIGH | LOW | HIGH |
|
||||||
|
+-----------+----------+-----------+------------+
|
||||||
|
*/
|
||||||
|
package rfswitch
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/sx126x"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CustomSwitch struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CustomSwitch) InitRFSwitch() {
|
||||||
|
machine.PC4.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.PC5.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.PC3.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s CustomSwitch) SetRfSwitchMode(mode int) error {
|
||||||
|
switch mode {
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_TX_HP:
|
||||||
|
machine.PC4.Set(false)
|
||||||
|
machine.PC5.Set(true)
|
||||||
|
machine.PC3.Set(true)
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_TX_LP:
|
||||||
|
machine.PC4.Set(true)
|
||||||
|
machine.PC5.Set(true)
|
||||||
|
machine.PC3.Set(true)
|
||||||
|
|
||||||
|
case sx126x.RFSWITCH_RX:
|
||||||
|
machine.PC4.Set(true)
|
||||||
|
machine.PC5.Set(false)
|
||||||
|
machine.PC3.Set(true)
|
||||||
|
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//go:build espat
|
||||||
|
// +build espat
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"tinygo.org/x/drivers/espat"
|
||||||
|
)
|
||||||
|
|
||||||
|
// these are the default pins for the Arduino Nano33 IoT.
|
||||||
|
// change these to connect to a different UART or pins for the ESP8266/ESP32
|
||||||
|
var (
|
||||||
|
uart = machine.UART1
|
||||||
|
tx = machine.PA22
|
||||||
|
rx = machine.PA23
|
||||||
|
|
||||||
|
adaptor *espat.Device
|
||||||
|
)
|
||||||
|
|
||||||
|
func initAdaptor() *espat.Device {
|
||||||
|
uart.Configure(machine.UARTConfig{TX: tx, RX: rx})
|
||||||
|
|
||||||
|
adaptor = espat.New(uart)
|
||||||
|
adaptor.Configure()
|
||||||
|
|
||||||
|
return adaptor
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
// This example opens a TCP connection and sends some data,
|
||||||
|
// for the purpose of testing speed and connectivity.
|
||||||
|
//
|
||||||
|
// You can open a server to accept connections from this program using:
|
||||||
|
//
|
||||||
|
// nc -w 5 -lk 8080
|
||||||
|
//
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/net"
|
||||||
|
)
|
||||||
|
|
||||||
|
// access point info
|
||||||
|
const ssid = ""
|
||||||
|
const pass = ""
|
||||||
|
|
||||||
|
// IP address of the server aka "hub". Replace with your own info.
|
||||||
|
const serverIP = ""
|
||||||
|
|
||||||
|
var buf = &bytes.Buffer{}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
initAdaptor()
|
||||||
|
|
||||||
|
connectToAP()
|
||||||
|
|
||||||
|
for {
|
||||||
|
sendBatch()
|
||||||
|
time.Sleep(500 * time.Millisecond)
|
||||||
|
}
|
||||||
|
println("Done.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendBatch() {
|
||||||
|
|
||||||
|
// make TCP connection
|
||||||
|
ip := net.ParseIP(serverIP)
|
||||||
|
raddr := &net.TCPAddr{IP: ip, Port: 8080}
|
||||||
|
laddr := &net.TCPAddr{Port: 8080}
|
||||||
|
|
||||||
|
message("---------------\r\nDialing TCP connection")
|
||||||
|
conn, err := net.DialTCP("tcp", laddr, raddr)
|
||||||
|
for ; err != nil; conn, err = net.DialTCP("tcp", laddr, raddr) {
|
||||||
|
message(err.Error())
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
n := 0
|
||||||
|
w := 0
|
||||||
|
start := time.Now()
|
||||||
|
|
||||||
|
// send data
|
||||||
|
message("Sending data")
|
||||||
|
|
||||||
|
for i := 0; i < 1000; i++ {
|
||||||
|
buf.Reset()
|
||||||
|
fmt.Fprint(buf,
|
||||||
|
"\r---------------------------- i == ", i, " ----------------------------"+
|
||||||
|
"\r---------------------------- i == ", i, " ----------------------------")
|
||||||
|
if w, err = conn.Write(buf.Bytes()); err != nil {
|
||||||
|
println("error:", err.Error(), "\r")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
n += w
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.Reset()
|
||||||
|
ms := time.Now().Sub(start).Milliseconds()
|
||||||
|
fmt.Fprint(buf, "\nWrote ", n, " bytes in ", ms, " ms\r\n")
|
||||||
|
message(buf.String())
|
||||||
|
|
||||||
|
if _, err := conn.Write(buf.Bytes()); err != nil {
|
||||||
|
println("error:", err.Error(), "\r")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Right now this code is never reached. Need a way to trigger it...
|
||||||
|
println("Disconnecting TCP...")
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// connect to access point
|
||||||
|
func connectToAP() {
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Connecting to " + ssid)
|
||||||
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
|
if err != nil { // error connecting to AP
|
||||||
|
for {
|
||||||
|
println(err)
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Connected.")
|
||||||
|
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
ip, err := adaptor.GetClientIP()
|
||||||
|
for ; err != nil; ip, err = adaptor.GetClientIP() {
|
||||||
|
message(err.Error())
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
message(ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
func message(msg string) {
|
||||||
|
println(msg, "\r")
|
||||||
|
}
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
//go:build rtl8720dn
|
||||||
|
// +build rtl8720dn
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"device/sam"
|
||||||
|
"machine"
|
||||||
|
"runtime/interrupt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/net"
|
||||||
|
"tinygo.org/x/drivers/rtl8720dn"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
adaptor *rtl8720dn.RTL8720DN
|
||||||
|
|
||||||
|
uart UARTx
|
||||||
|
)
|
||||||
|
|
||||||
|
func initAdaptor() *rtl8720dn.RTL8720DN {
|
||||||
|
adaptor, err := setupRTL8720DN()
|
||||||
|
if err != nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
net.UseDriver(adaptor)
|
||||||
|
|
||||||
|
return adaptor
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleInterrupt(interrupt.Interrupt) {
|
||||||
|
// should reset IRQ
|
||||||
|
uart.Receive(byte((uart.Bus.DATA.Get() & 0xFF)))
|
||||||
|
uart.Bus.INTFLAG.SetBits(sam.SERCOM_USART_INT_INTFLAG_RXC)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setupRTL8720DN() (*rtl8720dn.RTL8720DN, error) {
|
||||||
|
machine.RTL8720D_CHIP_PU.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
machine.RTL8720D_CHIP_PU.Low()
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
machine.RTL8720D_CHIP_PU.High()
|
||||||
|
time.Sleep(1000 * time.Millisecond)
|
||||||
|
|
||||||
|
uart = UARTx{
|
||||||
|
UART: &machine.UART{
|
||||||
|
Buffer: machine.NewRingBuffer(),
|
||||||
|
Bus: sam.SERCOM0_USART_INT,
|
||||||
|
SERCOM: 0,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
uart.Interrupt = interrupt.New(sam.IRQ_SERCOM0_2, handleInterrupt)
|
||||||
|
uart.Configure(machine.UARTConfig{TX: machine.PB24, RX: machine.PC24, BaudRate: 614400})
|
||||||
|
|
||||||
|
rtl := rtl8720dn.New(uart)
|
||||||
|
//rtl.Debug(debug)
|
||||||
|
|
||||||
|
_, err := rtl.Rpc_tcpip_adapter_init()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return rtl, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type UARTx struct {
|
||||||
|
*machine.UART
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u UARTx) Read(p []byte) (n int, err error) {
|
||||||
|
if u.Buffered() == 0 {
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
return u.UART.Read(p)
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
//go:build wifinina
|
||||||
|
// +build wifinina
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"tinygo.org/x/drivers/wifinina"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// default interface for the Arduino Nano33 IoT.
|
||||||
|
spi = machine.NINA_SPI
|
||||||
|
|
||||||
|
// ESP32/ESP8266 chip that has the WIFININA firmware flashed on it
|
||||||
|
adaptor *wifinina.Device
|
||||||
|
)
|
||||||
|
|
||||||
|
func initAdaptor() *wifinina.Device {
|
||||||
|
// Configure SPI for 8Mhz, Mode 0, MSB First
|
||||||
|
spi.Configure(machine.SPIConfig{
|
||||||
|
Frequency: 8 * 1e6,
|
||||||
|
SDO: machine.NINA_SDO,
|
||||||
|
SDI: machine.NINA_SDI,
|
||||||
|
SCK: machine.NINA_SCK,
|
||||||
|
})
|
||||||
|
|
||||||
|
adaptor = wifinina.New(spi,
|
||||||
|
machine.NINA_CS,
|
||||||
|
machine.NINA_ACK,
|
||||||
|
machine.NINA_GPIO0,
|
||||||
|
machine.NINA_RESETN)
|
||||||
|
adaptor.Configure()
|
||||||
|
|
||||||
|
return adaptor
|
||||||
|
}
|
||||||
@@ -128,19 +128,15 @@ func waitSerial() {
|
|||||||
|
|
||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
if len(ssid) == 0 || len(pass) == 0 {
|
|
||||||
for {
|
|
||||||
println("Connection failed: Either ssid or password not set")
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
println("Connecting to " + ssid)
|
println("Connecting to " + ssid)
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
if err != nil { // error connecting to AP
|
||||||
println("Connection status: " + st.String())
|
for {
|
||||||
time.Sleep(1 * time.Second)
|
println(err)
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -132,22 +132,18 @@ func waitSerial() {
|
|||||||
|
|
||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
if len(ssid) == 0 || len(pass) == 0 {
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Connecting to " + ssid)
|
||||||
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
|
if err != nil { // error connecting to AP
|
||||||
for {
|
for {
|
||||||
println("Connection failed: Either ssid or password not set")
|
println(err)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
message("Connecting to " + ssid)
|
println("Connected.")
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
|
||||||
message("Connection status: " + st.String())
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
|
||||||
}
|
|
||||||
message("Connected.")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
message(err.Error())
|
message(err.Error())
|
||||||
|
|||||||
@@ -104,14 +104,16 @@ func main() {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
println("Connecting to " + ssid)
|
println("Connecting to " + ssid)
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
if err != nil { // error connecting to AP
|
||||||
println("Connection status: " + st.String())
|
for {
|
||||||
time.Sleep(1 * time.Second)
|
println(err)
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
println(err.Error())
|
println(err.Error())
|
||||||
|
|||||||
@@ -116,13 +116,16 @@ func publishing() {
|
|||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
println("Connecting to " + ssid)
|
println("Connecting to " + ssid)
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
if err != nil { // error connecting to AP
|
||||||
println("Connection status: " + st.String())
|
for {
|
||||||
time.Sleep(1 * time.Second)
|
println(err)
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Connected.")
|
println("Connected.")
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
|
|||||||
@@ -151,21 +151,18 @@ func clearBuffer() {
|
|||||||
|
|
||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
if len(ssid) == 0 || len(pass) == 0 {
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Connecting to " + ssid)
|
||||||
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
|
if err != nil { // error connecting to AP
|
||||||
for {
|
for {
|
||||||
println("Connection failed: Either ssid or password not set")
|
println(err)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
message("Connecting to " + ssid)
|
println("Connected.")
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
|
||||||
message("Connection status: " + st.String())
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
|
||||||
}
|
|
||||||
message("Connected.")
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
//go:build nano_rp2040
|
||||||
|
// +build nano_rp2040
|
||||||
|
|
||||||
|
// This examples shows how to control RGB LED connected to
|
||||||
|
// NINA-W102 chip on Arduino Nano RP2040 Connect board
|
||||||
|
// Built-in LED code added for API comparison
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/wifinina"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
LED = machine.LED
|
||||||
|
|
||||||
|
// Arduino Nano RP2040 Connect board RGB LED pins
|
||||||
|
// See https://docs.arduino.cc/static/3525d638b5c76a2d19588d6b41cd02a0/ABX00053-full-pinout.pdf
|
||||||
|
LED_R wifinina.Pin = 27
|
||||||
|
LED_G wifinina.Pin = 25
|
||||||
|
LED_B wifinina.Pin = 26
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
|
||||||
|
// these are the default pins for the Arduino Nano-RP2040 Connect
|
||||||
|
spi = machine.NINA_SPI
|
||||||
|
|
||||||
|
// this is the ESP chip that has the WIFININA firmware flashed on it
|
||||||
|
device *wifinina.Device
|
||||||
|
)
|
||||||
|
|
||||||
|
func setup() {
|
||||||
|
|
||||||
|
// Configure SPI for 8Mhz, Mode 0, MSB First
|
||||||
|
spi.Configure(machine.SPIConfig{
|
||||||
|
Frequency: 8 * 1e6,
|
||||||
|
SDO: machine.NINA_SDO,
|
||||||
|
SDI: machine.NINA_SDI,
|
||||||
|
SCK: machine.NINA_SCK,
|
||||||
|
})
|
||||||
|
|
||||||
|
device = wifinina.New(spi,
|
||||||
|
machine.NINA_CS,
|
||||||
|
machine.NINA_ACK,
|
||||||
|
machine.NINA_GPIO0,
|
||||||
|
machine.NINA_RESETN)
|
||||||
|
device.Configure()
|
||||||
|
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
|
||||||
|
LED.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
LED_R.Configure(wifinina.PinConfig{Mode: wifinina.PinOutput})
|
||||||
|
LED_G.Configure(wifinina.PinConfig{Mode: wifinina.PinOutput})
|
||||||
|
LED_B.Configure(wifinina.PinConfig{Mode: wifinina.PinOutput})
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
setup()
|
||||||
|
|
||||||
|
LED.Low() // OFF
|
||||||
|
LED_R.High() // OFF
|
||||||
|
LED_G.High() // OFF
|
||||||
|
LED_B.High() // OFF
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
LED.Low()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
LED.High()
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
LED_R.Low() // ON
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
LED_R.High() // OFF
|
||||||
|
LED_G.Low() // ON
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
LED_G.High() // OFF
|
||||||
|
LED_B.Low() // ON
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
LED_B.High() // OFF
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -113,14 +113,17 @@ func sendBatch() {
|
|||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
message("Connecting to " + ssid)
|
println("Connecting to " + ssid)
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
if err != nil { // error connecting to AP
|
||||||
message("Connection status: " + st.String())
|
for {
|
||||||
time.Sleep(1 * time.Second)
|
println(err)
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message("Connected.")
|
|
||||||
|
println("Connected.")
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
|
|||||||
@@ -122,21 +122,18 @@ func makeHTTPSRequest() {
|
|||||||
|
|
||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
if len(ssid) == 0 || len(pass) == 0 {
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Connecting to " + ssid)
|
||||||
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
|
if err != nil { // error connecting to AP
|
||||||
for {
|
for {
|
||||||
println("Connection failed: Either ssid or password not set")
|
println(err)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
message("Connecting to " + ssid)
|
println("Connected.")
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
|
||||||
message("Connection status: " + st.String())
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
|
||||||
}
|
|
||||||
message("Connected.")
|
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
|
|||||||
@@ -76,15 +76,17 @@ func main() {
|
|||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
message("Connecting to " + ssid)
|
println("Connecting to " + ssid)
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
if err != nil { // error connecting to AP
|
||||||
message("Connection status: " + st.String())
|
for {
|
||||||
time.Sleep(1 * time.Second)
|
println(err)
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
message("Connected.")
|
|
||||||
time.Sleep(2 * time.Second)
|
println("Connected.")
|
||||||
|
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
message(err.Error())
|
message(err.Error())
|
||||||
|
|||||||
@@ -124,22 +124,18 @@ func makeHTTPRequest() {
|
|||||||
|
|
||||||
// connect to access point
|
// connect to access point
|
||||||
func connectToAP() {
|
func connectToAP() {
|
||||||
if len(ssid) == 0 || len(pass) == 0 {
|
time.Sleep(2 * time.Second)
|
||||||
|
println("Connecting to " + ssid)
|
||||||
|
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
||||||
|
if err != nil { // error connecting to AP
|
||||||
for {
|
for {
|
||||||
println("Connection failed: Either ssid or password not set")
|
println(err)
|
||||||
time.Sleep(10 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
message("Connecting to " + ssid)
|
println("Connected.")
|
||||||
adaptor.SetPassphrase(ssid, pass)
|
|
||||||
for st, _ := adaptor.GetConnectionStatus(); st != wifinina.StatusConnected; {
|
|
||||||
message("Connection status: " + st.String())
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
st, _ = adaptor.GetConnectionStatus()
|
|
||||||
}
|
|
||||||
message("Connected.")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
ip, _, _, err := adaptor.GetIP()
|
ip, _, _, err := adaptor.GetIP()
|
||||||
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
for ; err != nil; ip, _, _, err = adaptor.GetIP() {
|
||||||
message(err.Error())
|
message(err.Error())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//go:build !digispark && !arduino && !qtpy
|
//go:build !digispark && !arduino && !qtpy && !m5stamp_c3
|
||||||
// +build !digispark,!arduino,!qtpy
|
// +build !digispark,!arduino,!qtpy,!m5stamp_c3
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//go:build qtpy || m5stamp_c3
|
||||||
|
// +build qtpy m5stamp_c3
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "machine"
|
||||||
|
|
||||||
|
// Replace neo and led in the code below to match the pin
|
||||||
|
// that you are using if different.
|
||||||
|
var neo machine.Pin = machine.WS2812
|
||||||
|
var led = machine.NoPin
|
||||||
@@ -5,11 +5,6 @@ package main
|
|||||||
|
|
||||||
import "machine"
|
import "machine"
|
||||||
|
|
||||||
// Replace neo and led in the code below to match the pin
|
|
||||||
// that you are using if different.
|
|
||||||
var neo machine.Pin = machine.NEOPIXELS
|
|
||||||
var led = machine.NoPin
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
pwr := machine.NEOPIXELS_POWER
|
pwr := machine.NEOPIXELS_POWER
|
||||||
pwr.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
pwr.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers/xpt2046"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
|
||||||
|
clk := machine.GPIO0
|
||||||
|
cs := machine.GPIO1
|
||||||
|
din := machine.GPIO2
|
||||||
|
dout := machine.GPIO3
|
||||||
|
irq := machine.GPIO4
|
||||||
|
|
||||||
|
touchScreen := xpt2046.New(clk, cs, din, dout, irq)
|
||||||
|
|
||||||
|
touchScreen.Configure(&xpt2046.Config{
|
||||||
|
Precision: 10, //Maximum number of samples for a single ReadTouchPoint to improve accuracy.
|
||||||
|
})
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
//Wait for a touch
|
||||||
|
for !touchScreen.Touched() {
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
touch := touchScreen.ReadTouchPoint()
|
||||||
|
//X and Y are 16 bit with 12 bit resolution and need to be scaled for the display size
|
||||||
|
//Z is 24 bit and is typically > 2000 for a touch
|
||||||
|
println("touch:", touch.X, touch.Y, touch.Z)
|
||||||
|
//Example of scaling for a 240x320 display
|
||||||
|
println("screen:", (touch.X*240)>>16, (touch.Y*320)>>16)
|
||||||
|
|
||||||
|
//Wait for touch to end
|
||||||
|
for touchScreen.Touched() {
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
// Package ft6336 provides a driver for the FT6336 I2C Self-Capacitive touch
|
||||||
|
// panel controller.
|
||||||
|
//
|
||||||
|
// Datasheet: https://focuslcds.com/content/FT6236.pdf
|
||||||
|
//
|
||||||
|
package ft6336
|
||||||
|
|
||||||
|
import (
|
||||||
|
"machine"
|
||||||
|
|
||||||
|
"tinygo.org/x/drivers"
|
||||||
|
"tinygo.org/x/drivers/touch"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Device wraps FT6336 I2C Self-Capacitive touch
|
||||||
|
type Device struct {
|
||||||
|
bus drivers.I2C
|
||||||
|
buf []byte
|
||||||
|
Address uint8
|
||||||
|
intPin machine.Pin
|
||||||
|
}
|
||||||
|
|
||||||
|
// New returns FT6336 device for the provided I2C bus using default address.
|
||||||
|
func New(i2c drivers.I2C, intPin machine.Pin) *Device {
|
||||||
|
return &Device{
|
||||||
|
bus: i2c,
|
||||||
|
buf: make([]byte, 11),
|
||||||
|
Address: Address,
|
||||||
|
intPin: intPin,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config contains settings for FT6636.
|
||||||
|
type Config struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure the FT6336 device.
|
||||||
|
func (d *Device) Configure(config Config) error {
|
||||||
|
d.write1Byte(0xA4, 0x00)
|
||||||
|
d.intPin.Configure(machine.PinConfig{Mode: machine.PinInputPulldown})
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetGMode sets interrupt mode.
|
||||||
|
// 0x00 : Interrupt Polling mode
|
||||||
|
// 0x01 : Interrupt Trigger mode (default)
|
||||||
|
func (d *Device) SetGMode(v uint8) {
|
||||||
|
d.write1Byte(RegGMode, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetGMode gets interrupt mode.
|
||||||
|
func (d *Device) GetGMode() uint8 {
|
||||||
|
return d.read8bit(RegGMode)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPeriodActive sets report rate in Active mode.
|
||||||
|
func (d *Device) SetPeriodActive(v uint8) {
|
||||||
|
d.write1Byte(RegPeriodActive, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPeriodActive gets report rate in Active mode.
|
||||||
|
func (d *Device) GetPeriodActive() uint8 {
|
||||||
|
return d.read8bit(RegPeriodActive)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetFirmwareID gets firmware version.
|
||||||
|
func (d *Device) GetFirmwareID() uint8 {
|
||||||
|
return d.read8bit(RegFirmid)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read reads the registers.
|
||||||
|
func (d *Device) Read() []byte {
|
||||||
|
d.bus.Tx(uint16(d.Address), []byte{0x02}, d.buf[:])
|
||||||
|
return d.buf[:]
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReadTouchPoint reads a single touch.Point from the device. The maximum value
|
||||||
|
// for each touch.Point is 0xFFFF.
|
||||||
|
func (d *Device) ReadTouchPoint() touch.Point {
|
||||||
|
d.Read()
|
||||||
|
z := 0xFFFFF
|
||||||
|
if d.buf[0] == 0 {
|
||||||
|
z = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
//Scale X&Y to 16 bit for consistency across touch drivers
|
||||||
|
return touch.Point{
|
||||||
|
X: (int(d.buf[1]&0x0F)<<8 + int(d.buf[2])) * ((1 << 16) / 320),
|
||||||
|
Y: (int(d.buf[3]&0x0F)<<8 + int(d.buf[4])) * ((1 << 16) / 270),
|
||||||
|
Z: z,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Touched returns if touched or not.
|
||||||
|
func (d *Device) Touched() bool {
|
||||||
|
p := d.ReadTouchPoint()
|
||||||
|
return p.Z > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) write1Byte(reg, data uint8) {
|
||||||
|
d.bus.WriteRegister(d.Address, reg, []byte{data})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Device) read8bit(reg uint8) uint8 {
|
||||||
|
d.bus.ReadRegister(d.Address, reg, d.buf[:1])
|
||||||
|
return d.buf[0]
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user