rp2040

RP2040 Programming without SDK
Log | Files | Refs

commit 6bad484a354ed430735733a969df3aa663e2c0b0
parent 5a718f4e0005fd215cf4362025175a187e26cdaa
Author: Matsuda Kenji <info@mtkn.jp>
Date:   Mon, 25 Aug 2025 08:53:32 +0900

add cons written in go

Diffstat:
Aconsgo/go.mod | 5+++++
Aconsgo/go.sum | 2++
Aconsgo/main.go | 118+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 125 insertions(+), 0 deletions(-)

diff --git a/consgo/go.mod b/consgo/go.mod @@ -0,0 +1,5 @@ +module cons + +go 1.24.1 + +require golang.org/x/sys v0.35.0 diff --git a/consgo/go.sum b/consgo/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= diff --git a/consgo/main.go b/consgo/main.go @@ -0,0 +1,118 @@ +package main + +import ( + "fmt" + "io" + "log" + + "golang.org/x/sys/unix" +) + +const ttyFile = "/dev/ttyU0" + +func main() { + fd, err := device_open(ttyFile) + if err != nil { + log.Fatal(err) + } + defer unix.Close(fd) + if err = setparms(fd, 115200); err != nil { + log.Fatal(err) + } + if err = flush(fd); err != nil { + log.Fatal(err) + } + + go reader(fd) + writer(fd) +} + +func reader(fd int) { + buf := make([]byte, 64) + for { + n, err := unix.Read(fd, buf) + if err == io.EOF { + break + } else if err != nil { + log.Printf("read from tty: %v", err) + break + } + log.Printf("read from tty: %q", buf[:n]) + _, err = unix.Write(unix.Stdout, buf[:n]) + if err != nil { + log.Printf("write to stdout: %v", err) + break + } + } +} + +func writer(fd int) { + buf := make([]byte, 64) + for { + n, err := unix.Read(unix.Stdin, buf) + if n == 0 || err == io.EOF { + break + } else if err != nil { + log.Printf("read from stdin: %v", err) + break + } + log.Printf("from terminal: %q", buf[:n]) + _, err = unix.Write(fd, buf[:n]) + if err != nil { + log.Printf("write to tty: %v", err) + break + } + } +} + +func device_open(path string) (fd int, err error) { + fd, err = unix.Open(path, unix.O_RDWR|unix.O_NDELAY|unix.O_NOCTTY, 0) + if err != nil { + return 0, fmt.Errorf("open: %w", err) + } + defer func() { + if err != nil { + unix.Close(fd) + } + }() + n, err := unix.FcntlInt(uintptr(fd), unix.F_GETFL, 0) + if err != nil { + return 0, fmt.Errorf("getfl: %w", err) + } + _, err = unix.FcntlInt(uintptr(fd), unix.F_SETFL, n&^unix.O_NDELAY) + if err != nil { + return 0, fmt.Errorf("setfl: %w", err) + } + return fd, nil +} + +func setparms(fd int, baud int32) error { + tty, err := unix.IoctlGetTermios(fd, unix.TIOCGETA) + if err != nil { + return fmt.Errorf("gettermios: %w", err) + } + tty.Iflag = unix.IGNBRK + tty.Iflag &= ^(uint32(unix.IXON) | uint32(unix.IXOFF) | uint32(unix.IXANY)) + tty.Oflag = 0 + tty.Cflag = (tty.Cflag &^ unix.CSIZE) | unix.CS8 + tty.Cflag |= unix.CLOCAL | unix.CREAD + tty.Cflag &= ^uint32(unix.CSTOPB) + tty.Lflag = 0 + tty.Cc[unix.VMIN] = 1 + tty.Cc[unix.VTIME] = 5 + tty.Ispeed = baud + tty.Ospeed = baud + err = unix.IoctlSetTermios(fd, unix.TIOCSETA, tty) + if err != nil { + return fmt.Errorf("settermios: %w", err) + } + return nil +} + +func flush(fd int) error { + _, err := unix.IoctlGetInt(fd, unix.TIOCFLUSH) + if err != nil { + return fmt.Errorf("tiocflush: %w", err) + } + return nil +}