Skip to content

Commit

Permalink
Merge pull request #2893 from cesanta/picow
Browse files Browse the repository at this point in the history
Add Pico-W example
  • Loading branch information
cpq authored Sep 12, 2024
2 parents eb6a8af + 8b3e415 commit f0e113a
Show file tree
Hide file tree
Showing 14 changed files with 443 additions and 0 deletions.
29 changes: 29 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.13)
include(pico-sdk/pico_sdk_init.cmake)

project(firmware)
pico_sdk_init()

add_executable(firmware
driver_pico-w.c
main.c
mongoose.c
net.c
packed_fs.c
)

target_include_directories(firmware PUBLIC
.
)

target_link_libraries(firmware hardware_pio hardware_dma pico_stdlib cyw43_driver_picow)
pico_add_extra_outputs(firmware) # create map/bin/hex file etc.

pico_enable_stdio_usb(firmware 1) # Route stdio
pico_enable_stdio_uart(firmware 0) # to USB

# Mongoose build flags in mongoose_config.h

# Example build options
add_definitions(-DHTTP_URL="http://0.0.0.0/")

22 changes: 22 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
RM = rm -rf
MKBUILD = rm -rf build && mkdir -p build # test -d build || mkdir build
ifeq ($(OS),Windows_NT)
RM = cmd /C del /Q /F /S
MKBUILD = if not exist build mkdir build
endif

all example:
true

build: pico-sdk build/firmware.uf2

build/firmware.uf2:
$(MKBUILD)
cd build && cmake -G "Unix Makefiles" .. && make

pico-sdk:
git clone --depth 1 -b 1.5.1 https://github.com/raspberrypi/pico-sdk $@
cd $@ && git submodule update --init

clean:
$(RM) pico-sdk build
4 changes: 4 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

# Mongoose on PICO W


164 changes: 164 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/cyw43_configport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
/*
* Copyright (c) 2022 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/

// This header is included by cyw43_driver to setup its environment

// THIS FILE HAS BEEN EDITED, ORIGINAL FILE IN PICO-SDK

#ifndef _CYW43_CONFIGPORT_H
#define _CYW43_CONFIGPORT_H

#include "boards/pico_w.h"
#include "hardware/gpio.h"
#include "pico/error.h"
#include "pico/time.h"

#ifdef __cplusplus
extern "C" {
#endif

// Use our own TCP/IP stack
#define CYW43_LWIP 0

#ifndef CYW43_HOST_NAME
#define CYW43_HOST_NAME "Mongoose"
#endif

#ifndef CYW43_GPIO
#define CYW43_GPIO 1
#endif

#ifndef CYW43_LOGIC_DEBUG
#define CYW43_LOGIC_DEBUG 0
#endif

#ifndef CYW43_USE_OTP_MAC
#define CYW43_USE_OTP_MAC 1
#endif

#ifndef CYW43_NO_NETUTILS
#define CYW43_NO_NETUTILS 1
#endif

#ifndef CYW43_IOCTL_TIMEOUT_US
#define CYW43_IOCTL_TIMEOUT_US 1000000
#endif

#ifndef CYW43_USE_STATS
#define CYW43_USE_STATS 0
#endif

// todo should this be user settable?
#ifndef CYW43_HAL_MAC_WLAN0
#define CYW43_HAL_MAC_WLAN0 0
#endif

#ifndef STATIC
#define STATIC static
#endif

#ifndef CYW43_USE_SPI
#define CYW43_USE_SPI 1
#endif

#ifndef CYW43_SPI_PIO
#define CYW43_SPI_PIO 1
#endif

#ifndef CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE
#if CYW43_ENABLE_BLUETOOTH
#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "wb43439A0_7_95_49_00_combined.h"
#else
#define CYW43_CHIPSET_FIRMWARE_INCLUDE_FILE "w43439A0_7_95_49_00_combined.h"
#endif
#endif

#ifndef CYW43_WIFI_NVRAM_INCLUDE_FILE
#define CYW43_WIFI_NVRAM_INCLUDE_FILE "wifi_nvram_43439.h"
#endif

// Note, these are negated, because cyw43_driver negates them before returning!
#define CYW43_EPERM (-PICO_ERROR_NOT_PERMITTED) // Operation not permitted
#define CYW43_EIO (-PICO_ERROR_IO) // I/O error
#define CYW43_EINVAL (-PICO_ERROR_INVALID_ARG) // Invalid argument
#define CYW43_ETIMEDOUT (-PICO_ERROR_TIMEOUT) // Connection timed out

#define CYW43_NUM_GPIOS CYW43_WL_GPIO_COUNT

#define cyw43_hal_pin_obj_t uint

// get the number of elements in a fixed-size array
#define CYW43_ARRAY_SIZE(a) count_of(a)

static inline uint32_t cyw43_hal_ticks_us(void) {
return time_us_32();
}

static inline uint32_t cyw43_hal_ticks_ms(void) {
return to_ms_since_boot(get_absolute_time());
}

static inline int cyw43_hal_pin_read(cyw43_hal_pin_obj_t pin) {
return gpio_get(pin);
}

static inline void cyw43_hal_pin_low(cyw43_hal_pin_obj_t pin) {
gpio_clr_mask(1 << pin);
}

static inline void cyw43_hal_pin_high(cyw43_hal_pin_obj_t pin) {
gpio_set_mask(1 << pin);
}

#define CYW43_HAL_PIN_MODE_INPUT (GPIO_IN)
#define CYW43_HAL_PIN_MODE_OUTPUT (GPIO_OUT)

#define CYW43_HAL_PIN_PULL_NONE (0)
#define CYW43_HAL_PIN_PULL_UP (1)
#define CYW43_HAL_PIN_PULL_DOWN (2)

static inline void cyw43_hal_pin_config(cyw43_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, __unused uint32_t alt) {
assert((mode == CYW43_HAL_PIN_MODE_INPUT || mode == CYW43_HAL_PIN_MODE_OUTPUT) && alt == 0);
gpio_set_dir(pin, mode);
gpio_set_pulls(pin, pull == CYW43_HAL_PIN_PULL_UP, pull == CYW43_HAL_PIN_PULL_DOWN);
}

void cyw43_hal_get_mac(int idx, uint8_t buf[6]);

void cyw43_hal_generate_laa_mac(int idx, uint8_t buf[6]);


// documentation is king
#define CYW43_THREAD_ENTER
#define CYW43_THREAD_EXIT
#define CYW43_THREAD_LOCK_CHECK

// ??? and the ';' at the end is needed
#define CYW43_SDPCM_SEND_COMMON_WAIT (void) 0;
#define CYW43_DO_IOCTL_WAIT (void) 0;

#define cyw43_delay_ms sleep_ms
#define cyw43_delay_us sleep_us
static inline void cyw43_schedule_internal_poll_dispatch(void (*func)(void)){
(void)func; // do nothing, we'll call it anyway
}

#define CYW43_POST_POLL_HOOK

// Allow malloc and free to be changed
#ifndef cyw43_malloc
#define cyw43_malloc malloc
#endif
#ifndef cyw43_free
#define cyw43_free free
#endif

#ifdef __cplusplus
}
#endif


#endif
79 changes: 79 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/driver_pico-w.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2024 Cesanta Software Limited
// All rights reserved

#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#include "pico/stdlib.h"
#include "pico/unique_id.h"
#include "cyw43.h"
#include "cyw43_country.h"

#include "mongoose.h"
#include "driver_pico-w.h"


static struct mg_tcpip_if *s_ifp;

static bool mg_tcpip_driver_pico_w_init(struct mg_tcpip_if *ifp) {
struct mg_tcpip_driver_pico_w_data *d = (struct mg_tcpip_driver_pico_w_data *) ifp->driver_data;
s_ifp = ifp;
// initialize WiFi chip and connect to network
cyw43_init(&cyw43_state);
cyw43_wifi_set_up(&cyw43_state, CYW43_ITF_STA, true, CYW43_COUNTRY_WORLDWIDE);
cyw43_wifi_join(&cyw43_state, strlen(d->ssid), d->ssid, strlen(d->pass), d->pass, CYW43_AUTH_WPA2_AES_PSK, NULL, CYW43_ITF_STA);
cyw43_wifi_get_mac(&cyw43_state, CYW43_ITF_STA, ifp->mac);
return true;
}

static size_t mg_tcpip_driver_pico_w_tx(const void *buf, size_t len,
struct mg_tcpip_if *ifp) {
return cyw43_send_ethernet(&cyw43_state, CYW43_ITF_STA, len, buf, false) ? 0 : len;
(void) ifp;
}

static bool mg_tcpip_driver_pico_w_up(struct mg_tcpip_if *ifp) {
return cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA) == CYW43_LINK_JOIN ? 1 : 0;
}

void driver_pico_w_poll(void) {
cyw43_poll();
}

struct mg_tcpip_driver mg_tcpip_driver_pico_w = {
mg_tcpip_driver_pico_w_init,
mg_tcpip_driver_pico_w_tx,
NULL,
mg_tcpip_driver_pico_w_up,
};

void cyw43_cb_tcpip_init(cyw43_t *self, int itf) {}
void cyw43_cb_tcpip_deinit(cyw43_t *self, int itf) {}
void cyw43_cb_tcpip_set_link_up(cyw43_t *self, int itf) {}
void cyw43_cb_tcpip_set_link_down(cyw43_t *self, int itf) {}

// Called once per outstanding frame during a call to cyw43_poll
void cyw43_cb_process_ethernet(void *cb_data, int itf, size_t len, const uint8_t *buf) {
if (itf != CYW43_ITF_STA) return;
mg_tcpip_qwrite((void *) buf, len, s_ifp);
(void) cb_data;
}

// Return mac address
void cyw43_hal_get_mac(__unused int idx, uint8_t buf[6]) {
memcpy(buf, cyw43_state.mac, 6);
}

// Generate a mac address if one is not set in otp
void cyw43_hal_generate_laa_mac(__unused int idx, uint8_t buf[6]) {
pico_unique_board_id_t board_id;
MG_DEBUG(("No MAC in cyw43 OTP, generated from board id"));
pico_get_unique_board_id(&board_id);
memcpy(buf, &board_id.id[2], 6);
buf[0] &= (uint8_t)~0x1; // unicast
buf[0] |= 0x2; // locally administered
}

// there's life beyond lwIP
void pbuf_copy_partial(void){(void)0;}
10 changes: 10 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/driver_pico-w.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#pragma once

struct mg_tcpip_driver_pico_w_data {
char *ssid;
char *pass;
};

extern struct mg_tcpip_driver mg_tcpip_driver_pico_w;

void driver_pico_w_poll(void);
52 changes: 52 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// Copyright (c) 2024 Cesanta Software Limited
// All rights reserved

#include "pico/stdlib.h"

#include "mongoose.h"
#include "net.h"

#include "driver_pico-w.h"

#define WIFI_SSID "yourWiFiSSID"
#define WIFI_PASS "yourWiFiPassword"


int main(void) {
// initialize stdio
stdio_init_all();

struct mg_mgr mgr; // Initialise Mongoose event manager
mg_mgr_init(&mgr); // and attach it to the interface
mg_log_set(MG_LL_DEBUG); // Set log level

// Initialise WiFi creds
struct mg_tcpip_driver_pico_w_data driver_data = {
.ssid = WIFI_SSID,
.pass = WIFI_PASS
};
// Initialise Mongoose network stack
// Either set use_dhcp or enter a static config.
// For static configuration, specify IP/mask/GW in network byte order
struct mg_tcpip_if mif = {
.ip = 0,
.driver = &mg_tcpip_driver_pico_w,
.driver_data = &driver_data,
.recv_queue.size = 8192
};

mg_tcpip_init(&mgr, &mif);
MG_INFO(("Init done, starting main loop"));

MG_INFO(("Initialising application..."));
web_init(&mgr);

MG_INFO(("Starting event loop"));
for (;;) {
driver_pico_w_poll();
mg_mgr_poll(&mgr, 0);
}

return 0;
}

1 change: 1 addition & 0 deletions examples/rp2040/pico-w-sdk-builtin/mongoose.c
1 change: 1 addition & 0 deletions examples/rp2040/pico-w-sdk-builtin/mongoose.h
5 changes: 5 additions & 0 deletions examples/rp2040/pico-w-sdk-builtin/mongoose_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#define MG_ARCH MG_ARCH_RP2040

#define MG_ENABLE_TCPIP 1
#define MG_ENABLE_TCPIP_DRIVER_INIT 0
#define MG_ENABLE_PACKED_FS 1
1 change: 1 addition & 0 deletions examples/rp2040/pico-w-sdk-builtin/net.c
1 change: 1 addition & 0 deletions examples/rp2040/pico-w-sdk-builtin/net.h
1 change: 1 addition & 0 deletions examples/rp2040/pico-w-sdk-builtin/packed_fs.c
Loading

0 comments on commit f0e113a

Please sign in to comment.