usb_osal_freertos.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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_t usb_osal_thread_create(const char *name, uint32_t stack_size, uint32_t prio, usb_thread_entry_t entry, void *args)
  13. {
  14. TaskHandle_t htask = NULL;
  15. stack_size /= sizeof(StackType_t);
  16. xTaskCreate(entry, name, stack_size, args, configMAX_PRIORITIES - 1 - prio, &htask);
  17. return (usb_osal_thread_t)htask;
  18. }
  19. void usb_osal_thread_delete(usb_osal_thread_t thread)
  20. {
  21. vTaskDelete(thread);
  22. }
  23. usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
  24. {
  25. return (usb_osal_sem_t)xSemaphoreCreateCounting(1, initial_count);
  26. }
  27. void usb_osal_sem_delete(usb_osal_sem_t sem)
  28. {
  29. vSemaphoreDelete((SemaphoreHandle_t)sem);
  30. }
  31. int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
  32. {
  33. if (timeout == USB_OSAL_WAITING_FOREVER) {
  34. return (xSemaphoreTake((SemaphoreHandle_t)sem, portMAX_DELAY) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  35. } else {
  36. return (xSemaphoreTake((SemaphoreHandle_t)sem, pdMS_TO_TICKS(timeout)) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  37. }
  38. }
  39. int usb_osal_sem_give(usb_osal_sem_t sem)
  40. {
  41. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  42. int ret;
  43. if (xPortIsInsideInterrupt()) {
  44. ret = xSemaphoreGiveFromISR((SemaphoreHandle_t)sem, &xHigherPriorityTaskWoken);
  45. if (ret == pdPASS) {
  46. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  47. }
  48. } else {
  49. ret = xSemaphoreGive((SemaphoreHandle_t)sem);
  50. }
  51. return (ret == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  52. }
  53. void usb_osal_sem_reset(usb_osal_sem_t sem)
  54. {
  55. xQueueReset((QueueHandle_t)sem);
  56. }
  57. usb_osal_mutex_t usb_osal_mutex_create(void)
  58. {
  59. return (usb_osal_mutex_t)xSemaphoreCreateMutex();
  60. }
  61. void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
  62. {
  63. vSemaphoreDelete((SemaphoreHandle_t)mutex);
  64. }
  65. int usb_osal_mutex_take(usb_osal_mutex_t mutex)
  66. {
  67. return (xSemaphoreTake((SemaphoreHandle_t)mutex, portMAX_DELAY) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  68. }
  69. int usb_osal_mutex_give(usb_osal_mutex_t mutex)
  70. {
  71. return (xSemaphoreGive((SemaphoreHandle_t)mutex) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  72. }
  73. usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
  74. {
  75. return (usb_osal_mq_t)xQueueCreate(max_msgs, sizeof(uintptr_t));
  76. }
  77. void usb_osal_mq_delete(usb_osal_mq_t mq)
  78. {
  79. vQueueDelete((QueueHandle_t)mq);
  80. }
  81. int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
  82. {
  83. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  84. int ret;
  85. ret = xQueueSendFromISR((usb_osal_mq_t)mq, &addr, &xHigherPriorityTaskWoken);
  86. if (ret == pdPASS) {
  87. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  88. }
  89. return (ret == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  90. }
  91. int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
  92. {
  93. if (timeout == USB_OSAL_WAITING_FOREVER) {
  94. return (xQueueReceive((usb_osal_mq_t)mq, addr, portMAX_DELAY) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  95. } else {
  96. return (xQueueReceive((usb_osal_mq_t)mq, addr, pdMS_TO_TICKS(timeout)) == pdPASS) ? 0 : -USB_ERR_TIMEOUT;
  97. }
  98. }
  99. static void __usb_timeout(TimerHandle_t *handle)
  100. {
  101. struct usb_osal_timer *timer = (struct usb_osal_timer *)pvTimerGetTimerID((TimerHandle_t)handle);
  102. timer->handler(timer->argument);
  103. }
  104. struct usb_osal_timer *usb_osal_timer_create(const char *name, uint32_t timeout_ms, usb_timer_handler_t handler, void *argument, bool is_period)
  105. {
  106. struct usb_osal_timer *timer;
  107. timer = pvPortMalloc(sizeof(struct usb_osal_timer));
  108. if (timer == NULL) {
  109. return NULL;
  110. }
  111. memset(timer, 0, sizeof(struct usb_osal_timer));
  112. timer->handler = handler;
  113. timer->argument = argument;
  114. timer->timer = (void *)xTimerCreate("usb_tim", pdMS_TO_TICKS(timeout_ms), is_period, timer, (TimerCallbackFunction_t)__usb_timeout);
  115. if (timer->timer == NULL) {
  116. return NULL;
  117. }
  118. return timer;
  119. }
  120. void usb_osal_timer_delete(struct usb_osal_timer *timer)
  121. {
  122. xTimerStop(timer->timer, 0);
  123. xTimerDelete(timer->timer, 0);
  124. vPortFree(timer);
  125. }
  126. void usb_osal_timer_start(struct usb_osal_timer *timer)
  127. {
  128. BaseType_t xHigherPriorityTaskWoken = pdFALSE;
  129. int ret;
  130. if (xPortIsInsideInterrupt()) {
  131. ret = xTimerStartFromISR(timer->timer, &xHigherPriorityTaskWoken);
  132. if (ret == pdPASS) {
  133. portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
  134. }
  135. } else {
  136. xTimerStart(timer->timer, 0);
  137. }
  138. }
  139. void usb_osal_timer_stop(struct usb_osal_timer *timer)
  140. {
  141. xTimerStop(timer->timer, 0);
  142. }
  143. size_t usb_osal_enter_critical_section(void)
  144. {
  145. size_t ret;
  146. if (xPortIsInsideInterrupt()) {
  147. ret = taskENTER_CRITICAL_FROM_ISR();
  148. } else {
  149. taskENTER_CRITICAL();
  150. ret = 1;
  151. }
  152. return ret;
  153. }
  154. void usb_osal_leave_critical_section(size_t flag)
  155. {
  156. if (xPortIsInsideInterrupt()) {
  157. taskEXIT_CRITICAL_FROM_ISR(flag);
  158. } else {
  159. taskEXIT_CRITICAL();
  160. }
  161. }
  162. void usb_osal_msleep(uint32_t delay)
  163. {
  164. vTaskDelay(pdMS_TO_TICKS(delay));
  165. }