1 /***********************************************************************************************//**
2  * \file cyabs_rtos_zephyr.c
3  *
4  * \brief
5  * Implementation for Zephyr RTOS abstraction
6  *
7  ***************************************************************************************************
8  * \copyright
9  * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
10  * an affiliate of Cypress Semiconductor Corporation
11  *
12  * SPDX-License-Identifier: Apache-2.0
13  *
14  * Licensed under the Apache License, Version 2.0 (the "License");
15  * you may not use this file except in compliance with the License.
16  * You may obtain a copy of the License at
17  *
18  *     http://www.apache.org/licenses/LICENSE-2.0
19  *
20  * Unless required by applicable law or agreed to in writing, software
21  * distributed under the License is distributed on an "AS IS" BASIS,
22  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23  * See the License for the specific language governing permissions and
24  * limitations under the License.
25  **************************************************************************************************/
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <cy_utils.h>
30 #include <cyabs_rtos.h>
31 
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35 
36 
37 /*
38  *                 Error Converter
39  */
40 
41 /* Last received error status */
42 static cy_rtos_error_t dbgErr;
43 
cy_rtos_last_error(void)44 cy_rtos_error_t cy_rtos_last_error(void)
45 {
46 	return dbgErr;
47 }
48 
49 /* Converts internal error type to external error type */
error_converter(cy_rtos_error_t internalError)50 static cy_rslt_t error_converter(cy_rtos_error_t internalError)
51 {
52 	cy_rslt_t value;
53 
54 	switch (internalError) {
55 	case 0:
56 		value = CY_RSLT_SUCCESS;
57 		break;
58 
59 	case -EAGAIN:
60 		value = CY_RTOS_TIMEOUT;
61 		break;
62 
63 	case -EINVAL:
64 		value = CY_RTOS_BAD_PARAM;
65 		break;
66 
67 	case -ENOMEM:
68 		value = CY_RTOS_NO_MEMORY;
69 		break;
70 
71 	default:
72 		value = CY_RTOS_GENERAL_ERROR;
73 		break;
74 	}
75 
76 	/* Update the last known error status */
77 	dbgErr = internalError;
78 
79 	return value;
80 }
81 
free_thead_obj(cy_thread_t * thread)82 static void free_thead_obj(cy_thread_t *thread)
83 {
84 	/* Free allocated stack buffer */
85 	if ((*thread)->memptr != NULL) {
86 		k_free((*thread)->memptr);
87 	}
88 
89 	/* Free object */
90 	k_free(*thread);
91 }
92 
93 
94 /*
95  *                 Threads
96  */
97 
thread_entry_function_wrapper(void * p1,void * p2,void * p3)98 static void thread_entry_function_wrapper(void *p1, void *p2, void *p3)
99 {
100 	CY_UNUSED_PARAMETER(p3);
101 	((cy_thread_entry_fn_t)p2)(p1);
102 }
103 
cy_rtos_create_thread(cy_thread_t * thread,cy_thread_entry_fn_t entry_function,const char * name,void * stack,uint32_t stack_size,cy_thread_priority_t priority,cy_thread_arg_t arg)104 cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function,
105 				const char *name, void *stack, uint32_t stack_size,
106 				cy_thread_priority_t priority, cy_thread_arg_t arg)
107 {
108 	cy_rslt_t status = CY_RSLT_SUCCESS;
109 	cy_rtos_error_t status_internal = 0;
110 
111 	if ((thread == NULL) || (stack_size < CY_RTOS_MIN_STACK_SIZE)) {
112 		status = CY_RTOS_BAD_PARAM;
113 	} else if ((stack != NULL) && (0 != (((uint32_t)stack) & CY_RTOS_ALIGNMENT_MASK))) {
114 		status = CY_RTOS_ALIGNMENT_ERROR;
115 	} else {
116 		void *stack_alloc = NULL;
117 		k_tid_t my_tid = NULL;
118 
119 		/* Allocate cy_thread_t object */
120 		*thread = k_malloc(sizeof(k_thread_wrapper_t));
121 
122 		/* Allocate stack if NULL was passed */
123 		if ((uint32_t *)stack == NULL) {
124 			stack_alloc = k_aligned_alloc(Z_KERNEL_STACK_OBJ_ALIGN,
125 						      K_KERNEL_STACK_LEN(stack_size));
126 
127 			/* Store pointer to allocated stack,
128 			 * NULL if not allocated by cy_rtos_thread_create (passed by application).
129 			 */
130 			(*thread)->memptr = stack_alloc;
131 		} else {
132 			stack_alloc = stack;
133 			(*thread)->memptr = NULL;
134 		}
135 
136 		if (stack_alloc == NULL) {
137 			status = CY_RTOS_NO_MEMORY;
138 		} else {
139 			/* Create thread */
140 			my_tid = k_thread_create(&(*thread)->z_thread, stack_alloc, stack_size,
141 						 thread_entry_function_wrapper,
142 						 (cy_thread_arg_t)arg, (void *)entry_function, NULL,
143 						 priority, 0, K_NO_WAIT);
144 
145 			/* Set thread name */
146 			status_internal = k_thread_name_set(my_tid, name);
147 			/* NOTE: k_thread_name_set returns -ENOSYS if thread name
148 			 * configuration option not enabled.
149 			 */
150 		}
151 
152 		if ((my_tid == NULL) || ((status_internal != 0) && (status_internal != -ENOSYS))) {
153 			status = CY_RTOS_GENERAL_ERROR;
154 
155 			/* Free allocated thread object and stack buffer */
156 			free_thead_obj(thread);
157 		}
158 	}
159 
160 	return status;
161 }
162 
cy_rtos_exit_thread(void)163 cy_rslt_t cy_rtos_exit_thread(void)
164 {
165 	cy_rslt_t status = CY_RSLT_SUCCESS;
166 
167 	if (k_is_in_isr()) {
168 		status = CY_RTOS_GENERAL_ERROR;
169 	} else {
170 		cy_thread_t thread = (cy_thread_t)k_current_get();
171 
172 		/* Abort thread */
173 		k_thread_abort((k_tid_t)&(thread)->z_thread);
174 
175 		CODE_UNREACHABLE;
176 	}
177 
178 	return status;
179 }
180 
cy_rtos_terminate_thread(cy_thread_t * thread)181 cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread)
182 {
183 	cy_rslt_t status = CY_RSLT_SUCCESS;
184 
185 	if (thread == NULL) {
186 		status = CY_RTOS_BAD_PARAM;
187 	} else if (k_is_in_isr()) {
188 		status = CY_RTOS_GENERAL_ERROR;
189 	} else {
190 		/* Abort thread */
191 		k_thread_abort((k_tid_t)&(*thread)->z_thread);
192 
193 		/* Free allocated stack buffer */
194 		if ((*thread)->memptr != NULL) {
195 			k_free((*thread)->memptr);
196 		}
197 	}
198 
199 	return status;
200 }
201 
cy_rtos_is_thread_running(cy_thread_t * thread,bool * running)202 cy_rslt_t cy_rtos_is_thread_running(cy_thread_t *thread, bool *running)
203 {
204 	cy_rslt_t status = CY_RSLT_SUCCESS;
205 
206 	if ((thread == NULL) || (running == NULL)) {
207 		status = CY_RTOS_BAD_PARAM;
208 	} else {
209 		*running = (k_current_get() == &(*thread)->z_thread) ? true : false;
210 	}
211 
212 	return status;
213 }
cy_rtos_get_thread_state(cy_thread_t * thread,cy_thread_state_t * state)214 cy_rslt_t cy_rtos_get_thread_state(cy_thread_t *thread, cy_thread_state_t *state)
215 {
216 	cy_rslt_t status = CY_RSLT_SUCCESS;
217 
218 	if ((thread == NULL) || (state == NULL)) {
219 		status = CY_RTOS_BAD_PARAM;
220 	} else {
221 		if (k_is_in_isr()) {
222 			*state = CY_THREAD_STATE_UNKNOWN;
223 		} else if (k_current_get() == &(*thread)->z_thread) {
224 			*state = CY_THREAD_STATE_RUNNING;
225 		}
226 		if (((*thread)->z_thread.base.thread_state & _THREAD_DEAD) != 0) {
227 			*state = CY_THREAD_STATE_TERMINATED;
228 		} else {
229 			switch ((*thread)->z_thread.base.thread_state) {
230 			case _THREAD_DUMMY:
231 				*state = CY_THREAD_STATE_UNKNOWN;
232 				break;
233 
234 			case _THREAD_SUSPENDED:
235 			case _THREAD_SLEEPING:
236 			case _THREAD_PENDING:
237 				*state = CY_THREAD_STATE_BLOCKED;
238 				break;
239 
240 			case _THREAD_QUEUED:
241 				*state = CY_THREAD_STATE_READY;
242 				break;
243 
244 			default:
245 				*state = CY_THREAD_STATE_UNKNOWN;
246 				break;
247 			}
248 		}
249 	}
250 
251 	return status;
252 }
253 
cy_rtos_join_thread(cy_thread_t * thread)254 cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread)
255 {
256 	cy_rslt_t status = CY_RSLT_SUCCESS;
257 	cy_rtos_error_t status_internal;
258 
259 	if (thread == NULL) {
260 		status = CY_RTOS_BAD_PARAM;
261 	} else {
262 		if (*thread != NULL) {
263 			/* Sleep until a thread exits */
264 			status_internal = k_thread_join(&(*thread)->z_thread, K_FOREVER);
265 			status = error_converter(status_internal);
266 
267 			if (status == CY_RSLT_SUCCESS) {
268 				/* Free allocated thread object and stack buffer */
269 				free_thead_obj(thread);
270 			}
271 		}
272 	}
273 
274 	return status;
275 }
276 
cy_rtos_get_thread_handle(cy_thread_t * thread)277 cy_rslt_t cy_rtos_get_thread_handle(cy_thread_t *thread)
278 {
279 	cy_rslt_t status = CY_RSLT_SUCCESS;
280 
281 	if (thread == NULL) {
282 		status = CY_RTOS_BAD_PARAM;
283 	} else {
284 		*thread = (cy_thread_t)k_current_get();
285 	}
286 
287 	return status;
288 }
289 
cy_rtos_wait_thread_notification(cy_time_t timeout_ms)290 cy_rslt_t cy_rtos_wait_thread_notification(cy_time_t timeout_ms)
291 {
292 	cy_rtos_error_t status_internal;
293 	cy_rslt_t status = CY_RSLT_SUCCESS;
294 
295 	if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
296 		status_internal = k_sleep(K_FOREVER);
297 	} else {
298 		status_internal = k_msleep((int32_t)timeout_ms);
299 		if (status_internal == 0) {
300 			status = CY_RTOS_TIMEOUT;
301 		}
302 	}
303 
304 	if ((status_internal < 0) && (status_internal != K_TICKS_FOREVER)) {
305 		status = error_converter(status_internal);
306 	}
307 
308 	return status;
309 }
310 
cy_rtos_thread_set_notification(cy_thread_t * thread)311 cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread)
312 {
313 	cy_rslt_t status = CY_RSLT_SUCCESS;
314 
315 	if (thread == NULL) {
316 		status = CY_RTOS_BAD_PARAM;
317 	} else {
318 		k_wakeup(&(*thread)->z_thread);
319 	}
320 
321 	return status;
322 }
323 
324 
325 /*
326  *                 Mutexes
327  */
328 
cy_rtos_init_mutex2(cy_mutex_t * mutex,bool recursive)329 cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive)
330 {
331 	cy_rtos_error_t status_internal;
332 	cy_rslt_t status;
333 
334 	/* Non recursive mutex is not supported by Zephyr */
335 	CY_UNUSED_PARAMETER(recursive);
336 
337 	if (mutex == NULL) {
338 		status = CY_RTOS_BAD_PARAM;
339 	} else {
340 		/* Initialize a mutex object */
341 		status_internal = k_mutex_init(mutex);
342 		status = error_converter(status_internal);
343 	}
344 
345 	return status;
346 }
347 
cy_rtos_get_mutex(cy_mutex_t * mutex,cy_time_t timeout_ms)348 cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms)
349 {
350 	cy_rtos_error_t status_internal;
351 	cy_rslt_t status;
352 
353 	if (mutex == NULL) {
354 		status = CY_RTOS_BAD_PARAM;
355 	} else if (k_is_in_isr()) {
356 		/* Mutexes may not be locked in ISRs */
357 		status = CY_RTOS_GENERAL_ERROR;
358 	} else {
359 		/* Convert timeout value */
360 		k_timeout_t k_timeout =
361 			(timeout_ms == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout_ms);
362 
363 		/* Lock a mutex */
364 		status_internal = k_mutex_lock(mutex, k_timeout);
365 		status = error_converter(status_internal);
366 	}
367 
368 	return status;
369 }
370 
cy_rtos_set_mutex(cy_mutex_t * mutex)371 cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex)
372 {
373 	cy_rtos_error_t status_internal;
374 	cy_rslt_t status;
375 
376 	if (mutex == NULL) {
377 		status = CY_RTOS_BAD_PARAM;
378 	} else if (k_is_in_isr()) {
379 		/* Mutexes may not be unlocked in ISRs */
380 		status = CY_RTOS_GENERAL_ERROR;
381 	} else {
382 		/* Unlock a mutex */
383 		status_internal = k_mutex_unlock(mutex);
384 		status = error_converter(status_internal);
385 	}
386 
387 	return status;
388 }
389 
cy_rtos_deinit_mutex(cy_mutex_t * mutex)390 cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex)
391 {
392 	cy_rslt_t status = CY_RSLT_SUCCESS;
393 
394 	if (mutex == NULL) {
395 		status = CY_RTOS_BAD_PARAM;
396 	} else {
397 		/* Force unlock mutex, do not care about return */
398 		(void)k_mutex_unlock(mutex);
399 	}
400 
401 	return status;
402 }
403 
404 
405 /*
406  *                 Semaphores
407  */
408 
cy_rtos_init_semaphore(cy_semaphore_t * semaphore,uint32_t maxcount,uint32_t initcount)409 cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount)
410 {
411 	cy_rtos_error_t status_internal;
412 	cy_rslt_t status;
413 
414 	if (semaphore == NULL) {
415 		status = CY_RTOS_BAD_PARAM;
416 	} else {
417 		/* Initialize a semaphore object */
418 		status_internal = k_sem_init(semaphore, initcount, maxcount);
419 		status = error_converter(status_internal);
420 	}
421 
422 	return status;
423 }
424 
cy_rtos_get_semaphore(cy_semaphore_t * semaphore,cy_time_t timeout_ms,bool in_isr)425 cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr)
426 {
427 	cy_rtos_error_t status_internal;
428 	cy_rslt_t status;
429 
430 	if (semaphore == NULL) {
431 		status = CY_RTOS_BAD_PARAM;
432 	} else {
433 		/* Convert timeout value */
434 		k_timeout_t k_timeout;
435 
436 		if (k_is_in_isr()) {
437 			/* NOTE: Based on Zephyr documentation when k_sem_take
438 			 * is called from ISR timeout must be set to K_NO_WAIT.
439 			 */
440 			k_timeout = K_NO_WAIT;
441 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
442 			k_timeout = K_FOREVER;
443 		} else {
444 			k_timeout = K_MSEC(timeout_ms);
445 		}
446 
447 		/* Take a semaphore */
448 		status_internal = k_sem_take(semaphore, k_timeout);
449 		status = error_converter(status_internal);
450 
451 		if (k_is_in_isr() && (status_internal == -EBUSY)) {
452 			status = CY_RSLT_SUCCESS;
453 		}
454 	}
455 
456 	return status;
457 }
458 
cy_rtos_set_semaphore(cy_semaphore_t * semaphore,bool in_isr)459 cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr)
460 {
461 	cy_rslt_t status = CY_RSLT_SUCCESS;
462 
463 	if (semaphore == NULL) {
464 		status = CY_RTOS_BAD_PARAM;
465 	} else {
466 		/* Give a semaphore */
467 		k_sem_give(semaphore);
468 	}
469 
470 	return status;
471 }
472 
cy_rtos_get_count_semaphore(cy_semaphore_t * semaphore,size_t * count)473 cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count)
474 {
475 	cy_rslt_t status = CY_RSLT_SUCCESS;
476 
477 	if ((semaphore == NULL) || (count == NULL)) {
478 		status = CY_RTOS_BAD_PARAM;
479 	} else {
480 		*count = k_sem_count_get(semaphore);
481 	}
482 
483 	return status;
484 }
485 
cy_rtos_deinit_semaphore(cy_semaphore_t * semaphore)486 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore)
487 {
488 	cy_rslt_t status = CY_RSLT_SUCCESS;
489 
490 	if (semaphore == NULL) {
491 		status = CY_RTOS_BAD_PARAM;
492 	} else {
493 		k_sem_reset(semaphore);
494 	}
495 
496 	return status;
497 }
498 
499 
500 /*
501  *                 Events
502  */
503 
cy_rtos_init_event(cy_event_t * event)504 cy_rslt_t cy_rtos_init_event(cy_event_t *event)
505 {
506 	cy_rslt_t status = CY_RSLT_SUCCESS;
507 
508 	if (event == NULL) {
509 		status = CY_RTOS_BAD_PARAM;
510 	} else {
511 		/* Initialize an event object */
512 		k_event_init(event);
513 	}
514 
515 	return status;
516 }
517 
cy_rtos_setbits_event(cy_event_t * event,uint32_t bits,bool in_isr)518 cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
519 {
520 	cy_rslt_t status = CY_RSLT_SUCCESS;
521 
522 	if (event == NULL) {
523 		status = CY_RTOS_BAD_PARAM;
524 	} else {
525 		/* Post the new bits */
526 		k_event_post(event, bits);
527 	}
528 
529 	return status;
530 }
531 
cy_rtos_clearbits_event(cy_event_t * event,uint32_t bits,bool in_isr)532 cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
533 {
534 	cy_rslt_t status = CY_RSLT_SUCCESS;
535 
536 	if (event == NULL) {
537 		status = CY_RTOS_BAD_PARAM;
538 	} else {
539 		uint32_t current_bits;
540 
541 		/* Reads events value */
542 		status = cy_rtos_getbits_event(event, &current_bits);
543 
544 		/* Set masked value */
545 		k_event_set(event, (~bits & current_bits));
546 	}
547 
548 	return status;
549 }
550 
cy_rtos_getbits_event(cy_event_t * event,uint32_t * bits)551 cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits)
552 {
553 	cy_rslt_t status = CY_RSLT_SUCCESS;
554 
555 	if ((event == NULL) || (bits == NULL)) {
556 		status = CY_RTOS_BAD_PARAM;
557 	} else {
558 		/* NOTE: Zephyr does not provide function for get bits,
559 		 * retrieve it from event object.
560 		 */
561 		*bits = event->events;
562 	}
563 
564 	return status;
565 }
566 
cy_rtos_waitbits_event(cy_event_t * event,uint32_t * bits,bool clear,bool all,cy_time_t timeout)567 cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all,
568 				 cy_time_t timeout)
569 {
570 	cy_rslt_t status;
571 
572 	if ((event == NULL) || (bits == NULL)) {
573 		status = CY_RTOS_BAD_PARAM;
574 	} else {
575 		uint32_t wait_for = *bits;
576 		k_timeout_t k_timeout =
577 			(timeout == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout);
578 
579 		if (all) {
580 			/* Wait for all of the specified events */
581 			*bits = k_event_wait_all(event, wait_for, false, k_timeout);
582 		} else {
583 			/* Wait for any of the specified events */
584 			*bits = k_event_wait(event, wait_for, false, k_timeout);
585 		}
586 
587 		/* Check timeout */
588 		status = (*bits == 0) ? CY_RTOS_TIMEOUT : CY_RSLT_SUCCESS;
589 
590 		/* Return full current events */
591 		cy_rtos_getbits_event(event, bits);
592 
593 		/* Crear bits if required */
594 		if ((status == CY_RSLT_SUCCESS) && (clear == true)) {
595 			cy_rtos_clearbits_event(event, wait_for, false);
596 		}
597 	}
598 	return status;
599 }
600 
cy_rtos_deinit_event(cy_event_t * event)601 cy_rslt_t cy_rtos_deinit_event(cy_event_t *event)
602 {
603 	cy_rslt_t status = CY_RSLT_SUCCESS;
604 
605 	if (event != NULL) {
606 		/* Clear event */
607 		k_event_set(event, 0);
608 	} else {
609 		status = CY_RTOS_BAD_PARAM;
610 	}
611 	return status;
612 }
613 
614 
615 /*
616  *                 Queues
617  */
618 
cy_rtos_init_queue(cy_queue_t * queue,size_t length,size_t itemsize)619 cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize)
620 {
621 	cy_rtos_error_t status_internal;
622 	cy_rslt_t status;
623 
624 	if (queue == NULL) {
625 		status = CY_RTOS_BAD_PARAM;
626 	} else {
627 		/* Initialize a message queue */
628 		status_internal = k_msgq_alloc_init(queue, itemsize, length);
629 		status = error_converter(status_internal);
630 	}
631 
632 	return status;
633 }
634 
cy_rtos_put_queue(cy_queue_t * queue,const void * item_ptr,cy_time_t timeout_ms,bool in_isr)635 cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms,
636 			    bool in_isr)
637 {
638 	cy_rtos_error_t status_internal;
639 	cy_rslt_t status;
640 
641 	if ((queue == NULL) || (item_ptr == NULL)) {
642 		status = CY_RTOS_BAD_PARAM;
643 	} else {
644 		/* Convert timeout value */
645 		k_timeout_t k_timeout;
646 
647 		if (k_is_in_isr()) {
648 			k_timeout = K_NO_WAIT;
649 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
650 			k_timeout = K_FOREVER;
651 		} else {
652 			k_timeout = K_MSEC(timeout_ms);
653 		}
654 
655 		/* Send a message to a message queue */
656 		status_internal = k_msgq_put(queue, item_ptr, k_timeout);
657 		status = error_converter(status_internal);
658 	}
659 
660 	return status;
661 }
662 
cy_rtos_get_queue(cy_queue_t * queue,void * item_ptr,cy_time_t timeout_ms,bool in_isr)663 cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr)
664 {
665 	cy_rtos_error_t status_internal;
666 	cy_rslt_t status;
667 
668 	if ((queue == NULL) || (item_ptr == NULL)) {
669 		status = CY_RTOS_BAD_PARAM;
670 	} else {
671 		/* Convert timeout value */
672 		k_timeout_t k_timeout;
673 
674 		if (k_is_in_isr()) {
675 			k_timeout = K_NO_WAIT;
676 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
677 			k_timeout = K_FOREVER;
678 		} else {
679 			k_timeout = K_MSEC(timeout_ms);
680 		}
681 
682 		/* Receive a message from a message queue */
683 		status_internal = k_msgq_get(queue, item_ptr, k_timeout);
684 		status = error_converter(status_internal);
685 	}
686 
687 	return status;
688 }
689 
cy_rtos_count_queue(cy_queue_t * queue,size_t * num_waiting)690 cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting)
691 {
692 	cy_rslt_t status = CY_RSLT_SUCCESS;
693 
694 	if ((queue == NULL) || (num_waiting == NULL)) {
695 		status = CY_RTOS_BAD_PARAM;
696 	} else {
697 		/* Get the number of messages in a message queue */
698 		*num_waiting = k_msgq_num_used_get(queue);
699 	}
700 
701 	return status;
702 }
703 
cy_rtos_space_queue(cy_queue_t * queue,size_t * num_spaces)704 cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces)
705 {
706 	cy_rslt_t status = CY_RSLT_SUCCESS;
707 
708 	if ((queue == NULL) || (num_spaces == NULL)) {
709 		status = CY_RTOS_BAD_PARAM;
710 	} else {
711 		/* Get the amount of free space in a message queue */
712 		*num_spaces = k_msgq_num_free_get(queue);
713 	}
714 
715 	return status;
716 }
717 
cy_rtos_reset_queue(cy_queue_t * queue)718 cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue)
719 {
720 	cy_rslt_t status = CY_RSLT_SUCCESS;
721 
722 	if (queue == NULL) {
723 		status = CY_RTOS_BAD_PARAM;
724 	} else {
725 		/* Reset a message queue */
726 		k_msgq_purge(queue);
727 	}
728 
729 	return status;
730 }
731 
cy_rtos_deinit_queue(cy_queue_t * queue)732 cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue)
733 {
734 	cy_rtos_error_t status_internal;
735 	cy_rslt_t status;
736 
737 	if (queue == NULL) {
738 		status = CY_RTOS_BAD_PARAM;
739 	} else {
740 		/* Reset a message queue */
741 		status = cy_rtos_reset_queue(queue);
742 
743 		if (status == CY_RSLT_SUCCESS) {
744 			/* Release allocated buffer for a queue */
745 			status_internal = k_msgq_cleanup(queue);
746 			status = error_converter(status_internal);
747 		}
748 	}
749 
750 	return status;
751 }
752 
753 
754 /*
755  *                 Timers
756  */
zephyr_timer_event_handler(struct k_timer * timer)757 static void zephyr_timer_event_handler(struct k_timer *timer)
758 {
759 	cy_timer_t *_timer = (cy_timer_t *)timer;
760 
761 	((cy_timer_callback_t)_timer->callback_function)(
762 		(cy_timer_callback_arg_t)_timer->arg);
763 }
764 
cy_rtos_init_timer(cy_timer_t * timer,cy_timer_trigger_type_t type,cy_timer_callback_t fun,cy_timer_callback_arg_t arg)765 cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
766 			     cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
767 {
768 	cy_rslt_t status = CY_RSLT_SUCCESS;
769 
770 	if ((timer == NULL) || (fun == NULL)) {
771 		status = CY_RTOS_BAD_PARAM;
772 	} else {
773 		timer->callback_function = (void *)fun;
774 		timer->trigger_type = (uint32_t)type;
775 		timer->arg = (void *)arg;
776 
777 		k_timer_init(&timer->z_timer, zephyr_timer_event_handler, NULL);
778 	}
779 
780 	return status;
781 }
782 
cy_rtos_start_timer(cy_timer_t * timer,cy_time_t num_ms)783 cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms)
784 {
785 	cy_rslt_t status = CY_RSLT_SUCCESS;
786 
787 	if (timer == NULL) {
788 		status = CY_RTOS_BAD_PARAM;
789 	} else {
790 		if ((cy_timer_trigger_type_t)timer->trigger_type == CY_TIMER_TYPE_ONCE) {
791 			/* Called once only */
792 			k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_NO_WAIT);
793 		} else {
794 			/* Called periodically until stopped */
795 			k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_MSEC(num_ms));
796 		}
797 	}
798 
799 	return status;
800 }
801 
cy_rtos_stop_timer(cy_timer_t * timer)802 cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer)
803 {
804 	cy_rslt_t status = CY_RSLT_SUCCESS;
805 
806 	if (timer == NULL) {
807 		status = CY_RTOS_BAD_PARAM;
808 	} else {
809 		/* Stop timer */
810 		k_timer_stop(&timer->z_timer);
811 	}
812 
813 	return status;
814 }
815 
cy_rtos_is_running_timer(cy_timer_t * timer,bool * state)816 cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state)
817 {
818 	cy_rslt_t status = CY_RSLT_SUCCESS;
819 
820 	if ((timer == NULL) || (state == NULL)) {
821 		status = CY_RTOS_BAD_PARAM;
822 	} else {
823 		/* Check if running */
824 		*state = (k_timer_remaining_get(&timer->z_timer) != 0u);
825 	}
826 
827 	return status;
828 }
829 
cy_rtos_deinit_timer(cy_timer_t * timer)830 cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer)
831 {
832 	cy_rslt_t status;
833 
834 	if (timer == NULL) {
835 		status = CY_RTOS_BAD_PARAM;
836 	} else {
837 		bool running;
838 
839 		/* Get current timer state */
840 		status = cy_rtos_is_running_timer(timer, &running);
841 
842 		/* Check if running */
843 		if ((status == CY_RSLT_SUCCESS) && (running)) {
844 			/* Stop timer */
845 			status = cy_rtos_stop_timer(timer);
846 		}
847 	}
848 
849 	return status;
850 }
851 
852 
853 /*
854  *                 Time
855  */
856 
cy_rtos_get_time(cy_time_t * tval)857 cy_rslt_t cy_rtos_get_time(cy_time_t *tval)
858 {
859 	cy_rslt_t status = CY_RSLT_SUCCESS;
860 
861 	if (tval == NULL) {
862 		status = CY_RTOS_BAD_PARAM;
863 	} else {
864 		/* Get system uptime (32-bit version) */
865 		*tval = k_uptime_get_32();
866 	}
867 
868 	return status;
869 }
870 
cy_rtos_delay_milliseconds(cy_time_t num_ms)871 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
872 {
873 	cy_rslt_t status = CY_RSLT_SUCCESS;
874 
875 	if (k_is_in_isr()) {
876 		status = CY_RTOS_GENERAL_ERROR;
877 	} else {
878 		k_msleep(num_ms);
879 	}
880 
881 	return status;
882 }
883 
884 #if defined(__cplusplus)
885 }
886 #endif
887