Expand description
esp32-wroom-rp
This crate is an Espressif ESP32-WROOM WiFi module communications driver for RP2040 series microcontroller implemented in Rust. It currently supports the ESP32-WROOM-32E and ESP32-WROOM-32UE modules. Future implementations intend to add support for the ESP32-WROOM-DA module.
It’s intended to communicate with recent versions of most Arduino-derived WiFiNINA firmwares that run on an ESP32-WROOM-XX WiFi module. For example, Adafruit makes such WiFi hardware, referred to as the Airlift, and maintains its firmware.
This driver is implemented on top of embedded-hal, which makes it platform-independent, but is currently only intended to be used with rp2040-hal for your application.
Please see the README.md for details on where to obtain and how to connect your RP2040-based device (e.g. Pico) to your ESP32-WROOM-XX WiFi board.
Once connected, note that all communication with the WiFi board occurs via a SPI bus. As the example below (and all examples under the directory cross/
)
show, you first need to create an embedded_hal::spi::Spi
instance. See the rp2040-hal documentation along
with the datasheet for your device on what specific SPI ports are available to you.
You’ll also need to reserve 4 important GPIO pins (3 output, 1 input) that are used to mediate communication between the two boards. The examples
also demonstrate how to do this through instantiating an instance of esp32_wroom_rp::gpio::EspControlPins
.
NOTE: This crate is still under active development. This API will remain volatile until 1.0.0.
§Usage
First add this to your Cargo.toml
[dependencies]
esp32_wroom_rp = 0.3.0
...
Next:
// The macro for our start-up function
use cortex_m_rt::entry;
// Needed for debug output symbols to be linked in binary image
use defmt_rtt as _;
use panic_probe as _;
// Alias for our HAL crate
use rp2040_hal as hal;
use embedded_hal::spi::MODE_0;
use fugit::RateExtU32;
use hal::clocks::Clock;
use hal::pac;
use esp32_wroom_rp::gpio::EspControlPins;
use esp32_wroom_rp::wifi::Wifi;
// The linker will place this boot block at the start of our program image. We
// need this to help the ROM bootloader get our code up and running.
#[link_section = ".boot2"]
#[used]
pub static BOOT2: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25Q080;
// External high-speed crystal on the Raspberry Pi Pico board is 12 MHz. Adjust
// if your board has a different frequency
const XTAL_FREQ_HZ: u32 = 12_000_000u32;
// Entry point to our bare-metal application.
//
// The `#[entry]` macro ensures the Cortex-M start-up code calls this function
// as soon as all global variables are initialized.
#[entry]
fn main() -> ! {
// Grab our singleton objects
let mut pac = pac::Peripherals::take().unwrap();
let core = pac::CorePeripherals::take().unwrap();
// Set up the watchdog driver - needed by the clock setup code
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);
// Configure the clocks
let clocks = hal::clocks::init_clocks_and_plls(
XTAL_FREQ_HZ,
pac.XOSC,
pac.CLOCKS,
pac.PLL_SYS,
pac.PLL_USB,
&mut pac.RESETS,
&mut watchdog,
)
.ok()
.unwrap();
let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
// The single-cycle I/O block controls our GPIO pins
let sio = hal::Sio::new(pac.SIO);
// Set the pins to their default state
let pins = hal::gpio::Pins::new(
pac.IO_BANK0,
pac.PADS_BANK0,
sio.gpio_bank0,
&mut pac.RESETS,
);
defmt::info!("ESP32-WROOM-RP get NINA firmware version example");
// These are implicitly used by the spi driver if they are in the correct mode
let _spi_miso = pins.gpio16.into_mode::<hal::gpio::FunctionSpi>();
let _spi_sclk = pins.gpio18.into_mode::<hal::gpio::FunctionSpi>();
let _spi_mosi = pins.gpio19.into_mode::<hal::gpio::FunctionSpi>();
let spi = hal::Spi::<_, _, 8>::new(pac.SPI0);
// Exchange the uninitialized SPI driver for an initialized one
let spi = spi.init(
&mut pac.RESETS,
clocks.peripheral_clock.freq(),
8.MHz(),
&MODE_0,
);
let esp_pins = EspControlPins {
// CS on pin x (GPIO7)
cs: pins.gpio7.into_mode::<hal::gpio::PushPullOutput>(),
// GPIO0 on pin x (GPIO2)
gpio0: pins.gpio2.into_mode::<hal::gpio::PushPullOutput>(),
// RESETn on pin x (GPIO11)
resetn: pins.gpio11.into_mode::<hal::gpio::PushPullOutput>(),
// ACK on pin x (GPIO10)
ack: pins.gpio10.into_mode::<hal::gpio::FloatingInput>(),
};
let mut wifi = Wifi::init(spi, esp_pins, &mut delay).unwrap();
let firmware_version = wifi.firmware_version();
defmt::info!("NINA firmware version: {:?}", firmware_version);
// Infinitely sit in a main loop
loop {}
}
§More examples
Please refer to the cross/
directory in this crate’s source for examples that demonstrate how to use every part of its public API.
Modules§
- gpio
- GPIO pin control interface of a connected ESP32-WROOM target WiFi board.
- network
- Defines common network functions, types and error definitions.
- protocol
- Defines functions, types and error definitions related to the WiFiNINA protocol communication specification.
- tcp_
client - Send/receive data to/from a TCP server and associated types.
- wifi
- Perform common core WiFi functions such as join a network, resolve a DNS hostname, etc.
Structs§
- Firmware
Version - A structured representation of a connected NINA firmware device’s version number (e.g. 1.7.4).
Enums§
- Error
- Highest level error types for this crate.