Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
soypat opened this issue Dec 20, 2022 · 1 comment
Open

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

soypat opened this issue Dec 20, 2022 · 1 comment

Comments

@soypat
Copy link
Contributor

soypat commented Dec 20, 2022

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:
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
Copy link
Contributor Author

soypat commented Feb 4, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant