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 
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/EventP.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_EVENTS 5
25 K_MEM_SLAB_DEFINE(event_slab, sizeof(struct k_event), DPL_MAX_EVENTS,\
26           MEM_ALIGN);
27 
28 
dpl_event_pool_alloc()29 static struct k_event *dpl_event_pool_alloc()
30 {
31     struct k_event *event_ptr = NULL;
32 
33     if (k_mem_slab_alloc(&event_slab, (void **)&event_ptr, K_NO_WAIT) < 0) {
34 
35          __ASSERT(0, "Increase size of DPL event pool");
36     }
37     return event_ptr;
38 }
39 
dpl_event_pool_free(struct k_event * event)40 static void dpl_event_pool_free(struct k_event *event)
41 {
42     k_mem_slab_free(&event_slab, (void *)event);
43 
44     return;
45 }
46 
47 /*
48  *  ======== EventP_create ========
49  */
EventP_create(void)50 EventP_Handle EventP_create(void)
51 {
52     struct k_event *event = dpl_event_pool_alloc();
53     k_event_init(event);
54     return (EventP_Handle) event;
55 }
56 
57 /*
58  *  ======== EventP_delete ========
59  */
EventP_delete(EventP_Handle handle)60 void EventP_delete(EventP_Handle handle)
61 {
62     if (handle != NULL)
63     {
64         dpl_event_pool_free((struct k_event *) handle);
65     }
66 }
67 
68 #endif /* CONFIG_DYNAMIC_DPL_OBJECTS */
69 
70 /*
71  *  ======== EventP_construct ========
72  */
EventP_construct(EventP_Struct * obj)73 EventP_Handle EventP_construct(EventP_Struct *obj)
74 {
75     struct k_event *event;
76     event = (struct k_event*)obj;
77 
78     if (event) {
79         k_event_init(event);
80     }
81 
82     return (EventP_Handle)event;
83 }
84 
85 /*
86  *  ======== EventP_destruct ========
87  */
EventP_destruct(EventP_Struct * obj)88 void EventP_destruct(EventP_Struct *obj)
89 {
90     struct k_event *event;
91 
92     event = (struct k_event *)obj->data;
93 
94     k_event_clear(event, 0xFFFFFFFF);
95 }
96 
97 /*
98  *  ======== EventP_pend ========
99  */
EventP_pend(EventP_Handle event,uint32_t eventMask,bool waitForAll,uint32_t timeout)100 uint32_t EventP_pend(EventP_Handle event, uint32_t eventMask, bool waitForAll, uint32_t timeout)
101 {
102     uint32_t eventBits, tickPeriod;
103     k_timeout_t eventTimeout;
104 
105 
106     if (timeout == EventP_WAIT_FOREVER)
107     {
108         eventTimeout = K_FOREVER;
109     }
110     else if (timeout == EventP_NO_WAIT)
111     {
112         eventTimeout = K_NO_WAIT;
113     }
114     else
115     {
116         /* if necessary, convert ClockP ticks to Zephyr ticks */
117         /* Should really be ClockP_getSystemTickPeriod() but this causes issues with ielftool post build step */
118         tickPeriod = ClockP_TICK_PERIOD;
119         eventTimeout = K_TICKS(timeout);
120     }
121 
122     if(waitForAll)
123     {
124        /* Wait for all event bits */
125        eventBits = k_event_wait_all((struct k_event *) event, eventMask, false, eventTimeout);
126     }
127     else
128     {
129         /* Wait for any event bits */
130         eventBits = k_event_wait((struct k_event *) event, eventMask, false, eventTimeout);
131     }
132 
133     /* Clear the events that caused the return */
134     k_event_clear((struct k_event *) event, eventBits);
135 
136     /* Check if wait returned because of timeout */
137     if (((eventBits == 0)) || ((eventBits != eventMask) && (waitForAll == true)))
138     {
139         return 0;
140     }
141     else
142     {
143         return eventBits;
144     }
145 }
146 
147 /*
148  *  ======== EventP_post ========
149  */
EventP_post(EventP_Handle event,uint32_t eventMask)150 void EventP_post(EventP_Handle event, uint32_t eventMask)
151 {
152     /* Unpend all tasks waiting for these events, and merge these events with
153        the ones already tracked by the object
154     */
155     k_event_set((struct k_event *) event, eventMask);
156 }
157 
158 /*
159  *  ======== EventP_clear ========
160  */
EventP_clear(EventP_Handle event,uint32_t eventMask)161 void EventP_clear(EventP_Handle event, uint32_t eventMask)
162 {
163     k_event_clear((struct k_event *) event, eventMask);
164 }
165 
166 /*
167  *  ======== EventP_get ========
168  */
EventP_get(EventP_Handle event)169 uint32_t EventP_get(EventP_Handle event)
170 {
171     uint32_t events = ((struct k_event *)event)->events;
172     return events;
173 }