From 2505aa7fc02219884d98ab9f0da77af6f50644f7 Mon Sep 17 00:00:00 2001 From: Ian McLinden Date: Fri, 5 Apr 2024 13:31:24 -0500 Subject: [PATCH] Add support for nullbits BIT-C PRO --- Cargo.toml | 3 +- README.md | 13 + boards/nullbits-bit-c-pro/.gitignore | 11 + boards/nullbits-bit-c-pro/CHANGELOG.md | 12 + boards/nullbits-bit-c-pro/Cargo.toml | 51 ++ boards/nullbits-bit-c-pro/README.md | 103 +++ .../examples/bit_c_pro_blinky.rs | 69 ++ .../examples/bit_c_pro_hid_keyboard.rs | 152 ++++ boards/nullbits-bit-c-pro/src/lib.rs | 683 ++++++++++++++++++ 9 files changed, 1096 insertions(+), 1 deletion(-) create mode 100644 boards/nullbits-bit-c-pro/.gitignore create mode 100644 boards/nullbits-bit-c-pro/CHANGELOG.md create mode 100644 boards/nullbits-bit-c-pro/Cargo.toml create mode 100644 boards/nullbits-bit-c-pro/README.md create mode 100644 boards/nullbits-bit-c-pro/examples/bit_c_pro_blinky.rs create mode 100644 boards/nullbits-bit-c-pro/examples/bit_c_pro_hid_keyboard.rs create mode 100644 boards/nullbits-bit-c-pro/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 62f014e8..5dabe28a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "boards/adafruit-trinkey-qt2040", "boards/arduino_nano_connect", "boards/boardsource-blok", + "boards/nullbits-bit-c-pro", "boards/pimoroni_badger2040", "boards/pimoroni-pico-explorer", "boards/pimoroni-pico-lipo-16mb", @@ -48,7 +49,7 @@ hd44780-driver = "0.4.0" heapless = "0.7.16" i2c-pio = "0.8.0" nb = "1.1" -panic-halt= "0.2.0" +panic-halt = "0.2.0" panic-probe = "0.3.1" pio = "0.2.1" pio-proc = "0.2.2" diff --git a/README.md b/README.md index b158b9a8..795a034e 100644 --- a/README.md +++ b/README.md @@ -191,6 +191,19 @@ RP2040 chip according to how it is connected up on the Blok. [boardsource-blok]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/boardsource-blok [Boardsource]: https://boardsource.xyz/ +### [nullbits-bit-c-pro] - Board Support for the [BIT-C PRO] + +You should include this crate if you are writing code that you want to run on +a [BIT-C PRO] - an RP2040 based controller, made by [nullbits], +built for the keyboard community. + +This crate includes the [rp2040-hal], but also configures each pin of the +RP2040 chip according to how it is connected up on the BIT-C PRO. + +[nullbits-bit-c-pro]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/nullbits-bit-c-pro +[BIT-C PRO]: https://nullbits.co/bit-c-pro +[nullbits]: https://nullbits.co/ + ### [pimoroni_badger2040] - Board Support for the [Pimoroni Badger2040] You should include this crate if you are writing code that you want to run on diff --git a/boards/nullbits-bit-c-pro/.gitignore b/boards/nullbits-bit-c-pro/.gitignore new file mode 100644 index 00000000..ff47c2d7 --- /dev/null +++ b/boards/nullbits-bit-c-pro/.gitignore @@ -0,0 +1,11 @@ +# Generated by Cargo +# will have compiled files and executables +debug/ +target/ + +# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries +# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html +Cargo.lock + +# These are backup files generated by rustfmt +**/*.rs.bk diff --git a/boards/nullbits-bit-c-pro/CHANGELOG.md b/boards/nullbits-bit-c-pro/CHANGELOG.md new file mode 100644 index 00000000..c5c905f5 --- /dev/null +++ b/boards/nullbits-bit-c-pro/CHANGELOG.md @@ -0,0 +1,12 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## Unreleased + +## 0.1.0 - 2024-04-05 + +- Initial release diff --git a/boards/nullbits-bit-c-pro/Cargo.toml b/boards/nullbits-bit-c-pro/Cargo.toml new file mode 100644 index 00000000..da804984 --- /dev/null +++ b/boards/nullbits-bit-c-pro/Cargo.toml @@ -0,0 +1,51 @@ +[package] +name = "nullbits-bit-c-pro" +version = "0.1.0" +edition = "2021" +authors = ["Ian McLinden", "The rp-rs Developers"] +homepage = "https://github.com/rp-rs/rp-hal-boards/tree/main/boards/nullbits-bit-c-pro" +description = "Board Support Package for the rp2040 based BIT-C PRO" +license = "MIT OR Apache-2.0" +repository = "https://github.com/rp-rs/rp-hal-boards.git" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +cortex-m-rt = { workspace = true, optional = true } +rp2040-boot2 = { workspace = true, optional = true } +rp2040-hal.workspace = true + +[dev-dependencies] +cortex-m.workspace = true +panic-halt.workspace = true +embedded-hal.workspace = true +usb-device.workspace = true +usbd-hid.workspace = true +critical-section.workspace = true + + +[features] +# This is the set of features we enable by default +default = ["boot2", "rt", "critical-section-impl", "rom-func-cache"] + +# critical section that is safe for multicore use +critical-section-impl = ["rp2040-hal/critical-section-impl"] + +# 2nd stage bootloaders for rp2040 +boot2 = ["rp2040-boot2"] + +# Minimal startup / runtime for Cortex-M microcontrollers +rt = ["cortex-m-rt", "rp2040-hal/rt"] + +# This enables a fix for USB errata 5: USB device fails to exit RESET state on busy USB bus. +# Only required for RP2040 B0 and RP2040 B1, but it also works for RP2040 B2 and above +rp2040-e5 = ["rp2040-hal/rp2040-e5"] + +# Memoize(cache) ROM function pointers on first use to improve performance +rom-func-cache = ["rp2040-hal/rom-func-cache"] + +# Disable automatic mapping of language features (like floating point math) to ROM functions +disable-intrinsics = ["rp2040-hal/disable-intrinsics"] + +# This enables ROM functions for f64 math that were not present in the earliest RP2040s +rom-v2-intrinsics = ["rp2040-hal/rom-v2-intrinsics"] diff --git a/boards/nullbits-bit-c-pro/README.md b/boards/nullbits-bit-c-pro/README.md new file mode 100644 index 00000000..c1e99cbc --- /dev/null +++ b/boards/nullbits-bit-c-pro/README.md @@ -0,0 +1,103 @@ +# [nullbits-bit-c-pro] - Board Support for the [BIT-C PRO] + +You should include this crate if you are writing code that you want to run on +a [BIT-C PRO] - an RP2040 based controller, made by [nullbits], built for the keyboard community. + +This crate includes the [rp2040-hal], but also configures each pin of the +RP2040 chip according to how it is connected up on the BIT-C PRO. + +More Information about the board from the [BIT-C PRO Docs]. +A [pinout diagram] is also available. + +[nullbits-bit-c-pro]: https://github.com/rp-rs/rp-hal-boards/tree/main/boards/nullbits-bit-c-pro +[BIT-C PRO]: https://nullbits.co/bit-c-pro +[nullbits]: https://nullbits.co/ +[BIT-C PRO Docs]: https://github.com/nullbitsco/docs/blob/main/bit-c-pro/user_guide_en.md +[pinout diagram]: https://nullbits.co/static/img/bitc_pro_pinout.png + +## Using + +To use this crate, your `Cargo.toml` file should contain: + +```toml +nullbits-bit-c-pro = "0.1.0" +``` + +In your program, you will need to call `nullbits_bit_c_pro::Pins::new` to create +a new `Pins` structure. This will set up all the GPIOs for any on-board +devices. See the [examples](./examples) folder for more details. + +## Examples + +### General Instructions + +To compile an example, clone the _rp-hal-boards_ repository and run: + +```console +rp-hal-boards/boards/nullbits-bit-c-pro $ cargo build --release --example +``` + +You will get an ELF file called +`./target/thumbv6m-none-eabi/release/examples/`, where the `target` +folder is located at the top of the _rp-hal-boards_ repository checkout. Normally +you would also need to specify `--target=thumbv6m-none-eabi` but when +building examples from this git repository, that is set as the default. + +If you want to convert the ELF file to a UF2 and automatically copy it to the +USB drive exported by the RP2040 bootloader, simply boot your board into +bootloader mode and run: + +```console +rp-hal-boards/boards/nullbits-bit-c-pro $ cargo run --release --example +``` + +If you get an error about not being able to find `elf2uf2-rs`, try: + +```console +$ cargo install elf2uf2-rs +``` +then try repeating the `cargo run` command above. + +### [bit_c_pro_blinky](./examples/bit_c_pro_blinky.rs) + +Flashes the BIT-C PRO's three on-board LEDs in sequence. + +### [bit_c_pro_hid_keyboard](./examples/bit_c_pro_hid_keyboard.rs) + +Demonstrates emulating a USB Human Input Device (HID) Keyboard. + +## Contributing + +Contributions are what make the open source community such an amazing place to +be learn, inspire, and create. Any contributions you make are **greatly +appreciated**. + +The steps are: + +1. Fork the Project by clicking the 'Fork' button at the top of the page. +2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) +3. Make some changes to the code or documentation. +4. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) +5. Push to the Feature Branch (`git push origin feature/AmazingFeature`) +6. Create a [New Pull Request](https://github.com/rp-rs/rp-hal-boards/pulls) +7. An admin will review the Pull Request and discuss any changes that may be required. +8. Once everyone is happy, the Pull Request can be merged by an admin, and your work is part of our project! + +## Code of Conduct + +Contribution to this crate is organized under the terms of the [Rust Code of +Conduct][CoC], and the maintainer of this crate, the [rp-rs team], promises +to intervene to uphold that code of conduct. + +[CoC]: CODE_OF_CONDUCT.md +[rp-rs team]: https://github.com/orgs/rp-rs/teams/rp-rs + +## License + +The contents of this repository are dual-licensed under the _MIT OR Apache +2.0_ License. That means you can choose either the MIT license or the +Apache-2.0 license when you re-use this code. See `MIT` or `APACHE2.0` for more +information on each specific license. + +Any submissions to this project (e.g. as Pull Requests) must be made available +under these terms. diff --git a/boards/nullbits-bit-c-pro/examples/bit_c_pro_blinky.rs b/boards/nullbits-bit-c-pro/examples/bit_c_pro_blinky.rs new file mode 100644 index 00000000..13ae4682 --- /dev/null +++ b/boards/nullbits-bit-c-pro/examples/bit_c_pro_blinky.rs @@ -0,0 +1,69 @@ +//! Blinks the 3 colour LEDs on a BIT-C PRO in sequence +#![no_std] +#![no_main] + +use embedded_hal::digital::OutputPin; +use panic_halt as _; + +use nullbits_bit_c_pro as bsp; + +use bsp::hal::{ + clocks::{init_clocks_and_plls, Clock}, + gpio::PinState, + pac, + sio::Sio, + watchdog::Watchdog, +}; + +/// Entry point to our bare-metal application. +/// +/// The `#[rp2040_hal::entry]` macro ensures the Cortex-M start-up code calls this function +/// as soon as all global variables and the spinlock are initialised. +#[rp2040_hal::entry] +fn main() -> ! { + let mut pac = pac::Peripherals::take().unwrap(); + let core = pac::CorePeripherals::take().unwrap(); + let mut watchdog = Watchdog::new(pac.WATCHDOG); + let sio = Sio::new(pac.SIO); + + let clocks = init_clocks_and_plls( + bsp::XOSC_CRYSTAL_FREQ, + 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()); + + let pins = bsp::Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + let mut led_red = pins.led_red.into_push_pull_output_in_state(PinState::High); + let mut led_green = pins + .led_green + .into_push_pull_output_in_state(PinState::High); + let mut led_blue = pins.led_blue.into_push_pull_output_in_state(PinState::High); + + loop { + led_red.set_low().unwrap(); + delay.delay_ms(500); + led_red.set_high().unwrap(); + led_green.set_low().unwrap(); + delay.delay_ms(500); + led_green.set_high().unwrap(); + led_blue.set_low().unwrap(); + delay.delay_ms(500); + led_blue.set_high().unwrap(); + } +} + +// End of file diff --git a/boards/nullbits-bit-c-pro/examples/bit_c_pro_hid_keyboard.rs b/boards/nullbits-bit-c-pro/examples/bit_c_pro_hid_keyboard.rs new file mode 100644 index 00000000..7c4003a6 --- /dev/null +++ b/boards/nullbits-bit-c-pro/examples/bit_c_pro_hid_keyboard.rs @@ -0,0 +1,152 @@ +//! # Keyboard Input Example for the BIT-C PRO +//! +//! Creates a USB HID Class Keyboard device, +//! with the USB driver running in the main thread. +//! +//! When GPIO D2, D3, D4, or D5, are pulled low +//! send 'h', 'e', l', or 'o', respectively. +//! +#![no_std] +#![no_main] + +use nullbits_bit_c_pro as bsp; + +use bsp::{ + entry, + hal::{ + self, + clocks::{init_clocks_and_plls, Clock}, + pac, + pac::interrupt, + timer::Timer, + watchdog::Watchdog, + Sio, + }, + Pins, XOSC_CRYSTAL_FREQ, +}; +use embedded_hal::digital::InputPin; +use panic_halt as _; +use usb_device::{ + bus::UsbBusAllocator, + device::{StringDescriptors, UsbDevice, UsbDeviceBuilder, UsbVidPid}, +}; +use usbd_hid::{descriptor::KeyboardReport, descriptor::SerializedDescriptor, hid_class::HIDClass}; + +// shared with the interrupt +static mut USB_BUS: Option> = None; +static mut USB_HID: Option> = None; +static mut USB_DEVICE: Option> = None; + +#[entry] +fn main() -> ! { + let mut pac = pac::Peripherals::take().unwrap(); + + let mut watchdog = Watchdog::new(pac.WATCHDOG); + + let clocks = init_clocks_and_plls( + XOSC_CRYSTAL_FREQ, + pac.XOSC, + pac.CLOCKS, + pac.PLL_SYS, + pac.PLL_USB, + &mut pac.RESETS, + &mut watchdog, + ) + .ok() + .unwrap(); + + let sio = Sio::new(pac.SIO); + let pins = Pins::new( + pac.IO_BANK0, + pac.PADS_BANK0, + sio.gpio_bank0, + &mut pac.RESETS, + ); + + let _timer = Timer::new(pac.TIMER, &mut pac.RESETS, &clocks); + + let usb_bus = UsbBusAllocator::new(hal::usb::UsbBus::new( + pac.USBCTRL_REGS, + pac.USBCTRL_DPRAM, + clocks.usb_clock, + true, + &mut pac.RESETS, + )); + unsafe { + USB_BUS = Some(usb_bus); + } + + let bus_ref = unsafe { USB_BUS.as_ref().unwrap() }; + + let usb_hid = HIDClass::new(bus_ref, KeyboardReport::desc(), 10); + unsafe { + USB_HID = Some(usb_hid); + } + + let usb_device = UsbDeviceBuilder::new(bus_ref, UsbVidPid(0x1209, 0x0001)) + .strings(&[StringDescriptors::default().product("keyboard input")]) + .unwrap() + .build(); + unsafe { + USB_DEVICE = Some(usb_device); + } + + // enable usb interrupt + unsafe { + pac::NVIC::unmask(hal::pac::Interrupt::USBCTRL_IRQ); + } + + let core = pac::CorePeripherals::take().unwrap(); + let mut delay = cortex_m::delay::Delay::new(core.SYST, clocks.system_clock.freq().to_Hz()); + + let mut d2 = pins.d2.into_pull_up_input(); + let mut d3 = pins.d3.into_pull_up_input(); + let mut d4 = pins.d4.into_pull_up_input(); + let mut d5 = pins.d5.into_pull_up_input(); + + loop { + let mut keycodes = [0u8; 6]; + + // naively insert keycode + if d2.is_low().unwrap_or(false) { + keycodes[0] = 0x0b; // 'h' + } + if d3.is_low().unwrap_or(false) { + keycodes[0] = 0x08 // 'e' + } + if d4.is_low().unwrap_or(false) { + keycodes[0] = 0x0f // 'l' + } + if d5.is_low().unwrap_or(false) { + keycodes[0] = 0x12 // 'o' + } + + push_report(KeyboardReport { + modifier: 0x00, + reserved: 0x00, + leds: 0x00, + keycodes, + }); + delay.delay_ms(10); + } +} + +/// Submit a new Keyboard Report to the USB stack. +/// +/// We do this with interrupts disabled, to avoid a race hazard with the USB IRQ. +fn push_report(report: KeyboardReport) { + let _ = critical_section::with(|_| unsafe { + // Now interrupts are disabled + USB_HID.as_mut().map(|hid| hid.push_input(&report)) + }) + .unwrap(); +} + +/// This function is called whenever the USB Hardware generates an IRQ +#[allow(non_snake_case)] +#[interrupt] +unsafe fn USBCTRL_IRQ() { + let usb_device = USB_DEVICE.as_mut().unwrap(); + let usb_hid = USB_HID.as_mut().unwrap(); + usb_device.poll(&mut [usb_hid]); +} diff --git a/boards/nullbits-bit-c-pro/src/lib.rs b/boards/nullbits-bit-c-pro/src/lib.rs new file mode 100644 index 00000000..705638ea --- /dev/null +++ b/boards/nullbits-bit-c-pro/src/lib.rs @@ -0,0 +1,683 @@ +#![no_std] + +pub extern crate rp2040_hal as hal; + +#[cfg(feature = "rt")] +extern crate cortex_m_rt; +#[cfg(feature = "rt")] +pub use hal::entry; + +// BIT-C uses BY25Q32BSTIG flash chip. Should work with BOOT_LOADER_W25X10CL + +/// 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. +#[cfg(feature = "boot2")] +#[link_section = ".boot2"] +#[no_mangle] +#[used] +pub static BOOT2_FIRMWARE: [u8; 256] = rp2040_boot2::BOOT_LOADER_W25X10CL; + +pub use hal::pac; + +hal::bsp_pins!( + /// D0 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 RX` | [crate::D0Spi0Rx] | + /// | `UART0 TX` | [crate::D0Uart0Tx] | + /// | `I2C0 SDA` | [crate::D0I2C0Sda] | + /// | `PWM0 A` | [crate::D0Pwm0A] | + /// | `PIO0` | [crate::D0Pio0] | + /// | `PIO1` | [crate::D0Pio1] | + Gpio0 { + name: d0, + aliases: { + /// UART Function alias for pin [crate::Pins::d0]. + FunctionUart, PullNone: D0Uart0Tx, + /// SPI Function alias for pin [crate::Pins::d0]. + FunctionSpi, PullNone: D0Spi0Rx, + /// I2C Function alias for pin [crate::Pins::d0]. + FunctionI2C, PullUp: D0I2C0Sda, + /// PWM Function alias for pin [crate::Pins::d0]. + FunctionPwm, PullNone: D0Pwm0A, + /// PIO0 Function alias for pin [crate::Pins::d0]. + FunctionPio0, PullNone: D0Pio0, + /// PIO1 Function alias for pin [crate::Pins::d0]. + FunctionPio1, PullNone: D0Pio1 + } + }, + + /// D1 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 CSn` | [crate::D1Spi0Csn] | + /// | `UART0 RX` | [crate::D1Uart0Rx] | + /// | `I2C0 SCL` | [crate::D1I2C0Scl] | + /// | `PWM0 B` | [crate::D1Pwm0B] | + /// | `PIO0` | [crate::D1Pio0] | + /// | `PIO1` | [crate::D1Pio1] | + Gpio1 { + name: d1, + aliases: { + /// UART Function alias for pin [crate::Pins::d1]. + FunctionUart, PullNone: D1Uart0Rx, + /// SPI Function alias for pin [crate::Pins::d1]. + FunctionSpi, PullNone: D1Spi0Csn, + /// I2C Function alias for pin [crate::Pins::d1]. + FunctionI2C, PullUp: D1I2C0Scl, + /// PWM Function alias for pin [crate::Pins::d1]. + FunctionPwm, PullNone: D1Pwm0B, + /// PIO0 Function alias for pin [crate::Pins::d1]. + FunctionPio0, PullNone: D1Pio0, + /// PIO1 Function alias for pin [crate::Pins::d1]. + FunctionPio1, PullNone: D1Pio1 + } + }, + + /// D2 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 SCK` | [crate::D2Spi0Sck] | + /// | `UART0 CTS` | [crate::D2Uart0Cts] | + /// | `I2C1 SDA` | [crate::D2I2C1Sda] | + /// | `PWM1 A` | [crate::D2Pwm1A] | + /// | `PIO0` | [crate::D2Pio0] | + /// | `PIO1` | [crate::D2Pio1] | + Gpio2 { + name: d2, + aliases: { + /// UART Function alias for pin [crate::Pins::d2]. + FunctionUart, PullNone: D2Uart0Cts, + /// SPI Function alias for pin [crate::Pins::d2]. + FunctionSpi, PullNone: D2Spi0Sck, + /// I2C Function alias for pin [crate::Pins::d2]. + FunctionI2C, PullUp: D2I2C1Sda, + /// PWM Function alias for pin [crate::Pins::d2]. + FunctionPwm, PullNone: D2Pwm1A, + /// PIO0 Function alias for pin [crate::Pins::d2]. + FunctionPio0, PullNone: D2Pio0, + /// PIO1 Function alias for pin [crate::Pins::d2]. + FunctionPio1, PullNone: D2Pio1 + } + }, + + /// D3 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 TX` | [crate::D3Spi0Tx] | + /// | `UART0 RTS` | [crate::D3Uart0Rts] | + /// | `I2C1 SCL` | [crate::D3I2C1Scl] | + /// | `PWM1 B` | [crate::D3Pwm1B] | + /// | `PIO0` | [crate::D3Pio0] | + /// | `PIO1` | [crate::D3Pio1] | + Gpio3 { + name: d3, + aliases: { + /// UART Function alias for pin [crate::Pins::d3]. + FunctionUart, PullNone: D3Uart0Rts, + /// SPI Function alias for pin [crate::Pins::d3]. + FunctionSpi, PullNone: D3Spi0Tx, + /// I2C Function alias for pin [crate::Pins::d3]. + FunctionI2C, PullUp: D3I2C1Scl, + /// PWM Function alias for pin [crate::Pins::d3]. + FunctionPwm, PullNone: D3Pwm1B, + /// PIO0 Function alias for pin [crate::Pins::d3]. + FunctionPio0, PullNone: D3Pio0, + /// PIO1 Function alias for pin [crate::Pins::d3]. + FunctionPio1, PullNone: D3Pio1 + } + }, + + /// D4 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 RX` | [crate::D4Spi0Rx] | + /// | `UART1 TX` | [crate::D4Uart1Tx] | + /// | `I2C0 SDA` | [crate::D4I2C0Sda] | + /// | `PWM2 A` | [crate::D4Pwm2A] | + /// | `PIO0` | [crate::D4Pio0] | + /// | `PIO1` | [crate::D4Pio1] | + Gpio4 { + name: d4, + aliases: { + /// UART Function alias for pin [crate::Pins::d4]. + FunctionUart, PullNone: D4Uart1Tx, + /// SPI Function alias for pin [crate::Pins::d4]. + FunctionSpi, PullNone: D4Spi0Rx, + /// I2C Function alias for pin [crate::Pins::d4]. + FunctionI2C, PullUp: D4I2C0Sda, + /// PWM Function alias for pin [crate::Pins::d4]. + FunctionPwm, PullNone: D4Pwm2A, + /// PIO0 Function alias for pin [crate::Pins::d4]. + FunctionPio0, PullNone: D4Pio0, + /// PIO1 Function alias for pin [crate::Pins::d4]. + FunctionPio1, PullNone: D4Pio1 + } + }, + + /// D5 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 CSn` | [crate::D5Spi0Csn] | + /// | `UART1 RX` | [crate::D5Uart1Rx] | + /// | `I2C0 SCL` | [crate::D5I2C0Scl] | + /// | `PWM2 B` | [crate::D5Pwm2B] | + /// | `PIO0` | [crate::D5Pio0] | + /// | `PIO1` | [crate::D5Pio1] | + Gpio5 { + name: d5, + aliases: { + /// UART Function alias for pin [crate::Pins::d5]. + FunctionUart, PullNone: D5Uart1Rx, + /// SPI Function alias for pin [crate::Pins::d5]. + FunctionSpi, PullNone: D5Spi0Csn, + /// I2C Function alias for pin [crate::Pins::d5]. + FunctionI2C, PullUp: D5I2C0Scl, + /// PWM Function alias for pin [crate::Pins::d5]. + FunctionPwm, PullNone: D5Pwm2B, + /// PIO0 Function alias for pin [crate::Pins::d5]. + FunctionPio0, PullNone: D5Pio0, + /// PIO1 Function alias for pin [crate::Pins::d5]. + FunctionPio1, PullNone: D5Pio1 + } + }, + + /// D6 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 SCK` | [crate::D6Spi0Sck] | + /// | `UART1 CTS` | [crate::D6Uart1Cts] | + /// | `I2C1 SDA` | [crate::D6I2C1Sda] | + /// | `PWM3 A` | [crate::D6Pwm3A] | + /// | `PIO0` | [crate::D6Pio0] | + /// | `PIO1` | [crate::D6Pio1] | + Gpio6 { + name: d6, + aliases: { + /// UART Function alias for pin [crate::Pins::d6]. + FunctionUart, PullNone: D6Uart1Cts, + /// SPI Function alias for pin [crate::Pins::d6]. + FunctionSpi, PullNone: D6Spi0Sck, + /// I2C Function alias for pin [crate::Pins::d6]. + FunctionI2C, PullUp: D6I2C1Sda, + /// PWM Function alias for pin [crate::Pins::d6]. + FunctionPwm, PullNone: D6Pwm3A, + /// PIO0 Function alias for pin [crate::Pins::d6]. + FunctionPio0, PullNone: D6Pio0, + /// PIO1 Function alias for pin [crate::Pins::d6]. + FunctionPio1, PullNone: D6Pio1 + } + }, + + /// D7 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 TX` | [crate::D7Spi0Tx] | + /// | `UART1 RTS` | [crate::D7Uart1Rts] | + /// | `I2C1 SCL` | [crate::D7I2C1Scl] | + /// | `PWM3 B` | [crate::D7Pwm3B] | + /// | `PIO0` | [crate::D7Pio0] | + /// | `PIO1` | [crate::D7Pio1] | + Gpio7 { + name: d7, + aliases: { + /// UART Function alias for pin [crate::Pins::d7]. + FunctionUart, PullNone: D7Uart1Rts, + /// SPI Function alias for pin [crate::Pins::d7]. + FunctionSpi, PullNone: D7Spi0Tx, + /// I2C Function alias for pin [crate::Pins::d7]. + FunctionI2C, PullUp: D7I2C1Scl, + /// PWM Function alias for pin [crate::Pins::d7]. + FunctionPwm, PullNone: D7Pwm3B, + /// PIO0 Function alias for pin [crate::Pins::d7]. + FunctionPio0, PullNone: D7Pio0, + /// PIO1 Function alias for pin [crate::Pins::d7]. + FunctionPio1, PullNone: D7Pio1 + } + }, + + /// D8 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 RX` | [crate::D8Spi1Rx] | + /// | `UART1 TX` | [crate::D8Uart1Tx] | + /// | `I2C0 SDA` | [crate::D8I2C0Sda] | + /// | `PWM4 A` | [crate::D8Pwm4A] | + /// | `PIO0` | [crate::D8Pio0] | + /// | `PIO1` | [crate::D8Pio1] | + Gpio8 { + name: d8, + aliases: { + /// UART Function alias for pin [crate::Pins::d8]. + FunctionUart, PullNone: D8Uart1Tx, + /// SPI Function alias for pin [crate::Pins::d8]. + FunctionSpi, PullNone: D8Spi1Rx, + /// I2C Function alias for pin [crate::Pins::d8]. + FunctionI2C, PullUp: D8I2C0Sda, + /// PWM Function alias for pin [crate::Pins::d8]. + FunctionPwm, PullNone: D8Pwm4A, + /// PIO0 Function alias for pin [crate::Pins::d8]. + FunctionPio0, PullNone: D8Pio0, + /// PIO1 Function alias for pin [crate::Pins::d8]. + FunctionPio1, PullNone: D8Pio1 + } + }, + + /// D9 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 CSn` | [crate::D9Spi1Csn] | + /// | `UART1 RX` | [crate::D9Uart1Rx] | + /// | `I2C0 SCL` | [crate::D9I2C0Scl] | + /// | `PWM4 B` | [crate::D9Pwm4B] | + /// | `PIO0` | [crate::D9Pio0] | + /// | `PIO1` | [crate::D9Pio1] | + Gpio9 { + name: d9, + aliases: { + /// UART Function alias for pin [crate::Pins::d9]. + FunctionUart, PullNone: D9Uart1Rx, + /// SPI Function alias for pin [crate::Pins::d9]. + FunctionSpi, PullNone: D9Spi1Csn, + /// I2C Function alias for pin [crate::Pins::d9]. + FunctionI2C, PullUp: D9I2C0Scl, + /// PWM Function alias for pin [crate::Pins::d9]. + FunctionPwm, PullNone: D9Pwm4B, + /// PIO0 Function alias for pin [crate::Pins::d9]. + FunctionPio0, PullNone: D9Pio0, + /// PIO1 Function alias for pin [crate::Pins::d9]. + FunctionPio1, PullNone: D9Pio1 + } + }, + + /// D11 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 TX` | [crate::D11Spi1Tx] | + /// | `UART1 RTS` | [crate::D11Uart1Rts] | + /// | `I2C1 SCL` | [crate::D11I2C1Scl] | + /// | `PWM5 B` | [crate::D11Pwm5B] | + /// | `PIO0` | [crate::D11Pio0] | + /// | `PIO1` | [crate::D11Pio1] | + Gpio11 { + name: d11, + aliases: { + /// UART Function alias for pin [crate::Pins::d11]. + FunctionUart, PullNone: D11Uart1Rts, + /// SPI Function alias for pin [crate::Pins::d11]. + FunctionSpi, PullNone: D11Spi1Tx, + /// I2C Function alias for pin [crate::Pins::d11]. + FunctionI2C, PullUp: D11I2C1Scl, + /// PWM Function alias for pin [crate::Pins::d11]. + FunctionPwm, PullNone: D11Pwm5B, + /// PIO0 Function alias for pin [crate::Pins::d11]. + FunctionPio0, PullNone: D11Pio0, + /// PIO1 Function alias for pin [crate::Pins::d11]. + FunctionPio1, PullNone: D11Pio1 + } + }, + + /// D12 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 RX` | [crate::D12Spi1Rx] | + /// | `UART0 TX` | [crate::D12Uart0Tx] | + /// | `I2C0 SDA` | [crate::D12I2C0Sda] | + /// | `PWM6 A` | [crate::D12Pwm6A] | + /// | `PIO0` | [crate::D12Pio0] | + /// | `PIO1` | [crate::D12Pio1] | + Gpio12 { + name: d12, + aliases: { + /// UART Function alias for pin [crate::Pins::d12]. + FunctionUart, PullNone: D12Uart0Tx, + /// SPI Function alias for pin [crate::Pins::d12]. + FunctionSpi, PullNone: D12Spi1Rx, + /// I2C Function alias for pin [crate::Pins::d12]. + FunctionI2C, PullUp: D12I2C0Sda, + /// PWM Function alias for pin [crate::Pins::d12]. + FunctionPwm, PullNone: D12Pwm6A, + /// PIO0 Function alias for pin [crate::Pins::d12]. + FunctionPio0, PullNone: D12Pio0, + /// PIO1 Function alias for pin [crate::Pins::d12]. + FunctionPio1, PullNone: D12Pio1 + } + }, + + /// D13 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 CSn` | [crate::D13Spi1Csn] | + /// | `UART0 RX` | [crate::D13Uart0Rx] | + /// | `I2C0 SCL` | [crate::D13I2C0Scl] | + /// | `PWM6 B` | [crate::D13Pwm6B] | + /// | `PIO0` | [crate::D13Pio0] | + /// | `PIO1` | [crate::D13Pio1] | + Gpio13 { + name: d13, + aliases: { + /// UART Function alias for pin [crate::Pins::d13]. + FunctionUart, PullNone: D13Uart0Rx, + /// SPI Function alias for pin [crate::Pins::d13]. + FunctionSpi, PullNone: D13Spi1Csn, + /// I2C Function alias for pin [crate::Pins::d13]. + FunctionI2C, PullUp: D13I2C0Scl, + /// PWM Function alias for pin [crate::Pins::d13]. + FunctionPwm, PullNone: D13Pwm6B, + /// PIO0 Function alias for pin [crate::Pins::d13]. + FunctionPio0, PullNone: D13Pio0, + /// PIO1 Function alias for pin [crate::Pins::d13]. + FunctionPio1, PullNone: D13Pio1 + } + }, + + /// D14 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 SCK` | [crate::D14Spi1Sck] | + /// | `UART0 CTS` | [crate::D14Uart0Cts] | + /// | `I2C1 SDA` | [crate::D14I2C1Sda] | + /// | `PWM7 A` | [crate::D14Pwm7A] | + /// | `PIO0` | [crate::D14Pio0] | + /// | `PIO1` | [crate::D14Pio1] | + Gpio14 { + name: d14, + aliases: { + /// UART Function alias for pin [crate::Pins::d14]. + FunctionUart, PullNone: D14Uart0Cts, + /// SPI Function alias for pin [crate::Pins::d14]. + FunctionSpi, PullNone: D14Spi1Sck, + /// I2C Function alias for pin [crate::Pins::d14]. + FunctionI2C, PullUp: D14I2C1Sda, + /// PWM Function alias for pin [crate::Pins::d14]. + FunctionPwm, PullNone: D14Pwm7A, + /// PIO0 Function alias for pin [crate::Pins::d14]. + FunctionPio0, PullNone: D14Pio0, + /// PIO1 Function alias for pin [crate::Pins::d14]. + FunctionPio1, PullNone: D14Pio1 + } + }, + + /// GPIO 16 is connected to the red LED, active low, + /// and supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `PWM0 A` | [crate::LedRedPwm0A] | + Gpio16 { + name: led_red, + aliases: { + /// PWM Function alias for pin [crate::Pins::led_red]. + FunctionPwm, PullNone: LedRedPwm0A + } + }, + + /// GPIO 17 is connected to the green LED, active low, + /// and supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `PWM0 B` | [crate::LedGrnPwm0B] | + Gpio17 { + name: led_green, + aliases: { + /// PWM Function alias for pin [crate::Pins::led_green]. + FunctionPwm, PullNone: LedGrnPwm0B + } + }, + + /// GPIO 18 is connected to the blue LED, active low, + /// and supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `PWM1 A` | [crate::LedBluPwm1A] | + /// + Gpio18 { + name: led_blue, + aliases: { + /// PWM Function alias for pin [crate::Pins::led_green]. + FunctionPwm, PullNone: LedBluPwm1A + } + }, + + /// D10 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 CSn` | [crate::D10Spi0Csn] | + /// | `UART1 RX` | [crate::D10Uart1Rx] | + /// | `I2C0 SCL` | [crate::D10I2C0Scl] | + /// | `PWM2 B` | [crate::D10Pwm2B] | + /// | `PIO0` | [crate::D10Pio0] | + /// | `PIO1` | [crate::D10Pio1] | + Gpio21 { + name: d10, + aliases: { + /// UART Function alias for pin [crate::Pins::d10]. + FunctionUart, PullNone: D10Uart1Rx, + /// SPI Function alias for pin [crate::Pins::d10]. + FunctionSpi, PullNone: D10Spi0Csn, + /// I2C Function alias for pin [crate::Pins::d10]. + FunctionI2C, PullUp: D10I2C0Scl, + /// PWM Function alias for pin [crate::Pins::d10]. + FunctionPwm, PullNone: D10Pwm2B, + /// PIO0 Function alias for pin [crate::Pins::d10]. + FunctionPio0, PullNone: D10Pio0, + /// PIO1 Function alias for pin [crate::Pins::d10]. + FunctionPio1, PullNone: D10Pio1 + } + }, + + /// MOSI supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 TX` | [crate::Mosi] | + /// | `UART1 RTS` | [crate::MosiUart1Rts] | + /// | `I2C1 SCL` | [crate::MosiI2C1Scl] | + /// | `PWM3 B` | [crate::MosiPwm3B] | + /// | `PIO0` | [crate::MosiPio0] | + /// | `PIO1` | [crate::MosiPio1] | + Gpio23 { + name: mosi, + aliases: { + /// UART Function alias for pin [crate::Pins::mosi]. + FunctionUart, PullNone: MosiUart1Rts, + /// SPI Function alias for pin [crate::Pins::mosi]. + FunctionSpi, PullNone: Mosi, + /// I2C Function alias for pin [crate::Pins::mosi]. + FunctionI2C, PullUp: MosiI2C1Scl, + /// PWM Function alias for pin [crate::Pins::mosi]. + FunctionPwm, PullNone: MosiPwm3B, + /// PIO0 Function alias for pin [crate::Pins::mosi]. + FunctionPio0, PullNone: MosiPio0, + /// PIO1 Function alias for pin [crate::Pins::mosi]. + FunctionPio1, PullNone: MosiPio1 + } + }, + + /// MISO supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 RX` | [crate::Miso] | + /// | `UART1 TX` | [crate::MisoUart1Tx] | + /// | `I2C0 SDA` | [crate::MisoI2C0Sda] | + /// | `PWM2 A` | [crate::MisoPwm2A] | + /// | `PIO0` | [crate::MisoPio0] | + /// | `PIO1` | [crate::MisoPio1] | + Gpio20 { + name: miso, + aliases: { + /// UART Function alias for pin [crate::Pins::miso]. + FunctionUart, PullNone: MisoUart1Tx, + /// SPI Function alias for pin [crate::Pins::miso]. + FunctionSpi, PullNone: Miso, + /// I2C Function alias for pin [crate::Pins::miso]. + FunctionI2C, PullUp: MisoI2C0Sda, + /// PWM Function alias for pin [crate::Pins::miso]. + FunctionPwm, PullNone: MisoPwm2A, + /// PIO0 Function alias for pin [crate::Pins::miso]. + FunctionPio0, PullNone: MisoPio0, + /// PIO1 Function alias for pin [crate::Pins::miso]. + FunctionPio1, PullNone: MisoPio1 + } + }, + + /// SCK supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI0 SCK` | [crate::Sck] | + /// | `UART1 CTS` | [crate::SckUart1Cts] | + /// | `I2C1 SDA` | [crate::SckI2C1Sda] | + /// | `PWM3 A` | [crate::SckPwm3A] | + /// | `PIO0` | [crate::SckPio0] | + /// | `PIO1` | [crate::SckPio1] | + Gpio22 { + name: sck, + aliases: { + /// UART Function alias for pin [crate::Pins::sck]. + FunctionUart, PullNone: SckUart1Cts, + /// SPI Function alias for pin [crate::Pins::sck]. + FunctionSpi, PullNone: Sck, + /// I2C Function alias for pin [crate::Pins::sck]. + FunctionI2C, PullUp: SckI2C1Sda, + /// PWM Function alias for pin [crate::Pins::sck]. + FunctionPwm, PullNone: SckPwm3A, + /// PIO0 Function alias for pin [crate::Pins::sck]. + FunctionPio0, PullNone: SckPio0, + /// PIO1 Function alias for pin [crate::Pins::sck]. + FunctionPio1, PullNone: SckPio1 + } + }, + + /// A0 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 SCK` | [crate::A0Spi1Sck] | + /// | `UART1 CTS` | [crate::A0Uart1Cts] | + /// | `I2C1 SDA` | [crate::A0I2C1Sda] | + /// | `PWM5 A` | [crate::A0Pwm5A] | + /// | `PIO0` | [crate::A0Pio0] | + /// | `PIO1` | [crate::A0Pio1] | + Gpio26 { + name: a0, + aliases: { + /// UART Function alias for pin [crate::Pins::a0]. + FunctionUart, PullNone: A0Uart1Cts, + /// SPI Function alias for pin [crate::Pins::a0]. + FunctionSpi, PullNone: A0Spi1Sck, + /// I2C Function alias for pin [crate::Pins::a0]. + FunctionI2C, PullUp: A0I2C1Sda, + /// PWM Function alias for pin [crate::Pins::a0]. + FunctionPwm, PullNone: A0Pwm5A, + /// PIO0 Function alias for pin [crate::Pins::a0]. + FunctionPio0, PullNone: A0Pio0, + /// PIO1 Function alias for pin [crate::Pins::a0]. + FunctionPio1, PullNone: A0Pio1 + } + }, + + /// A1 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 TX` | [crate::A1Spi1Tx] | + /// | `UART1 RTS` | [crate::A1Uart1Rts] | + /// | `I2C1 SCL` | [crate::A1I2C1Scl] | + /// | `PWM5 B` | [crate::A1Pwm5B] | + /// | `PIO0` | [crate::A1Pio0] | + /// | `PIO1` | [crate::A1Pio1] | + Gpio27 { + name: a1, + aliases: { + /// UART Function alias for pin [crate::Pins::a1]. + FunctionUart, PullNone: A1Uart1Rts, + /// SPI Function alias for pin [crate::Pins::a1]. + FunctionSpi, PullNone: A1Spi1Tx, + /// I2C Function alias for pin [crate::Pins::a1]. + FunctionI2C, PullUp: A1I2C1Scl, + /// PWM Function alias for pin [crate::Pins::a1]. + FunctionPwm, PullNone: A1Pwm5B, + /// PIO0 Function alias for pin [crate::Pins::a1]. + FunctionPio0, PullNone: A1Pio0, + /// PIO1 Function alias for pin [crate::Pins::a1]. + FunctionPio1, PullNone: A1Pio1 + } + }, + + /// A2 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 RX` | [crate::A2Spi1Rx] | + /// | `UART0 TX` | [crate::A2Uart0Tx] | + /// | `I2C0 SDA` | [crate::A2I2C0Sda] | + /// | `PWM6 A` | [crate::A2Pwm6A] | + /// | `PIO0` | [crate::A2Pio0] | + /// | `PIO1` | [crate::A2Pio1] | + Gpio28 { + name: a2, + aliases: { + /// UART Function alias for pin [crate::Pins::a2]. + FunctionUart, PullNone: A2Uart0Tx, + /// SPI Function alias for pin [crate::Pins::a2]. + FunctionSpi, PullNone: A2Spi1Rx, + /// I2C Function alias for pin [crate::Pins::a2]. + FunctionI2C, PullUp: A2I2C0Sda, + /// PWM Function alias for pin [crate::Pins::a2]. + FunctionPwm, PullNone: A2Pwm6A, + /// PIO0 Function alias for pin [crate::Pins::a2]. + FunctionPio0, PullNone: A2Pio0, + /// PIO1 Function alias for pin [crate::Pins::a2]. + FunctionPio1, PullNone: A2Pio1 + } + }, + + /// A3 supports following functions: + /// + /// | Function | Alias with applied function | + /// |--------------|-----------------------------| + /// | `SPI1 CS` | [crate::A3Spi1CSn] | + /// | `UART0 RX` | [crate::A3Uart0Rx] | + /// | `I2C0 SCL` | [crate::A3I2C0Scl] | + /// | `PWM6 B` | [crate::A3Pwm6B] | + /// | `PIO0` | [crate::A3Pio0] | + /// | `PIO1` | [crate::A3Pio1] | + Gpio29 { + name: a3, + aliases: { + /// UART Function alias for pin [crate::Pins::a3]. + FunctionUart, PullNone: A3Uart0Rx, + /// SPI Function alias for pin [crate::Pins::a3]. + FunctionSpi, PullNone: A3Spi1CSn, + /// I2C Function alias for pin [crate::Pins::a3]. + FunctionI2C, PullUp: A3I2C0Scl, + /// PWM Function alias for pin [crate::Pins::a3]. + FunctionPwm, PullNone: A3Pwm6B, + /// PIO0 Function alias for pin [crate::Pins::a3]. + FunctionPio0, PullNone: A3Pio0, + /// PIO1 Function alias for pin [crate::Pins::a3]. + FunctionPio1, PullNone: A3Pio1 + } + }, +); + +pub const XOSC_CRYSTAL_FREQ: u32 = 12_000_000;