Skip to content

Commit

Permalink
Fix usb_cdc on rp2350 (#367)
Browse files Browse the repository at this point in the history
* Fix usb_cdc on rp2350

* Fix usb-cdc readme

* Fix usb-cdc readme
  • Loading branch information
patryk4815 authored Jan 28, 2025
1 parent ceefa56 commit 68b5ad1
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 14 deletions.
4 changes: 2 additions & 2 deletions examples/raspberrypi/rp2xxx/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ examples will eventually be able to run on either chip with no changes due to th
Routes the SYS clock divided by 1000 out to GPIO25.
- [watchdog timer](src/watchdog_timer.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) or [Pico2](https://www.raspberrypi.com/products/raspberry-pi-pico-2/) boards
Enables a watchdog timer for 1 second, and demonstrates the chip resetting when the watchdog timer elapses
- [usb device](src/usb_cdc.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) or [Pico2](https://www.raspberrypi.com/products/raspberry-pi-pico-2/) boards
A really basic example for a raw USB device. You can use the Python 3 script [`scripts/usb_device_loopback.py`](scripts/usb_device_loopback.py) to test the USB device.

### RP2040 Only

Expand All @@ -42,8 +44,6 @@ examples will eventually be able to run on either chip with no changes due to th
Showcases how to use the PIO to emit a basic square wave.
- [uart](src/rp2040_only/uart.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) board
Showcases how to use the UART together with `std.log`.
- [usb device](src/rp2040_only/usb_cdc.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) board
A really basic example for a raw USB device. You can use the Python 3 script [`scripts/usb_device_loopback.py`](scripts/usb_device_loopback.py) to test the USB device.
- [usb hid](src/rp2040_only/usb_hid.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) board
A really basic example how to implement a USB HID device. You can use the Python 3 script [`scripts/hid_test.py`](scripts/hid_test.py) to test the HID device.
- [ws2812](src/ws2812.zig) on the [Pico](https://www.raspberrypi.com/products/raspberry-pi-pico/) board
Expand Down
2 changes: 1 addition & 1 deletion examples/raspberrypi/rp2xxx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub fn build(b: *std.Build) void {
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_uart-echo", .file = "src/rp2040_only/uart_echo.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_uart-log", .file = "src/rp2040_only/uart_log.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_usb-hid", .file = "src/rp2040_only/usb_hid.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_usb-cdc", .file = "src/rp2040_only/usb_cdc.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_multicore", .file = "src/rp2040_only/blinky_core1.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_hd44780", .file = "src/rp2040_only/hd44780.zig" },
.{ .target = mb.ports.rp2xxx.boards.raspberrypi.pico, .name = "pico_pcf8574", .file = "src/rp2040_only/pcf8574.zig" },
Expand All @@ -49,6 +48,7 @@ pub fn build(b: *std.Build) void {
.{ .name = "custom-clock-config", .file = "src/custom_clock_config.zig" },
.{ .name = "watchdog-timer", .file = "src/watchdog_timer.zig" },
.{ .name = "pico_stepper", .file = "src/stepper.zig" },
.{ .name = "pico_usb-cdc", .file = "src/usb_cdc.zig" },
};

var available_examples = std.ArrayList(Example).init(b.allocator);
Expand Down
File renamed without changes.
1 change: 1 addition & 0 deletions port/raspberrypi/rp2xxx/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ pub fn init(dep: *std.Build.Dependency) Self {
.{ .kind = .flash, .offset = 0x10000000, .length = 2048 * 1024 },
.{ .kind = .ram, .offset = 0x20000000, .length = 256 * 1024 },
},
.patches = @import("patches/rp2350.zig").patches,
},
.hal = hal,
.linker_script = b.path("rp2350_arm.ld"),
Expand Down
47 changes: 47 additions & 0 deletions port/raspberrypi/rp2xxx/patches/rp2350.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pub const patches = &.{
.{
.add_enum = .{
.parent = "types.peripherals.USB_DPRAM",
.@"enum" = .{
.name = "EndpointType",
.bitsize = 2,
.fields = &.{
.{ .value = 0x0, .name = "control" },
.{ .value = 0x1, .name = "isochronous" },
.{ .value = 0x2, .name = "bulk" },
.{ .value = 0x3, .name = "interrupt" },
},
},
},
},
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP1_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP1_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP2_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP2_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP3_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP3_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP4_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP4_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP5_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP5_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP6_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP6_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP7_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP7_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP8_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP8_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP9_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP9_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP10_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP10_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP11_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP11_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP12_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP12_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP13_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP13_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP14_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP14_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP15_IN_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
.{ .set_enum_type = .{ .of = "types.peripherals.USB_DPRAM.EP15_OUT_CONTROL.ENDPOINT_TYPE", .to = "types.peripherals.USB_DPRAM.EndpointType" } },
};
52 changes: 43 additions & 9 deletions port/raspberrypi/rp2xxx/src/hal/rom.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@
//! 4. Debugging Support Functions (TODO)
//! 5. Miscellaneous Functions (TODO)

const std = @import("std");
const microzig = @import("microzig");
const chip = microzig.hal.compatibility.chip;

/// Function codes to lookup public functions that provide useful RP2040 functionality
pub const Code = enum(u32) {
popcount32 = rom_table_code('P', '3'),
reverse32 = rom_table_code('R', '3'),
clz32 = rom_table_code('L', '3'),
ctz32 = rom_table_code('T', '3'),
memset = rom_table_code('M', 'S'),
memset4 = rom_table_code('S', '4'),
memcpy = rom_table_code('M', 'C'),
memcpy44 = rom_table_code('C', '4'),
reset_usb_boot = rom_table_code('U', 'B'),
popcount32 = rom_table_code('P', '3'), // Only avaiable on: RP2040
reverse32 = rom_table_code('R', '3'), // Only avaiable on: RP2040
clz32 = rom_table_code('L', '3'), // Only avaiable on: RP2040
ctz32 = rom_table_code('T', '3'), // Only avaiable on: RP2040
memset = rom_table_code('M', 'S'), // Only avaiable on: RP2040
memset4 = rom_table_code('S', '4'), // Only avaiable on: RP2040
memcpy = rom_table_code('M', 'C'), // Only avaiable on: RP2040
memcpy44 = rom_table_code('C', '4'), // Only avaiable on: RP2040
connect_internal_flash = rom_table_code('I', 'F'),
flash_exit_xip = rom_table_code('E', 'X'),
flash_range_erase = rom_table_code('R', 'E'),
Expand Down Expand Up @@ -136,6 +139,11 @@ pub fn rom_func_lookup(code: Code) *anyopaque {

/// Return a count of the number of 1 bits in value
pub fn popcount32(value: u32) u32 {
if (chip == .RP2350) {
// RP2350, supports fast assembly version
return @popCount(value);
}

const S = struct {
var f: ?*signatures.popcount32 = null;
};
Expand All @@ -146,6 +154,11 @@ pub fn popcount32(value: u32) u32 {

/// Return a count of the number of 1 bits in value
pub fn reverse32(value: u32) u32 {
if (chip == .RP2350) {
// RP2350, supports fast assembly version
return @bitReverse(value);
}

const S = struct {
var f: ?*signatures.reverse32 = null;
};
Expand All @@ -156,6 +169,11 @@ pub fn reverse32(value: u32) u32 {

/// Return the number of consecutive high order 0 bits of value
pub fn clz32(value: u32) u32 {
if (chip == .RP2350) {
// RP2350, supports fast assembly version
return @clz(value);
}

const S = struct {
var f: ?*signatures.clz32 = null;
};
Expand All @@ -166,6 +184,11 @@ pub fn clz32(value: u32) u32 {

/// Return the number of consecutive low order 0 bits of value
pub fn ctz32(value: u32) u32 {
if (chip == .RP2350) {
// RP2350, supports fast assembly version
return @ctz(value);
}

const S = struct {
var f: ?*signatures.ctz32 = null;
};
Expand All @@ -180,6 +203,11 @@ pub fn ctz32(value: u32) u32 {

/// Sets all bytes of dest to the value c and returns ptr
pub fn memset(dest: []u8, c: u8) []u8 {
if (chip == .RP2350) {
@memset(dest, c);
return dest;
}

const S = struct {
var f: ?*signatures.memset = null;
};
Expand All @@ -190,6 +218,12 @@ pub fn memset(dest: []u8, c: u8) []u8 {

/// Copies n bytes from src to dest; The number of bytes copied is the size of the smaller slice
pub fn memcpy(dest: []u8, src: []const u8) []u8 {
if (chip == .RP2350) {
// For some reason @memcpy crash chip with HardFault interrupt (UNALIGNED)
std.mem.copyForwards(u8, dest, src);
return dest;
}

const S = struct {
var f: ?*signatures.memcpy = null;
};
Expand Down
4 changes: 2 additions & 2 deletions port/raspberrypi/rp2xxx/src/hal/usb.zig
Original file line number Diff line number Diff line change
Expand Up @@ -360,8 +360,8 @@ pub fn F(comptime config: UsbConfig) type {
var setup_packet: [8]u8 = .{0} ** 8;
const spl: u32 = peripherals.USB_DPRAM.SETUP_PACKET_LOW.raw;
const sph: u32 = peripherals.USB_DPRAM.SETUP_PACKET_HIGH.raw;
_ = rom.memcpy(setup_packet[0..4], std.mem.asBytes(&spl));
_ = rom.memcpy(setup_packet[4..8], std.mem.asBytes(&sph));
@memcpy(setup_packet[0..4], std.mem.asBytes(&spl));
@memcpy(setup_packet[4..8], std.mem.asBytes(&sph));
// Reinterpret as setup packet
return std.mem.bytesToValue(usb.types.SetupPacket, &setup_packet);
}
Expand Down

0 comments on commit 68b5ad1

Please sign in to comment.