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,bool in_isr)311 cy_rslt_t cy_rtos_thread_set_notification(cy_thread_t *thread, bool in_isr)
312 {
313 	CY_UNUSED_PARAMETER(in_isr);
314 
315 	cy_rslt_t status = CY_RSLT_SUCCESS;
316 
317 	if (thread == NULL) {
318 		status = CY_RTOS_BAD_PARAM;
319 	} else {
320 		k_wakeup(&(*thread)->z_thread);
321 	}
322 
323 	return status;
324 }
325 
326 
327 /*
328  *                 Mutexes
329  */
330 
cy_rtos_init_mutex2(cy_mutex_t * mutex,bool recursive)331 cy_rslt_t cy_rtos_init_mutex2(cy_mutex_t *mutex, bool recursive)
332 {
333 	cy_rtos_error_t status_internal;
334 	cy_rslt_t status;
335 
336 	/* Non recursive mutex is not supported by Zephyr */
337 	CY_UNUSED_PARAMETER(recursive);
338 
339 	if (mutex == NULL) {
340 		status = CY_RTOS_BAD_PARAM;
341 	} else {
342 		/* Initialize a mutex object */
343 		status_internal = k_mutex_init(mutex);
344 		status = error_converter(status_internal);
345 	}
346 
347 	return status;
348 }
349 
cy_rtos_get_mutex(cy_mutex_t * mutex,cy_time_t timeout_ms)350 cy_rslt_t cy_rtos_get_mutex(cy_mutex_t *mutex, cy_time_t timeout_ms)
351 {
352 	cy_rtos_error_t status_internal;
353 	cy_rslt_t status;
354 
355 	if (mutex == NULL) {
356 		status = CY_RTOS_BAD_PARAM;
357 	} else if (k_is_in_isr()) {
358 		/* Mutexes may not be locked in ISRs */
359 		status = CY_RTOS_GENERAL_ERROR;
360 	} else {
361 		/* Convert timeout value */
362 		k_timeout_t k_timeout =
363 			(timeout_ms == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout_ms);
364 
365 		/* Lock a mutex */
366 		status_internal = k_mutex_lock(mutex, k_timeout);
367 		status = error_converter(status_internal);
368 	}
369 
370 	return status;
371 }
372 
cy_rtos_set_mutex(cy_mutex_t * mutex)373 cy_rslt_t cy_rtos_set_mutex(cy_mutex_t *mutex)
374 {
375 	cy_rtos_error_t status_internal;
376 	cy_rslt_t status;
377 
378 	if (mutex == NULL) {
379 		status = CY_RTOS_BAD_PARAM;
380 	} else if (k_is_in_isr()) {
381 		/* Mutexes may not be unlocked in ISRs */
382 		status = CY_RTOS_GENERAL_ERROR;
383 	} else {
384 		/* Unlock a mutex */
385 		status_internal = k_mutex_unlock(mutex);
386 		status = error_converter(status_internal);
387 	}
388 
389 	return status;
390 }
391 
cy_rtos_deinit_mutex(cy_mutex_t * mutex)392 cy_rslt_t cy_rtos_deinit_mutex(cy_mutex_t *mutex)
393 {
394 	cy_rslt_t status = CY_RSLT_SUCCESS;
395 
396 	if (mutex == NULL) {
397 		status = CY_RTOS_BAD_PARAM;
398 	} else {
399 		/* Force unlock mutex, do not care about return */
400 		(void)k_mutex_unlock(mutex);
401 	}
402 
403 	return status;
404 }
405 
406 
407 /*
408  *                 Semaphores
409  */
410 
cy_rtos_init_semaphore(cy_semaphore_t * semaphore,uint32_t maxcount,uint32_t initcount)411 cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, uint32_t initcount)
412 {
413 	cy_rtos_error_t status_internal;
414 	cy_rslt_t status;
415 
416 	if (semaphore == NULL) {
417 		status = CY_RTOS_BAD_PARAM;
418 	} else {
419 		/* Initialize a semaphore object */
420 		status_internal = k_sem_init(semaphore, initcount, maxcount);
421 		status = error_converter(status_internal);
422 	}
423 
424 	return status;
425 }
426 
cy_rtos_get_semaphore(cy_semaphore_t * semaphore,cy_time_t timeout_ms,bool in_isr)427 cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr)
428 {
429 	CY_UNUSED_PARAMETER(in_isr);
430 
431 	cy_rtos_error_t status_internal;
432 	cy_rslt_t status;
433 
434 	if (semaphore == NULL) {
435 		status = CY_RTOS_BAD_PARAM;
436 	} else {
437 		/* Convert timeout value */
438 		k_timeout_t k_timeout;
439 
440 		if (k_is_in_isr()) {
441 			/* NOTE: Based on Zephyr documentation when k_sem_take
442 			 * is called from ISR timeout must be set to K_NO_WAIT.
443 			 */
444 			k_timeout = K_NO_WAIT;
445 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
446 			k_timeout = K_FOREVER;
447 		} else {
448 			k_timeout = K_MSEC(timeout_ms);
449 		}
450 
451 		/* Take a semaphore */
452 		status_internal = k_sem_take(semaphore, k_timeout);
453 		status = error_converter(status_internal);
454 
455 		if (k_is_in_isr() && (status_internal == -EBUSY)) {
456 			status = CY_RSLT_SUCCESS;
457 		}
458 	}
459 
460 	return status;
461 }
462 
cy_rtos_set_semaphore(cy_semaphore_t * semaphore,bool in_isr)463 cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr)
464 {
465 	CY_UNUSED_PARAMETER(in_isr);
466 
467 	cy_rslt_t status = CY_RSLT_SUCCESS;
468 
469 	if (semaphore == NULL) {
470 		status = CY_RTOS_BAD_PARAM;
471 	} else {
472 		/* Give a semaphore */
473 		k_sem_give(semaphore);
474 	}
475 
476 	return status;
477 }
478 
cy_rtos_get_count_semaphore(cy_semaphore_t * semaphore,size_t * count)479 cy_rslt_t cy_rtos_get_count_semaphore(cy_semaphore_t *semaphore, size_t *count)
480 {
481 	cy_rslt_t status = CY_RSLT_SUCCESS;
482 
483 	if ((semaphore == NULL) || (count == NULL)) {
484 		status = CY_RTOS_BAD_PARAM;
485 	} else {
486 		*count = k_sem_count_get(semaphore);
487 	}
488 
489 	return status;
490 }
491 
cy_rtos_deinit_semaphore(cy_semaphore_t * semaphore)492 cy_rslt_t cy_rtos_deinit_semaphore(cy_semaphore_t *semaphore)
493 {
494 	cy_rslt_t status = CY_RSLT_SUCCESS;
495 
496 	if (semaphore == NULL) {
497 		status = CY_RTOS_BAD_PARAM;
498 	} else {
499 		k_sem_reset(semaphore);
500 	}
501 
502 	return status;
503 }
504 
505 
506 /*
507  *                 Events
508  */
509 
cy_rtos_init_event(cy_event_t * event)510 cy_rslt_t cy_rtos_init_event(cy_event_t *event)
511 {
512 	cy_rslt_t status = CY_RSLT_SUCCESS;
513 
514 	if (event == NULL) {
515 		status = CY_RTOS_BAD_PARAM;
516 	} else {
517 		/* Initialize an event object */
518 		k_event_init(event);
519 	}
520 
521 	return status;
522 }
523 
cy_rtos_setbits_event(cy_event_t * event,uint32_t bits,bool in_isr)524 cy_rslt_t cy_rtos_setbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
525 {
526 	CY_UNUSED_PARAMETER(in_isr);
527 
528 	cy_rslt_t status = CY_RSLT_SUCCESS;
529 
530 	if (event == NULL) {
531 		status = CY_RTOS_BAD_PARAM;
532 	} else {
533 		/* Post the new bits */
534 		k_event_post(event, bits);
535 	}
536 
537 	return status;
538 }
539 
cy_rtos_clearbits_event(cy_event_t * event,uint32_t bits,bool in_isr)540 cy_rslt_t cy_rtos_clearbits_event(cy_event_t *event, uint32_t bits, bool in_isr)
541 {
542 	CY_UNUSED_PARAMETER(in_isr);
543 
544 	cy_rslt_t status = CY_RSLT_SUCCESS;
545 
546 	if (event == NULL) {
547 		status = CY_RTOS_BAD_PARAM;
548 	} else {
549 		uint32_t current_bits;
550 
551 		/* Reads events value */
552 		status = cy_rtos_getbits_event(event, &current_bits);
553 
554 		/* Set masked value */
555 		k_event_set(event, (~bits & current_bits));
556 	}
557 
558 	return status;
559 }
560 
cy_rtos_getbits_event(cy_event_t * event,uint32_t * bits)561 cy_rslt_t cy_rtos_getbits_event(cy_event_t *event, uint32_t *bits)
562 {
563 	cy_rslt_t status = CY_RSLT_SUCCESS;
564 
565 	if ((event == NULL) || (bits == NULL)) {
566 		status = CY_RTOS_BAD_PARAM;
567 	} else {
568 		/* NOTE: Zephyr does not provide function for get bits,
569 		 * retrieve it from event object.
570 		 */
571 		*bits = event->events;
572 	}
573 
574 	return status;
575 }
576 
cy_rtos_waitbits_event(cy_event_t * event,uint32_t * bits,bool clear,bool all,cy_time_t timeout)577 cy_rslt_t cy_rtos_waitbits_event(cy_event_t *event, uint32_t *bits, bool clear, bool all,
578 				 cy_time_t timeout)
579 {
580 	cy_rslt_t status;
581 
582 	if ((event == NULL) || (bits == NULL)) {
583 		status = CY_RTOS_BAD_PARAM;
584 	} else {
585 		uint32_t wait_for = *bits;
586 		k_timeout_t k_timeout =
587 			(timeout == CY_RTOS_NEVER_TIMEOUT) ? K_FOREVER : K_MSEC(timeout);
588 
589 		if (all) {
590 			/* Wait for all of the specified events */
591 			*bits = k_event_wait_all(event, wait_for, false, k_timeout);
592 		} else {
593 			/* Wait for any of the specified events */
594 			*bits = k_event_wait(event, wait_for, false, k_timeout);
595 		}
596 
597 		/* Check timeout */
598 		status = (*bits == 0) ? CY_RTOS_TIMEOUT : CY_RSLT_SUCCESS;
599 
600 		/* Return full current events */
601 		cy_rtos_getbits_event(event, bits);
602 
603 		/* Crear bits if required */
604 		if ((status == CY_RSLT_SUCCESS) && (clear == true)) {
605 			cy_rtos_clearbits_event(event, wait_for, false);
606 		}
607 	}
608 	return status;
609 }
610 
cy_rtos_deinit_event(cy_event_t * event)611 cy_rslt_t cy_rtos_deinit_event(cy_event_t *event)
612 {
613 	cy_rslt_t status = CY_RSLT_SUCCESS;
614 
615 	if (event != NULL) {
616 		/* Clear event */
617 		k_event_set(event, 0);
618 	} else {
619 		status = CY_RTOS_BAD_PARAM;
620 	}
621 	return status;
622 }
623 
624 
625 /*
626  *                 Queues
627  */
628 
cy_rtos_init_queue(cy_queue_t * queue,size_t length,size_t itemsize)629 cy_rslt_t cy_rtos_init_queue(cy_queue_t *queue, size_t length, size_t itemsize)
630 {
631 	cy_rtos_error_t status_internal;
632 	cy_rslt_t status;
633 
634 	if (queue == NULL) {
635 		status = CY_RTOS_BAD_PARAM;
636 	} else {
637 		/* Initialize a message queue */
638 		status_internal = k_msgq_alloc_init(queue, itemsize, length);
639 		status = error_converter(status_internal);
640 	}
641 
642 	return status;
643 }
644 
cy_rtos_put_queue(cy_queue_t * queue,const void * item_ptr,cy_time_t timeout_ms,bool in_isr)645 cy_rslt_t cy_rtos_put_queue(cy_queue_t *queue, const void *item_ptr, cy_time_t timeout_ms,
646 			    bool in_isr)
647 {
648 	CY_UNUSED_PARAMETER(in_isr);
649 
650 	cy_rtos_error_t status_internal;
651 	cy_rslt_t status;
652 
653 	if ((queue == NULL) || (item_ptr == NULL)) {
654 		status = CY_RTOS_BAD_PARAM;
655 	} else {
656 		/* Convert timeout value */
657 		k_timeout_t k_timeout;
658 
659 		if (k_is_in_isr()) {
660 			k_timeout = K_NO_WAIT;
661 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
662 			k_timeout = K_FOREVER;
663 		} else {
664 			k_timeout = K_MSEC(timeout_ms);
665 		}
666 
667 		/* Send a message to a message queue */
668 		status_internal = k_msgq_put(queue, item_ptr, k_timeout);
669 		status = error_converter(status_internal);
670 	}
671 
672 	return status;
673 }
674 
cy_rtos_get_queue(cy_queue_t * queue,void * item_ptr,cy_time_t timeout_ms,bool in_isr)675 cy_rslt_t cy_rtos_get_queue(cy_queue_t *queue, void *item_ptr, cy_time_t timeout_ms, bool in_isr)
676 {
677 	CY_UNUSED_PARAMETER(in_isr);
678 
679 	cy_rtos_error_t status_internal;
680 	cy_rslt_t status;
681 
682 	if ((queue == NULL) || (item_ptr == NULL)) {
683 		status = CY_RTOS_BAD_PARAM;
684 	} else {
685 		/* Convert timeout value */
686 		k_timeout_t k_timeout;
687 
688 		if (k_is_in_isr()) {
689 			k_timeout = K_NO_WAIT;
690 		} else if (timeout_ms == CY_RTOS_NEVER_TIMEOUT) {
691 			k_timeout = K_FOREVER;
692 		} else {
693 			k_timeout = K_MSEC(timeout_ms);
694 		}
695 
696 		/* Receive a message from a message queue */
697 		status_internal = k_msgq_get(queue, item_ptr, k_timeout);
698 		status = error_converter(status_internal);
699 	}
700 
701 	return status;
702 }
703 
cy_rtos_count_queue(cy_queue_t * queue,size_t * num_waiting)704 cy_rslt_t cy_rtos_count_queue(cy_queue_t *queue, size_t *num_waiting)
705 {
706 	cy_rslt_t status = CY_RSLT_SUCCESS;
707 
708 	if ((queue == NULL) || (num_waiting == NULL)) {
709 		status = CY_RTOS_BAD_PARAM;
710 	} else {
711 		/* Get the number of messages in a message queue */
712 		*num_waiting = k_msgq_num_used_get(queue);
713 	}
714 
715 	return status;
716 }
717 
cy_rtos_space_queue(cy_queue_t * queue,size_t * num_spaces)718 cy_rslt_t cy_rtos_space_queue(cy_queue_t *queue, size_t *num_spaces)
719 {
720 	cy_rslt_t status = CY_RSLT_SUCCESS;
721 
722 	if ((queue == NULL) || (num_spaces == NULL)) {
723 		status = CY_RTOS_BAD_PARAM;
724 	} else {
725 		/* Get the amount of free space in a message queue */
726 		*num_spaces = k_msgq_num_free_get(queue);
727 	}
728 
729 	return status;
730 }
731 
cy_rtos_reset_queue(cy_queue_t * queue)732 cy_rslt_t cy_rtos_reset_queue(cy_queue_t *queue)
733 {
734 	cy_rslt_t status = CY_RSLT_SUCCESS;
735 
736 	if (queue == NULL) {
737 		status = CY_RTOS_BAD_PARAM;
738 	} else {
739 		/* Reset a message queue */
740 		k_msgq_purge(queue);
741 	}
742 
743 	return status;
744 }
745 
cy_rtos_deinit_queue(cy_queue_t * queue)746 cy_rslt_t cy_rtos_deinit_queue(cy_queue_t *queue)
747 {
748 	cy_rtos_error_t status_internal;
749 	cy_rslt_t status;
750 
751 	if (queue == NULL) {
752 		status = CY_RTOS_BAD_PARAM;
753 	} else {
754 		/* Reset a message queue */
755 		status = cy_rtos_reset_queue(queue);
756 
757 		if (status == CY_RSLT_SUCCESS) {
758 			/* Release allocated buffer for a queue */
759 			status_internal = k_msgq_cleanup(queue);
760 			status = error_converter(status_internal);
761 		}
762 	}
763 
764 	return status;
765 }
766 
767 
768 /*
769  *                 Timers
770  */
zephyr_timer_event_handler(struct k_timer * timer)771 static void zephyr_timer_event_handler(struct k_timer *timer)
772 {
773 	cy_timer_t *_timer = (cy_timer_t *)timer;
774 
775 	((cy_timer_callback_t)_timer->callback_function)(
776 		(cy_timer_callback_arg_t)_timer->arg);
777 }
778 
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)779 cy_rslt_t cy_rtos_init_timer(cy_timer_t *timer, cy_timer_trigger_type_t type,
780 			     cy_timer_callback_t fun, cy_timer_callback_arg_t arg)
781 {
782 	cy_rslt_t status = CY_RSLT_SUCCESS;
783 
784 	if ((timer == NULL) || (fun == NULL)) {
785 		status = CY_RTOS_BAD_PARAM;
786 	} else {
787 		timer->callback_function = (void *)fun;
788 		timer->trigger_type = (uint32_t)type;
789 		timer->arg = (void *)arg;
790 
791 		k_timer_init(&timer->z_timer, zephyr_timer_event_handler, NULL);
792 	}
793 
794 	return status;
795 }
796 
cy_rtos_start_timer(cy_timer_t * timer,cy_time_t num_ms)797 cy_rslt_t cy_rtos_start_timer(cy_timer_t *timer, cy_time_t num_ms)
798 {
799 	cy_rslt_t status = CY_RSLT_SUCCESS;
800 
801 	if (timer == NULL) {
802 		status = CY_RTOS_BAD_PARAM;
803 	} else {
804 		if ((cy_timer_trigger_type_t)timer->trigger_type == CY_TIMER_TYPE_ONCE) {
805 			/* Called once only */
806 			k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_NO_WAIT);
807 		} else {
808 			/* Called periodically until stopped */
809 			k_timer_start(&timer->z_timer, K_MSEC(num_ms), K_MSEC(num_ms));
810 		}
811 	}
812 
813 	return status;
814 }
815 
cy_rtos_stop_timer(cy_timer_t * timer)816 cy_rslt_t cy_rtos_stop_timer(cy_timer_t *timer)
817 {
818 	cy_rslt_t status = CY_RSLT_SUCCESS;
819 
820 	if (timer == NULL) {
821 		status = CY_RTOS_BAD_PARAM;
822 	} else {
823 		/* Stop timer */
824 		k_timer_stop(&timer->z_timer);
825 	}
826 
827 	return status;
828 }
829 
cy_rtos_is_running_timer(cy_timer_t * timer,bool * state)830 cy_rslt_t cy_rtos_is_running_timer(cy_timer_t *timer, bool *state)
831 {
832 	cy_rslt_t status = CY_RSLT_SUCCESS;
833 
834 	if ((timer == NULL) || (state == NULL)) {
835 		status = CY_RTOS_BAD_PARAM;
836 	} else {
837 		/* Check if running */
838 		*state = (k_timer_remaining_get(&timer->z_timer) != 0u);
839 	}
840 
841 	return status;
842 }
843 
cy_rtos_deinit_timer(cy_timer_t * timer)844 cy_rslt_t cy_rtos_deinit_timer(cy_timer_t *timer)
845 {
846 	cy_rslt_t status;
847 
848 	if (timer == NULL) {
849 		status = CY_RTOS_BAD_PARAM;
850 	} else {
851 		bool running;
852 
853 		/* Get current timer state */
854 		status = cy_rtos_is_running_timer(timer, &running);
855 
856 		/* Check if running */
857 		if ((status == CY_RSLT_SUCCESS) && (running)) {
858 			/* Stop timer */
859 			status = cy_rtos_stop_timer(timer);
860 		}
861 	}
862 
863 	return status;
864 }
865 
866 
867 /*
868  *                 Time
869  */
870 
cy_rtos_get_time(cy_time_t * tval)871 cy_rslt_t cy_rtos_get_time(cy_time_t *tval)
872 {
873 	cy_rslt_t status = CY_RSLT_SUCCESS;
874 
875 	if (tval == NULL) {
876 		status = CY_RTOS_BAD_PARAM;
877 	} else {
878 		/* Get system uptime (32-bit version) */
879 		*tval = k_uptime_get_32();
880 	}
881 
882 	return status;
883 }
884 
cy_rtos_delay_milliseconds(cy_time_t num_ms)885 cy_rslt_t cy_rtos_delay_milliseconds(cy_time_t num_ms)
886 {
887 	cy_rslt_t status = CY_RSLT_SUCCESS;
888 
889 	if (k_is_in_isr()) {
890 		status = CY_RTOS_GENERAL_ERROR;
891 	} else {
892 		k_msleep(num_ms);
893 	}
894 
895 	return status;
896 }
897 
898 #if defined(__cplusplus)
899 }
900 #endif
901