1 /***********************************************************************************************//**
2 * \file cybsp_wifi.c
3 *
4 * \brief
5 * Provides utility functions that are used by board support packages.
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 "cybsp.h"
28 #include "cybsp_wifi.h"
29 #include "cy_network_buffer.h"
30 #include "cyabs_rtos.h"
31 #include "whd_types.h"
32 #include "cyhal.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 /**
39 * \addtogroup group_bsp_wifi
40 * \{
41 * Macros to abstract out whether the LEDs & Buttons are wired high or active low.
42 */
43
44 /** Defines the amount of stack memory available for the wifi thread. */
45 #if !defined(CY_WIFI_THREAD_STACK_SIZE)
46 #define CY_WIFI_THREAD_STACK_SIZE (5120)
47 #endif
48
49 /** Defines the priority of the thread that services wifi packets. Legal values are defined by the
50 * RTOS being used.
51 */
52 #if !defined(CY_WIFI_THREAD_PRIORITY)
53 #define CY_WIFI_THREAD_PRIORITY (CY_RTOS_PRIORITY_HIGH)
54 #endif
55
56 /** Defines the country this will operate in for wifi initialization parameters. See the
57 * wifi-host-driver's whd_country_code_t for legal options.
58 */
59 #if !defined(CY_WIFI_COUNTRY)
60 #define CY_WIFI_COUNTRY (WHD_COUNTRY_AUSTRALIA)
61 #endif
62
63 /** Defines the priority of the interrupt that handles out-of-band notifications from the wifi
64 * chip. Legal values are defined by the MCU running this code.
65 */
66 #if !defined(CY_WIFI_OOB_INTR_PRIORITY)
67 #define CY_WIFI_OOB_INTR_PRIORITY (2)
68 #endif
69
70 /** Defines whether to use the out-of-band pin to allow the WIFI chip to wake up the MCU. */
71 #if defined(CY_WIFI_HOST_WAKE_SW_FORCE)
72 #define CY_USE_OOB_INTR (CY_WIFI_HOST_WAKE_SW_FORCE)
73 #else
74 #define CY_USE_OOB_INTR (1u)
75 #endif // defined(CY_WIFI_HOST_WAKE_SW_FORCE)
76
77 /** \} group_bsp_wifi */
78
79 #define DEFAULT_OOB_PIN (0)
80 #define WLAN_POWER_UP_DELAY_MS (250)
81 #define WLAN_CBUCK_DISCHARGE_MS (10)
82
83 #if defined(COMPONENT_WIFI_INTERFACE_SDIO) || \
84 defined(COMPONENT_WIFI_INTERFACE_SPI) || \
85 defined(COMPONENT_WIFI_INTERFACE_M2M)
86
87 // Old versions of the BSP performed WIFI SDIO init as part of cybsp_init() this has been replaced
88 // with just minimal resource reservation when needed in the latest versions of BSPs.
89 #define CYBSP_WIFI_SDIO_NEEDS_INIT (1)
90
91 #else
92
93 #if (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SDIO_INTERFACE)
94 #define COMPONENT_WIFI_INTERFACE_SDIO
95 #elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_SPI_INTERFACE)
96 #define COMPONENT_WIFI_INTERFACE_SPI
97 #elif (CYBSP_WIFI_INTERFACE_TYPE == CYBSP_M2M_INTERFACE)
98 #define COMPONENT_WIFI_INTERFACE_M2M
99 #else
100 // For old versions of HAL/BSP fallback to the default interface
101 #define COMPONENT_WIFI_INTERFACE_SDIO
102 #endif
103
104 #endif // if defined(COMPONENT_WIFI_INTERFACE_SDIO) || defined(COMPONENT_WIFI_INTERFACE_SPI) ||
105 // defined(COMPONENT_WIFI_INTERFACE_M2M)
106
107 #if !defined(COMPONENT_WIFI_INTERFACE_M2M)
108
109 #define SDIO_ENUMERATION_TRIES (500)
110 #define SDIO_RETRY_DELAY_MS (1)
111 #define SDIO_BUS_LEVEL_MAX_RETRIES (5)
112
113 #define SDIO_FREQ_25MHZ (25000000)
114 #define SDIO_FREQ_50MHZ (50000000)
115
116 // Switching to 1.8 Request / Switching to 1.8V Accepted
117 #define SDIO_CMD5_S18R_BIT (1UL << 24)
118 // Number of I/O functions position in CMD5 response (R4)
119 #define SDIO_CMD5_RESP_IO_FUNC_POS (28)
120 // Mask of I/O Number in CMD5 response (R4). This field is 3-bit wide
121 #define SDIO_CMD5_RESP_IO_FUNC_MSK (0x7)
122 // The IO OCR register mask in CMD5 request / response (R4)
123 #define SDIO_CMD5_IO_OCR_MSK (0x00FFFFFFUL)
124 // C bit in CMD5 response. Set to 1 if Card is ready to operate after initialization
125 #define SDIO_CMD5_RESP_IORDY (1UL << 31)
126
127 // Per SDIO Specification - IO_RW_DIRECT Command (CMD52)
128
129 // This bit determines the direction of the I/O operation. If this bit is 0, this command shall read
130 // data from the SDIO
131 #define SDIO_CMD52_ARG_RW_READ (0)
132 #define SDIO_CMD52_ARG_RW_WRITE (1)
133 // The Read after Write flag. If this bit is set to 1 and the R/W flag is set to 1, then the command
134 // shall read the value of the register after the write
135 #define SDIO_CMD52_ARG_RAW_NOT_SET (0)
136 #define SDIO_CMD52_ARG_RAW_SET (1)
137 // The number of the function within the I/O card you wish to read or write. Function 0 selects the
138 // common I/O area (CIA)
139 #define SDIO_FUNC_NUM_0 (0)
140
141 // Per SDIO Specification -Card Common Control Registers (CCCR)
142
143 // Bus Speed Select register
144 #define SDIO_CMD52_CCCR_SPEED_SLCT_ADDR (0x00013)
145 // Select High Speed by setting BSS0 bit
146 #define SDIO_CMD52_CCCR_SPEED_SLCT_HS (0x2)
147
148 // Per SDIO specification - IO_RW_DIRECT Response (R5)
149
150 // | Start | Dir | CMD Index | Stuff | Response Flags Bit | Read or Write Data | CRC7 | End |
151 // ------------------------------------------------------------------------------------------
152 // | 1 | 1 | 6 | 16 | 8 | 8 | 7 | 1 |
153
154 // Expected response for High Speed support check command
155 // | CMD=DAT lines free | High-Speed support |
156 // | 00010000b | 00000001b |
157 #define SDIO_CMD52_CCCR_SPEED_SELECT_RESP_HS_SUPPORTED (0x00001001)
158 // Expected response for High Speed support check command
159 // | CMD=DAT lines free | HS/SDR25 activated |
160 // | 00010000b | 00000010b |
161 #define SDIO_CMD52_CCCR_SPEED_SELECT_RESP_HS_SELECTED (0x00001002)
162
163 // *SUSPEND-FORMATTING*
164 #if (CY_USE_OOB_INTR != 0)
165 // Setup configuration based on configurator or BSP, where configurator has precedence.
166 #if defined(CYCFG_WIFI_HOST_WAKE_ENABLED)
167 #define CY_WIFI_HOST_WAKE_GPIO CYCFG_WIFI_HOST_WAKE_GPIO
168 #define CY_WIFI_HOST_WAKE_IRQ_EVENT CYCFG_WIFI_HOST_WAKE_IRQ_EVENT
169 #else
170 // Setup host-wake pin
171 #if defined(CYBSP_WIFI_HOST_WAKE)
172 #define CY_WIFI_HOST_WAKE_GPIO CYBSP_WIFI_HOST_WAKE
173 #else
174 #error "CYBSP_WIFI_HOST_WAKE must be defined"
175 #endif
176 // Setup host-wake irq
177 #if defined(CYBSP_WIFI_HOST_WAKE_IRQ_EVENT)
178 #define CY_WIFI_HOST_WAKE_IRQ_EVENT CYBSP_WIFI_HOST_WAKE_IRQ_EVENT
179 #else
180 #error "CYBSP_WIFI_HOST_WAKE_IRQ_EVENT must be defined"
181 #endif
182 #endif // if defined(CYCFG_WIFI_HOST_WAKE_ENABLED)
183 #else // if (CY_USE_OOB_INTR != 0)
184 #define CY_WIFI_HOST_WAKE_GPIO CYHAL_NC_PIN_VALUE
185 #define CY_WIFI_HOST_WAKE_IRQ_EVENT 0
186 #endif // (CY_USE_OOB_INTR != 0)
187 // *RESUME-FORMATTING*
188
189 // Add compatability for HAL 1.x
190 #if !defined(CYHAL_API_VERSION)
191 typedef cyhal_transfer_t cyhal_sdio_transfer_type_t;
192 #define CYHAL_SDIO_XFER_TYPE_READ CYHAL_READ
193 #define CYHAL_SDIO_XFER_TYPE_WRITE CYHAL_WRITE
194 #endif
195
196 #endif // if !defined(COMPONENT_WIFI_INTERFACE_M2M)
197
198 static whd_driver_t whd_drv;
199
200 extern whd_resource_source_t resource_ops;
201
202 static whd_init_config_t init_config_default =
203 {
204 .thread_stack_size = CY_WIFI_THREAD_STACK_SIZE,
205 .thread_stack_start = NULL,
206 .thread_priority = (uint32_t)CY_WIFI_THREAD_PRIORITY,
207 .country = CY_WIFI_COUNTRY
208 };
209
210 static whd_buffer_funcs_t buffer_if_default =
211 {
212 .whd_host_buffer_get = cy_host_buffer_get,
213 .whd_buffer_release = cy_buffer_release,
214 .whd_buffer_get_current_piece_data_pointer = cy_buffer_get_current_piece_data_pointer,
215 .whd_buffer_get_current_piece_size = cy_buffer_get_current_piece_size,
216 .whd_buffer_set_size = cy_buffer_set_size,
217 .whd_buffer_add_remove_at_front = cy_buffer_add_remove_at_front,
218 };
219
220 static whd_netif_funcs_t netif_if_default =
221 {
222 .whd_network_process_ethernet_data = cy_network_process_ethernet_data,
223 };
224
225 #if !defined(COMPONENT_WIFI_INTERFACE_M2M)
226 static const whd_oob_config_t OOB_CONFIG =
227 {
228 .host_oob_pin = CY_WIFI_HOST_WAKE_GPIO,
229 .dev_gpio_sel = DEFAULT_OOB_PIN,
230 .is_falling_edge = (CY_WIFI_HOST_WAKE_IRQ_EVENT == CYHAL_GPIO_IRQ_FALL)
231 ? WHD_TRUE
232 : WHD_FALSE,
233 .intr_priority = CY_WIFI_OOB_INTR_PRIORITY
234 };
235
236
237 //--------------------------------------------------------------------------------------------------
238 // _cybsp_wifi_reset_wifi_chip
239 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_reset_wifi_chip(void)240 static void _cybsp_wifi_reset_wifi_chip(void)
241 {
242 // WiFi into reset
243 // Allow CBUCK regulator to discharge
244 (void)cyhal_system_delay_ms(WLAN_CBUCK_DISCHARGE_MS);
245 // WiFi out of reset
246 cyhal_gpio_write(CYBSP_WIFI_WL_REG_ON, true);
247 (void)cyhal_system_delay_ms(WLAN_POWER_UP_DELAY_MS);
248 }
249
250
251 #endif // if !defined(COMPONENT_WIFI_INTERFACE_M2M)
252
253
254 #if defined(COMPONENT_WIFI_INTERFACE_SDIO)
255 //--------------------------------------------------------------------------------------------------
256 // _cybsp_wifi_sdio_try_send_cmd
257 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_sdio_try_send_cmd(cyhal_sdio_t * sdio_object,cyhal_sdio_transfer_type_t direction,cyhal_sdio_command_t command,uint32_t argument,uint32_t * response)258 static cy_rslt_t _cybsp_wifi_sdio_try_send_cmd(cyhal_sdio_t* sdio_object,
259 cyhal_sdio_transfer_type_t direction,
260 cyhal_sdio_command_t command, uint32_t argument,
261 uint32_t* response)
262 {
263 uint8_t loop_count = 0;
264 cy_rslt_t result = CYBSP_RSLT_WIFI_SDIO_ENUM_TIMEOUT;
265 do
266 {
267 result = cyhal_sdio_send_cmd(sdio_object, direction, command, argument, response);
268 if (result != CY_RSLT_SUCCESS)
269 {
270 cyhal_system_delay_ms(SDIO_RETRY_DELAY_MS);
271 }
272 loop_count++;
273 } while((result != CY_RSLT_SUCCESS) && (loop_count <= SDIO_BUS_LEVEL_MAX_RETRIES));
274 return result;
275 }
276
277
278 #if !defined(CYHAL_UDB_SDIO)
279 //--------------------------------------------------------------------------------------------------
280 // _cybsp_wifi_create_cmd_52_arg
281 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_create_cmd_52_arg(uint8_t rw,uint8_t func,uint8_t raw,uint32_t addr,uint8_t data)282 static uint32_t _cybsp_wifi_create_cmd_52_arg(uint8_t rw, uint8_t func, uint8_t raw, uint32_t addr,
283 uint8_t data)
284 {
285 return (((rw & 0x01) << 31) /* set R/W flag */
286 | ((func & 0x07) << 28) /* set the function number */
287 | ((raw & 0x01) << 27) /* set the RAW flag */
288 | ((addr & 0x1FFFF) << 9) /* set the address */
289 | data); /* set the data */
290 }
291
292
293 #endif /* !defined(CYHAL_UDB_SDIO) */
294
295 //--------------------------------------------------------------------------------------------------
296 // _cybsp_wifi_sdio_card_init
297 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_sdio_card_init(cyhal_sdio_t * sdio_object)298 static cy_rslt_t _cybsp_wifi_sdio_card_init(cyhal_sdio_t* sdio_object)
299 {
300 cy_rslt_t result;
301 uint32_t loop_count = 0;
302 uint32_t rel_addr;
303
304 uint32_t response = 0;
305 uint32_t no_argument = 0;
306
307 #if !defined(CYHAL_UDB_SDIO)
308 uint32_t argument = 0;
309 uint32_t io_num = 0;
310 bool abort_sdio = false;
311 #else
312 const bool abort_sdio = false;
313 #endif /* !defined(CYHAL_UDB_SDIO) */
314
315 do
316 {
317 // Send CMD0 to set it to idle state
318 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_WRITE,
319 CYHAL_SDIO_CMD_GO_IDLE_STATE,
320 no_argument, &response /*ignored*/);
321
322 // CMD5.
323 if (result == CY_RSLT_SUCCESS)
324 {
325 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_READ,
326 CYHAL_SDIO_CMD_IO_SEND_OP_COND,
327 no_argument,
328 &response /*ignored on UDB-based SDIO*/);
329 }
330
331 // UDB-based SDIO does not support io volt switch sequence
332 #if !defined(CYHAL_UDB_SDIO)
333 if (result == CY_RSLT_SUCCESS)
334 {
335 // Check number of IO functions, that are supported by device
336 io_num = (response >> SDIO_CMD5_RESP_IO_FUNC_POS) & SDIO_CMD5_RESP_IO_FUNC_MSK;
337 if (io_num > 0)
338 {
339 // Sending 1.8V switch request
340 argument = (response & SDIO_CMD5_IO_OCR_MSK) | SDIO_CMD5_S18R_BIT;
341
342 // CMD5.
343 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_WRITE,
344 CYHAL_SDIO_CMD_IO_SEND_OP_COND,
345 argument, &response);
346
347 if (CY_RSLT_SUCCESS == result)
348 {
349 // IORDY = 1 (Card is ready to operate)
350 if (response & SDIO_CMD5_RESP_IORDY)
351 {
352 // Switching to 1.8V accepted
353 if (response & SDIO_CMD5_S18R_BIT)
354 {
355 // CMD11.
356 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object,
357 CYHAL_SDIO_XFER_TYPE_WRITE,
358 CYHAL_SDIO_CMD_VOLTAGE_SWITCH,
359 no_argument,
360 &response);
361
362 if (CY_RSLT_SUCCESS == result)
363 {
364 #if defined(CYBSP_WIFI_SDIO_VOLT_SEL)
365 cyhal_gpio_t io_volt_sel_pin = CYBSP_WIFI_SDIO_VOLT_SEL;
366 #else
367 // No actual voltage switch will be done as no pin provided.
368 cyhal_gpio_t io_volt_sel_pin = NC;
369 #endif /* defined(CYBSP_WIFI_SDIO_VOLT_SEL) */
370
371 // Perform voltage switch sequence
372 // And, if pin provided, switch the voltage
373 result = cyhal_sdio_set_io_voltage(sdio_object, io_volt_sel_pin,
374 CYHAL_SDIO_IO_VOLTAGE_1_8V,
375 CYHAL_SDIO_IO_VOLT_ACTION_SWITCH_SEQ_ONLY);
376
377 if (CYHAL_SDIO_RSLT_ERR_UNSUPPORTED == result)
378 {
379 // Changing IO voltage is not supported by current
380 // implementation. No reason to try again.
381 abort_sdio = true;
382 }
383 }
384 }
385 // Nothing to do for 'else'. 1.8V is not supported.
386 }
387 else
388 {
389 result = CYBSP_RSLT_WIFI_SDIO_ENUM_NOT_READY;
390 }
391 }
392 }
393 else
394 {
395 result = CYBSP_RSLT_WIFI_SDIO_ENUM_IO_NOT_SUPPORTED;
396 // IO is not supported by this SD device, no reason to try enumeration again
397 abort_sdio = true;
398 }
399 }
400 #endif /* !defined(CYHAL_UDB_SDIO) */
401
402 if (CY_RSLT_SUCCESS == result)
403 {
404 // Send CMD3 to get RCA.
405 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_READ,
406 CYHAL_SDIO_CMD_SEND_RELATIVE_ADDR,
407 no_argument, &rel_addr);
408 }
409
410 if ((!abort_sdio) && (result != CY_RSLT_SUCCESS))
411 {
412 cyhal_system_delay_ms(SDIO_RETRY_DELAY_MS);
413 }
414 loop_count++;
415 } while ((!abort_sdio) && (result != CY_RSLT_SUCCESS) &&
416 (loop_count <= SDIO_ENUMERATION_TRIES));
417
418 if (result == CY_RSLT_SUCCESS)
419 {
420 // Send CMD7 with the returned RCA to select the card
421 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_WRITE,
422 CYHAL_SDIO_CMD_SELECT_CARD,
423 rel_addr,
424 &response /*ignored*/);
425 }
426
427 uint32_t sdio_frequency = SDIO_FREQ_25MHZ;
428
429 // use constant 25 MHz frequency for UDB-based SDIO
430 // and perform supported speed check and switch for SDHC-based SDIO
431 #if !defined(CYHAL_UDB_SDIO)
432 if (result == CY_RSLT_SUCCESS)
433 {
434 uint32_t tmp_arg = _cybsp_wifi_create_cmd_52_arg(SDIO_CMD52_ARG_RW_READ, SDIO_FUNC_NUM_0,
435 SDIO_CMD52_ARG_RAW_NOT_SET,
436 SDIO_CMD52_CCCR_SPEED_SLCT_ADDR, 0x00);
437 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_WRITE,
438 CYHAL_SDIO_CMD_IO_RW_DIRECT,
439 tmp_arg, &response);
440
441 if (result == CY_RSLT_SUCCESS)
442 {
443 if (SDIO_CMD52_CCCR_SPEED_SELECT_RESP_HS_SUPPORTED == response)
444 {
445 tmp_arg = _cybsp_wifi_create_cmd_52_arg(SDIO_CMD52_ARG_RW_WRITE, SDIO_FUNC_NUM_0,
446 SDIO_CMD52_ARG_RAW_NOT_SET,
447 SDIO_CMD52_CCCR_SPEED_SLCT_ADDR,
448 SDIO_CMD52_CCCR_SPEED_SLCT_HS);
449 result = _cybsp_wifi_sdio_try_send_cmd(sdio_object, CYHAL_SDIO_XFER_TYPE_WRITE,
450 CYHAL_SDIO_CMD_IO_RW_DIRECT,
451 tmp_arg, &response);
452
453 if (result == CY_RSLT_SUCCESS)
454 {
455 if (SDIO_CMD52_CCCR_SPEED_SELECT_RESP_HS_SELECTED == response)
456 {
457 // High Speed mode switch allowed, configure clock frequency for 50 MHz
458 sdio_frequency = SDIO_FREQ_50MHZ;
459 }
460 }
461 else
462 {
463 result = CYBSP_RSLT_WIFI_SDIO_HS_SWITCH_FAILED;
464 }
465 }
466 }
467 }
468 #endif /* !defined(CYHAL_UDB_SDIO) */
469
470 if (result == CY_RSLT_SUCCESS)
471 {
472 cyhal_sdio_cfg_t config = { .frequencyhal_hz = sdio_frequency, .block_size = 0 };
473 result = cyhal_sdio_configure(sdio_object, &config);
474 }
475 return result;
476 }
477
478
479 //--------------------------------------------------------------------------------------------------
480 // _cybsp_wifi_sdio_init_bus2
481 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_sdio_init_bus2(cyhal_sdio_t * obj)482 static cy_rslt_t _cybsp_wifi_sdio_init_bus2(cyhal_sdio_t* obj)
483 {
484 cy_rslt_t result = _cybsp_wifi_sdio_card_init(obj);
485 if (result == CY_RSLT_SUCCESS)
486 {
487 // If the configurator reserved the pin, we need to release it here since
488 // WHD will try to reserve it again. WHD has no idea about configurators
489 // and expects it can reserve the pin that it is going to manage.
490 #if defined(CYCFG_WIFI_HOST_WAKE_ENABLED)
491 cyhal_resource_inst_t pinRsc = cyhal_utils_get_gpio_resource(CY_WIFI_HOST_WAKE_GPIO);
492 cyhal_hwmgr_free(&pinRsc);
493 #endif
494
495 whd_sdio_config_t whd_sdio_config =
496 {
497 .sdio_1bit_mode = WHD_FALSE,
498 .high_speed_sdio_clock = WHD_FALSE,
499 .oob_config = OOB_CONFIG
500 };
501 whd_bus_sdio_attach(whd_drv, &whd_sdio_config, obj);
502 }
503 return result;
504 }
505
506
507 #if defined(CYBSP_WIFI_SDIO_NEEDS_INIT)
508 static cyhal_sdio_t sdio_obj;
509 #endif
510
511 //--------------------------------------------------------------------------------------------------
512 // _cybsp_wifi_sdio_init_bus
513 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_sdio_init_bus(void)514 static cy_rslt_t _cybsp_wifi_sdio_init_bus(void)
515 {
516 #if defined(CYBSP_WIFI_SDIO_NEEDS_INIT)
517 cy_rslt_t result = cyhal_sdio_init(&sdio_obj, CYBSP_WIFI_SDIO_CMD, CYBSP_WIFI_SDIO_CLK,
518 CYBSP_WIFI_SDIO_D0, CYBSP_WIFI_SDIO_D1, CYBSP_WIFI_SDIO_D2,
519 CYBSP_WIFI_SDIO_D3);
520
521 if (result == CY_RSLT_SUCCESS)
522 {
523 result = _cybsp_wifi_sdio_init_bus2(&sdio_obj);
524 if (result != CY_RSLT_SUCCESS)
525 {
526 cyhal_sdio_free(&sdio_obj);
527 }
528 }
529 #else // if defined(CYBSP_WIFI_SDIO_NEEDS_INIT)
530 cyhal_sdio_t* sdio_p = cybsp_get_wifi_sdio_obj();
531 cy_rslt_t result = _cybsp_wifi_sdio_init_bus2(sdio_p);
532 #endif // if defined(CYBSP_WIFI_SDIO_NEEDS_INIT)
533
534 return result;
535 }
536
537
538 #elif defined(COMPONENT_WIFI_INTERFACE_SPI)
539
540 //--------------------------------------------------------------------------------------------------
541 // _cybsp_wifi_spi_init_bus
542 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_spi_init_bus(void)543 static cy_rslt_t _cybsp_wifi_spi_init_bus(void)
544 {
545 static cyhal_spi_t spi_obj;
546 cy_rslt_t rslt = cyhal_spi_init(&spi_obj,
547 CYBSP_WIFI_SPI_MOSI, CYBSP_WIFI_SPI_MISO, CYBSP_WIFI_SPI_SCLK,
548 CYBSP_WIFI_SPI_SSEL,
549 NULL, 32, CYHAL_SPI_MODE_00_MSB, false);
550 if (CY_RSLT_SUCCESS == rslt)
551 {
552 rslt = cyhal_spi_set_frequency(&spi_obj, 50000000); // 50 MHz operation
553 if (CY_RSLT_SUCCESS == rslt)
554 {
555 whd_spi_config_t whd_spi_config =
556 {
557 .is_normal_mode = false,
558 .oob_config = OOB_CONFIG
559 };
560 rslt = whd_bus_spi_attach(whd_drv, &whd_spi_config, &spi_obj);
561 }
562 else
563 {
564 cyhal_spi_free(&spi_obj);
565 }
566 }
567
568 return rslt;
569 }
570
571
572 #elif defined(COMPONENT_WIFI_INTERFACE_M2M)
573
574 static cyhal_m2m_t m2m_obj;
575
576 //--------------------------------------------------------------------------------------------------
577 // _cybsp_wifi_m2m_init_bus
578 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_m2m_init_bus(void)579 static cy_rslt_t _cybsp_wifi_m2m_init_bus(void)
580 {
581 cy_rslt_t rslt;
582
583 whd_m2m_config_t whd_m2m_config =
584 {
585 .is_normal_mode = false,
586 };
587 // Note: The m2m itself is initialized in the WHD
588 rslt = whd_bus_m2m_attach(whd_drv, &whd_m2m_config, &m2m_obj);
589
590 return rslt;
591 }
592
593
594 #endif // defined(COMPONENT_WIFI_INTERFACE_M2M)
595
596
597 //--------------------------------------------------------------------------------------------------
598 // _cybsp_wifi_bus_init
599 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_bus_init(void)600 static inline cy_rslt_t _cybsp_wifi_bus_init(void)
601 {
602 #if !defined(COMPONENT_WIFI_INTERFACE_M2M)
603 _cybsp_wifi_reset_wifi_chip();
604 #endif
605 #if defined(COMPONENT_WIFI_INTERFACE_SDIO)
606 return _cybsp_wifi_sdio_init_bus();
607 #elif defined(COMPONENT_WIFI_INTERFACE_SPI)
608 return _cybsp_wifi_spi_init_bus();
609 #elif defined(COMPONENT_WIFI_INTERFACE_M2M)
610 return _cybsp_wifi_m2m_init_bus();
611 #endif
612 }
613
614
615 //--------------------------------------------------------------------------------------------------
616 // _cybsp_wifi_bus_detach
617 //--------------------------------------------------------------------------------------------------
_cybsp_wifi_bus_detach(void)618 static inline void _cybsp_wifi_bus_detach(void)
619 {
620 #if defined(COMPONENT_WIFI_INTERFACE_SDIO)
621 whd_bus_sdio_detach(whd_drv);
622 #elif defined(COMPONENT_WIFI_INTERFACE_SPI)
623 whd_bus_spi_detach(whd_drv);
624 #elif defined(COMPONENT_WIFI_INTERFACE_M2M)
625 whd_bus_m2m_detach(whd_drv);
626 #endif
627 }
628
629
630 //--------------------------------------------------------------------------------------------------
631 // cybsp_wifi_init_primary_extended
632 //--------------------------------------------------------------------------------------------------
cybsp_wifi_init_primary_extended(whd_interface_t * interface,whd_init_config_t * init_config,whd_resource_source_t * resource_if,whd_buffer_funcs_t * buffer_if,whd_netif_funcs_t * netif_if)633 cy_rslt_t cybsp_wifi_init_primary_extended(whd_interface_t* interface,
634 whd_init_config_t* init_config,
635 whd_resource_source_t* resource_if,
636 whd_buffer_funcs_t* buffer_if,
637 whd_netif_funcs_t* netif_if)
638 {
639 #if defined(COMPONENT_WIFI_INTERFACE_M2M)
640 cy_rslt_t result = CY_RSLT_SUCCESS;
641 #else
642 cy_rslt_t result = cyhal_gpio_init(CYBSP_WIFI_WL_REG_ON, CYHAL_GPIO_DIR_OUTPUT,
643 CYHAL_GPIO_DRIVE_PULLUP, false);
644 #endif
645
646 if (result == CY_RSLT_SUCCESS)
647 {
648 if (init_config == NULL)
649 {
650 init_config = &init_config_default;
651 }
652 if (resource_if == NULL)
653 {
654 resource_if = &resource_ops;
655 }
656 if (buffer_if == NULL)
657 {
658 buffer_if = &buffer_if_default;
659 }
660 if (netif_if == NULL)
661 {
662 netif_if = &netif_if_default;
663 }
664
665 result = whd_init(&whd_drv, init_config, resource_if, buffer_if, netif_if);
666 if (result == CY_RSLT_SUCCESS)
667 {
668 result = _cybsp_wifi_bus_init();
669
670 if (result == CY_RSLT_SUCCESS)
671 {
672 result = whd_wifi_on(whd_drv, interface);
673
674 if (result != CY_RSLT_SUCCESS)
675 {
676 _cybsp_wifi_bus_detach();
677 }
678 }
679
680 if (result != CY_RSLT_SUCCESS)
681 {
682 whd_deinit(*interface);
683 }
684 }
685
686 #if !defined(COMPONENT_WIFI_INTERFACE_M2M)
687 if (result != CY_RSLT_SUCCESS)
688 {
689 cyhal_gpio_free(CYBSP_WIFI_WL_REG_ON);
690 }
691 #endif
692 }
693
694 return result;
695 }
696
697
698 //--------------------------------------------------------------------------------------------------
699 // cybsp_wifi_init_secondary
700 //--------------------------------------------------------------------------------------------------
cybsp_wifi_init_secondary(whd_interface_t * interface,whd_mac_t * mac_address)701 cy_rslt_t cybsp_wifi_init_secondary(whd_interface_t* interface, whd_mac_t* mac_address)
702 {
703 return whd_add_secondary_interface(whd_drv, mac_address, interface);
704 }
705
706
707 //--------------------------------------------------------------------------------------------------
708 // cybsp_wifi_deinit
709 //--------------------------------------------------------------------------------------------------
cybsp_wifi_deinit(whd_interface_t interface)710 cy_rslt_t cybsp_wifi_deinit(whd_interface_t interface)
711 {
712 cy_rslt_t result = whd_wifi_off(interface);
713
714 if (result == CY_RSLT_SUCCESS)
715 {
716 _cybsp_wifi_bus_detach();
717 #if !defined(COMPONENT_WIFI_INTERFACE_M2M)
718 cyhal_gpio_free(CYBSP_WIFI_WL_REG_ON);
719 #endif
720 // While deinit() takes an interface, it only uses it to get the underlying whd driver to
721 // cleanup. As a result, we only need to call this on one of the interfaces.
722 result = whd_deinit(interface);
723
724 #if defined(CYBSP_WIFI_SDIO_NEEDS_INIT)
725 if (result == CY_RSLT_SUCCESS)
726 {
727 cyhal_sdio_free(&sdio_obj);
728 }
729 #endif
730 }
731 return result;
732 }
733
734
735 //--------------------------------------------------------------------------------------------------
736 // cybsp_get_wifi_driver
737 //--------------------------------------------------------------------------------------------------
cybsp_get_wifi_driver(void)738 whd_driver_t cybsp_get_wifi_driver(void)
739 {
740 return whd_drv;
741 }
742
743
744 #if defined(__cplusplus)
745 }
746 #endif
747