For this example we assume that the application is running stand-alone without an operating system.
Before the library can do anything it needs to start up the WiFi hardware by downloading a firmware image. The firmware image is relatively big (around 144kB) and is not included in the library since it is only needed once. It is up to the application to decide where to store the firmware image and how to read it into the wl_api library.
Step one is to write a function of the type wl_fw_download_cb_t that wl_api will call to retrive the firmware image. Assuming that you have some spare RAM on your platform you can simply include the firmware image from the fw.h header file and write a firmware read function like this
static void fw_download_cb(void* ctx, uint8_t** buf, uint32_t* len) { *buf = (uint8_t*) fw_buf; *len = fw_len; }
If the firmware image is stored in ROM this function may have to read it back block by block instead.
The wl_api library is initialized like this
if ( wl_init(NULL, fw_download_cb, init_complete_cb) != WL_SUCCESS ) { app_error("Init failed"); return 0; }
The library startup process will now require wl_poll() to be called a number of times before it can complete. In addition, if the application needs to know when the startup process has completed so that it can, for example, start up an IP stack it will have to supply a valid callback function of the type wl_init_complete_cb_t as a parameter to the wl_init() call and start polling the wl_api library.
The init complete callback will only be executed during a call to wl_poll() or another wl_api function. This simplifies the implementation since no internal locking is required and the wl_api library becomes OS-independent.
static void init_complete_cb(void* ctx) { init_ip_stack(); }
Registering the event callback is straightforward :
if (wl_register_event_cb(event_cb, NULL) != WL_SUCCESS) { app_error("Failed to register event handler"); return 0; }
The wl_poll() function takes a free running "tick" counter with millisecond resolution as an argument so that it can trigger internal timers when necessary. Assuming that such a tick counter is provided by the macro GET_MS_TICK() the wl_api execution loop becomes
while (TRUE) { wl_poll(GET_MS_TICK()); }
In a stand-alone application this loop would usually be the main application loop and include application specific calls as well.
After some number of main loop iterations the WL_EVENT_INIT_COMPLETE event is posted and the application can initialize its IP stack.
Functions | |
wl_err_t | wl_register_event_cb (wl_event_cb_t cb, void *ctx) |
Register an event handler. | |
wl_err_t | wl_init (void *ctx, wl_fw_download_cb_t fw_download_cb, wl_init_complete_cb_t init_complete_cb) |
Initialize the wl_api library. | |
void | wl_poll (uint32_t tick) |
WiFi driver forward progress function. | |
Typedefs | |
typedef void(* | wl_event_cb_t )(struct wl_event_t event, void *ctx) |
WiFi event callback. | |
typedef void(* | wl_rx_isr_t )(void *ctx) |
WiFi event callback. | |
typedef void( | wl_fw_download_cb_t )(void *ctx, uint8_t **buf, uint32_t *len) |
Firmware access function. | |
typedef void( | wl_init_complete_cb_t )(void *ctx) |
Initialization complete callback function. | |
Enumerations | |
enum | wl_err_t { WL_FAILURE = -1, WL_SUCCESS = 1, WL_OOM, WL_INVALID_LENGTH, WL_NOT_SUPPORTED, WL_ABSORBED, WL_RESOURCES, WL_BUSY, WL_RETRY, WL_INVALID_ARGS, WL_AVAIL, WL_CARD_FAILURE, WL_FIRMWARE_INVALID } |
wl_err_t wl_init | ( | void * | ctx, | |
wl_fw_download_cb_t | fw_download_cb, | |||
wl_init_complete_cb_t | init_complete_cb | |||
) |
Initialize the wl_api library.
Note that wl_poll() must be called for this function to progress towards complete init
The startup process will proceed asynchronously and will inkove init_complete_cb when completed. The callback will not be invoked if any error occurs during initialization.
ctx | Opaque context pointer that will be passed to the callbacks when they are invoked. This parameter is never accessed by the API. | |
fw_download_cb | callback function to invoke during firmware download. | |
init_complete_cb | callback function to invoke when initialization is complete. |
void wl_poll | ( | uint32_t | tick | ) |
WiFi driver forward progress function.
This function must be called in stand-alone environments to ensure forward progress. Periodic timers are triggered from this function so it should be called as often as possible if precision timing is required (traffic timeouts, authentication timeouts etc).
tick | A tick count in us. This is used to expire timers in the driver. |
wl_err_t wl_register_event_cb | ( | wl_event_cb_t | cb, | |
void * | ctx | |||
) |
Register an event handler.
Register an event handler with the driver. This event handler will be called whenever a event listed in wl_event_id_t occurs. See wl_event_cb_t and wl_event_id_t for more details.
cb | Event callback function to register. | |
ctx | Opaque context pointer that will be passed to the callback when it is invoked. This parameter is never accessed by the API. |
typedef void(* wl_event_cb_t)(struct wl_event_t event, void *ctx) |
WiFi event callback.
This function receives WiFi events that the application wants notification of. This function is supplied by the user of the API.
event | Struct describing the type of event and, for some events, additional information regarding the status of the event. See wl_event_t for additional information. | |
ctx | A context handle. This handle is passed untouched to the callback and has the same value as the context registered with the callback in wl_register_event_cb(). |
typedef void( wl_fw_download_cb_t)(void *ctx, uint8_t **buf, uint32_t *len) |
Firmware access function.
Reads the WiFi firmware image. This function is supplied by the user of this API since storage for the firmware image is managed by the application.
This function should read a number of bytes of the firmware of the firmware image. The number of remaining bytes is given as the input value of len. Upon return, buf should point to a buffer which holds the read data and len should hold the number of bytes read. Hence, len is both an input and an output parameter.
The offset where reading starts should be incremented sequentially by the ouput value of len bytes upon completion of each call.
This function will be called repeatedly until the complete firmware image has been read. The last call will have the input value of len set to 0 to indicate that no more data is needed and that any dynamically allocated buffer which holds firmware data are safe to free.
ctx | Opaque context pointer as provided to wl_init() that will be passed back to the callback. | |
buf | Should be assigned the address of the buffer holding the read data upon return. | |
len | Should hold the value of the number of bytes read upon return. |
typedef void( wl_init_complete_cb_t)(void *ctx) |
Initialization complete callback function.
Invoked when WiFi initialization is complete.
ctx | Opaque context pointer as provided to wl_init() that will be passed back to the callback. |
typedef void(* wl_rx_isr_t)(void *ctx) |
WiFi event callback.
This function is invoked in interrupt context when there is new data available from the mac. This function is supplied by the user of the API.
This function is typically used only by the TCP/IP stack driver.
ctx | A context handle. This handle is passed untouched to the callback and has the same value as the context registered with the callback in wl_register_event_cb(). |
enum wl_err_t |