github.com/aykevl/tinygo@v0.5.0/src/machine/buffer.go (about)

     1  package machine
     2  
     3  const bufferSize = 128
     4  
     5  //go:volatile
     6  type volatileByte byte
     7  
     8  // RingBuffer is ring buffer implementation inspired by post at
     9  // https://www.embeddedrelated.com/showthread/comp.arch.embedded/77084-1.php
    10  //
    11  // It has some limitations currently due to how "volatile" variables that are
    12  // members of a struct are not compiled correctly by TinyGo.
    13  // See https://github.com/tinygo-org/tinygo/issues/151 for details.
    14  type RingBuffer struct {
    15  	rxbuffer [bufferSize]volatileByte
    16  	head     volatileByte
    17  	tail     volatileByte
    18  }
    19  
    20  // NewRingBuffer returns a new ring buffer.
    21  func NewRingBuffer() *RingBuffer {
    22  	return &RingBuffer{}
    23  }
    24  
    25  // Used returns how many bytes in buffer have been used.
    26  func (rb *RingBuffer) Used() uint8 {
    27  	return uint8(rb.head - rb.tail)
    28  }
    29  
    30  // Put stores a byte in the buffer. If the buffer is already
    31  // full, the method will return false.
    32  func (rb *RingBuffer) Put(val byte) bool {
    33  	if rb.Used() != bufferSize {
    34  		rb.head++
    35  		rb.rxbuffer[rb.head%bufferSize] = volatileByte(val)
    36  		return true
    37  	}
    38  	return false
    39  }
    40  
    41  // Get returns a byte from the buffer. If the buffer is empty,
    42  // the method will return a false as the second value.
    43  func (rb *RingBuffer) Get() (byte, bool) {
    44  	if rb.Used() != 0 {
    45  		rb.tail++
    46  		return byte(rb.rxbuffer[rb.tail%bufferSize]), true
    47  	}
    48  	return 0, false
    49  }