zig-riscv-embedded

Experimental Zig-based CoAP node for the HiFive1 RISC-V board

git clone https://git.8pit.net/zig-riscv-embedded.git

 1package main
 2
 3import (
 4	"bytes"
 5	"errors"
 6
 7	"github.com/Lobaro/slip"
 8	"go.bug.st/serial"
 9)
10
11type Packet struct {
12	FrameType byte
13	Data      []byte
14}
15
16type SerialEndpoint struct {
17	port serial.Port
18
19	RX <-chan Packet
20	TX chan<- []byte
21}
22
23func NewSerialEP(path string) (*SerialEndpoint, error) {
24	mode := &serial.Mode{
25		BaudRate: baudRate,
26		DataBits: 8,
27		Parity:   serial.NoParity,
28		StopBits: serial.OneStopBit,
29	}
30
31	port, err := serial.Open(path, mode)
32	if err != nil {
33		return nil, err
34	}
35
36	rx := make(chan Packet)
37	tx := make(chan []byte)
38
39	ep := &SerialEndpoint{
40		port: port,
41		RX:   rx,
42		TX:   tx,
43	}
44
45	go ep.rcvLoop(rx)
46	go ep.sndLoop(tx)
47
48	return ep, nil
49}
50
51func (s *SerialEndpoint) sndLoop(ch <-chan []byte) {
52	writer := slip.NewSlipMuxWriter(NewSlowWriter(s.port))
53
54	for {
55		data := <-ch
56
57		err := writer.WritePacket(slip.FRAME_COAP, data)
58		if err != nil {
59			logger.Println("handleCoap:", err)
60			continue
61		}
62	}
63}
64
65func (s *SerialEndpoint) rcvLoop(ch chan<- Packet) {
66	reader := slip.NewSlipMuxReader(s.port)
67
68	for {
69		packet, frame, err := reader.ReadPacket()
70
71		var perr *serial.PortError
72		if errors.As(err, &perr) && perr.Code() == serial.PortClosed {
73			logger.Fatal("[SerialEndpoint]", err)
74		} else if err != nil {
75			logger.Println("[SerialEndpoint]", err)
76			continue
77		}
78
79		packet = bytes.TrimPrefix(packet, []byte{0})
80		ch <- Packet{frame, packet}
81	}
82}
83
84func (s *SerialEndpoint) Close() {
85	// close(s.Chan)
86	// TODO: Close TTYIO
87}