1 /*
2 * Copyright (c) 2022, sakumisu
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include "usb_osal.h"
7 #include "usb_errno.h"
8 #include <FreeRTOS.h>
9 #include "semphr.h"
10 #include "timers.h"
11 #include "event_groups.h"
12
usb_osal_thread_create(const char * name,uint32_t stack_size,uint32_t prio,usb_thread_entry_t entry,void * args)13 usb_osal_thread_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
14 {
15 TaskHandle_t htask = NULL;
16 stack_size /= sizeof(StackType_t);
17 xTaskCreate(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask);
18 return (usb_osal_thread_t)htask;
19 }
20
usb_osal_thread_delete(usb_osal_thread_t thread)21 void usb_osal_thread_delete(usb_osal_thread_t thread)
22 {
23 vTaskDelete(thread);
24 }
25
usb_osal_sem_create(uint32_t initial_count)26 usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
27 {
28 return (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count);
29 }
30
usb_osal_sem_delete(usb_osal_sem_t sem)31 void usb_osal_sem_delete(usb_osal_sem_t sem)
32 {
33 vSemaphoreDelete((SemaphoreHandle_t)sem);
34 }
35
usb_osal_sem_take(usb_osal_sem_t sem,uint32_t timeout)36 int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
37 {
38 if (timeout == USB_OSAL_WAITING_FOREVER) {
39 return (xSemaphoreTake((SemaphoreHandle_t)sem, portMAX_DELAY) == pdPASS) ? 0 : -ETIMEDOUT;
40 } else {
41 return (xSemaphoreTake((SemaphoreHandle_t)sem, pdMS_TO_TICKS(timeout)) == pdPASS) ? 0 : -ETIMEDOUT;
42 }
43 }
44
usb_osal_sem_give(usb_osal_sem_t sem)45 int usb_osal_sem_give(usb_osal_sem_t sem)
46 {
47 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
48 int ret;
49
50 if (xPortIsInsideInterrupt()) {
51 ret = xSemaphoreGiveFromISR((SemaphoreHandle_t)sem, &xHigherPriorityTaskWoken);
52 if (ret == pdPASS) {
53 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
54 }
55 } else {
56 ret = xSemaphoreGive((SemaphoreHandle_t)sem);
57 }
58
59 return (ret == pdPASS) ? 0 : -ETIMEDOUT;
60 }
61
usb_osal_mutex_create(void)62 usb_osal_mutex_t usb_osal_mutex_create(void)
63 {
64 return (usb_osal_mutex_t)xSemaphoreCreateMutex();
65 }
66
usb_osal_mutex_delete(usb_osal_mutex_t mutex)67 void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
68 {
69 vSemaphoreDelete((SemaphoreHandle_t)mutex);
70 }
71
usb_osal_mutex_take(usb_osal_mutex_t mutex)72 int usb_osal_mutex_take(usb_osal_mutex_t mutex)
73 {
74 return (xSemaphoreTake((SemaphoreHandle_t)mutex, portMAX_DELAY) == pdPASS) ? 0 : -ETIMEDOUT;
75 }
76
usb_osal_mutex_give(usb_osal_mutex_t mutex)77 int usb_osal_mutex_give(usb_osal_mutex_t mutex)
78 {
79 return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -ETIMEDOUT;
80 }
81
usb_osal_mq_create(uint32_t max_msgs)82 usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
83 {
84 return (usb_osal_mq_t)xQueueCreate(max_msgs, sizeof(uintptr_t));
85 }
86
usb_osal_mq_send(usb_osal_mq_t mq,uintptr_t addr)87 int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
88 {
89 BaseType_t xHigherPriorityTaskWoken = pdFALSE;
90 int ret;
91
92 ret = xQueueSendFromISR((usb_osal_mq_t)mq, &addr, &xHigherPriorityTaskWoken);
93 if (ret == pdPASS) {
94 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
95 }
96
97 return (ret == pdPASS) ? 0 : -ETIMEDOUT;
98 }
99
usb_osal_mq_recv(usb_osal_mq_t mq,uintptr_t * addr,uint32_t timeout)100 int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
101 {
102 if (timeout == USB_OSAL_WAITING_FOREVER) {
103 return (xQueueReceive((usb_osal_mq_t)mq, addr, portMAX_DELAY) == pdPASS) ? 0 : -ETIMEDOUT;
104 } else {
105 return (xQueueReceive((usb_osal_mq_t)mq, addr, pdMS_TO_TICKS(timeout)) == pdPASS) ? 0 : -ETIMEDOUT;
106 }
107 }
108
usb_osal_enter_critical_section(void)109 size_t usb_osal_enter_critical_section(void)
110 {
111 taskDISABLE_INTERRUPTS();
112 return 1;
113 }
114
usb_osal_leave_critical_section(size_t flag)115 void usb_osal_leave_critical_section(size_t flag)
116 {
117 (void)flag;
118 taskENABLE_INTERRUPTS();
119 }
120
usb_osal_msleep(uint32_t delay)121 void usb_osal_msleep(uint32_t delay)
122 {
123 vTaskDelay(pdMS_TO_TICKS(delay));
124 }
125