//go:build atmega || esp || nrf || sam || sifive || stm32 || k210 || nxp || rp2040 package machine import "errors" var errUARTBufferEmpty = errors.New("UART buffer empty") // UARTParity is the parity setting to be used for UART communication. type UARTParity uint8 const ( // ParityNone means to not use any parity checking. This is // the most common setting. ParityNone UARTParity = iota // ParityEven means to expect that the total number of 1 bits sent // should be an even number. ParityEven // ParityOdd means to expect that the total number of 1 bits sent // should be an odd number. ParityOdd ) // To implement the UART interface for a board, you must declare a concrete type as follows: // // type UART struct { // Buffer *RingBuffer // } // // You can also add additional members to this struct depending on your implementation, // but the *RingBuffer is required. // When you are declaring your UARTs for your board, make sure that you also declare the // RingBuffer using the NewRingBuffer() function when you declare your UART: // // UART{Buffer: NewRingBuffer()} // // Read from the RX buffer. func (uart *UART) Read(data []byte) (n int, err error) { // check if RX buffer is empty size := uart.Buffered() if size == 0 { return 0, nil } // Make sure we do not read more from buffer than the data slice can hold. if len(data) < size { size = len(data) } // only read number of bytes used from buffer for i := 0; i < size; i++ { v, _ := uart.ReadByte() data[i] = v } return size, nil } // WriteByte writes a byte of data over the UART's Tx. // This function blocks until the data is finished being sent. func (uart *UART) WriteByte(c byte) error { err := uart.writeByte(c) if err != nil { return err } uart.flush() // flush() blocks until all data has been transmitted. return nil } // Write data over the UART's Tx. // This function blocks until the data is finished being sent. func (uart *UART) Write(data []byte) (n int, err error) { for i, v := range data { err = uart.writeByte(v) if err != nil { return i, err } } uart.flush() // flush() blocks until all data has been transmitted. return len(data), nil } // ReadByte reads a single byte from the RX buffer. // If there is no data in the buffer, returns an error. func (uart *UART) ReadByte() (byte, error) { // check if RX buffer is empty buf, ok := uart.Buffer.Get() if !ok { return 0, errUARTBufferEmpty } return buf, nil } // Buffered returns the number of bytes currently stored in the RX buffer. func (uart *UART) Buffered() int { return int(uart.Buffer.Used()) } // Receive handles adding data to the UART's data buffer. // Usually called by the IRQ handler for a machine. func (uart *UART) Receive(data byte) { uart.Buffer.Put(data) }