1 /*
2  * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "esp_private/wifi.h"
8 #include "soc/soc_caps.h"
9 #include "esp_attr.h"
10 #include "esp32s3/rom/ets_sys.h"
11 #include "esp_heap_adapter.h"
12 #include "esp_timer.h"
13 #include "soc/rtc.h"
14 #include "esp_private/esp_clk.h"
15 #include "private/esp_coexist_adapter.h"
16 #include "soc/system_reg.h"
17 
18 #include <zephyr/logging/log.h>
19 LOG_MODULE_REGISTER(esp32_coex_adapter, CONFIG_WIFI_LOG_LEVEL);
20 
esp_wifi_free(void * mem)21 void esp_wifi_free(void *mem)
22 {
23 	esp_wifi_free_func(mem);
24 }
25 
esp_coex_common_env_is_chip_wrapper(void)26 bool IRAM_ATTR esp_coex_common_env_is_chip_wrapper(void)
27 {
28 #ifdef CONFIG_IDF_ENV_FPGA
29     return false;
30 #else
31     return true;
32 #endif
33 }
34 
esp_coex_common_spin_lock_create_wrapper(void)35 void * esp_coex_common_spin_lock_create_wrapper(void)
36 {
37 	unsigned int *wifi_spin_lock = (unsigned int *) wifi_malloc(sizeof(unsigned int));
38 	if (wifi_spin_lock == NULL) {
39 		LOG_ERR("spin_lock_create_wrapper allocation failed");
40 	}
41 
42 	return (void *)wifi_spin_lock;
43 }
44 
esp_coex_common_int_disable_wrapper(void * wifi_int_mux)45 uint32_t IRAM_ATTR esp_coex_common_int_disable_wrapper(void *wifi_int_mux)
46 {
47 	unsigned int *int_mux = (unsigned int *) wifi_int_mux;
48 
49 	*int_mux = irq_lock();
50 	return 0;
51 }
52 
esp_coex_common_int_restore_wrapper(void * wifi_int_mux,uint32_t tmp)53 void IRAM_ATTR esp_coex_common_int_restore_wrapper(void *wifi_int_mux, uint32_t tmp)
54 {
55 	unsigned int *key = (unsigned int *) wifi_int_mux;
56 
57 	irq_unlock(*key);
58 }
59 
esp_coex_common_task_yield_from_isr_wrapper(void)60 void IRAM_ATTR esp_coex_common_task_yield_from_isr_wrapper(void)
61 {
62 	k_yield();
63 }
64 
esp_coex_common_semphr_create_wrapper(uint32_t max,uint32_t init)65 void * esp_coex_common_semphr_create_wrapper(uint32_t max, uint32_t init)
66 {
67 	struct k_sem *sem = (struct k_sem *) wifi_malloc(sizeof(struct k_sem));
68 
69 	if (sem == NULL) {
70 		LOG_ERR("semphr_create_wrapper allocation failed");
71 	}
72 
73 	k_sem_init(sem, init, max);
74 
75 	return (void *) sem;
76 }
77 
esp_coex_common_semphr_delete_wrapper(void * semphr)78 void esp_coex_common_semphr_delete_wrapper(void *semphr)
79 {
80 	esp_wifi_free(semphr);
81 }
82 
esp_coex_common_semphr_take_wrapper(void * semphr,uint32_t block_time_tick)83 int32_t esp_coex_common_semphr_take_wrapper(void *semphr, uint32_t block_time_tick)
84 {
85 	if (block_time_tick == OSI_FUNCS_TIME_BLOCKING) {
86 		int ret = k_sem_take((struct k_sem *)semphr, K_FOREVER);
87 		if (ret == 0) {
88 			return 1;
89 		}
90 	} else {
91 		int ret = k_sem_take((struct k_sem *)semphr, K_TICKS(block_time_tick));
92 
93 		if (ret == 0) {
94 			return 1;
95 		}
96 	}
97 	return 0;
98 }
99 
esp_coex_common_semphr_give_wrapper(void * semphr)100 int32_t esp_coex_common_semphr_give_wrapper(void *semphr)
101 {
102 	k_sem_give((struct k_sem *) semphr);
103 	return 1;
104 }
105 
esp_coex_common_timer_disarm_wrapper(void * timer)106 void IRAM_ATTR esp_coex_common_timer_disarm_wrapper(void *timer)
107 {
108 	ets_timer_disarm(timer);
109 }
110 
esp_coex_common_timer_done_wrapper(void * ptimer)111 void esp_coex_common_timer_done_wrapper(void *ptimer)
112 {
113 	ets_timer_done(ptimer);
114 }
115 
esp_coex_common_timer_setfn_wrapper(void * ptimer,void * pfunction,void * parg)116 void esp_coex_common_timer_setfn_wrapper(void *ptimer, void *pfunction, void *parg)
117 {
118 	ets_timer_setfn(ptimer, pfunction, parg);
119 }
120 
esp_coex_common_timer_arm_us_wrapper(void * ptimer,uint32_t us,bool repeat)121 void IRAM_ATTR esp_coex_common_timer_arm_us_wrapper(void *ptimer, uint32_t us, bool repeat)
122 {
123 	ets_timer_arm_us(ptimer, us, repeat);
124 }
125 
esp_coex_common_malloc_internal_wrapper(size_t size)126 void * IRAM_ATTR esp_coex_common_malloc_internal_wrapper(size_t size)
127 {
128 	return wifi_malloc(size);
129 }
130 
esp_coex_common_clk_slowclk_cal_get_wrapper(void)131 uint32_t esp_coex_common_clk_slowclk_cal_get_wrapper(void)
132 {
133     /* The bit width of WiFi light sleep clock calibration is 12 while the one of
134      * system is 19. It should shift 19 - 12 = 7.
135     */
136     if (GET_PERI_REG_MASK(SYSTEM_BT_LPCK_DIV_FRAC_REG, SYSTEM_LPCLK_SEL_XTAL)) {
137         uint64_t time_per_us = 1000000ULL;
138         return (((time_per_us << RTC_CLK_CAL_FRACT) / (MHZ(1))) >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH));
139     } else {
140         return (esp_clk_slowclk_cal_get() >> (RTC_CLK_CAL_FRACT - SOC_WIFI_LIGHT_SLEEP_CLK_WIDTH));
141     }
142 }
143 
144 /* static wrapper */
145 
esp_coex_semphr_take_from_isr_wrapper(void * semphr,void * hptw)146 static int32_t IRAM_ATTR esp_coex_semphr_take_from_isr_wrapper(void *semphr, void *hptw)
147 {
148 	int *hpt = (int *) hptw;
149 
150 	int ret = k_sem_take((struct k_sem *)semphr, K_NO_WAIT);
151 
152 	if (ret == 0) {
153 		return 1;
154 	}
155 
156 	*hpt = 0;
157 	return 0;
158 }
159 
esp_coex_semphr_give_from_isr_wrapper(void * semphr,void * hptw)160 static int32_t IRAM_ATTR esp_coex_semphr_give_from_isr_wrapper(void *semphr, void *hptw)
161 {
162 	int *hpt = (int *) hptw;
163 
164 	k_sem_give((struct k_sem *)semphr);
165 
166 	*hpt = 0;
167 	return 0;
168 }
169 
esp_coexist_debug_matrix_init_wrapper(int evt,int sig,bool rev)170 static int esp_coexist_debug_matrix_init_wrapper(int evt, int sig, bool rev)
171 {
172 #if CONFIG_ESP_COEX_GPIO_DEBUG
173     return esp_coexist_debug_matrix_init(evt, sig, rev);
174 #else
175     return ESP_ERR_NOT_SUPPORTED;
176 #endif
177 }
178 
coex_is_in_isr_wrapper(void)179 int32_t IRAM_ATTR coex_is_in_isr_wrapper(void)
180 {
181 	return k_is_in_isr();
182 }
183 
184 coex_adapter_funcs_t g_coex_adapter_funcs = {
185     ._version = COEX_ADAPTER_VERSION,
186     ._task_yield_from_isr = esp_coex_common_task_yield_from_isr_wrapper,
187     ._semphr_create = esp_coex_common_semphr_create_wrapper,
188     ._semphr_delete = esp_coex_common_semphr_delete_wrapper,
189     ._semphr_take_from_isr = esp_coex_semphr_take_from_isr_wrapper,
190     ._semphr_give_from_isr = esp_coex_semphr_give_from_isr_wrapper,
191     ._semphr_take = esp_coex_common_semphr_take_wrapper,
192     ._semphr_give = esp_coex_common_semphr_give_wrapper,
193     ._is_in_isr = coex_is_in_isr_wrapper,
194     ._malloc_internal =  esp_coex_common_malloc_internal_wrapper,
195     ._free = esp_wifi_free,
196     ._esp_timer_get_time = esp_timer_get_time,
197     ._timer_disarm = esp_coex_common_timer_disarm_wrapper,
198     ._timer_done = esp_coex_common_timer_done_wrapper,
199     ._timer_setfn = esp_coex_common_timer_setfn_wrapper,
200     ._timer_arm_us = esp_coex_common_timer_arm_us_wrapper,
201     ._debug_matrix_init = esp_coexist_debug_matrix_init_wrapper,
202     ._magic = COEX_ADAPTER_MAGIC,
203 };
204