summaryrefslogtreecommitdiff
path: root/osal/usb_osal_rtems.c
blob: 701e4b7e3a8892659d358fd5958114e4ac92bc61 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
/*
 * Copyright (c) 2022, sakumisu
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#ifdef __rtems__

#include "usb_osal.h"
#include "usb_errno.h"
#include <rtems.h>

#define SYS_USB_MBOX_SIZE (sizeof(void *))

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)
{
    rtems_id id = 0;
    rtems_status_code res;

    res = rtems_task_create(
        rtems_build_name(name[0], name[1], name[2], name[3]),
        prio,
        stack_size,
        RTEMS_PREEMPT,
        0,
        &id);

    if (res != RTEMS_SUCCESSFUL) {
        return NULL;
    }

    res = rtems_task_start(id, (rtems_task_entry)entry, (rtems_task_argument)args);

    if (res != RTEMS_SUCCESSFUL) {
        rtems_task_delete(id);
        return NULL;
    }

    return (usb_osal_thread_t)id;
}

void usb_osal_thread_delete(usb_osal_thread_t thread)
{
    rtems_task_delete(thread);
}

usb_osal_sem_t usb_osal_sem_create(uint32_t initial_count)
{
    rtems_id semaphore = 0;
    rtems_status_code ret = rtems_semaphore_create(
        rtems_build_name('U', 'S', 'B', 's'),
        initial_count,
        RTEMS_COUNTING_SEMAPHORE,
        0,
        &semaphore);

    return semaphore;
}

void usb_osal_sem_delete(usb_osal_sem_t sem)
{
    rtems_semaphore_delete(sem);
}

int usb_osal_sem_take(usb_osal_sem_t sem, uint32_t timeout)
{
    rtems_status_code status;
    status = rtems_semaphore_obtain(sem, RTEMS_WAIT, timeout);
    return status == RTEMS_SUCCESSFUL ? 0 : -USB_ERR_TIMEOUT;
}

int usb_osal_sem_give(usb_osal_sem_t sem)
{
    rtems_status_code status = rtems_semaphore_release(sem);

    return (status == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}

usb_osal_mutex_t usb_osal_mutex_create(void)
{
    rtems_id mutex;
    rtems_status_code ret = rtems_semaphore_create(
        rtems_build_name('U', 'S', 'B', 'm'),
        1,
        RTEMS_PRIORITY | RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_LOCAL,
        0,
        &mutex);

    return mutex;
}

void usb_osal_mutex_delete(usb_osal_mutex_t mutex)
{
    rtems_semaphore_delete(mutex);
}

int usb_osal_mutex_take(usb_osal_mutex_t mutex)
{
    return (rtems_semaphore_obtain(mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}

int usb_osal_mutex_give(usb_osal_mutex_t mutex)
{
    return (rtems_semaphore_release(mutex) == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}

usb_osal_mq_t usb_osal_mq_create(uint32_t max_msgs)
{
    rtems_status_code ret;
    rtems_id mailbox = 0;
    ret = rtems_message_queue_create(
        rtems_build_name('U', 'S', 'B', 'q'),
        max_msgs,
        SYS_USB_MBOX_SIZE,
        RTEMS_DEFAULT_ATTRIBUTES,
        &mailbox);
    return mailbox;
}

int usb_osal_mq_send(usb_osal_mq_t mq, uintptr_t addr)
{
    rtems_status_code ret;
    ret = rtems_message_queue_send(mq, &addr, SYS_USB_MBOX_SIZE);
    return (ret == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}

int usb_osal_mq_recv(usb_osal_mq_t mq, uintptr_t *addr, uint32_t timeout)
{
    size_t size;
    rtems_status_code sc;
    sc = rtems_message_queue_receive(
        mq,
        addr,
        &size,
        RTEMS_WAIT,
        timeout);
    return (sc == RTEMS_SUCCESSFUL) ? 0 : -USB_ERR_TIMEOUT;
}

uint32_t usb_osal_enter_critical_section(void)
{
    rtems_interrupt_level pval;

#if RTEMS_SMP
    rtems_recursive_mutex_lock(&sys_arch_lock);
#else
    rtems_interrupt_disable(pval);
#endif
    return pval;
}

void usb_osal_leave_critical_section(size_t flag)
{
#if RTEMS_SMP
    rtems_recursive_mutex_unlock(&sys_arch_lock);
#else
    rtems_interrupt_enable(flag);
#endif
}

void usb_osal_msleep(uint32_t delay)
{
    rtems_task_wake_after(RTEMS_MILLISECONDS_TO_TICKS(delay));
}

#endif