Portable C driver library for communicating with the WINCS02 module via SPI.
This driver (nc_driver) provides a host-side library for the WINCS02 binary protocol over SPI. It can run on any MCU with a standard SPI peripheral — no MPLAB Harmony dependency.
driver/
├── README.md # This file
├── src/ # Core driver source (do not modify)
│ ├── *.c # 6 source files
│ └── include/ # Driver headers
├── port/ # Platform porting layer — start here
│ ├── winc_port_template.c # SPI, GPIO, init, and event-loop template
│ └── conf_winc_dev.h # Standalone configuration (bare-metal ready)
└── examples/ # Example usage
| Function | Purpose |
|---|---|
| SPI send/receive | Full-duplex SPI transfer with CS management |
| MCLR pin control | Drive reset pin low/high |
| INTOUT pin read | Check if interrupt pin is asserted (low) |
| Delay | Blocking millisecond delay |
| Debug printf | Optional but highly recommended for bring-up |
-
Copy
port/winc_port_template.cinto your project and implement the five platform functions for your MCU. -
Copy
port/conf_winc_dev.hinto your project include path. AdjustWINC_DEV_CACHE_LINE_SIZEfor your MCU (set to 1 if no cache). -
Add all
.cfiles fromsrc/and your porting file to your build. Addsrc/include/and your config file location to the include path. -
Build. The driver compiles with GCC, IAR, and XC32. No source modifications are needed.
The template file contains a complete commented-out example showing the full init sequence and event loop — uncomment and adapt for your application.
| Parameter | Value |
|---|---|
| Mode | 0 (CPOL=0, CPHA=0) |
| Bit order | MSB first |
| Max clock | 50 MHz (datasheet Table 3-11; actual max depends on layout) |
| CS control | Assert (low) at start, deassert (high) at end of each call |
| Dummy TX byte | 0xFF (WINCS02 interprets 0x00 as valid data) |
When pTransmitData is NULL, your implementation must send 0xFF for each
byte. This is the single most common cause of communication failures.
1. Platform init — configure SPI, GPIO for MCLR + INTOUT + CS
2. MCLR reset — drive low 100ms, release high
3. Wait for boot — WINCS02 takes ~3.5s to boot after MCLR release
(MISO reads 0x00 during boot, transitions to 0xFF when ready)
4. WINC_DevInit() — create driver context with receive buffer
5. WINC_SDIODeviceInit() — handshake over SPI (retry loop with 100ms delays)
6. WINC_DevBusStateSet() — set bus to ACTIVE (required before sending commands)
7. Register callbacks — WINC_DevAECCallbackRegister() for async events
8. Event loop — poll INTOUT, call WINC_DevHandleEvent() + WINC_DevUpdateEvent()
Steps 5-8 are shown in detail in winc_port_template.c.
WINC_SDIODeviceInit() returns a signed enum. Your retry loop must handle:
| Status | Value | Meaning | Action |
|---|---|---|---|
OK |
0 | Complete | Proceed to step 6 |
RESET_WAITING |
1 | Module still booting | Delay 100ms, retry |
OP_WAITING |
2 | CMD5 in progress | Delay 100ms, retry |
OP_FAILED |
-4 | CMD5 failed | Reset sdioState to UNKNOWN, retry |
RESET_FAILED |
-5 | CMD0 bad response | Check wiring, reset state, retry |
ERROR |
-2 | Unrecoverable | Hard-reset the module |
A tight retry loop without delays will burn CPU for ~3.5 seconds. Always include a delay (e.g. 100ms) between retries.
| Signal | WINCS02 Module Pin | Direction | Description |
|---|---|---|---|
| CS | 16 (CS1) | Host → Module | SPI chip select, active low |
| SCK | 18 (SCK1) | Host → Module | SPI clock |
| MOSI | 15 (SDI1) | Host → Module | SPI data in to module |
| MISO | 17 (SDO1) | Module → Host | SPI data out from module |
| MCLR | 4 | Host → Module | Master clear reset, active low |
| INTOUT | 13 | Module → Host | Interrupt request, active low, push-pull |
If using the bare WINCS02 module (not the Add-On Board), you must provide:
| Component | Pin | Value | Purpose |
|---|---|---|---|
| Pull-up resistor | MCLR (pin 4) | 10K to VDD | Holds module out of reset |
| Pull-up resistor | STRAP1 (pin 10) | 10K to VDD | Selects SPI host interface |
| Pull-up resistor | STRAP2 (pin 26) | 10K to VDD | Selects SPI host interface |
| Decoupling cap | VDD (pin 20) | 4.7uF + 0.1uF | Power supply filtering |
| Decoupling cap | VDDIO (pin 23) | 0.1uF | I/O supply filtering |
| Tristate I/O | Pin 11 (Reserved) | — | Datasheet requires connection |
The WINCS02 Add-On Board (EV68G27A) includes all of these — just connect the mikroBUS header signals and ground.
If using the add-on board, connect these mikroBUS pins to your host MCU:
| Add-On Board Pin | mikroBUS Label | Host MCU Pin | Signal |
|---|---|---|---|
| J204 pin 6 | MOSI | SPI MOSI (TX) | SPI data to module |
| J204 pin 5 | MISO | SPI MISO (RX) | SPI data from module |
| J204 pin 4 | SCK | SPI CLK | SPI clock |
| J204 pin 3 | CS | GPIO output | Chip select |
| J204 pin 2 | RST | GPIO output | MCLR reset |
| J205 pin 2 | INT | GPIO input | INTOUT interrupt |
| J204 pin 8 | GND | GND | Common ground (mandatory) |
Power the add-on board via its USB Type-C connector. Set jumper JP200 to the USB position.
For bare-metal (no RTOS), the provided port/conf_winc_dev.h works
out of the box. The lock macros are left undefined, which activates the
driver's built-in no-op defaults in winc_dev.h.
For an RTOS, define the WINC_CONF_LOCK_* macros in conf_winc_dev.h — see the
FreeRTOS example in that file.
If you are using MPLAB Harmony, use the integrated driver and services:
- wireless_wifi — WINCS02 driver at
driver/wincs02/ - wireless_system_rnwf — system services
- wireless_apps_rnwf — example applications
Note: The WINCS02 driver lives in
wireless_wifi; thewireless_system_rnwfservices layer is optional.
The driver version is defined in src/include/winc_dev.h
(WINC_DEV_DRIVER_VERSION_*) and matches the firmware release it was
generated from (currently v3.3.0). Use the driver with the matching firmware
version.
The higher-level MQTT, TLS context, firmware update and mDNS helper modules
are only provided with the MPLAB Harmony and Zephyr drivers. With this driver,
MQTT, TLS and firmware update are available through the command API
(WINC_Cmd* functions in winc_cmds.h).
See the Binary Protocol API Specification (PDF, Markdown) for the complete protocol reference.
| Symptom | Likely Cause |
|---|---|
SDIO init returns RESET_WAITING forever |
Module still booting — wait longer (needs ~3.5s after MCLR) |
SDIO init returns RESET_FAILED |
SPI wiring wrong, MOSI/MISO swapped, or CS not toggling |
| SPI test reads 0x00 after boot complete | GND not connected between boards |
| Commands sent but no AEC events received | WINC_DevBusStateSet(ACTIVE) not called, or INTOUT not polled |
WINC_DevInit() returns invalid handle |
Receive buffer is NULL or too small |
| Scan/connect commands fail silently | Command buffer freed before STATUS_COMPLETE callback |