1 /*
2 * Copyright (c) 2024, Texas Instruments Incorporated
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/kernel_structs.h>
9 #include <assert.h>
10 #include <zephyr/sys/__assert.h>
11
12 #include <inc/hw_types.h>
13 #include <inc/hw_ints.h>
14
15 #include <driverlib/interrupt.h>
16
17 #include <kernel/zephyr/dpl/dpl.h>
18 #include <ti/drivers/dpl/MessageQueueP.h>
19 #include <ti/drivers/dpl/ClockP.h>
20 #include <ti/drivers/dpl/HwiP.h>
21
22 #ifdef CONFIG_DYNAMIC_DPL_OBJECTS
23 /* We can't easily dynamically allocate kernel objects */
24 #define DPL_MAX_MSGQS 4
25 K_MEM_SLAB_DEFINE(msgq_slab, sizeof(struct k_msgq) , DPL_MAX_MSGQS, MEM_ALIGN);
26
dpl_msgq_pool_alloc()27 static struct k_msgq *dpl_msgq_pool_alloc()
28 {
29 struct k_msgq *msgq_ptr = NULL;
30
31 if (k_mem_slab_alloc(&msgq_slab, (void **)&msgq_ptr, K_NO_WAIT) < 0) {
32
33 __ASSERT(0, "Increase size of DPL message queue pool");
34 }
35 return msgq_ptr;
36 }
37
dpl_msgq_pool_free(struct k_msgq * msgq)38 static void dpl_msgq_pool_free(struct k_msgq *msgq)
39 {
40
41 k_mem_slab_free(&msgq_slab, (void *)msgq);
42
43 return;
44 }
45
46 /*
47 * ======== MessageQueueP_create ========
48 */
MessageQueueP_create(size_t msgSize,size_t msgCount)49 MessageQueueP_Handle MessageQueueP_create(size_t msgSize, size_t msgCount)
50 {
51 struct k_msgq *msgq = dpl_msgq_pool_alloc();
52 int status = k_msgq_alloc_init(msgq, msgSize, msgCount);
53 if(status != 0)
54 {
55 return NULL;
56 }
57 return (MessageQueueP_Handle) msgq;
58 }
59
60 /*
61 * ======== MessageQueueP_delete ========
62 */
MessageQueueP_delete(MessageQueueP_Handle handle)63 void MessageQueueP_delete(MessageQueueP_Handle handle)
64 {
65 if (handle != NULL)
66 {
67 struct k_msgq* msgq;
68 msgq = (struct k_msgq* )handle;
69 k_msgq_purge(msgq);
70 k_msgq_cleanup(msgq);
71 dpl_msgq_pool_free(msgq);
72 }
73 }
74 #endif /* CONFIG_DYNAMIC_DPL_OBJECTS */
75
76 /*
77 * ======== MessageQueueP_construct ========
78 */
MessageQueueP_construct(MessageQueueP_Struct * msgStruct,size_t msgSize,size_t msgCount,void * msgBuf)79 MessageQueueP_Handle MessageQueueP_construct(MessageQueueP_Struct *msgStruct,
80 size_t msgSize,
81 size_t msgCount,
82 void *msgBuf)
83 {
84 struct k_msgq* msgq;
85 msgq = (struct k_msgq* )msgStruct;
86 if (msgq) {
87 k_msgq_init(msgq, msgBuf, msgSize, msgCount);
88 }
89
90 return (MessageQueueP_Handle)msgq;
91 }
92
93 /*
94 * ======== MessageQueueP_destruct ========
95 */
MessageQueueP_destruct(MessageQueueP_Handle handle)96 void MessageQueueP_destruct(MessageQueueP_Handle handle)
97 {
98 k_msgq_purge((struct k_msgq* )handle);
99 }
100
101 /*
102 * ======== MessageQueueP_pend ========
103 */
MessageQueueP_pend(MessageQueueP_Handle handle,void * message,uint32_t timeout)104 MessageQueueP_Status MessageQueueP_pend(MessageQueueP_Handle handle, void *message, uint32_t timeout)
105 {
106 uint32_t tickPeriod;
107 k_timeout_t msgTimeout;
108
109 /* Timeout must be K_NO_WAIT if in an ISR */
110 if ((timeout == MessageQueueP_NO_WAIT) || k_is_in_isr())
111 {
112 msgTimeout = K_NO_WAIT;
113 }
114 else if (timeout == MessageQueueP_WAIT_FOREVER)
115 {
116 msgTimeout = K_FOREVER;
117 }
118 else
119 {
120 /* If necessary, convert ClockP ticks to Zephyr ticks */
121 /* Should really be ClockP_getSystemTickPeriod() but this causes issues with ielftool post build step */
122 tickPeriod = ClockP_TICK_PERIOD;
123 msgTimeout = K_TICKS(timeout);
124 }
125 int status = k_msgq_get((struct k_msgq*) handle, message, msgTimeout);
126 if(status == 0)
127 {
128 return MessageQueueP_OK;
129 }
130 return MessageQueueP_TIMEOUT;
131 }
132
133 /*
134 * ======== MessageQueueP_peek ========
135 */
MessageQueueP_peek(MessageQueueP_Handle handle,void * message,uint32_t timeout)136 MessageQueueP_Status MessageQueueP_peek(MessageQueueP_Handle handle, void *message, uint32_t timeout)
137 {
138 assert(timeout == MessageQueueP_NO_WAIT);
139 /* Zephyr peek does not support timeouts*/
140 uint32_t status = k_msgq_peek((struct k_msgq*) handle, message);
141
142 if(status == 0)
143 {
144 return MessageQueueP_OK;
145 }
146 return MessageQueueP_TIMEOUT;
147 }
148
149 /*
150 * ======== MessageQueueP_post ========
151 */
MessageQueueP_post(MessageQueueP_Handle handle,const void * message,uint32_t timeout)152 MessageQueueP_Status MessageQueueP_post(MessageQueueP_Handle handle, const void *message, uint32_t timeout)
153 {
154 uint32_t tickPeriod;
155 k_timeout_t msgTimeout;
156 uint64_t timeUS;
157
158 if (timeout == MessageQueueP_NO_WAIT)
159 {
160 msgTimeout = K_NO_WAIT;
161 }
162 else if (timeout == MessageQueueP_WAIT_FOREVER)
163 {
164 msgTimeout = K_FOREVER;
165 }
166 else
167 {
168 /* if necessary, convert ClockP ticks to Zephyr ticks */
169 /* Should really be ClockP_getSystemTickPeriod() but this causes issues with ielftool post build step */
170 tickPeriod = ClockP_TICK_PERIOD;
171 if (tickPeriod != CONFIG_SYS_CLOCK_TICKS_PER_SEC)
172 {
173 timeUS = timeout * (uint64_t)tickPeriod;
174 msgTimeout = K_USEC(timeUS);
175 }
176 else
177 {
178 msgTimeout = K_TICKS(timeout);
179 }
180 }
181
182 int status = k_msgq_put((struct k_msgq*) handle, message, msgTimeout);
183
184 if(status == 0)
185 {
186 return MessageQueueP_OK;
187 }
188 return MessageQueueP_TIMEOUT;
189 }
190
191 /*
192 * ======== MessageQueueP_postFront ========
193 */
MessageQueueP_postFront(MessageQueueP_Handle handle,const void * message,uint32_t timeout)194 MessageQueueP_Status MessageQueueP_postFront(MessageQueueP_Handle handle, const void *message, uint32_t timeout)
195 {
196 return MessageQueueP_post(handle, message, timeout);
197 }
198
199 /*
200 * ======== MessageQueueP_getPendingCount ========
201 */
MessageQueueP_getPendingCount(MessageQueueP_Handle handle)202 size_t MessageQueueP_getPendingCount(MessageQueueP_Handle handle)
203 {
204 size_t msgCount = k_msgq_num_used_get((struct k_msgq*) handle);
205 return msgCount;
206 }
207
208 /*
209 * ======== MessageQueueP_getFreeCount ========
210 */
MessageQueueP_getFreeCount(MessageQueueP_Handle handle)211 size_t MessageQueueP_getFreeCount(MessageQueueP_Handle handle)
212 {
213 size_t freeMsgCount = k_msgq_num_free_get((struct k_msgq*) handle);
214
215 return freeMsgCount;
216 }
217
218 /*
219 * ======== MessageQueueP_getMessageQueueObjectSize ========
220 */
MessageQueueP_getMessageQueueObjectSize(void)221 uint32_t MessageQueueP_getMessageQueueObjectSize(void)
222 {
223 return sizeof(struct k_msgq);
224 }
225