mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-08-08 13:03:39 +00:00
functioning USB-CDC class initialization
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
package usb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"runtime/volatile"
|
||||
)
|
||||
|
||||
const QueueSize = 8
|
||||
|
||||
type Queue struct {
|
||||
fifo [QueueSize]uint8
|
||||
tail volatile.Register32
|
||||
head volatile.Register32
|
||||
}
|
||||
|
||||
var (
|
||||
ErrReadBuffer = errors.New("cannot copy into read buffer")
|
||||
ErrWriteBuffer = errors.New("cannot copy from write buffer")
|
||||
ErrQueueEmpty = errors.New("data queue empty") // Read Error
|
||||
ErrQueueFull = errors.New("data queue full") // Write error
|
||||
)
|
||||
|
||||
// Reset discards all buffered data.
|
||||
//go:inline
|
||||
func (q *Queue) Reset() {
|
||||
for i := range q.fifo {
|
||||
q.fifo[i] = 0
|
||||
}
|
||||
q.tail.Set(0)
|
||||
q.head.Set(0)
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (q *Queue) Len() int {
|
||||
return int(q.tail.Get() - q.head.Get())
|
||||
}
|
||||
|
||||
//go:inline
|
||||
func (q *Queue) Cap() int {
|
||||
return cap(q.fifo)
|
||||
}
|
||||
|
||||
func (q *Queue) Read(data []uint8) (int, error) {
|
||||
|
||||
less := uint32(len(data))
|
||||
if less == 0 {
|
||||
return 0, ErrReadBuffer
|
||||
} // nothing to copy into
|
||||
|
||||
head := q.head.Get()
|
||||
used := q.tail.Get() - head
|
||||
|
||||
if used == 0 {
|
||||
return 0, ErrQueueEmpty
|
||||
} // empty queue
|
||||
|
||||
if less > used {
|
||||
less = used
|
||||
} // only get from used space
|
||||
|
||||
for i := uint32(0); i < less; i++ {
|
||||
data[i] = q.fifo[head%QueueSize]
|
||||
head++
|
||||
}
|
||||
q.head.Set(head)
|
||||
|
||||
return int(less), nil
|
||||
}
|
||||
|
||||
func (q *Queue) Write(data []uint8) (int, error) {
|
||||
|
||||
more := uint32(len(data))
|
||||
if more == 0 {
|
||||
return 0, ErrWriteBuffer
|
||||
} // nothing to copy from
|
||||
|
||||
tail := q.tail.Get()
|
||||
used := tail - q.head.Get()
|
||||
|
||||
if used == QueueSize {
|
||||
return 0, ErrQueueFull
|
||||
} // full queue
|
||||
|
||||
if used+more > QueueSize {
|
||||
more = QueueSize - used
|
||||
} // only put to unused space
|
||||
|
||||
for i := uint32(0); i < more; i++ {
|
||||
q.fifo[tail%QueueSize] = data[i]
|
||||
tail++
|
||||
}
|
||||
q.tail.Set(tail)
|
||||
|
||||
return int(more), nil
|
||||
}
|
||||
|
||||
func (q *Queue) Deq() (uint8, bool) {
|
||||
|
||||
tail := q.head.Get()
|
||||
if tail == q.tail.Get() {
|
||||
return 0, false
|
||||
} // empty queue
|
||||
|
||||
data := q.fifo[tail%QueueSize]
|
||||
q.head.Set(tail + 1)
|
||||
|
||||
return data, true
|
||||
}
|
||||
|
||||
func (q *Queue) Front() (uint8, bool) {
|
||||
|
||||
tail := q.head.Get()
|
||||
if tail == q.tail.Get() {
|
||||
return 0, false
|
||||
} // empty queue
|
||||
|
||||
return q.fifo[tail%QueueSize], true
|
||||
}
|
||||
|
||||
func (q *Queue) Enq(data uint8) bool {
|
||||
|
||||
head := q.tail.Get()
|
||||
if head-q.head.Get() == QueueSize {
|
||||
return false
|
||||
} // full queue
|
||||
|
||||
q.fifo[head%QueueSize] = data
|
||||
q.tail.Set(head + 1)
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user