mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-12 10:53:43 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 349b5ca87e |
@@ -144,7 +144,7 @@ The following 90 devices are supported.
|
|||||||
| [Waveshare GC9A01 TFT round display](https://www.waveshare.com/w/upload/5/5e/GC9A01A.pdf) | SPI |
|
| [Waveshare GC9A01 TFT round display](https://www.waveshare.com/w/upload/5/5e/GC9A01A.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 |
|
| [XPT2046 touch controller](http://grobotronics.com/images/datasheets/xpt2046-datasheet.pdf) | GPIO |
|
||||||
| [Semtech SX126x Lora](https://www.semtech.com/products/wireless-rf/lora-connect/sx1261) | SPI |
|
| [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 |
|
| [SSD1289 TFT color display](http://aitendo3.sakura.ne.jp/aitendo_data/product_img/lcd/tft2/M032C1289TP/3.2-SSD1289.pdf) | GPIO |
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !nano_33_ble
|
//go:build !nano_33_ble
|
||||||
|
// +build !nano_33_ble
|
||||||
|
|
||||||
package apds9960
|
package apds9960
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nano_33_ble
|
//go:build nano_33_ble
|
||||||
|
// +build nano_33_ble
|
||||||
|
|
||||||
package apds9960
|
package apds9960
|
||||||
|
|
||||||
|
|||||||
+5
-115
@@ -7,7 +7,6 @@ package bme280
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"math"
|
||||||
"time"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers"
|
"tinygo.org/x/drivers"
|
||||||
)
|
)
|
||||||
@@ -34,27 +33,11 @@ type calibrationCoefficients struct {
|
|||||||
h6 int8
|
h6 int8
|
||||||
}
|
}
|
||||||
|
|
||||||
type Oversampling byte
|
|
||||||
type Mode byte
|
|
||||||
type FilterCoefficient byte
|
|
||||||
type Period byte
|
|
||||||
|
|
||||||
// Config contains settings for filtering, sampling, and modes of operation
|
|
||||||
type Config struct {
|
|
||||||
Pressure Oversampling
|
|
||||||
Temperature Oversampling
|
|
||||||
Humidity Oversampling
|
|
||||||
Period Period
|
|
||||||
Mode Mode
|
|
||||||
IIR FilterCoefficient
|
|
||||||
}
|
|
||||||
|
|
||||||
// Device wraps an I2C connection to a BME280 device.
|
// Device wraps an I2C connection to a BME280 device.
|
||||||
type Device struct {
|
type Device struct {
|
||||||
bus drivers.I2C
|
bus drivers.I2C
|
||||||
Address uint16
|
Address uint16
|
||||||
calibrationCoefficients calibrationCoefficients
|
calibrationCoefficients calibrationCoefficients
|
||||||
Config Config
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new BME280 connection. The I2C bus must already be
|
// New creates a new BME280 connection. The I2C bus must already be
|
||||||
@@ -68,34 +51,9 @@ func New(bus drivers.I2C) Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigureWithSettings sets up the device for communication and
|
// Configure sets up the device for communication and
|
||||||
// read the calibration coefficients.
|
// read the calibration coefficientes.
|
||||||
//
|
|
||||||
// The default configuration is the Indoor Navigation settings
|
|
||||||
// from the BME280 datasheet.
|
|
||||||
func (d *Device) Configure() {
|
func (d *Device) Configure() {
|
||||||
d.ConfigureWithSettings(Config{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ConfigureWithSettings sets up the device for communication and
|
|
||||||
// read the calibration coefficients.
|
|
||||||
//
|
|
||||||
// The default configuration if config is left at defaults is
|
|
||||||
// the Indoor Navigation settings from the BME280 datasheet.
|
|
||||||
func (d *Device) ConfigureWithSettings(config Config) {
|
|
||||||
d.Config = config
|
|
||||||
|
|
||||||
// If config is not initialized, use Indoor Navigation defaults.
|
|
||||||
if d.Config == (Config{}) {
|
|
||||||
d.Config = Config{
|
|
||||||
Mode: ModeNormal,
|
|
||||||
Period: Period0_5ms,
|
|
||||||
Temperature: Sampling2X,
|
|
||||||
Humidity: Sampling1X,
|
|
||||||
Pressure: Sampling16X,
|
|
||||||
IIR: Coeff16,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var data [24]byte
|
var data [24]byte
|
||||||
err := d.bus.ReadRegister(uint8(d.Address), REG_CALIBRATION, data[:])
|
err := d.bus.ReadRegister(uint8(d.Address), REG_CALIBRATION, data[:])
|
||||||
@@ -135,18 +93,10 @@ func (d *Device) ConfigureWithSettings(config Config) {
|
|||||||
d.calibrationCoefficients.h4 = 0 + (int16(h2lsb[3]) << 4) | (int16(h2lsb[4] & 0x0F))
|
d.calibrationCoefficients.h4 = 0 + (int16(h2lsb[3]) << 4) | (int16(h2lsb[4] & 0x0F))
|
||||||
d.calibrationCoefficients.h5 = 0 + (int16(h2lsb[5]) << 4) | (int16(h2lsb[4]) >> 4)
|
d.calibrationCoefficients.h5 = 0 + (int16(h2lsb[5]) << 4) | (int16(h2lsb[4]) >> 4)
|
||||||
|
|
||||||
d.Reset()
|
d.bus.WriteRegister(uint8(d.Address), CTRL_HUMIDITY_ADDR, []byte{0x3f})
|
||||||
|
d.bus.WriteRegister(uint8(d.Address), CTRL_MEAS_ADDR, []byte{0xB7})
|
||||||
|
d.bus.WriteRegister(uint8(d.Address), CTRL_CONFIG, []byte{0x00})
|
||||||
|
|
||||||
d.bus.WriteRegister(uint8(d.Address), CTRL_CONFIG, []byte{byte(d.Config.Period<<5) | byte(d.Config.IIR<<2)})
|
|
||||||
d.bus.WriteRegister(uint8(d.Address), CTRL_HUMIDITY_ADDR, []byte{byte(d.Config.Humidity)})
|
|
||||||
|
|
||||||
// Normal mode, start measuring now
|
|
||||||
if d.Config.Mode == ModeNormal {
|
|
||||||
d.bus.WriteRegister(uint8(d.Address), CTRL_MEAS_ADDR, []byte{
|
|
||||||
byte(d.Config.Temperature<<5) |
|
|
||||||
byte(d.Config.Pressure<<2) |
|
|
||||||
byte(d.Config.Mode)})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connected returns whether a BME280 has been found.
|
// Connected returns whether a BME280 has been found.
|
||||||
@@ -162,20 +112,6 @@ func (d *Device) Reset() {
|
|||||||
d.bus.WriteRegister(uint8(d.Address), CMD_RESET, []byte{0xB6})
|
d.bus.WriteRegister(uint8(d.Address), CMD_RESET, []byte{0xB6})
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMode can set the device to Sleep, Normal or Forced mode
|
|
||||||
//
|
|
||||||
// Calling this method is optional, Configure can be used to set the
|
|
||||||
// initial mode if no mode change is desired. This method is most
|
|
||||||
// useful to switch between Sleep and Normal modes.
|
|
||||||
func (d *Device) SetMode(mode Mode) {
|
|
||||||
d.Config.Mode = mode
|
|
||||||
|
|
||||||
d.bus.WriteRegister(uint8(d.Address), CTRL_MEAS_ADDR, []byte{
|
|
||||||
byte(d.Config.Temperature<<5) |
|
|
||||||
byte(d.Config.Pressure<<2) |
|
|
||||||
byte(d.Config.Mode)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
|
// ReadTemperature returns the temperature in celsius milli degrees (°C/1000)
|
||||||
func (d *Device) ReadTemperature() (int32, error) {
|
func (d *Device) ReadTemperature() (int32, error) {
|
||||||
data, err := d.readData()
|
data, err := d.readData()
|
||||||
@@ -250,16 +186,6 @@ func readIntLE(msb byte, lsb byte) int16 {
|
|||||||
// readData does a burst read from 0xF7 to 0xF0 according to the datasheet
|
// readData does a burst read from 0xF7 to 0xF0 according to the datasheet
|
||||||
// resulting in an slice with 8 bytes 0-2 = pressure / 3-5 = temperature / 6-7 = humidity
|
// resulting in an slice with 8 bytes 0-2 = pressure / 3-5 = temperature / 6-7 = humidity
|
||||||
func (d *Device) readData() (data [8]byte, err error) {
|
func (d *Device) readData() (data [8]byte, err error) {
|
||||||
if d.Config.Mode == ModeForced {
|
|
||||||
// Write the CTRL_MEAS register to trigger a measurement
|
|
||||||
d.bus.WriteRegister(uint8(d.Address), CTRL_MEAS_ADDR, []byte{
|
|
||||||
byte(d.Config.Temperature<<5) |
|
|
||||||
byte(d.Config.Pressure<<2) |
|
|
||||||
byte(d.Config.Mode)})
|
|
||||||
|
|
||||||
time.Sleep(d.measurementDelay())
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.bus.ReadRegister(uint8(d.Address), REG_PRESSURE, data[:])
|
err = d.bus.ReadRegister(uint8(d.Address), REG_PRESSURE, data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
println(err)
|
println(err)
|
||||||
@@ -330,39 +256,3 @@ func (d *Device) calculateHumidity(data [8]byte, tFine int32) int32 {
|
|||||||
return int32(100 * h)
|
return int32(100 * h)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// measurementDelay returns how much time each measurement will take
|
|
||||||
// on the device.
|
|
||||||
//
|
|
||||||
// This is used in forced mode to wait until a measurement is complete.
|
|
||||||
func (d *Device) measurementDelay() time.Duration {
|
|
||||||
const MeasOffset = 1250
|
|
||||||
const MeasDur = 2300
|
|
||||||
const HumMeasOffset = 575
|
|
||||||
const MeasScalingFactor = 1000
|
|
||||||
|
|
||||||
// delay is based on over-sampling rate - this table converts from
|
|
||||||
// setting to number samples
|
|
||||||
sampleRateConv := []int{0, 1, 2, 4, 8, 16}
|
|
||||||
|
|
||||||
tempOsr := 16
|
|
||||||
if d.Config.Temperature <= Sampling16X {
|
|
||||||
tempOsr = sampleRateConv[d.Config.Temperature]
|
|
||||||
}
|
|
||||||
|
|
||||||
presOsr := 16
|
|
||||||
if d.Config.Temperature <= Sampling16X {
|
|
||||||
presOsr = sampleRateConv[d.Config.Pressure]
|
|
||||||
}
|
|
||||||
|
|
||||||
humOsr := 16
|
|
||||||
if d.Config.Temperature <= Sampling16X {
|
|
||||||
humOsr = sampleRateConv[d.Config.Humidity]
|
|
||||||
}
|
|
||||||
|
|
||||||
max_delay := ((MeasOffset + (MeasDur * tempOsr) +
|
|
||||||
((MeasDur * presOsr) + HumMeasOffset) +
|
|
||||||
((MeasDur * humOsr) + HumMeasOffset)) / MeasScalingFactor)
|
|
||||||
|
|
||||||
return time.Duration(max_delay) * time.Millisecond
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -20,50 +20,6 @@ const (
|
|||||||
CHIP_ID = 0x60
|
CHIP_ID = 0x60
|
||||||
)
|
)
|
||||||
|
|
||||||
// Increasing sampling rate increases precision but also the wait time for measurements. The datasheet has a table of
|
|
||||||
// suggested values for oversampling, output data rates, and iir filter coefficients by use case.
|
|
||||||
const (
|
|
||||||
SamplingOff Oversampling = iota
|
|
||||||
Sampling1X
|
|
||||||
Sampling2X
|
|
||||||
Sampling4X
|
|
||||||
Sampling8X
|
|
||||||
Sampling16X
|
|
||||||
)
|
|
||||||
|
|
||||||
// In normal mode (the default) the sensor takes masurements periodically. In forced
|
|
||||||
// mode, the sensor takes a measurement only when requested.
|
|
||||||
//
|
|
||||||
// For use-cases with infrequent sampling, forced mode is more power efficient.
|
|
||||||
const (
|
|
||||||
ModeNormal Mode = 0x03
|
|
||||||
ModeForced Mode = 0x01
|
|
||||||
ModeSleep Mode = 0x00
|
|
||||||
)
|
|
||||||
|
|
||||||
// IIR filter coefficients, higher values means steadier measurements but slower reaction times
|
|
||||||
const (
|
|
||||||
Coeff0 FilterCoefficient = iota
|
|
||||||
Coeff2
|
|
||||||
Coeff4
|
|
||||||
Coeff8
|
|
||||||
Coeff16
|
|
||||||
)
|
|
||||||
|
|
||||||
// Period of standby in normal mode which controls how often measurements are taken
|
|
||||||
//
|
|
||||||
// Note Period10ms and Period20ms are out of sequence, but are per the datasheet
|
|
||||||
const (
|
|
||||||
Period0_5ms Period = 0b000
|
|
||||||
Period62_5ms = 0b001
|
|
||||||
Period125ms = 0b010
|
|
||||||
Period250ms = 0b011
|
|
||||||
Period500ms = 0b100
|
|
||||||
Period1000ms = 0b101
|
|
||||||
Period10ms = 0b110
|
|
||||||
Period20ms = 0b111
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
SEALEVEL_PRESSURE float32 = 1013.25 // in hPa
|
SEALEVEL_PRESSURE float32 = 1013.25 // in hPa
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -54,12 +54,6 @@ func (l *Device) Tone(hz, duration float64) (err error) {
|
|||||||
|
|
||||||
tempo := ((60 / l.BPM) * (duration * 1000))
|
tempo := ((60 / l.BPM) * (duration * 1000))
|
||||||
|
|
||||||
// no tone during rest, just let the duration pass.
|
|
||||||
if hz == Rest {
|
|
||||||
time.Sleep(time.Duration(tempo) * time.Millisecond)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for i := 0.0; i < tempo*1000; i += tone * 2.0 {
|
for i := 0.0; i < tempo*1000; i += tone * 2.0 {
|
||||||
if err = l.On(); err != nil {
|
if err = l.On(); err != nil {
|
||||||
return
|
return
|
||||||
|
|||||||
+3
-3
@@ -1,9 +1,9 @@
|
|||||||
package buzzer
|
package buzzer
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Whole = 4.0
|
Whole = 4
|
||||||
Half = 2.0
|
Half = 2
|
||||||
Quarter = 1.0
|
Quarter = 1
|
||||||
Eighth = 0.500
|
Eighth = 0.500
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo
|
//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,4 +1,5 @@
|
|||||||
//go:build mimxrt1062 || stm32f405 || atsamd51 || stm32f103xx || k210 || stm32f407
|
//go:build mimxrt1062 || stm32f405 || atsamd51 || stm32f103xx || k210 || stm32f407
|
||||||
|
// +build mimxrt1062 stm32f405 atsamd51 stm32f103xx k210 stm32f407
|
||||||
|
|
||||||
package dht // import "tinygo.org/x/drivers/dht"
|
package dht // import "tinygo.org/x/drivers/dht"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !mimxrt1062 && !stm32f405 && !atsamd51 && !stm32f103xx && !k210 && !stm32f407
|
//go:build !mimxrt1062 && !stm32f405 && !atsamd51 && !stm32f103xx && !k210 && !stm32f407
|
||||||
|
// +build !mimxrt1062,!stm32f405,!atsamd51,!stm32f103xx,!k210,!stm32f407
|
||||||
|
|
||||||
package dht // import "tinygo.org/x/drivers/dht"
|
package dht // import "tinygo.org/x/drivers/dht"
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo
|
//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.
|
||||||
//
|
//
|
||||||
@@ -10,7 +11,6 @@ package dht // import "tinygo.org/x/drivers/dht"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"machine"
|
"machine"
|
||||||
"runtime/interrupt"
|
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -160,8 +160,8 @@ func (t *device) read() error {
|
|||||||
// interrupts
|
// interrupts
|
||||||
func receiveSignals(pin machine.Pin, result []counter) {
|
func receiveSignals(pin machine.Pin, result []counter) {
|
||||||
i := uint8(0)
|
i := uint8(0)
|
||||||
mask := interrupt.Disable()
|
machine.UART1.Interrupt.Disable()
|
||||||
defer interrupt.Restore(mask)
|
defer machine.UART1.Interrupt.Enable()
|
||||||
for ; i < 40; i++ {
|
for ; i < 40; i++ {
|
||||||
result[i*2] = expectChange(pin, false)
|
result[i*2] = expectChange(pin, false)
|
||||||
result[i*2+1] = expectChange(pin, true)
|
result[i*2+1] = expectChange(pin, true)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo
|
//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,4 +1,5 @@
|
|||||||
//go:build tinygo
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
package dht // import "tinygo.org/x/drivers/dht"
|
package dht // import "tinygo.org/x/drivers/dht"
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build m5stack_core2
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build m5stack_core2
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd21
|
//go:build atsamd21
|
||||||
|
// +build atsamd21
|
||||||
|
|
||||||
package initdisplay
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build feather_m0 || feather_m4 || feather_m4_can || feather_nrf52840 || feather_nrf52840_sense || feather_stm32f405 || feather_rp2040
|
//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
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build m5stack
|
//go:build m5stack
|
||||||
|
// +build m5stack
|
||||||
|
|
||||||
package initdisplay
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build m5stack_core2
|
//go:build m5stack_core2
|
||||||
|
// +build m5stack_core2
|
||||||
|
|
||||||
package initdisplay
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pyportal
|
//go:build pyportal
|
||||||
|
// +build pyportal
|
||||||
|
|
||||||
package initdisplay
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build wioterminal
|
//go:build wioterminal
|
||||||
|
// +build wioterminal
|
||||||
|
|
||||||
package initdisplay
|
package initdisplay
|
||||||
|
|
||||||
|
|||||||
@@ -100,8 +100,10 @@ func getCurrentTime(conn *net.UDPSerialConn) (time.Time, error) {
|
|||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
continue // no packet received yet
|
continue // no packet received yet
|
||||||
} else if n != NTP_PACKET_SIZE {
|
} else if n != NTP_PACKET_SIZE {
|
||||||
|
if n != NTP_PACKET_SIZE {
|
||||||
return time.Time{}, fmt.Errorf("expected NTP packet size of %d: %d", NTP_PACKET_SIZE, n)
|
return time.Time{}, fmt.Errorf("expected NTP packet size of %d: %d", NTP_PACKET_SIZE, n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return parseNTPpacket(), nil
|
return parseNTPpacket(), nil
|
||||||
}
|
}
|
||||||
return time.Time{}, errors.New("no packet received after 1 second")
|
return time.Time{}, errors.New("no packet received after 1 second")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build feather_m4 || feather_m4_can || feather_nrf52840
|
//go:build feather_m4 || feather_m4_can || feather_nrf52840
|
||||||
|
// +build feather_m4 feather_m4_can feather_nrf52840
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build grandcentral_m4
|
//go:build grandcentral_m4
|
||||||
|
// +build grandcentral_m4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd21 && !p1am_100
|
//go:build atsamd21 && !p1am_100
|
||||||
|
// +build atsamd21,!p1am_100
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build p1am_100
|
//go:build p1am_100
|
||||||
|
// +build p1am_100
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pygamer
|
//go:build pygamer
|
||||||
|
// +build pygamer
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pyportal
|
//go:build pyportal
|
||||||
|
// +build pyportal
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build thingplus_rp2040
|
//go:build thingplus_rp2040
|
||||||
|
// +build thingplus_rp2040
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build wioterminal
|
//go:build wioterminal
|
||||||
|
// +build wioterminal
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo
|
//go:build tinygo
|
||||||
|
// +build tinygo
|
||||||
|
|
||||||
package console
|
package console
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build feather_m4 || feather_m4_can || feather_nrf52840
|
//go:build feather_m4 || feather_m4_can || feather_nrf52840
|
||||||
|
// +build feather_m4 feather_m4_can feather_nrf52840
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build grandcentral_m4
|
//go:build grandcentral_m4
|
||||||
|
// +build grandcentral_m4
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd21 && !p1am_100
|
//go:build atsamd21 && !p1am_100
|
||||||
|
// +build atsamd21,!p1am_100
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build p1am_100
|
//go:build p1am_100
|
||||||
|
// +build p1am_100
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pygamer
|
//go:build pygamer
|
||||||
|
// +build pygamer
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pyportal
|
//go:build pyportal
|
||||||
|
// +build pyportal
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build thingplus_rp2040
|
//go:build thingplus_rp2040
|
||||||
|
// +build thingplus_rp2040
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build wioterminal
|
//go:build wioterminal
|
||||||
|
// +build wioterminal
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build gnse
|
//go:build gnse
|
||||||
|
// +build gnse
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Generic Node Sensor Edition
|
Generic Node Sensor Edition
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build lorae5
|
//go:build lorae5
|
||||||
|
// +build lorae5
|
||||||
|
|
||||||
package radio
|
package radio
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nucleowl55jc
|
//go:build nucleowl55jc
|
||||||
|
// +build nucleowl55jc
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Nucleo WL55JC1
|
Nucleo WL55JC1
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build espat
|
//go:build espat
|
||||||
|
// +build espat
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build rtl8720dn
|
//go:build rtl8720dn
|
||||||
|
// +build rtl8720dn
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build wifinina
|
//go:build wifinina
|
||||||
|
// +build wifinina
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -111,8 +111,10 @@ func getCurrentTime(conn *net.UDPSerialConn) (time.Time, error) {
|
|||||||
} else if n == 0 {
|
} else if n == 0 {
|
||||||
continue // no packet received yet
|
continue // no packet received yet
|
||||||
} else if n != NTP_PACKET_SIZE {
|
} else if n != NTP_PACKET_SIZE {
|
||||||
|
if n != NTP_PACKET_SIZE {
|
||||||
return time.Time{}, fmt.Errorf("expected NTP packet size of %d: %d", NTP_PACKET_SIZE, n)
|
return time.Time{}, fmt.Errorf("expected NTP packet size of %d: %d", NTP_PACKET_SIZE, n)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return parseNTPpacket(), nil
|
return parseNTPpacket(), nil
|
||||||
}
|
}
|
||||||
return time.Time{}, errors.New("no packet received after 1 second")
|
return time.Time{}, errors.New("no packet received after 1 second")
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nano_rp2040
|
//go:build nano_rp2040
|
||||||
|
// +build nano_rp2040
|
||||||
|
|
||||||
// This examples shows how to control RGB LED connected to
|
// This examples shows how to control RGB LED connected to
|
||||||
// NINA-W102 chip on Arduino Nano RP2040 Connect board
|
// NINA-W102 chip on Arduino Nano RP2040 Connect board
|
||||||
|
|||||||
@@ -1,209 +0,0 @@
|
|||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"machine"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/net/http"
|
|
||||||
"tinygo.org/x/drivers/wifinina"
|
|
||||||
)
|
|
||||||
|
|
||||||
// You can override the settings with the init() in another source code:
|
|
||||||
//
|
|
||||||
// func init() {
|
|
||||||
// ssid = "your-ssid"
|
|
||||||
// pass = "your-password"
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// Or use -ldflags option on tinygo command to set at compile-time:
|
|
||||||
//
|
|
||||||
// tinygo flash ... -ldflags '-X "main.ssid=xxx" -X "main.pass=xxx"' ...
|
|
||||||
//
|
|
||||||
|
|
||||||
var (
|
|
||||||
ssid string
|
|
||||||
pass string
|
|
||||||
)
|
|
||||||
|
|
||||||
var led = machine.LED
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
|
||||||
|
|
||||||
err := run()
|
|
||||||
for err != nil {
|
|
||||||
fmt.Printf("error: %s\r\n", err.Error())
|
|
||||||
time.Sleep(5 * time.Second)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func run() error {
|
|
||||||
|
|
||||||
spi := machine.NINA_SPI
|
|
||||||
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()
|
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
println("Connecting to " + ssid)
|
|
||||||
err := adaptor.ConnectToAccessPoint(ssid, pass, 10*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
println("Connected.")
|
|
||||||
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
ip, subnet, gateway, err := adaptor.GetIP()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("IP Address : %s\r\n", ip)
|
|
||||||
fmt.Printf("Mask : %s\r\n", subnet)
|
|
||||||
fmt.Printf("Gateway : %s\r\n", gateway)
|
|
||||||
|
|
||||||
http.UseDriver(adaptor)
|
|
||||||
|
|
||||||
http.HandleFunc("/", root)
|
|
||||||
http.HandleFunc("/hello", hello)
|
|
||||||
http.HandleFunc("/cnt", cnt)
|
|
||||||
http.HandleFunc("/6", sixlines)
|
|
||||||
http.HandleFunc("/off", LED_OFF)
|
|
||||||
http.HandleFunc("/on", LED_ON)
|
|
||||||
|
|
||||||
return http.ListenAndServe(":80", nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func root(w http.ResponseWriter, r *http.Request) {
|
|
||||||
access := 1
|
|
||||||
|
|
||||||
cookie, err := r.Cookie("access")
|
|
||||||
if err != nil {
|
|
||||||
if err == http.ErrNoCookie {
|
|
||||||
cookie = &http.Cookie{
|
|
||||||
Name: "access",
|
|
||||||
Value: "1",
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
http.Error(w, fmt.Sprintf("%s", err.Error()), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
v, err := strconv.ParseInt(cookie.Value, 10, 0)
|
|
||||||
if err != nil {
|
|
||||||
http.Error(w, fmt.Sprintf("invalid cookie.Value : %s", cookie.Value), http.StatusBadRequest)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
cookie.Value = fmt.Sprintf("%d", v+1)
|
|
||||||
access = int(v) + 1
|
|
||||||
}
|
|
||||||
http.SetCookie(w, cookie)
|
|
||||||
w.WriteHeader(http.StatusOK)
|
|
||||||
|
|
||||||
fmt.Fprintf(w, `
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>TinyGo HTTP Server</title>
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
var counter = 0
|
|
||||||
function ledOn() { fetch("/on"); }
|
|
||||||
function ledOff() { fetch("/off"); }
|
|
||||||
function fetchCnt() { fetch("/cnt").then(response => response.json()).then(json => { counter = json.cnt; cnt.innerHTML = counter; }); }
|
|
||||||
function incrCnt() { counter = counter + 1; fetch("/cnt?cnt=" + counter, { method: 'POST' }).then(response => response.json()).then(json => { counter = json.cnt; cnt.innerHTML = counter; }); }
|
|
||||||
function setCnt() { fetch("/cnt", {
|
|
||||||
method: "POST",
|
|
||||||
body: "cnt=" + document.getElementsByName("cnt")[0].value,
|
|
||||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
|
||||||
}).then(response => response.json()).then(json => { counter = json.cnt; cnt.innerHTML = counter; }); return false; }
|
|
||||||
function onLoad() { fetchCnt(); }
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body onLoad="onLoad()">
|
|
||||||
<h5>TinyGo HTTP Server</h5>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
access: %d
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<a href="/hello">/hello</a><br>
|
|
||||||
<a href="/6">/6</a><br>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
LED<br>
|
|
||||||
<a href="javascript:ledOn();">/on</a><br>
|
|
||||||
<a href="javascript:ledOff();">/off</a><br>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
|
|
||||||
<p>
|
|
||||||
<a href="/cnt">/cnt</a><br>
|
|
||||||
cnt: <span id="cnt"></span><br>
|
|
||||||
<a href="javascript:incrCnt()">incrCnt()</a><br>
|
|
||||||
<form id="form1" style="display: inline" onSubmit="return setCnt()">
|
|
||||||
<input type="text" name="cnt">
|
|
||||||
<input type="button" value="set cnt", onClick="setCnt()">
|
|
||||||
</form>
|
|
||||||
</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
`, access)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sixlines(w http.ResponseWriter, r *http.Request) {
|
|
||||||
// https://fukuno.jig.jp/3267
|
|
||||||
fmt.Fprint(w, `<body onload='onkeydown=e=>K=parseInt(e.key[5]||6,28)/3-8;Z=X=[B=A=12];Y=_=>`+
|
|
||||||
`{for(C=[q=c=i=4];f=i--*K;c-=!Z[h+(K+6?p+K:C[i]=p*A-(p/9|0)*145)])p=B[i];for(c?0:K+6?h+=K:B=C;`+
|
|
||||||
`i=K=q--;f+=Z[A+p])X[p=h+B[q]]=1;h+=A;if(f|B)for(Z=X,X=[l=228],B=[[-7,-20,6,h=17,-9,3,3][t=++t%7]-4,0,1,t-6?-A:2];l--;)`+
|
|
||||||
`for(l%A?l-=l%A*!Z[l]:(P++,c=l+=A);--c>A;)Z[c]=Z[c-A];for(S="";i<240;S+=X[i]|(X[i]=Z[i]|=++i%A<2|i>228)?i%A?"■":"■<br>":" ");`+
|
|
||||||
`D.innerHTML=S+P;setTimeout(Y,i-P)};Y(h=K=t=P=0)'id=D>`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func LED_ON(w http.ResponseWriter, r *http.Request) {
|
|
||||||
led.High()
|
|
||||||
w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`)
|
|
||||||
fmt.Fprintf(w, "led.High()")
|
|
||||||
}
|
|
||||||
|
|
||||||
func LED_OFF(w http.ResponseWriter, r *http.Request) {
|
|
||||||
led.Low()
|
|
||||||
w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`)
|
|
||||||
fmt.Fprintf(w, "led.Low()")
|
|
||||||
}
|
|
||||||
|
|
||||||
func hello(w http.ResponseWriter, r *http.Request) {
|
|
||||||
w.Header().Set(`Content-Type`, `text/plain; charset=UTF-8`)
|
|
||||||
fmt.Fprintf(w, "hello")
|
|
||||||
}
|
|
||||||
|
|
||||||
var counter int
|
|
||||||
|
|
||||||
func cnt(w http.ResponseWriter, r *http.Request) {
|
|
||||||
r.ParseForm()
|
|
||||||
if r.Method == "POST" {
|
|
||||||
c := r.Form.Get("cnt")
|
|
||||||
if c != "" {
|
|
||||||
i64, _ := strconv.ParseInt(c, 0, 0)
|
|
||||||
counter = int(i64)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Set(`Content-Type`, `application/json`)
|
|
||||||
fmt.Fprintf(w, `{"cnt": %d}`, counter)
|
|
||||||
}
|
|
||||||
|
|
||||||
func message(msg string) {
|
|
||||||
println(msg, "\r")
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build arduino
|
//go:build arduino
|
||||||
|
// +build arduino
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build digispark
|
//go:build digispark
|
||||||
|
// +build digispark
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !digispark && !arduino && !qtpy && !m5stamp_c3 && !thingplus_rp2040
|
//go:build !digispark && !arduino && !qtpy && !m5stamp_c3 && !thingplus_rp2040
|
||||||
|
// +build !digispark,!arduino,!qtpy,!m5stamp_c3,!thingplus_rp2040
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build qtpy || m5stamp_c3
|
//go:build qtpy || m5stamp_c3
|
||||||
|
// +build qtpy m5stamp_c3
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build qtpy
|
//go:build qtpy
|
||||||
|
// +build qtpy
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build thingplus_rp2040
|
//go:build thingplus_rp2040
|
||||||
|
// +build thingplus_rp2040
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd51
|
//go:build atsamd51
|
||||||
|
// +build atsamd51
|
||||||
|
|
||||||
package flash
|
package flash
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !nano_33_ble
|
//go:build !nano_33_ble
|
||||||
|
// +build !nano_33_ble
|
||||||
|
|
||||||
package hts221
|
package hts221
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nano_33_ble
|
//go:build nano_33_ble
|
||||||
|
// +build nano_33_ble
|
||||||
|
|
||||||
package hts221
|
package hts221
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd51 || atsame5x
|
//go:build atsamd51 || atsame5x
|
||||||
|
// +build atsamd51 atsame5x
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build esp32
|
//go:build esp32
|
||||||
|
// +build esp32
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nrf52840
|
//go:build nrf52840
|
||||||
|
// +build nrf52840
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !esp32 && !atsamd51 && !atsame5x && !stm32f4 && !rp2040 && !nrf52840
|
//go:build !esp32 && !atsamd51 && !atsame5x && !stm32f4 && !rp2040 && !nrf52840
|
||||||
|
// +build !esp32,!atsamd51,!atsame5x,!stm32f4,!rp2040,!nrf52840
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build rp2040
|
//go:build rp2040
|
||||||
|
// +build rp2040
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build stm32f4
|
//go:build stm32f4
|
||||||
|
// +build stm32f4
|
||||||
|
|
||||||
package i2csoft
|
package i2csoft
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd51
|
//go:build atsamd51
|
||||||
|
// +build atsamd51
|
||||||
|
|
||||||
package ili9341
|
package ili9341
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !atsamd51 && !atsame5x && !atsamd21
|
//go:build !atsamd51 && !atsame5x && !atsamd21
|
||||||
|
// +build !atsamd51,!atsame5x,!atsamd21
|
||||||
|
|
||||||
package ili9341
|
package ili9341
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd21
|
//go:build atsamd21
|
||||||
|
// +build atsamd21
|
||||||
|
|
||||||
package ili9341
|
package ili9341
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build atsamd51 || atsame5x
|
//go:build atsamd51 || atsame5x
|
||||||
|
// +build atsamd51 atsame5x
|
||||||
|
|
||||||
package ili9341
|
package ili9341
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build ignore
|
//go:build ignore
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
//go:build gofuzz
|
//go:build gofuzz
|
||||||
|
// +build gofuzz
|
||||||
|
|
||||||
package png
|
package png
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !nano_33_ble
|
//go:build !nano_33_ble
|
||||||
|
// +build !nano_33_ble
|
||||||
|
|
||||||
package lps22hb
|
package lps22hb
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nano_33_ble
|
//go:build nano_33_ble
|
||||||
|
// +build nano_33_ble
|
||||||
|
|
||||||
package lps22hb
|
package lps22hb
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !xiao_ble
|
//go:build !xiao_ble
|
||||||
|
// +build !xiao_ble
|
||||||
|
|
||||||
package lsm6ds3tr
|
package lsm6ds3tr
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build xiao_ble
|
//go:build xiao_ble
|
||||||
|
// +build xiao_ble
|
||||||
|
|
||||||
package lsm6ds3tr
|
package lsm6ds3tr
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !nano_33_ble
|
//go:build !nano_33_ble
|
||||||
|
// +build !nano_33_ble
|
||||||
|
|
||||||
package lsm9ds1
|
package lsm9ds1
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build nano_33_ble
|
//go:build nano_33_ble
|
||||||
|
// +build nano_33_ble
|
||||||
|
|
||||||
// Nano 33 BLE [Sense] has LSM9DS1 unit on-board.
|
// Nano 33 BLE [Sense] has LSM9DS1 unit on-board.
|
||||||
// This custom Configure function powers unit up
|
// This custom Configure function powers unit up
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build microbit
|
//go:build microbit
|
||||||
|
// +build microbit
|
||||||
|
|
||||||
// Package microbitmatrix implements a driver for the BBC micro:bit's LED matrix.
|
// Package microbitmatrix implements a driver for the BBC micro:bit's LED matrix.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build microbit_v2
|
//go:build microbit_v2
|
||||||
|
// +build microbit_v2
|
||||||
|
|
||||||
// Package microbitmatrix implements a driver for the BBC micro:bit version 2 LED matrix.
|
// Package microbitmatrix implements a driver for the BBC micro:bit version 2 LED matrix.
|
||||||
//
|
//
|
||||||
|
|||||||
+3
-1
@@ -87,7 +87,9 @@ type Client struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// DefaultClient is the default Client and is used by Get, Head, and Post.
|
// DefaultClient is the default Client and is used by Get, Head, and Post.
|
||||||
var DefaultClient = &Client{}
|
var DefaultClient = &Client{
|
||||||
|
Transport: DefaultTransport,
|
||||||
|
}
|
||||||
|
|
||||||
// RoundTripper is an interface representing the ability to execute a
|
// RoundTripper is an interface representing the ability to execute a
|
||||||
// single HTTP transaction, obtaining the Response for a given Request.
|
// single HTTP transaction, obtaining the Response for a given Request.
|
||||||
|
|||||||
+95
-101
@@ -5,7 +5,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net/textproto"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -27,11 +26,7 @@ func (c *Client) Do(req *Request) (*Response, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
transport := c.Transport
|
res, err := c.Transport.RoundTrip(req)
|
||||||
if transport == nil {
|
|
||||||
transport = DefaultTransport
|
|
||||||
}
|
|
||||||
res, err := transport.RoundTrip(req)
|
|
||||||
|
|
||||||
if c.Jar != nil {
|
if c.Jar != nil {
|
||||||
if rc := res.Cookies(); len(rc) > 0 {
|
if rc := res.Cookies(); len(rc) > 0 {
|
||||||
@@ -202,123 +197,122 @@ func (t *Transport) doResp(conn net.Conn, req *Request) (*Response, error) {
|
|||||||
Header: map[string][]string{},
|
Header: map[string][]string{},
|
||||||
}
|
}
|
||||||
|
|
||||||
br := bufio.NewReader(conn)
|
// Header
|
||||||
tp := textproto.NewReader(br)
|
var scanner *bufio.Scanner
|
||||||
|
cont := true
|
||||||
for {
|
ofs := 0
|
||||||
line, err := tp.ReadLine()
|
remain := int64(0)
|
||||||
|
for cont {
|
||||||
|
for n, err := conn.Read(buf[ofs:]); n > 0; n, err = conn.Read(buf[ofs:]) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.ErrNoProgress {
|
println("Read error: " + err.Error())
|
||||||
// default: no timeout
|
} else {
|
||||||
|
// Take care of the case where "\r\n\r\n" is on the boundary of a buffer
|
||||||
|
start := ofs
|
||||||
|
if start > 3 {
|
||||||
|
start -= 3
|
||||||
|
}
|
||||||
|
idx := bytes.Index(buf[start:ofs+n], []byte("\r\n\r\n"))
|
||||||
|
if idx == -1 {
|
||||||
|
ofs += n
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
conn.Close()
|
idx += start + 4
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
status := strings.SplitN(line, " ", 2)
|
scanner = bufio.NewScanner(bytes.NewReader(buf[0 : ofs+n]))
|
||||||
|
if resp.Status == "" && scanner.Scan() {
|
||||||
|
status := strings.SplitN(scanner.Text(), " ", 2)
|
||||||
if len(status) != 2 {
|
if len(status) != 2 {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, fmt.Errorf("invalid status : %q", line)
|
return nil, fmt.Errorf("invalid status : %q", scanner.Text())
|
||||||
}
|
}
|
||||||
resp.Proto = status[0]
|
resp.Proto = status[0]
|
||||||
fmt.Sscanf(status[0], "HTTP/%d.%d", &resp.ProtoMajor, &resp.ProtoMinor)
|
fmt.Sscanf(status[0], "HTTP/%d.%d", &resp.ProtoMajor, &resp.ProtoMinor)
|
||||||
|
|
||||||
resp.Status = status[1]
|
resp.Status = status[1]
|
||||||
fmt.Sscanf(status[1], "%d", &resp.StatusCode)
|
fmt.Sscanf(status[1], "%d", &resp.StatusCode)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := tp.ReadMIMEHeader()
|
for scanner.Scan() {
|
||||||
if err != nil {
|
text := scanner.Text()
|
||||||
conn.Close()
|
if text == "" {
|
||||||
return nil, err
|
// end of header
|
||||||
|
if idx < n+ofs {
|
||||||
|
ofs = ofs + n - idx
|
||||||
|
for i := 0; i < ofs; i++ {
|
||||||
|
buf[i] = buf[i+idx]
|
||||||
}
|
}
|
||||||
for k, v := range m {
|
|
||||||
//fmt.Printf("%s: %s\n", k, v)
|
|
||||||
|
|
||||||
if strings.ToLower(k) == "content-length" {
|
|
||||||
resp.ContentLength, err = strconv.ParseInt(v[0], 10, 64)
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Header.Get(k) == "" {
|
|
||||||
resp.Header.Set(k, v[0])
|
|
||||||
v = v[1:]
|
|
||||||
}
|
|
||||||
for _, vv := range v {
|
|
||||||
resp.Header.Add(k, vv)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.Header.Get("Transfer-Encoding") == "chunked" {
|
|
||||||
// chunked
|
|
||||||
cur := 0
|
|
||||||
end := 0
|
|
||||||
for {
|
|
||||||
length := 0
|
|
||||||
if len(buf) < cur+6 {
|
|
||||||
// This is not a very accurate check, but in many cases it should be fine.
|
|
||||||
return nil, fmt.Errorf("slice out of range : use http.SetBuf() to change the allocation to %d bytes or more", cur+6)
|
|
||||||
}
|
|
||||||
for i := 0; ; i++ {
|
|
||||||
buf[cur+i], err = br.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
length = i + 1
|
|
||||||
if i > 1 && buf[cur+i-1] == '\r' && buf[cur+i] == '\n' {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//fmt.Printf("cur:%d length:%d\n", cur, length)
|
|
||||||
|
|
||||||
size, err := strconv.ParseInt(string(buf[cur:cur+length-2]), 16, 64)
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
//cur += length
|
|
||||||
//fmt.Printf("cur:%d length:%d size:%d\n", cur, length, size)
|
|
||||||
|
|
||||||
end = cur + int(size) + 2 // size + 2 (\r\n)
|
|
||||||
if len(buf) < end {
|
|
||||||
return nil, fmt.Errorf("slice out of range : use http.SetBuf() to change the allocation to %d bytes or more", end)
|
|
||||||
}
|
|
||||||
for i := 0; i < int(size)+2; i++ {
|
|
||||||
buf[cur+i], err = br.ReadByte()
|
|
||||||
if err != nil {
|
|
||||||
conn.Close()
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cur += int(size)
|
|
||||||
|
|
||||||
if size == 0 {
|
|
||||||
end = end - 2
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//fmt.Printf("%q\n", buf[:end])
|
|
||||||
resp.Body = io.NopCloser(bytes.NewReader(buf[:end]))
|
|
||||||
} else {
|
} else {
|
||||||
end := int(resp.ContentLength)
|
ofs = 0
|
||||||
if len(buf) < end {
|
|
||||||
return nil, fmt.Errorf("slice out of range : use http.SetBuf() to change the allocation to %d bytes or more", end)
|
|
||||||
}
|
}
|
||||||
for i := 0; i < end; i++ {
|
break
|
||||||
buf[i], err = br.ReadByte()
|
} else {
|
||||||
|
header := strings.SplitN(text, ": ", 2)
|
||||||
|
if len(header) != 2 {
|
||||||
|
conn.Close()
|
||||||
|
return nil, fmt.Errorf("invalid header : %q", text)
|
||||||
|
}
|
||||||
|
if resp.Header.Get(header[0]) == "" {
|
||||||
|
resp.Header.Set(header[0], header[1])
|
||||||
|
} else {
|
||||||
|
resp.Header.Add(header[0], header[1])
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.ToLower(header[0]) == "content-length" {
|
||||||
|
resp.ContentLength, err = strconv.ParseInt(header[1], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
remain = resp.ContentLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cont = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body
|
||||||
|
remain -= int64(ofs)
|
||||||
|
if remain <= 0 {
|
||||||
|
resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs]))
|
||||||
|
return resp, conn.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
cont = true
|
||||||
|
lastRequestTime := time.Now()
|
||||||
|
for cont {
|
||||||
|
for {
|
||||||
|
end := ofs + 0x400
|
||||||
|
if len(buf) < end {
|
||||||
|
return nil, fmt.Errorf("slice out of range : use http.SetBuf() to change the allocation to %d bytes or more", end)
|
||||||
|
}
|
||||||
|
n, err := conn.Read(buf[ofs : ofs+0x400])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
conn.Close()
|
||||||
|
return nil, err
|
||||||
|
} else {
|
||||||
|
ofs += n
|
||||||
|
remain -= int64(n)
|
||||||
|
if remain <= 0 {
|
||||||
|
resp.Body = io.NopCloser(bytes.NewReader(buf[:ofs]))
|
||||||
|
cont = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if time.Now().Sub(lastRequestTime).Milliseconds() >= 1000 {
|
||||||
|
conn.Close()
|
||||||
|
return nil, fmt.Errorf("time out")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
resp.Body = io.NopCloser(bytes.NewReader(buf[:end]))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resp, conn.Close()
|
return resp, conn.Close()
|
||||||
|
|||||||
@@ -71,13 +71,10 @@ func (d *Driver) ConnectTCPSocket(addr, port string) error {
|
|||||||
name[6] = byte(ipaddr[2])
|
name[6] = byte(ipaddr[2])
|
||||||
name[7] = byte(ipaddr[3])
|
name[7] = byte(ipaddr[3])
|
||||||
|
|
||||||
result, err := d.Rpc_lwip_connect(socket, name, uint32(len(name)))
|
_, err = d.Rpc_lwip_connect(socket, name, uint32(len(name)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if result == -1 {
|
|
||||||
return fmt.Errorf("failed to connect to %d.%d.%d.%d port %s", addr[0], addr[1], addr[2], addr[3], port)
|
|
||||||
}
|
|
||||||
|
|
||||||
readset := []byte{}
|
readset := []byte{}
|
||||||
writeset := []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
writeset := []byte{0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
|
||||||
@@ -344,11 +341,8 @@ func (d *Driver) ReadSocket(b []byte) (n int, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
if nn == -76 {
|
if nn < 0 {
|
||||||
// no data
|
return 0, fmt.Errorf("error %d", n)
|
||||||
return 0, nil
|
|
||||||
} else if nn < 0 {
|
|
||||||
return 0, fmt.Errorf("error %d", nn)
|
|
||||||
} else if nn == 0 || nn == -30848 {
|
} else if nn == 0 || nn == -30848 {
|
||||||
return 0, d.DisconnectSocket()
|
return 0, d.DisconnectSocket()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build pybadge
|
//go:build pybadge
|
||||||
|
// +build pybadge
|
||||||
|
|
||||||
package shifter
|
package shifter
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build rp2040
|
//go:build rp2040
|
||||||
|
// +build rp2040
|
||||||
|
|
||||||
package ssd1289
|
package ssd1289
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build stm32wlx
|
//go:build stm32wlx
|
||||||
|
// +build stm32wlx
|
||||||
|
|
||||||
package sx126x
|
package sx126x
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ type rangingData struct {
|
|||||||
status RangeStatus
|
status RangeStatus
|
||||||
signalRateMCPS int32 //MCPS : Mega Count Per Second
|
signalRateMCPS int32 //MCPS : Mega Count Per Second
|
||||||
ambientRateMCPS int32
|
ambientRateMCPS int32
|
||||||
effectiveSPADCount uint16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type resultBuffer struct {
|
type resultBuffer struct {
|
||||||
@@ -338,11 +337,6 @@ func (d *Device) AmbientRate() int32 {
|
|||||||
return d.rangingData.ambientRateMCPS
|
return d.rangingData.ambientRateMCPS
|
||||||
}
|
}
|
||||||
|
|
||||||
// EffectiveSPADCount returns the effective number of SPADs
|
|
||||||
func (d *Device) EffectiveSPADCount() uint16 {
|
|
||||||
return d.rangingData.effectiveSPADCount
|
|
||||||
}
|
|
||||||
|
|
||||||
// getRangingData stores in the buffer the ranging data
|
// getRangingData stores in the buffer the ranging data
|
||||||
func (d *Device) getRangingData() {
|
func (d *Device) getRangingData() {
|
||||||
d.rangingData.mm = uint16((uint32(d.results.mmCrosstalkSD0)*2011 + 0x0400) / 0x0800)
|
d.rangingData.mm = uint16((uint32(d.results.mmCrosstalkSD0)*2011 + 0x0400) / 0x0800)
|
||||||
@@ -390,7 +384,6 @@ func (d *Device) getRangingData() {
|
|||||||
|
|
||||||
d.rangingData.signalRateMCPS = 1000000 * int32(d.results.signalRateCrosstalkMCPSSD0) / (1 << 7)
|
d.rangingData.signalRateMCPS = 1000000 * int32(d.results.signalRateCrosstalkMCPSSD0) / (1 << 7)
|
||||||
d.rangingData.ambientRateMCPS = 1000000 * int32(d.results.ambientRateMCPSSD0) / (1 << 7)
|
d.rangingData.ambientRateMCPS = 1000000 * int32(d.results.ambientRateMCPSSD0) / (1 << 7)
|
||||||
d.rangingData.effectiveSPADCount = d.results.effectiveSPADCount
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// setupManualCalibration configures the manual calibration
|
// setupManualCalibration configures the manual calibration
|
||||||
|
|||||||
@@ -1,323 +0,0 @@
|
|||||||
package wifinina
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bufio"
|
|
||||||
"bytes"
|
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"tinygo.org/x/drivers/net/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (d *Device) ListenAndServe(addr string, handler http.Handler) error {
|
|
||||||
|
|
||||||
if handler == nil {
|
|
||||||
handler = http.DefaultServeMux
|
|
||||||
}
|
|
||||||
|
|
||||||
server := newServer(d, handler)
|
|
||||||
|
|
||||||
if err := server.listen(addr); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
for {
|
|
||||||
client, err := server.accept()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := client.handleHTTP(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = client.stop(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Server stuff
|
|
||||||
|
|
||||||
type server struct {
|
|
||||||
device *Device
|
|
||||||
handler http.Handler
|
|
||||||
sock uint8
|
|
||||||
clients map[uint8]*client // keyed by client sock
|
|
||||||
}
|
|
||||||
|
|
||||||
func newServer(device *Device, handler http.Handler) *server {
|
|
||||||
return &server{
|
|
||||||
device: device,
|
|
||||||
handler: handler,
|
|
||||||
sock: NoSocketAvail,
|
|
||||||
clients: make(map[uint8]*client),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func portFromAddr(addr string) (uint16, error) {
|
|
||||||
// ignore anything before ':' in address
|
|
||||||
i := strings.LastIndex(addr, ":")
|
|
||||||
if i < 0 {
|
|
||||||
return 0, fmt.Errorf("Missing ':' in address")
|
|
||||||
}
|
|
||||||
v, err := strconv.ParseUint(addr[i+1:], 10, 16)
|
|
||||||
if err != nil {
|
|
||||||
return 0, fmt.Errorf("Parsing address err: %s", err)
|
|
||||||
}
|
|
||||||
return uint16(v), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *server) listen(addr string) error {
|
|
||||||
port, err := portFromAddr(addr)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Getting port err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s.sock, err = s.device.GetSocket()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Getting socket err: %s", err)
|
|
||||||
}
|
|
||||||
if s.sock == NoSocketAvail {
|
|
||||||
return fmt.Errorf("No socket available")
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.device.StartServer(port, s.sock, ProtoModeTCP)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *server) availServer(sock uint8) (uint8, error) {
|
|
||||||
d := s.device
|
|
||||||
|
|
||||||
d.mu.Lock()
|
|
||||||
defer d.mu.Unlock()
|
|
||||||
|
|
||||||
if err := d.waitForChipSelect(); err != nil {
|
|
||||||
d.spiChipDeselect()
|
|
||||||
return NoSocketAvail, fmt.Errorf("Wait for CS: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
l := d.sendCmd(CmdAvailDataTCP, 1)
|
|
||||||
l += d.sendParam8(sock, true)
|
|
||||||
d.addPadding(l)
|
|
||||||
d.spiChipDeselect()
|
|
||||||
_, err := d.waitRspCmd1(CmdAvailDataTCP)
|
|
||||||
if err != nil {
|
|
||||||
return NoSocketAvail, fmt.Errorf("Wait for Rsp: %s", err)
|
|
||||||
}
|
|
||||||
newsock, err := d.getUint16(2, err)
|
|
||||||
if err != nil {
|
|
||||||
return NoSocketAvail, fmt.Errorf("getUint16: %s", err)
|
|
||||||
}
|
|
||||||
return uint8(newsock >> 8), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *server) accept() (*client, error) {
|
|
||||||
|
|
||||||
for {
|
|
||||||
sock, err := s.availServer(s.sock)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("accept: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if sock == NoSocketAvail {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if client, ok := s.clients[sock]; ok {
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
client := newClient(s, sock)
|
|
||||||
s.clients[sock] = client
|
|
||||||
|
|
||||||
return client, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// client stuff
|
|
||||||
|
|
||||||
type client struct {
|
|
||||||
server *server
|
|
||||||
device *Device
|
|
||||||
sock uint8
|
|
||||||
|
|
||||||
// HTTP request
|
|
||||||
req *http.Request
|
|
||||||
reqBuf bytes.Buffer
|
|
||||||
readBuf [256]byte
|
|
||||||
|
|
||||||
// HTTP response
|
|
||||||
res bytes.Buffer
|
|
||||||
resHdr http.Header
|
|
||||||
resBuf bytes.Buffer
|
|
||||||
statusCode int
|
|
||||||
}
|
|
||||||
|
|
||||||
func newClient(server *server, sock uint8) *client {
|
|
||||||
return &client{
|
|
||||||
server: server,
|
|
||||||
device: server.device,
|
|
||||||
sock: sock,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// client implements http.ResponseWriter interface
|
|
||||||
|
|
||||||
func (c *client) Header() http.Header {
|
|
||||||
return c.resHdr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) Write(b []byte) (int, error) {
|
|
||||||
return c.resBuf.Write(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) WriteHeader(statusCode int) {
|
|
||||||
c.statusCode = statusCode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) status() uint8 {
|
|
||||||
d := c.device
|
|
||||||
|
|
||||||
d.mu.Lock()
|
|
||||||
defer d.mu.Unlock()
|
|
||||||
|
|
||||||
if err := d.waitForChipSelect(); err != nil {
|
|
||||||
d.spiChipDeselect()
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
l := d.sendCmd(CmdGetClientStateTCP, 1)
|
|
||||||
l += d.sendParam8(c.sock, true)
|
|
||||||
d.addPadding(l)
|
|
||||||
d.spiChipDeselect()
|
|
||||||
_, err := d.waitRspCmd1(CmdGetClientStateTCP)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
status, err := d.getUint8(1, err)
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return status
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) stop() error {
|
|
||||||
if err := c.device.StopClient(c.sock); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait max 5 secs for the connection to close
|
|
||||||
for i := 0; i < 50 && c.status() != TCPStateClosed; i++ {
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.status() != TCPStateClosed {
|
|
||||||
return fmt.Errorf("stop failed, client status %x", c.status())
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *client) handleHTTP() error {
|
|
||||||
|
|
||||||
c.reqBuf.Reset()
|
|
||||||
end := -1
|
|
||||||
|
|
||||||
// read the request
|
|
||||||
|
|
||||||
start := time.Now()
|
|
||||||
for {
|
|
||||||
|
|
||||||
// TODO use Server.ReadTimeout
|
|
||||||
if time.Since(start) > 1*time.Second {
|
|
||||||
return fmt.Errorf("ReadTimeout")
|
|
||||||
}
|
|
||||||
|
|
||||||
n, err := c.device.GetDataBuf(c.sock, c.readBuf[:])
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("GetDataBuf: %s", err)
|
|
||||||
}
|
|
||||||
if n == 0 {
|
|
||||||
time.Sleep(1 * time.Millisecond)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
c.reqBuf.Write(c.readBuf[:n])
|
|
||||||
bytesSoFar := c.reqBuf.Bytes()
|
|
||||||
|
|
||||||
if end == -1 {
|
|
||||||
|
|
||||||
// search for blank line marking end-of-header
|
|
||||||
end = bytes.Index(bytesSoFar, []byte("\r\n\r\n"))
|
|
||||||
if end == -1 {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// found end-of-header; parse header
|
|
||||||
end += len([]byte("\r\n\r\n"))
|
|
||||||
bufio := bufio.NewReader(bytes.NewReader(bytesSoFar[:end]))
|
|
||||||
c.req, err = http.ReadRequest(bufio)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
v := c.req.Header.Get("Content-Length")
|
|
||||||
if v == "" {
|
|
||||||
// no body; we're done reading request
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
length, _ := strconv.Atoi(v)
|
|
||||||
if end+length == len(bytesSoFar) {
|
|
||||||
// got the whole body
|
|
||||||
body := bytes.NewReader(bytesSoFar[end:])
|
|
||||||
c.req.Body = io.NopCloser(body)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
// continue reading request...
|
|
||||||
}
|
|
||||||
|
|
||||||
// build the response
|
|
||||||
|
|
||||||
c.statusCode = 200
|
|
||||||
|
|
||||||
c.resHdr = http.Header{}
|
|
||||||
c.resHdr.Add(`Content-Type`, `text/html; charset=UTF-8`)
|
|
||||||
c.resHdr.Add(`Connection`, `close`)
|
|
||||||
|
|
||||||
c.resBuf.Reset()
|
|
||||||
c.server.handler.ServeHTTP(c, c.req)
|
|
||||||
|
|
||||||
c.resHdr.Add(`Content-Length`, fmt.Sprintf("%d", c.resBuf.Len()))
|
|
||||||
|
|
||||||
c.res.Reset()
|
|
||||||
fmt.Fprintf(&c.res, "HTTP/1.1 %d %s\r\n", c.statusCode,
|
|
||||||
http.StatusText(c.statusCode))
|
|
||||||
if err := c.resHdr.Write(&c.res); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
c.res.WriteByte(byte('\n'))
|
|
||||||
c.res.Write(c.resBuf.Bytes())
|
|
||||||
|
|
||||||
// send the response
|
|
||||||
|
|
||||||
written, err := c.device.SendData(c.res.Bytes(), c.sock)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if written == 0 {
|
|
||||||
return ErrDataNotWritten
|
|
||||||
}
|
|
||||||
if sent, _ := c.device.CheckDataSent(c.sock); !sent {
|
|
||||||
return ErrCheckDataError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build none
|
//go:build none
|
||||||
|
// +build none
|
||||||
|
|
||||||
package main
|
package main
|
||||||
|
|
||||||
@@ -284,6 +285,7 @@ func main() {
|
|||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
fmt.Fprintln(f, "//go:build", architectures[*arch].buildTag)
|
fmt.Fprintln(f, "//go:build", architectures[*arch].buildTag)
|
||||||
|
fmt.Fprintln(f, "// +build", architectures[*arch].buildTag)
|
||||||
f.WriteString(`
|
f.WriteString(`
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build cortexm
|
//go:build cortexm
|
||||||
|
// +build cortexm
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo.riscv32
|
//go:build tinygo.riscv32
|
||||||
|
// +build tinygo.riscv32
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build avr
|
//go:build avr
|
||||||
|
// +build avr
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build cortexm
|
//go:build cortexm
|
||||||
|
// +build cortexm
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build !baremetal
|
//go:build !baremetal
|
||||||
|
// +build !baremetal
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build tinygo.riscv32
|
//go:build tinygo.riscv32
|
||||||
|
// +build tinygo.riscv32
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
//go:build xtensa
|
//go:build xtensa
|
||||||
|
// +build xtensa
|
||||||
|
|
||||||
package ws2812
|
package ws2812
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user