mirror of
https://github.com/tinygo-org/drivers.git
synced 2026-08-15 04:13:40 +00:00
espradio: implement support for wifi/BLE on the ESP32-C3
This is a work in progress. It does not yet work.
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
package espradio
|
||||
|
||||
// Various functions related to locks, mutexes, semaphores, and queues.
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// Use a single fake spinlock. This is also how the Rust port does it.
|
||||
var fakeSpinLock uint8
|
||||
|
||||
//export espradio_spin_lock_create
|
||||
func espradio_spin_lock_create() unsafe.Pointer {
|
||||
return unsafe.Pointer(&fakeSpinLock)
|
||||
}
|
||||
|
||||
//export espradio_spin_lock_delete
|
||||
func espradio_spin_lock_delete(lock unsafe.Pointer) {
|
||||
}
|
||||
|
||||
// Use a global array of mutexes, because the binary blobs don't need that many.
|
||||
var mutexes [2]sync.Mutex
|
||||
var mutexIndex uint32
|
||||
|
||||
//export espradio_recursive_mutex_create
|
||||
func espradio_recursive_mutex_create() unsafe.Pointer {
|
||||
// Allocate a mutex from the global array.
|
||||
// If the radio needs more mutexes, this will result in an index out of
|
||||
// range panic (hopefully including a source location, if using
|
||||
// `tinygo flash -monitor`).
|
||||
newIndex := atomic.AddUint32(&mutexIndex, 1)
|
||||
mutex := &mutexes[newIndex-1]
|
||||
return unsafe.Pointer(mutex)
|
||||
}
|
||||
|
||||
//export espradio_mutex_lock
|
||||
func espradio_mutex_lock(cmut unsafe.Pointer) int32 {
|
||||
// This is xSemaphoreTake with an infinite timeout in ESP-IDF. Therefore,
|
||||
// just lock the mutex and return true.
|
||||
// TODO: recursive locking. See:
|
||||
// https://www.freertos.org/RTOS-Recursive-Mutexes.html
|
||||
// For that we need to track the current goroutine - or maybe just whether
|
||||
// we're inside a special goroutine like the timer goroutine.
|
||||
mut := (*sync.Mutex)(cmut)
|
||||
mut.Lock()
|
||||
return 1
|
||||
}
|
||||
|
||||
//export espradio_mutex_unlock
|
||||
func espradio_mutex_unlock(cmut unsafe.Pointer) int32 {
|
||||
// Note: this is xSemaphoreGive in the ESP-IDF, which doesn't panic when
|
||||
// unlocking fails but rather returns false.
|
||||
mut := (*sync.Mutex)(cmut)
|
||||
mut.Unlock()
|
||||
return 1
|
||||
}
|
||||
|
||||
var semaphores [1]uint32
|
||||
var semaphoreIndex uint32
|
||||
|
||||
//export espradio_semphr_create
|
||||
func espradio_semphr_create(max, init uint32) unsafe.Pointer {
|
||||
newIndex := atomic.AddUint32(&semaphoreIndex, 1)
|
||||
sem := &semaphores[newIndex-1]
|
||||
return unsafe.Pointer(sem)
|
||||
}
|
||||
|
||||
type queueElementType [8]byte
|
||||
|
||||
// TODO: I think the return type results in undefined behavior (but it's still a
|
||||
// pointer so I hope LLVM won't use that fact).
|
||||
//
|
||||
//export espradio_wifi_create_queue
|
||||
func espradio_wifi_create_queue(queue_len, item_size int) chan queueElementType {
|
||||
if item_size > len(queueElementType{}) {
|
||||
panic("espradio: queue item_size too large")
|
||||
}
|
||||
return make(chan queueElementType, item_size)
|
||||
}
|
||||
Reference in New Issue
Block a user