blob: 4573e01f5ef25e541d5ce6ab4cc9d209ac2c18be [file] [log] [blame]
Austin Schuh41baf202022-01-01 14:33:40 -08001/*
2 * The MIT License (MIT)
3 *
4 * Copyright (c) 2019 Ha Thach (tinyusb.org)
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 * This file is part of the TinyUSB stack.
25 */
26
27#ifndef _TUSB_OSAL_FREERTOS_H_
28#define _TUSB_OSAL_FREERTOS_H_
29
30// FreeRTOS Headers
31#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,FreeRTOS.h)
32#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,semphr.h)
33#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,queue.h)
34#include TU_INCLUDE_PATH(CFG_TUSB_OS_INC_PATH,task.h)
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40//--------------------------------------------------------------------+
41// TASK API
42//--------------------------------------------------------------------+
43static inline void osal_task_delay(uint32_t msec)
44{
45 vTaskDelay( pdMS_TO_TICKS(msec) );
46}
47
48//--------------------------------------------------------------------+
49// Semaphore API
50//--------------------------------------------------------------------+
51typedef StaticSemaphore_t osal_semaphore_def_t;
52typedef SemaphoreHandle_t osal_semaphore_t;
53
54static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
55{
56 return xSemaphoreCreateBinaryStatic(semdef);
57}
58
59static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
60{
61 if ( !in_isr )
62 {
63 return xSemaphoreGive(sem_hdl) != 0;
64 }
65 else
66 {
67 BaseType_t xHigherPriorityTaskWoken;
68 BaseType_t res = xSemaphoreGiveFromISR(sem_hdl, &xHigherPriorityTaskWoken);
69
70#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
71 if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR();
72#else
73 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
74#endif
75
76 return res != 0;
77 }
78}
79
80static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
81{
82 uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec);
83 return xSemaphoreTake(sem_hdl, ticks);
84}
85
86static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
87{
88 xQueueReset(sem_hdl);
89}
90
91//--------------------------------------------------------------------+
92// MUTEX API (priority inheritance)
93//--------------------------------------------------------------------+
94typedef StaticSemaphore_t osal_mutex_def_t;
95typedef SemaphoreHandle_t osal_mutex_t;
96
97static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
98{
99 return xSemaphoreCreateMutexStatic(mdef);
100}
101
102static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
103{
104 return osal_semaphore_wait(mutex_hdl, msec);
105}
106
107static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
108{
109 return xSemaphoreGive(mutex_hdl);
110}
111
112//--------------------------------------------------------------------+
113// QUEUE API
114//--------------------------------------------------------------------+
115
116// role device/host is used by OS NONE for mutex (disable usb isr) only
117#define OSAL_QUEUE_DEF(_role, _name, _depth, _type) \
118 static _type _name##_##buf[_depth];\
119 osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf };
120
121typedef struct
122{
123 uint16_t depth;
124 uint16_t item_sz;
125 void* buf;
126
127 StaticQueue_t sq;
128}osal_queue_def_t;
129
130typedef QueueHandle_t osal_queue_t;
131
132static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
133{
134 return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq);
135}
136
137static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
138{
139 return xQueueReceive(qhdl, data, portMAX_DELAY);
140}
141
142static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
143{
144 if ( !in_isr )
145 {
146 return xQueueSendToBack(qhdl, data, OSAL_TIMEOUT_WAIT_FOREVER) != 0;
147 }
148 else
149 {
150 BaseType_t xHigherPriorityTaskWoken;
151 BaseType_t res = xQueueSendToBackFromISR(qhdl, data, &xHigherPriorityTaskWoken);
152
153#if CFG_TUSB_MCU == OPT_MCU_ESP32S2 || CFG_TUSB_MCU == OPT_MCU_ESP32S3
154 if ( xHigherPriorityTaskWoken ) portYIELD_FROM_ISR();
155#else
156 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
157#endif
158
159 return res != 0;
160 }
161}
162
163static inline bool osal_queue_empty(osal_queue_t qhdl)
164{
165 return uxQueueMessagesWaiting(qhdl) == 0;
166}
167
168#ifdef __cplusplus
169 }
170#endif
171
172#endif /* _TUSB_OSAL_FREERTOS_H_ */