Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

20 wifi support - Initial Work #22

Merged
merged 11 commits into from
Jul 19, 2024
23 changes: 10 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@ cmake_minimum_required(VERSION 3.18)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)

# Project/hardware-specific setup - set platform in project.cmake
include(build_options.cmake)

# Project/hardware-specific setup - set platform, board, and requested hardware
# options in project.cmake
include(project.cmake)

# Set the hardware directory and load any prebuild which may be present.
set(hardware_dir ${CMAKE_CURRENT_SOURCE_DIR}/hardware/${PLATFORM})
if(EXISTS ${hardware_dir}/prebuild.cmake)
include(${hardware_dir}/prebuild.cmake)
endif()

# Main project definition
project(${PROJ_NAME} C CXX ASM)

add_definitions(-DPROJECT_NAME=${PROJ_NAME}) # pass the project name to the preprocessor for use in the code
Expand Down Expand Up @@ -39,13 +46,7 @@ target_link_libraries(${PROJ_NAME} PUBLIC
cli
littlefs
cmake_git_version_tracking
hardware_i2c
hardware_spi
hardware_flash
hardware_adc
cmsis_core
tinyusb_device
${hardware_libs}
board_hal
)
target_include_directories(${PROJ_NAME} PUBLIC
${PROJECT_SOURCE_DIR}
Expand All @@ -54,20 +55,16 @@ target_include_directories(${PROJ_NAME} PUBLIC
${PROJECT_SOURCE_DIR}/driver_lib
${PROJECT_SOURCE_DIR}/littlefs/littlefs
${PROJECT_SOURCE_DIR}/git_version
${PROJECT_SOURCE_DIR}/${hardware_includes}
)

add_subdirectory(${PROJECT_SOURCE_DIR}/rtos)
add_subdirectory(${PROJECT_SOURCE_DIR}/services)
add_subdirectory(${PROJECT_SOURCE_DIR}/driver_lib)

if(DEFINED hardware_dir)
add_subdirectory(${hardware_dir})
endif()

# add any additional definitions, options
target_compile_definitions(${PROJ_NAME} PUBLIC
CFG_TUSB_CONFIG_FILE="hardware_config.h" # override standard TinyUSB config file location
)
target_compile_options(
${PROJ_NAME}
PRIVATE
Expand Down
3 changes: 3 additions & 0 deletions build_options.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This file contains all of the user-configurable option toggles for the OS.
# Options can be set to true/false here, on the command line, or through the cmake-gui tool.
option(HW_WIFI "Enable wifi support" false)
6 changes: 4 additions & 2 deletions cli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,24 @@ add_library(cli STATIC
${CMAKE_CURRENT_LIST_DIR}/node_etc.c
${CMAKE_CURRENT_LIST_DIR}/node_lib.c
)

target_link_libraries(cli PUBLIC
microshell
pico_stdlib
FreeRTOS-Kernel
cmake_git_version_tracking
board_hal
)

target_include_directories(cli PUBLIC
${CMAKE_CURRENT_LIST_DIR}
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/rtos
${PROJECT_SOURCE_DIR}/hardware/rp2040
${PROJECT_SOURCE_DIR}/driver_lib
${PROJECT_SOURCE_DIR}/services
${PROJECT_SOURCE_DIR}/littlefs/littlefs
${PROJECT_SOURCE_DIR}/git_version
)

target_compile_options(
cli
PRIVATE
Expand Down
42 changes: 35 additions & 7 deletions hardware/rp2040/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
add_library(board_hal INTERFACE)

# add source files to the top-level project
target_sources(${PROJ_NAME} PRIVATE
target_sources(board_hal INTERFACE
hardware_config.c
hw_gpio.c
hw_uart.c
Expand All @@ -16,16 +18,42 @@ target_sources(${PROJ_NAME} PRIVATE
hw_versions.c
)

target_include_directories(board_hal INTERFACE
${CMAKE_CURRENT_LIST_DIR}
)

target_link_libraries(board_hal INTERFACE
pico_stdlib
pico_unique_id
hardware_i2c
hardware_spi
hardware_flash
hardware_adc
tinyusb_device
)

target_compile_definitions(board_hal INTERFACE CFG_TUSB_CONFIG_FILE="hardware_config.h")

if(PICO_BOARD STREQUAL pico_w)
target_compile_definitions(board_hal INTERFACE USING_CYW43=1)

if(HW_WIFI)
message(STATUS "including hw_wifi and lwIP stack for pico_w")
target_compile_definitions(board_hal INTERFACE HW_WIFI=1) # cmake options come through as quoted strings for some reason
target_sources(board_hal INTERFACE hw_wifi.c)
target_link_libraries(board_hal INTERFACE pico_cyw43_arch_lwip_sys_freertos)
target_include_directories(board_hal INTERFACE ${CMAKE_CURRENT_LIST_DIR}/lwip_config)
else()
message(STATUS "lwIP stack will be unavailable : HW_WIFI set to 0")
target_compile_definitions(board_hal INTERFACE HW_WIFI=0)
target_link_libraries(board_hal INTERFACE pico_cyw43_arch_none)
endif()
endif()

function(hardware_build_extra)
# initialize the Pico/RP2040 SDK
pico_sdk_init()

if(PICO_BOARD STREQUAL "pico_w")
# Pass this parameter to the preprocessor if board type is pico_w
# since some HW config needs to change
target_compile_definitions(cli PUBLIC -DUSING_PICOW)
endif()

# disable Pico STDIO - interacting with CLI will be done via RTOS task queue only, no printf
pico_enable_stdio_usb(${PROJ_NAME} 0)
pico_enable_stdio_uart(${PROJ_NAME} 0)
Expand Down
14 changes: 7 additions & 7 deletions hardware/rp2040/hardware_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,16 @@
* @author Cavin McKinley (MCKNLY LLC)
*
* @date 02-14-2024
*
*
* @copyright Copyright (c) 2024 Cavin McKinley (MCKNLY LLC)
* Released under the MIT License
*
*
* SPDX-License-Identifier: MIT
******************************************************************************/

#include <string.h>
#include "hardware_config.h"

#ifdef USING_CYW43
#include "pico/cyw43_arch.h"
#endif

void hardware_init(void) {
// mutexes for accessing hardware peripherals (created within each hw init function)
SemaphoreHandle_t gpio_mutex = NULL;
Expand All @@ -37,7 +33,11 @@ void hardware_init(void) {
cli_uart_init();

// on pico w, we need to initialize the wifi chip
#ifdef USING_CYW43

// we only want to initialize the cyw43 arch if the hardware isn't using wifi
#if (HW_WIFI == 0) & defined(USING_CYW43)
#include "pico/cyw43_arch.h"

if(cyw43_arch_init()) {
uart_puts(UART_ID_CLI, timestamp());
uart_puts(UART_ID_CLI, "Failed to initialize CYW43 hardware.\r\n");
Expand Down
108 changes: 108 additions & 0 deletions hardware/rp2040/hw_wifi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#include "hw_wifi.h"

#include "pico/cyw43_arch.h"

bool hw_wifi_is_initialized() {
return cyw43_is_initialized(&cyw43_state);
}

bool hw_wifi_init() {
if (hw_wifi_is_initialized()) return true;
return !cyw43_arch_init();
}

bool hw_wifi_init_with_country(hw_wifi_country_t country_code) {
if (hw_wifi_is_initialized()) return true;
return !cyw43_arch_init_with_country(country_code);
}

void hw_wifi_deinit() {
if (hw_wifi_is_initialized()) return;
cyw43_arch_deinit();
}

// todo : this is locked to lwIP, and we maybe don't want that?
const ip_addr_t *hw_wifi_get_addr() {
return netif_ip4_addr(netif_list);
}

static uint32_t hw_wifi_auth_to_cyw43(hw_wifi_auth_t auth) {
switch (auth) {
case HW_WIFI_AUTH_MIXED:
return CYW43_AUTH_WPA2_MIXED_PSK;
case HW_WIFI_AUTH_WPA_TPIK_PSK:
return CYW43_AUTH_WPA_TKIP_PSK;
case HW_WIFI_AUTH_WPA2_AES_PSK:
return CYW43_AUTH_WPA2_AES_PSK;
default:
return CYW43_AUTH_OPEN;
}
}

bool hw_wifi_connect(const char *ssid, const char *password, hw_wifi_auth_t auth_type) {
uint32_t cw_auth = hw_wifi_auth_to_cyw43(auth_type);

return !cyw43_arch_wifi_connect_blocking(ssid, password, cw_auth);
}

bool hw_wifi_connect_async(const char *ssid, const char *password, hw_wifi_auth_t auth_type) {
uint32_t cw_auth = hw_wifi_auth_to_cyw43(auth_type);

return !cyw43_arch_wifi_connect_async(ssid, password, cw_auth);
}

static hw_wifi_mode_t current_mode = HW_WIFI_MODE_NONE;

// NOTE: the pico_w will _technically_ support simultaneous AP and STA mode
// connections, but this implementation does not.
void hw_wifi_enable_sta_mode() {
hw_wifi_disable_ap_mode();
cyw43_arch_enable_sta_mode();
current_mode = HW_WIFI_MODE_STA;
}

void hw_wifi_disable_sta_mode() {
if (current_mode == HW_WIFI_MODE_STA) {
cyw43_arch_disable_sta_mode();
current_mode = HW_WIFI_MODE_NONE;
}
}

void hw_wifi_enable_ap_mode(const char *ssid, const char *password, hw_wifi_auth_t auth_type) {
hw_wifi_disable_sta_mode();
cyw43_arch_enable_ap_mode(ssid, password, hw_wifi_auth_to_cyw43(auth_type));
}

void hw_wifi_disable_ap_mode() {
if (current_mode == HW_WIFI_MODE_AP) {
cyw43_arch_disable_ap_mode();
current_mode = HW_WIFI_MODE_NONE;
}
}

hw_wifi_status_t hw_wifi_get_status() {
// AP mode always returns LINKDOWN from cyw43
if (current_mode == HW_WIFI_MODE_AP) {
return HW_WIFI_STATUS_LINK_DOWN;
}

uint32_t status = cyw43_wifi_link_status(&cyw43_state, CYW43_ITF_STA);
switch (status) {
case CYW43_LINK_DOWN:
return HW_WIFI_STATUS_LINK_DOWN;
case CYW43_LINK_JOIN:
return HW_WIFI_STATUS_JOINING;
case CYW43_LINK_NOIP:
return HW_WIFI_STATUS_NOIP;
case CYW43_LINK_UP:
return HW_WIFI_STATUS_UP;
case CYW43_LINK_FAIL:
return HW_WIFI_STATUS_FAIL;
case CYW43_LINK_NONET:
return HW_WIFI_STATUS_NONET;
case CYW43_LINK_BADAUTH:
return HW_WIFI_STATUS_BADAUTH;
default:
return HW_WIFI_STATUS_UNKNOWN;
}
}
Loading