1 /*
2  * Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _PICO_CYW43_DRIVER_H
8 #define _PICO_CYW43_DRIVER_H
9 
10 /** \file pico/cyw43_driver.h
11  *  \defgroup pico_cyw43_driver pico_cyw43_driver
12  *
13  * \brief A wrapper around the lower level cyw43_driver, that integrates it with \ref pico_async_context
14  * for handling background work
15  */
16 
17 #include "pico.h"
18 
19 #if CYW43_PIN_WL_DYNAMIC
20 #include "cyw43_configport.h"
21 #endif
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 struct async_context;
28 
29 /*! \brief Initializes the lower level cyw43_driver and integrates it with the provided async_context
30  *  \ingroup pico_cyw43_driver
31  *
32  *  If the initialization succeeds, \ref lwip_nosys_deinit() can be called to shutdown lwIP support
33  *
34  * \param context the async_context instance that provides the abstraction for handling asynchronous work.
35  * \return true if the initialization succeeded
36 */
37 bool cyw43_driver_init(struct async_context *context);
38 
39 /*! \brief De-initialize the lowever level cyw43_driver and unhooks it from the async_context
40  *  \ingroup pico_cyw43_driver
41  *
42  * \param context the async_context the cyw43_driver support was added to via \ref cyw43_driver_init
43 */
44 void cyw43_driver_deinit(struct async_context *context);
45 
46 // PICO_CONFIG: CYW43_PIO_CLOCK_DIV_DYNAMIC, Enable runtime configuration of the clock divider for communication with the wireless chip, type=bool, default=0, group=pico_cyw43_driver
47 #ifndef CYW43_PIO_CLOCK_DIV_DYNAMIC
48 #define CYW43_PIO_CLOCK_DIV_DYNAMIC 0
49 #endif
50 
51 // PICO_CONFIG: CYW43_PIO_CLOCK_DIV_INT, Integer part of the clock divider for communication with the wireless chip, type=int, default=2, group=pico_cyw43_driver
52 #ifndef CYW43_PIO_CLOCK_DIV_INT
53 // backwards compatibility using old define
54 #ifdef CYW43_PIO_CLOCK_DIV
55 #define CYW43_PIO_CLOCK_DIV_INT CYW43_PIO_CLOCK_DIV
56 #else
57 #define CYW43_PIO_CLOCK_DIV_INT 2
58 #endif
59 #endif
60 
61 // PICO_CONFIG: CYW43_PIO_CLOCK_DIV_FRAC8, Fractional part of the clock divider for communication with the wireless chip 0-255, type=int, min=0, max=255, default=0, group=pico_cyw43_driver
62 #ifndef CYW43_PIO_CLOCK_DIV_FRAC8
63 #ifdef CYW43_PIO_CLOCK_DIV_FRAC
64 #define CYW43_PIO_CLOCK_DIV_FRAC8 CYW43_PIO_CLOCK_DIV_FRAC
65 #else
66 #define CYW43_PIO_CLOCK_DIV_FRAC8 0
67 #endif
68 #endif
69 
70 // PICO_CONFIG: CYW43_PIN_WL_DYNAMIC, flag to indicate if cyw43 SPI pins can be changed at runtime, type=bool, advanced=true, group=pico_cyw43_driver
71 
72 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_REG_ON, gpio pin to power up the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
73 
74 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_OUT, gpio pin for spi data out to the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
75 
76 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_DATA_IN, gpio pin for spi data in from the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
77 
78 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_HOST_WAKE, gpio (irq) pin for the irq line from the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
79 
80 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CLOCK, gpio pin for the spi clock line to the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
81 
82 // PICO_CONFIG: CYW43_DEFAULT_PIN_WL_CS, gpio pin for the spi chip select to the cyw43 chip, type=int, min=0, max=47 on RP2350B, 29 otherwise, advanced=true, group=pico_cyw43_driver
83 
84 #if CYW43_PIO_CLOCK_DIV_DYNAMIC
85 /*! \brief Set the clock divisor for the cyw43 pio clock
86  *  \ingroup pico_cyw43_driver
87  *
88  * SPI is used to communicate with the CYW43 device and this is implemented using a PIO running with a divisor of 2.
89  * If the system clock is changed it may be necessary to adjust for this to allow communications to succeed.
90  * This function is only available if \ref CYW43_PIO_CLOCK_DIV_DYNAMIC is true
91  *
92  * \param clock_div_int Integer part of the divisor
93  * \param clock_div_frac8 Fractional part in 1/256ths
94 */
95 void cyw43_set_pio_clkdiv_int_frac8(uint32_t clock_div_int, uint8_t clock_div_frac8);
96 
97 // backwards compatibility
cyw43_set_pio_clock_divisor(uint16_t clock_div_int,uint8_t clock_div_frac8)98 static inline void cyw43_set_pio_clock_divisor(uint16_t clock_div_int, uint8_t clock_div_frac8) {
99     return cyw43_set_pio_clkdiv_int_frac8(clock_div_int, clock_div_frac8);
100 }
101 #endif
102 
103 #if CYW43_PIN_WL_DYNAMIC
104 /*! \brief Set the gpio pins for the communication with the cyw43 device
105  *  \ingroup pico_cyw43_driver
106  *
107  * Set or change the pins used to communicate with the cyw43 device
108  * This function is only available if \ref CYW43_PIN_WL_DYNAMIC is true
109  *
110  * \note The cyw43 driver should not be de-initialised before this function is called or else the behaviour is undefined.
111  *
112  * \param pins An array containing the gpio pins to use
113  * \return PICO_OK if the pin configuration could be changed and is valid
114 */
115 int cyw43_set_pins_wl(uint pins[CYW43_PIN_INDEX_WL_COUNT]);
116 #endif
117 
118 #ifdef __cplusplus
119 }
120 #endif
121 #endif
122