Compare commits

...

5 Commits

Author SHA1 Message Date
soypat 5405842815 rewrite enum implementations 2023-12-26 22:44:25 -03:00
soypat 09b7b249fe working more or less 2023-12-26 22:35:48 -03:00
soypat 4bd873a82d add draft apds9930 2023-12-26 15:00:56 -08:00
Scott Feldman 8642886f73 correct netdever Accept() prototype
According to man page accept(2), accept returns new client sockfd and
remote peer ip:port.  This patch corrects the Accept() prototype in the
netdever interface to not take in an ip:port arg, but rather return an
ip:port for remote peer.

Tested with examples/net/tcpecho on wioterminal and nano-rp2040.  Here's
a run with wioterminal:

SERVER
============
sfeldma@nuc:~/work/drivers$ tinygo flash -monitor -target wioterminal -size short -stack-size=8kb ./examples/net/tcpecho
code    data     bss |   flash     ram
110876    2552   11212 |  113428   13764
Connected to /dev/ttyACM2. Press Ctrl-C to exit.

Realtek rtl8720dn Wifi network device driver (rtl8720dn)

Driver version           : 0.0.1
RTL8720 firmware version : 2.1.2
MAC address              : 2c:f7:f1:1c:9b:2f

Connecting to Wifi SSID 'test'...CONNECTED

DHCP-assigned IP         : 10.0.0.140
DHCP-assigned subnet     : 255.255.255.0
DHCP-assigned gateway    : 10.0.0.1

Starting TCP server listening on :8080
Client 10.0.0.190:50000 connected
Client 10.0.0.190:50000 closed

CLIENT
=============
nc -p 50000 10.0.0.140 8080
2023-12-19 09:33:54 +01:00
Simon Dismo 1a96fc4547 Add more line speeds to mcp2515.go (#626)
mcp2515: adding the possibility to configure lower line speeds on the CAN bus.
2023-12-11 20:40:36 +01:00
9 changed files with 461 additions and 17 deletions
+231
View File
@@ -0,0 +1,231 @@
package apds9930
import (
"errors"
"tinygo.org/x/drivers"
)
var errInvalidParam = errors.New("apds9930: invalid param")
type Dev struct {
bus drivers.I2C
_txerr error
addr uint16
buf [3]byte
}
func New(bus drivers.I2C, addr uint8) Dev {
return Dev{bus: bus, addr: uint16(addr)}
}
// Status contains info on:
//
// AVALID: Indicates that the ALS Ch0/Ch1 channels have completed an integration cycle.
// PSValid. Indicates that the PS has completed an integration cycle.
// AINTL ALS Interrupt. Indicates that the device is asserting an ALS interrupt
// PINT: Proximity Interrupt. Indicates that the device is asserting a proximity interrupt.
// PSAT: Proximity Saturation. Indicates that the proximity measurement is saturated
type Status uint8
func (s Status) ALSAvailable() bool { return s&(1<<0) != 0 } // AVALID
func (s Status) ProximityAvailable() bool { return s&(1<<1) != 0 } // PVALID
func (s Status) HasALSInterrupt() bool { return s&(1<<4) != 0 } // AINT
func (s Status) HasProxInterrupt() bool { return s&(1<<5) != 0 } // PINT
func (s Status) IsProximitySaturated() bool { return s&(1<<6) != 0 } // PSAT
type Enable uint8
const (
EnPower Enable = 1 << iota
EnALS
EnProx
EnWait
EnALSInt
EnProxInt
EnSleepAfterInt
)
// Luminic control gain.
type ALSGain uint8
const (
AGain1 ALSGain = iota
AGain8
AGain16
AGain120
)
type ProxGain uint8
const (
PGain1 ProxGain = iota
PGain2
PGain4
PGain8
)
type Drive uint8
const (
Drive100mA Drive = iota
Drive50mA
Drive25mA
Drive12_5mA
)
type Config struct {
ProxGain ProxGain
ALSGain ALSGain
LEDDrive Drive
}
func (d *Dev) Init(cfg Config) error {
if cfg.LEDDrive > Drive100mA {
return errInvalidParam
}
d.txNew()
d.txWrite8(regENABLE, 0x00) // disable all features.
d.txWrite8(regATIME, 0xee) // set default integration time.
d.txWrite8(regPPULSE, 0x04)
d.txWrite8(regWTIME, 0xee) // set default wait time.
d.txWrite8(regPTIME, 0xff) // set default pulse count.
var ctlval uint8 = 0b10 << 4 // Use Channel 1 diode.
ctlval |= uint8(cfg.LEDDrive&0b11) << 6
ctlval |= uint8(cfg.ProxGain&0b11) << 2
ctlval |= uint8(cfg.ALSGain & 0b11)
d.txWrite8(regCONTROL, ctlval)
return d.txErr()
}
func (d *Dev) Status() (Status, error) {
d.txNew()
v := d.txRead8(regSTATUS)
return Status(v), d.txErr()
}
// Enable sets the ENABLE register used primarily to
// power the APDS-9930 device on/off, enable functions, and interrupts.
// Arguments must be ORed, i.e: d.Enable(EnPower|EnProx); to enable proximity.
func (d *Dev) Enable(en Enable) error {
en &= 0b01111111 // Seventh bit reserved.
d.txNew()
d.txWrite8(regENABLE, uint8(en))
return d.txErr()
}
func (d *Dev) enableLightSensor(withInterrupts bool) error {
return nil
}
func (d *Dev) setAmbientLightGain() {
}
func (d *Dev) EnableProximity() error {
return d.Enable(EnPower | EnALS | EnProx | EnWait)
}
func (d *Dev) proxIntLowThresh() (uint16, error) {
d.txNew()
return d.txRead16(regPILTL), d.txErr()
}
func (d *Dev) setProxIntLowThresh(loThresh uint16) error {
d.txNew()
d.txWrite16(regPILTL, loThresh)
return d.txErr()
}
func (d *Dev) proxIntHighThresh() (uint16, error) {
d.txNew()
val := d.txRead16(regPIHTL)
return val, d.txErr()
}
func (d *Dev) setProxIntHighThresh(hiThresh uint16) error {
d.txNew()
d.txWrite16(regPIHTL, hiThresh)
return d.txErr()
}
func (d *Dev) LEDDrive() (Drive, error) {
d.txNew()
val := (d.txRead8(regCONTROL) >> 6) & 0b11
return Drive(val), d.txErr()
}
// SetLEDDrive drive strength for proximity and ALS
//
// Value LED Current
// 3 100 mA
// 2 50 mA
// 1 25 mA
// 0 12.5 mA
func (d *Dev) SetLEDDrive(drive Drive) error {
if drive > 3 {
return errInvalidParam
}
current, err := d.LEDDrive()
if err != nil {
return err
}
// Replace LED bits in Control register.
current &= 0b00111111
current |= drive << 6
d.txNew()
d.txWrite8(regCONTROL, uint8(current))
return d.txErr()
}
func (d *Dev) proxGain() (uint8, error) {
val := d.txRead8(regCONTROL)
return (val >> 2) & 0b11, d.txErr()
}
// ReadProximity returns a 10-bit value (0..1023), the higher the value the closer the object
func (d *Dev) ReadProximity() uint16 {
d.txNew()
v := d.txRead16(regPDATAL)
if d.txErr() != nil {
return 0
}
return v
}
func (d *Dev) txRead16(addr uint8) uint16 {
if d.txErr() != nil {
return 0
}
d.buf[0] = addr | protoAutoInc
d._txerr = d.bus.Tx(d.addr, d.buf[:1], d.buf[1:3])
return uint16(d.buf[1]) | uint16(d.buf[2])<<8
}
func (d *Dev) txRead8(addr uint8) uint8 {
if d.txErr() != nil {
return 0
}
d.buf[0] = addr | protoAutoInc
d._txerr = d.bus.Tx(d.addr, d.buf[:1], d.buf[1:2])
return d.buf[1]
}
func (d *Dev) txWrite16(addr uint8, val uint16) {
d.txWrite8(addr, uint8(val))
d.txWrite8(addr+1, uint8(val>>8))
}
func (d *Dev) txWrite8(reg uint8, val uint8) {
if d.txErr() != nil {
return
}
d.buf[0] = reg | 0x80
d.buf[1] = val
d._txerr = d.bus.Tx(d.addr, d.buf[:2], nil)
}
func (d *Dev) txNew() { d._txerr = nil }
func (d *Dev) txErr() error { return d._txerr }
+23
View File
@@ -0,0 +1,23 @@
package apds9930
const (
protoAutoInc = 0xA0
)
const (
regENABLE = 0x00
regATIME = 0x01
regPTIME = 0x02
regWTIME = 0x03
regPILTL = 0x08
regPILTH = 0x09
regPIHTL = 0x0A
regPIHTH = 0x0B
regCONFIG = 0x0D
regPPULSE = 0x0E
regCONTROL = 0x0F
regSTATUS = 0x13
regPDATAL = 0x18
regPDATAH = 0x19
regPOFFSET = 0x1E
)
+2 -2
View File
@@ -218,8 +218,8 @@ func (d *Device) Listen(sockfd int, backlog int) error {
return nil
}
func (d *Device) Accept(sockfd int, ip netip.AddrPort) (int, error) {
return -1, netdev.ErrNotSupported
func (d *Device) Accept(sockfd int) (int, netip.AddrPort, error) {
return -1, netip.AddrPort{}, netdev.ErrNotSupported
}
func (d *Device) sendChunk(sockfd int, buf []byte, deadline time.Time) (int, error) {
+43
View File
@@ -0,0 +1,43 @@
package main
import (
"machine"
"time"
"tinygo.org/x/drivers/apds9930"
)
func main() {
// Sleep to catch any errors through the serial monitor.
time.Sleep(1000 * time.Millisecond)
bus := machine.I2C0
// use Nano 33 BLE Sense's internal I2C bus
err := bus.Configure(machine.I2CConfig{
SCL: machine.GP1,
SDA: machine.GP0,
Frequency: 100 * machine.KHz,
})
if err != nil {
panic(err.Error())
}
sensor := apds9930.New(bus, 0x39)
err = sensor.Init(apds9930.Config{})
if err != nil {
panic(err)
}
err = sensor.EnableProximity()
if err != nil {
panic(err)
}
println("proximity enabled!")
for {
stat, _ := sensor.Status()
if !stat.ProximityAvailable() {
time.Sleep(5 * time.Millisecond)
continue
}
prox := sensor.ReadProximity()
println("proximity:", prox)
}
}
+4 -1
View File
@@ -30,16 +30,18 @@ var (
var buf [1024]byte
func echo(conn net.Conn) {
println("Client", conn.RemoteAddr(), "connected")
defer conn.Close()
_, err := io.CopyBuffer(conn, conn, buf[:])
if err != nil && err != io.EOF {
log.Fatal(err.Error())
}
println("Client", conn.RemoteAddr(), "closed")
}
func main() {
time.Sleep(time.Second)
time.Sleep(2 * time.Second)
link, _ := probe.Probe()
@@ -51,6 +53,7 @@ func main() {
log.Fatal(err)
}
println("Starting TCP server listening on", port)
l, err := net.Listen("tcp", port)
if err != nil {
log.Fatal(err.Error())
+112 -1
View File
@@ -236,16 +236,83 @@ func (d *Device) getMode() (byte, error) {
}
func (d *Device) configRate(speed, clock byte) error {
// TODO: add another baudrate
var cfg1, cfg2, cfg3 byte
set := true
switch clock {
case Clock16MHz:
switch speed {
case CAN5kBps:
cfg1 = mcp16mHz5kBpsCfg1
cfg2 = mcp16mHz5kBpsCfg2
cfg3 = mcp16mHz5kBpsCfg3
case CAN10kBps:
cfg1 = mcp16mHz10kBpsCfg1
cfg2 = mcp16mHz10kBpsCfg2
cfg3 = mcp16mHz10kBpsCfg3
case CAN20kBps:
cfg1 = mcp16mHz20kBpsCfg1
cfg2 = mcp16mHz20kBpsCfg2
cfg3 = mcp16mHz20kBpsCfg3
case CAN25kBps:
cfg1 = mcp16mHz25kBpsCfg1
cfg2 = mcp16mHz25kBpsCfg2
cfg3 = mcp16mHz25kBpsCfg3
case CAN31k25Bps:
cfg1 = mcp16mHz31k25BpsCfg1
cfg2 = mcp16mHz31k25BpsCfg2
cfg3 = mcp16mHz31k25BpsCfg3
case CAN33kBps:
cfg1 = mcp16mHz33kBpsCfg1
cfg2 = mcp16mHz33kBpsCfg2
cfg3 = mcp16mHz33kBpsCfg3
case CAN40kBps:
cfg1 = mcp16mHz40kBpsCfg1
cfg2 = mcp16mHz40kBpsCfg2
cfg3 = mcp16mHz40kBpsCfg3
case CAN47kBps:
cfg1 = mcp16mHz47kBpsCfg1
cfg2 = mcp16mHz47kBpsCfg2
cfg3 = mcp16mHz47kBpsCfg3
case CAN50kBps:
cfg1 = mcp16mHz50kBpsCfg1
cfg2 = mcp16mHz50kBpsCfg2
cfg3 = mcp16mHz50kBpsCfg3
case CAN80kBps:
cfg1 = mcp16mHz80kBpsCfg1
cfg2 = mcp16mHz80kBpsCfg2
cfg3 = mcp16mHz80kBpsCfg3
case CAN83k3Bps:
cfg1 = mcp16mHz83k3BpsCfg1
cfg2 = mcp16mHz83k3BpsCfg2
cfg3 = mcp16mHz83k3BpsCfg3
case CAN95kBps:
cfg1 = mcp16mHz95kBpsCfg1
cfg2 = mcp16mHz95kBpsCfg2
cfg3 = mcp16mHz95kBpsCfg3
case CAN100kBps:
cfg1 = mcp16mHz100kBpsCfg1
cfg2 = mcp16mHz100kBpsCfg2
cfg3 = mcp16mHz100kBpsCfg3
case CAN125kBps:
cfg1 = mcp16mHz125kBpsCfg1
cfg2 = mcp16mHz125kBpsCfg2
cfg3 = mcp16mHz125kBpsCfg3
case CAN200kBps:
cfg1 = mcp16mHz200kBpsCfg1
cfg2 = mcp16mHz200kBpsCfg2
cfg3 = mcp16mHz200kBpsCfg3
case CAN250kBps:
cfg1 = mcp16mHz250kBpsCfg1
cfg2 = mcp16mHz250kBpsCfg2
cfg3 = mcp16mHz250kBpsCfg3
case CAN500kBps:
cfg1 = mcp16mHz500kBpsCfg1
cfg2 = mcp16mHz500kBpsCfg2
cfg3 = mcp16mHz500kBpsCfg3
case CAN666kBps:
cfg1 = mcp16mHz666kBpsCfg1
cfg2 = mcp16mHz666kBpsCfg2
cfg3 = mcp16mHz666kBpsCfg3
case CAN1000kBps:
cfg1 = mcp16mHz1000kBpsCfg1
cfg2 = mcp16mHz1000kBpsCfg2
@@ -255,6 +322,50 @@ func (d *Device) configRate(speed, clock byte) error {
}
case Clock8MHz:
switch speed {
case CAN5kBps:
cfg1 = mcp8mHz5kBpsCfg1
cfg2 = mcp8mHz5kBpsCfg2
cfg3 = mcp8mHz5kBpsCfg3
case CAN10kBps:
cfg1 = mcp8mHz10kBpsCfg1
cfg2 = mcp8mHz10kBpsCfg2
cfg3 = mcp8mHz10kBpsCfg3
case CAN20kBps:
cfg1 = mcp8mHz20kBpsCfg1
cfg2 = mcp8mHz20kBpsCfg2
cfg3 = mcp8mHz20kBpsCfg3
case CAN31k25Bps:
cfg1 = mcp8mHz31k25BpsCfg1
cfg2 = mcp8mHz31k25BpsCfg2
cfg3 = mcp8mHz31k25BpsCfg3
case CAN40kBps:
cfg1 = mcp8mHz40kBpsCfg1
cfg2 = mcp8mHz40kBpsCfg2
cfg3 = mcp8mHz40kBpsCfg3
case CAN50kBps:
cfg1 = mcp8mHz50kBpsCfg1
cfg2 = mcp8mHz50kBpsCfg2
cfg3 = mcp8mHz50kBpsCfg3
case CAN80kBps:
cfg1 = mcp8mHz80kBpsCfg1
cfg2 = mcp8mHz80kBpsCfg2
cfg3 = mcp8mHz80kBpsCfg3
case CAN100kBps:
cfg1 = mcp8mHz100kBpsCfg1
cfg2 = mcp8mHz100kBpsCfg2
cfg3 = mcp8mHz100kBpsCfg3
case CAN125kBps:
cfg1 = mcp8mHz125kBpsCfg1
cfg2 = mcp8mHz125kBpsCfg2
cfg3 = mcp8mHz125kBpsCfg3
case CAN200kBps:
cfg1 = mcp8mHz200kBpsCfg1
cfg2 = mcp8mHz200kBpsCfg2
cfg3 = mcp8mHz200kBpsCfg3
case CAN250kBps:
cfg1 = mcp8mHz250kBpsCfg1
cfg2 = mcp8mHz250kBpsCfg2
cfg3 = mcp8mHz250kBpsCfg3
case CAN500kBps:
cfg1 = mcp8mHz500kBpsCfg1
cfg2 = mcp8mHz500kBpsCfg2
+1 -1
View File
@@ -82,7 +82,7 @@ type Netdever interface {
Bind(sockfd int, ip netip.AddrPort) error
Connect(sockfd int, host string, ip netip.AddrPort) error
Listen(sockfd int, backlog int) error
Accept(sockfd int, ip netip.AddrPort) (int, error)
Accept(sockfd int) (int, netip.AddrPort, error)
Send(sockfd int, buf []byte, flags int, deadline time.Time) (int, error)
Recv(sockfd int, buf []byte, flags int, deadline time.Time) (int, error)
Close(sockfd int) error
+20 -6
View File
@@ -437,6 +437,12 @@ func ipToName(ip netip.AddrPort) []byte {
return name
}
func nameToIp(name []byte) netip.AddrPort {
port := uint16(name[2])<<8 | uint16(name[3])
addr, _ := netip.AddrFromSlice(name[4:8])
return netip.AddrPortFrom(addr, port)
}
func (r *rtl8720dn) Bind(sockfd int, ip netip.AddrPort) error {
if debugging(debugNetdev) {
@@ -534,10 +540,10 @@ func (r *rtl8720dn) Listen(sockfd int, backlog int) error {
return nil
}
func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) {
func (r *rtl8720dn) Accept(sockfd int) (int, netip.AddrPort, error) {
if debugging(debugNetdev) {
fmt.Printf("[Accept] sockfd: %d, peer: %s\r\n", sockfd, ip)
fmt.Printf("[Accept] sockfd: %d\r\n", sockfd)
}
r.mu.Lock()
@@ -546,12 +552,12 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) {
var newSock int32
var lsock = sock(sockfd)
var socket = r.sockets[lsock]
var name = ipToName(ip)
var name = ipToName(netip.AddrPort{})
switch socket.protocol {
case netdev.IPPROTO_TCP:
default:
return -1, netdev.ErrProtocolNotSupported
return -1, netip.AddrPort{}, netdev.ErrProtocolNotSupported
}
for {
@@ -570,6 +576,14 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) {
continue
}
// Get remote peer ip:port
namelen = uint32(len(name))
result := r.rpc_lwip_getpeername(int32(newSock), name, &namelen)
if result == -1 {
return -1, netip.AddrPort{}, fmt.Errorf("Getpeername failed")
}
raddr := nameToIp(name)
// If we've already seen this socket, we can re-use
// the socket and return it. But, only if the socket
// is closed. If it's not closed, we'll just come back
@@ -582,12 +596,12 @@ func (r *rtl8720dn) Accept(sockfd int, ip netip.AddrPort) (int, error) {
continue
}
// Reuse client socket
return int(newSock), nil
return int(newSock), raddr, nil
}
// Create new socket for client and return fd
r.sockets[sock(newSock)] = newSocket(socket.protocol)
return int(newSock), nil
return int(newSock), raddr, nil
}
}
+25 -6
View File
@@ -676,10 +676,10 @@ func (w *wifinina) Listen(sockfd int, backlog int) error {
return nil
}
func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) {
func (w *wifinina) Accept(sockfd int) (int, netip.AddrPort, error) {
if debugging(debugNetdev) {
fmt.Printf("[Accept] sockfd: %d, peer: %s\r\n", sockfd, ip)
fmt.Printf("[Accept] sockfd: %d\r\n", sockfd)
}
w.mu.Lock()
@@ -692,7 +692,7 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) {
switch socket.protocol {
case netdev.IPPROTO_TCP:
default:
return -1, netdev.ErrProtocolNotSupported
return -1, netip.AddrPort{}, netdev.ErrProtocolNotSupported
}
for {
@@ -704,7 +704,7 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) {
// Check if we've faulted
if w.fault != nil {
return -1, w.fault
return -1, netip.AddrPort{}, w.fault
}
// TODO: BUG: Currently, a sock that is 100% busy will always be
@@ -720,6 +720,8 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) {
continue
}
raddr := w.getRemoteData(client)
// If we've already seen this socket, we can reuse
// the socket and return it. But, only if the socket
// is closed. If it's not closed, we'll just come back
@@ -732,12 +734,12 @@ func (w *wifinina) Accept(sockfd int, ip netip.AddrPort) (int, error) {
continue
}
// Reuse client socket
return int(client), nil
return int(client), raddr, nil
}
// Create new socket for client and return fd
w.sockets[client] = newSocket(socket.protocol)
return int(client), nil
return int(client), raddr, nil
}
}
@@ -1123,6 +1125,23 @@ func (w *wifinina) accept(s sock) sock {
return newsock
}
func (w *wifinina) getRemoteData(s sock) netip.AddrPort {
if debugging(debugCmd) {
fmt.Printf(" [cmdGetRemoteData] sock: %d\r\n", s)
}
sl := make([]string, 2)
l := w.reqRspStr1(cmdGetRemoteData, uint8(s), sl)
if l != 2 {
w.faultf("getRemoteData wanted l=2, got l=%d", l)
return netip.AddrPort{}
}
ip, _ := netip.AddrFromSlice([]byte(sl[0])[:4])
port := binary.BigEndian.Uint16([]byte(sl[1]))
return netip.AddrPortFrom(ip, port)
}
// insertDataBuf adds data to the buffer used for sending UDP data
func (w *wifinina) insertDataBuf(sock sock, buf []byte) bool {