github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/uart.go (about)

     1  //go:build atmega || esp || nrf || sam || sifive || stm32 || k210 || nxp || rp2040
     2  
     3  package machine
     4  
     5  import "errors"
     6  
     7  var errUARTBufferEmpty = errors.New("UART buffer empty")
     8  
     9  // UARTParity is the parity setting to be used for UART communication.
    10  type UARTParity uint8
    11  
    12  const (
    13  	// ParityNone means to not use any parity checking. This is
    14  	// the most common setting.
    15  	ParityNone UARTParity = iota
    16  
    17  	// ParityEven means to expect that the total number of 1 bits sent
    18  	// should be an even number.
    19  	ParityEven
    20  
    21  	// ParityOdd means to expect that the total number of 1 bits sent
    22  	// should be an odd number.
    23  	ParityOdd
    24  )
    25  
    26  // To implement the UART interface for a board, you must declare a concrete type as follows:
    27  //
    28  // 		type UART struct {
    29  // 			Buffer *RingBuffer
    30  // 		}
    31  //
    32  // You can also add additional members to this struct depending on your implementation,
    33  // but the *RingBuffer is required.
    34  // When you are declaring your UARTs for your board, make sure that you also declare the
    35  // RingBuffer using the NewRingBuffer() function when you declare your UART:
    36  //
    37  //		UART{Buffer: NewRingBuffer()}
    38  //
    39  
    40  // Read from the RX buffer.
    41  func (uart *UART) Read(data []byte) (n int, err error) {
    42  	// check if RX buffer is empty
    43  	size := uart.Buffered()
    44  	if size == 0 {
    45  		return 0, nil
    46  	}
    47  
    48  	// Make sure we do not read more from buffer than the data slice can hold.
    49  	if len(data) < size {
    50  		size = len(data)
    51  	}
    52  
    53  	// only read number of bytes used from buffer
    54  	for i := 0; i < size; i++ {
    55  		v, _ := uart.ReadByte()
    56  		data[i] = v
    57  	}
    58  
    59  	return size, nil
    60  }
    61  
    62  // WriteByte writes a byte of data over the UART's Tx.
    63  // This function blocks until the data is finished being sent.
    64  func (uart *UART) WriteByte(c byte) error {
    65  	err := uart.writeByte(c)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	uart.flush() // flush() blocks until all data has been transmitted.
    70  	return nil
    71  }
    72  
    73  // Write data over the UART's Tx.
    74  // This function blocks until the data is finished being sent.
    75  func (uart *UART) Write(data []byte) (n int, err error) {
    76  	for i, v := range data {
    77  		err = uart.writeByte(v)
    78  		if err != nil {
    79  			return i, err
    80  		}
    81  	}
    82  	uart.flush() // flush() blocks until all data has been transmitted.
    83  	return len(data), nil
    84  }
    85  
    86  // ReadByte reads a single byte from the RX buffer.
    87  // If there is no data in the buffer, returns an error.
    88  func (uart *UART) ReadByte() (byte, error) {
    89  	// check if RX buffer is empty
    90  	buf, ok := uart.Buffer.Get()
    91  	if !ok {
    92  		return 0, errUARTBufferEmpty
    93  	}
    94  	return buf, nil
    95  }
    96  
    97  // Buffered returns the number of bytes currently stored in the RX buffer.
    98  func (uart *UART) Buffered() int {
    99  	return int(uart.Buffer.Used())
   100  }
   101  
   102  // Receive handles adding data to the UART's data buffer.
   103  // Usually called by the IRQ handler for a machine.
   104  func (uart *UART) Receive(data byte) {
   105  	uart.Buffer.Put(data)
   106  }