tinygo-org / drivers

TinyGo drivers for sensors, displays, wireless adaptors, and other devices that use I2C, SPI, GPIO, ADC, and UART interfaces.
https://tinygo.org
BSD 3-Clause "New" or "Revised" License
599 stars 188 forks source link

tinygo-org/tinyio: RFC for new organization level package #491

Open soypat opened 1 year ago

soypat commented 1 year ago

A new package tinyio (working title) is proposed to solve the cyclic dependency problem between the tinygo and drivers packages detailed in #487. Additional benefits:

  1. Single source of truth for I/O interfaces:
    • Validating whether a target has a peripheral implementation (I2C). This is valuable for automatic documentation generation and compile-time validation, preventing bad implementations from making it into the tinygo package
    • No more discussion on whether it's a good idea to have interfaces defined in tinygo package. This is a fine line to tread as there are some interfaces that have been defined in the tinygo package like USB and UART interfaces.
  2. Opens TinyGo to the wider Go community
    • tinyio becomes the defacto standard for low level I/O since it is a pure native Go implementation

The transition to the tinyio package would not be immediate. The goal I propose is to decide on tinyio as being the goal to which the Go community strives for the future.

Example of `tinyio/tinyio.go` contents: ```go package drivers import ( "image/color" "io" "net" "time" ) // Pin type is not needed today, but may be useful to define here for types like PWMer. // Guarded by build tag `tinygo` type Pin = machine.Pin // Guarded by `!tinygo` build tag. type Pin uint8 // UART represents a UART connection. It is implemented by the machine.UART type. type UART interface { io.Reader io.Writer Buffered() int } // SPI represents a SPI bus. It is implemented by the machine.SPI type. type SPI interface { // Tx transmits the given buffer w and receives at the same time the buffer r. // The two buffers must be the same length. The only exception is when w or r are nil, // in which case Tx only transmits (without receiving) or only receives (while sending 0 bytes). Tx(w, r []byte) error // Transfer writes a single byte out on the SPI bus and receives a byte at the same time. // If you want to transfer multiple bytes, it is more efficient to use Tx instead. Transfer(b byte) (byte, error) } // I2C represents an I2C bus. It is notably implemented by the machine.I2C type. type I2C interface { // Excludes WriteRegister and ReadRegister since these are rarely implemented // as hardware-level functions and more commonly use the contents of // machine/i2c.go. They should instead be implemented as tinyio top level // package functions. Tx(addr uint16, w, r []byte) error } type Displayer interface { // Size returns the current size of the display. Size() (x, y int16) // SetPizel modifies the internal buffer. SetPixel(x, y int16, c color.RGBA) // Display sends the buffer (if any) to the screen. Display() error } // A Netdever is a network device driver for Tinygo; Tinygo's network device // driver model. type Netdever interface { // Probe initializes the network device and maintains the connection to // the network. For example, Probe will maintain the connection to the // Wifi access point for a Wifi network device. Probe() error // GetHostByName returns the IP address of either a hostname or IPv4 // address in standard dot notation. GetHostByName(name string) (net.IP, error) // Socketer is Berkely Sockets-like interface Socketer } type AddressFamily int type SockType int type Protocol int type SockAddr struct { port [2]byte // Network byte order ip [4]byte // Network byte order } type SockFlags int type SockOpt int type SockOptLevel int type Sockfd int // Berkely Sockets-like interface. See man page for socket(2), etc. type Socketer interface { Socket(family AddressFamily, sockType SockType, protocol Protocol) (Sockfd, error) Bind(sockfd Sockfd, myaddr SockAddr) error Connect(sockfd Sockfd, servaddr SockAddr) error Listen(sockfd Sockfd, backlog int) error Accept(sockfd Sockfd, peer SockAddr) error Send(sockfd Sockfd, buff []byte, flags SockFlags, timeout time.Duration) (int, error) SendTo(sockfd Sockfd, buff []byte, flags SockFlags, to SockAddr, timeout time.Duration) (int, error) Recv(sockfd Sockfd, buff []byte, flags SockFlags, timeout time.Duration) (int, error) RecvFrom(sockfd Sockfd, buff []byte, flags SockFlags, from SockAddr, timeout time.Duration) (int, error) Close(sockfd Sockfd) error SetSockOpt(sockfd Sockfd, level SockOptLevel, opt SockOpt, value interface{}) error } ```
soypat commented 1 year ago

I've created a repo with what I envision could be the first version of tinyio. https://github.com/soypat/tinyio