1#if (defined ESP_PLATFORM && !defined ROO_TESTING)
7#include "esp_heap_caps.h"
8#include "freertos/FreeRTOS.h"
9#include "freertos/semphr.h"
10#include "roo_logging.h"
16 : buffer_data_(nullptr),
18 mux_(portMUX_INITIALIZER_UNLOCKED) {
19 for (
size_t i = 0; i < kDmaBufferCount; ++i) {
24void DmaBufferPool::lockState() {
25 if (xPortInIsrContext()) {
26 portENTER_CRITICAL_ISR(&mux_);
28 portENTER_CRITICAL(&mux_);
32void DmaBufferPool::unlockState() {
33 if (xPortInIsrContext()) {
34 portEXIT_CRITICAL_ISR(&mux_);
36 portEXIT_CRITICAL(&mux_);
40size_t DmaBufferPool::acquireFreeSlot() {
42 for (
size_t i = 0; i < kDmaBufferCount; ++i) {
50 CHECK(
false) <<
"DmaBufferPool semaphore/signaling mismatch";
54bool DmaBufferPool::markSlotFree(
size_t index) {
55 bool released =
false;
58 in_use_[index] =
false;
65void DmaBufferPool::begin() {
66 CHECK_EQ(buffer_data_,
nullptr);
67 CHECK_EQ(available_,
nullptr);
69 const size_t pool_bytes = kDmaBufferCount * kDmaBufferCapacity;
70 buffer_data_ =
static_cast<roo::byte*
>(
71 heap_caps_malloc(pool_bytes, MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL));
72 CHECK_NOTNULL(buffer_data_);
74 available_ = xSemaphoreCreateCountingStatic(kDmaBufferCount, kDmaBufferCount,
76 CHECK_NOTNULL(available_);
78 for (
size_t i = 0; i < kDmaBufferCount; ++i) {
83void DmaBufferPool::end() {
84 if (buffer_data_ ==
nullptr)
return;
86 CHECK_NOTNULL(available_);
87 vSemaphoreDelete(available_);
90 heap_caps_free(buffer_data_);
91 buffer_data_ =
nullptr;
94DmaBufferPool::Buffer DmaBufferPool::acquire() {
95 CHECK_NOTNULL(buffer_data_);
96 CHECK_NOTNULL(available_);
98 CHECK_EQ(xSemaphoreTake(available_, portMAX_DELAY), pdTRUE);
99 size_t index = acquireFreeSlot();
100 CHECK_LT(index, kDmaBufferCount);
102 return Buffer{.data = buffer_data_ + index * kDmaBufferCapacity};
105void DmaBufferPool::release(Buffer buffer) {
106 CHECK_NOTNULL(buffer_data_);
107 CHECK_NOTNULL(available_);
108 CHECK_NOTNULL(buffer.data);
110 ptrdiff_t offset = buffer.data - buffer_data_;
112 CHECK_EQ(offset %
static_cast<ptrdiff_t
>(kDmaBufferCapacity), 0);
114 size_t index =
static_cast<size_t>(offset) / kDmaBufferCapacity;
115 CHECK_LT(index, kDmaBufferCount);
116 CHECK(markSlotFree(index))
117 <<
"Buffer released twice or not acquired from this pool";
119 if (xPortInIsrContext()) {
120 BaseType_t high_wakeup = pdFALSE;
121 CHECK_EQ(xSemaphoreGiveFromISR(available_, &high_wakeup), pdTRUE);
122 if (high_wakeup == pdTRUE) {
123 portYIELD_FROM_ISR();
128 CHECK_EQ(xSemaphoreGive(available_), pdTRUE);
Defines 140 opaque HTML named colors.