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