Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

irina-nita
Copy link
Contributor

@irina-nita irina-nita commented Jul 27, 2025

Pull Request Overview

This pull request adds:

  • chips/cyw43439: support for the PIO half-duplex SPI interface for the RP2040 chip used to communicate with the CYW43439 chip available on the Raspberry Pi Pico W board
  • support in boards/raspberry_pi_pico for enabling the PIO configuration and Ethernet Tap capsule
  • hil/wifi_cyw43: minimal WiFi HIL for peripherals that interact with the CYW43439 or other similar Cypress chips. The HIL contains four traits that provide interfaces for initializing the device and getting the MAC address, scanning networks and configuring station/access point mode.

Testing Strategy

  • WiFi HIL implementation tested by scanning/connecting to/creating networks
  • Ethernet HIL tested with the libtock-c lwIP example

TODO or Help Wanted

This PR needs to add an abstract interface for communicating with the CYW4343x chips. Besides the peripheral used for reading/writing to the chip, the process should be the same

Documentation Updated

  • Updated the relevant files in /docs, or no updates are required.

Formatting

  • Ran make prepush.

Added support for the PIO half-duplex SPI interface for the
RP2040 chip to provide read/write functionalities for communicating with
the CYW43439 chip available on the Raspberry Pi Pico W board. Support
is also added in the board main. A minimal WiFi HIL for the Cypress
43439 chips was added. Both WiFi HIL and EthernetTap HIL
implementation were provided for the RP2040 PIO.
@github-actions github-actions bot added the HIL This affects a Tock HIL interface. label Jul 27, 2025
Copy link
Contributor

@alexandruradovici alexandruradovici left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really nice, just a few ideas.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest that we add a firmware folder in Tock where we put these kinds of files.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a firmware directory in root

#[no_mangle]
#[link_section = ".stack_buffer"]
static mut STACK_MEMORY: [u8; 0x1500] = [0; 0x1500];
static mut STACK_MEMORY: [u8; 0x6000] = [0; 0x6000];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way we could reduce this size? Do we inow what causes it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I missed to modify this after adding a static buffer for packet construction. Fixed it now

>;
type TemperatureDriver = components::temperature::TemperatureComponentType<TemperatureRp2040Sensor>;

const WIFI: bool = option_env!("WIFI").is_some();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about adding a a feature in and assigning WIFI to cfg?

Is there a reason why we would want to disable WiFi?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's more that we don't want capsules like Ethernet to be available for Picos without Wifi. I tried using a wifi feature at first but the Tock board Makefile doesn't provide any "cargo flags" variable. Adding that would require re-writing some of the Makefile rules and I didn't want to create any clutter. My idea was that for Pico W we'd build with WIFI=1 make

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a capsule as this chip might be uses with other microcontrollers.

sm.set_enabled(true);
}

pub fn cyw43_spi_program_init(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this just an example?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's used for initializing the PIO in cyw43439.rs

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we have a bunch of these, one more can't hurt.

// SPDX-License-Identifier: Apache-2.0 OR MIT
// Copyright OxidOS Automotive 2025.

//! Interfaces for CYW43439 WiFi devices
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we document here how these traits relate to each other and how they should be used?

Changed back the stack size. Moved firmware files to root.
Fixed bug from calling recv in the transmit_frame method
in rp2040/cyw43439.
@brghena brghena added the WG-Network In the purview of the Network working group. label Jul 28, 2025
Copy link
Contributor

@brghena brghena left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here's some quick notes from skimming this. Not a full pass yet.

@@ -0,0 +1,5 @@
# Wifi firmware blobs

Firmware obtained from https://github.com/georgerobotics/cyw43-driver/tree/main/firmware
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why from some random github project? Does Infineon or Raspberry Pi not provide them directly?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed on the call today possibly relying on an external crate for firmware blobs. Maybe the same Crate embassy uses: https://crates.io/crates/cyw43-firmware

That should probably be discussed on a Core team call for approval.

sm.set_enabled(true);
}

pub fn cyw43_spi_program_init(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we have a bunch of these, one more can't hurt.

Comment on lines +222 to +225
_2mA = 0,
_4mA = 1,
_8mA = 2,
_12mA = 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The leading underscore here is misleading. It's often used for "internal" things in other languages.

These should match the datasheet whenever possible, and to the extend possible. Maybe call them DRIVE_2MA, DRIVE_4MA, etc.?

Comment on lines +411 to +414
_2mA = 0,
_4mA = 1,
_8mA = 2,
_12mA = 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update these to match whatever the "DRIVE" values are named above if you change them.

}
}

pub static NVRAM: &[u8] = b"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also came from a source, right? That should be cited. Looks like it can be found here: https://github.com/Infineon/wifi-resources It would be good to double-check that matches though.

/// ## Arguments
///
/// - `ssid`: SSID of found network
fn scanned_network(&self, ssid: Ssid);
Copy link
Contributor

@alexandruradovici alexandruradovici Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to know what kind of encryption it uses?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be fine to put this in the board's directory.

Adding a new top-level directory is probably not something we want to do. Putting it in chips/ is potentially an option, but I think would require some discussion and a plan for what types of binary blobs are acceptable and under what situations.

Another option is to embed the bytes in a rust file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this on the Network working group call and we're considering an external crate that the CYW* WiFi capsule would rely on which would contain the binary blobs. Notably, they're licensed differently than the rest of the Tock kernel and there are some concerns there.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would probably still be easiest to include from the board, then.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems general enough to just be called wifi.rs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Event though we discussed this during type networking call, I kind of agree with @bradjc that this seems general enough. I do not see how other devices might need anything else here.

Comment on lines +270 to +304
macro_rules! impl_bytes {
($t:ident) => {
impl $t {
/// Bytes consumed by this type.
pub const SIZE: usize = core::mem::size_of::<Self>();

/// Create from byte array.
#[allow(unused)]
pub fn from_bytes(bytes: &[u8; Self::SIZE]) -> &Self {
let alignment = core::mem::align_of::<Self>();
assert_eq!(
bytes.as_ptr().align_offset(alignment),
0,
"{} is not aligned",
core::any::type_name::<Self>()
);
unsafe { core::mem::transmute(bytes) }
}

/// Create from mutable byte array.
#[allow(unused)]
pub fn from_bytes_mut(bytes: &mut [u8; Self::SIZE]) -> &mut Self {
let alignment = core::mem::align_of::<Self>();
assert_eq!(
bytes.as_ptr().align_offset(alignment),
0,
"{} is not aligned",
core::any::type_name::<Self>()
);

unsafe { core::mem::transmute(bytes) }
}
}
};
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm worried about having these unsafes here in general, and based on learning how macros work in Rust having unsafe in a macro is even more scary. It's not clear to me what impl_bytes does or how necessary it is versus using a safe approach.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file might also be copied directly from Embassy, if I recall what we discussed on the Network working group call. Maybe we should be re-implementing these for Tock.

Comment on lines +19 to +32
pub(super) fn as_bytes<T: Sized>(data: &T) -> &[u8] {
unsafe {
core::slice::from_raw_parts(
core::ptr::from_ref::<T>(data) as *const u8,
core::mem::size_of::<T>(),
)
}
}

pub(super) fn slice8_mut(x: &mut [u32]) -> &mut [u8] {
let len = x.len() * 4;
unsafe { slice::from_raw_parts_mut(x.as_mut_ptr() as _, len) }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With these unsafes I don't know how necessary they are, but it would be good to add a # Safety comment that explains why they are safe.

/// ## Arguments
///
/// - `ssid`: SSID of found network
fn scanned_network(&self, ssid: Ssid);
Copy link
Contributor

@alexandruradovici alexandruradovici Jul 28, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
fn scanned_network(&self, ssid: Ssid);
fn scanned_network(&self, ssid: Ssid, encryption: Option<Encryption>, signal_strength: Option<u8>);
#[non_exhaustive]
enum Encryption {
   Open,
   Wep,
   Wpa1,
   Wpa2,
   Wpa3,
}

signal_strength defined in abs(dBm).
Just to make it more generic.

@brghena brghena self-assigned this Jul 29, 2025
@alevy
Copy link
Member

alevy commented Sep 6, 2025

@irina-nita @alexandruradovici @JADarius This seems quite close, but waiting on some feedback. Is there a timeline/estimate/plan for this?

@irina-nita
Copy link
Contributor Author

Hey, sorry for the lack of activity on this PR. I'm currently working on wrapping up and testing the migration from chips to capsules as discussed. Because of this, some comments will become obsolete, I think. I estimate that in a few days I'll be able to push the updated version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

HIL This affects a Tock HIL interface. waiting-on-author WG-Network In the purview of the Network working group.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants