Add basic project structure
This commit is contained in:
parent
39f71fed04
commit
b5c607fa3a
8 changed files with 285 additions and 0 deletions
29
.cargo/config.toml
Normal file
29
.cargo/config.toml
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||||||
|
# Choose a default "cargo run" tool:
|
||||||
|
# - probe-run provides flashing and defmt via a hardware debugger
|
||||||
|
# - cargo embed offers flashing, rtt, defmt and a gdb server via a hardware debugger
|
||||||
|
# it is configured via the Embed.toml in the root of this project
|
||||||
|
# - elf2uf2-rs loads firmware over USB when the rp2040 is in boot mode
|
||||||
|
# runner = "probe-run --chip RP2040"
|
||||||
|
# runner = "cargo embed"
|
||||||
|
runner = "elf2uf2-rs -d"
|
||||||
|
|
||||||
|
rustflags = [
|
||||||
|
"-C", "linker=flip-link",
|
||||||
|
"-C", "link-arg=--nmagic",
|
||||||
|
"-C", "link-arg=-Tlink.x",
|
||||||
|
"-C", "link-arg=-Tdefmt.x",
|
||||||
|
|
||||||
|
# Code-size optimizations.
|
||||||
|
# trap unreachable can save a lot of space, but requires nightly compiler.
|
||||||
|
# uncomment the next line if you wish to enable it
|
||||||
|
# "-Z", "trap-unreachable=no",
|
||||||
|
"-C", "inline-threshold=5",
|
||||||
|
"-C", "no-vectorize-loops",
|
||||||
|
]
|
||||||
|
|
||||||
|
[build]
|
||||||
|
target = "thumbv6m-none-eabi"
|
||||||
|
|
||||||
|
[env]
|
||||||
|
DEFMT_LOG = "debug"
|
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
/target
|
||||||
|
Cargo.lock
|
8
.vscode/settings.json
vendored
Normal file
8
.vscode/settings.json
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"workbench.colorCustomizations": {
|
||||||
|
"activityBar.background": "#2B1C76",
|
||||||
|
"titleBar.activeBackground": "#3D28A6",
|
||||||
|
"titleBar.activeForeground": "#FCFCFE"
|
||||||
|
},
|
||||||
|
"rust-analyzer.check.allTargets": false,
|
||||||
|
}
|
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "projekt_maus"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
cortex-m = "0.7.7"
|
||||||
|
cortex-m-rt = "0.7.3"
|
||||||
|
rp-pico = "0.7.0"
|
||||||
|
panic-halt = "0.2.0"
|
||||||
|
defmt = "0.3.2"
|
||||||
|
usb-device = "0.2.9"
|
||||||
|
usbd-hid = "0.6.1"
|
||||||
|
critical-section = "1.1.1"
|
82
Embed.toml
Normal file
82
Embed.toml
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
[default.probe]
|
||||||
|
# USB vendor ID
|
||||||
|
# usb_vid = "1337"
|
||||||
|
# USB product ID
|
||||||
|
# usb_pid = "1337"
|
||||||
|
# Serial number
|
||||||
|
# serial = "12345678"
|
||||||
|
# The protocol to be used for communicating with the target.
|
||||||
|
protocol = "Swd"
|
||||||
|
# The speed in kHz of the data link to the target.
|
||||||
|
speed = 20000
|
||||||
|
|
||||||
|
[default.flashing]
|
||||||
|
# Whether or not the target should be flashed.
|
||||||
|
enabled = true
|
||||||
|
# Whether or not the target should be halted after reset.
|
||||||
|
# DEPRECATED, moved to reset section
|
||||||
|
halt_afterwards = false
|
||||||
|
# Whether or not bytes erased but not rewritten with data from the ELF
|
||||||
|
# should be restored with their contents before erasing.
|
||||||
|
restore_unwritten_bytes = false
|
||||||
|
# The path where an SVG of the assembled flash layout should be written to.
|
||||||
|
# flash_layout_output_path = "out.svg"
|
||||||
|
# Triggers a full chip erase instead of a page by page erase.
|
||||||
|
do_chip_erase = false
|
||||||
|
|
||||||
|
[default.reset]
|
||||||
|
# Whether or not the target should be reset.
|
||||||
|
# When flashing is enabled as well, the target will be reset after flashing.
|
||||||
|
enabled = true
|
||||||
|
# Whether or not the target should be halted after reset.
|
||||||
|
halt_afterwards = false
|
||||||
|
|
||||||
|
[default.general]
|
||||||
|
# The chip name of the chip to be debugged.
|
||||||
|
chip = "RP2040"
|
||||||
|
# A list of chip descriptions to be loaded during runtime.
|
||||||
|
chip_descriptions = []
|
||||||
|
# The default log level to be used. Possible values are one of:
|
||||||
|
# "OFF", "ERROR", "WARN", "INFO", "DEBUG", "TRACE"
|
||||||
|
log_level = "WARN"
|
||||||
|
# Use this flag to assert the nreset & ntrst pins during attaching the probe to the chip.
|
||||||
|
connect_under_reset = false
|
||||||
|
|
||||||
|
[default.rtt]
|
||||||
|
# Whether or not an RTTUI should be opened after flashing.
|
||||||
|
enabled = true
|
||||||
|
# How the target handles RTT outputs that won't fit in the buffer. This can be
|
||||||
|
# overridden per-channel. If left unset, the firmware will determine the default
|
||||||
|
# for each RTT up channel.
|
||||||
|
# NoBlockSkip - Skip writing the data completely if it doesn't fit in its
|
||||||
|
# entirety.
|
||||||
|
# NoBlockTrim - Write as much as possible of the data and ignore the rest.
|
||||||
|
# BlockIfFull - Spin until the host reads data. Can result in app freezing.
|
||||||
|
#
|
||||||
|
up_mode = "NoBlockSkip"
|
||||||
|
|
||||||
|
# A list of channel associations to be displayed. If left empty, all channels are displayed.
|
||||||
|
# up, down (Optional) - RTT channel numbers
|
||||||
|
# name (Optional) - String to be displayed in the RTTUI tab
|
||||||
|
# up_mode (Optional) - RTT channel specific as described above
|
||||||
|
# format (Required) - How to interpret data from target firmware. One of:
|
||||||
|
# String - Directly show output from the target
|
||||||
|
# Defmt - Format output on the host, see https://defmt.ferrous-systems.com/
|
||||||
|
# BinaryLE - Display as raw hex
|
||||||
|
channels = [
|
||||||
|
{ up = 0, down = 0, name = "name", up_mode = "NoBlockSkip", format = "Defmt" },
|
||||||
|
]
|
||||||
|
# The duration in ms for which the logger should retry to attach to RTT.
|
||||||
|
timeout = 3000
|
||||||
|
# Whether timestamps in the RTTUI are enabled
|
||||||
|
show_timestamps = true
|
||||||
|
# Whether to save rtt history buffer on exit.
|
||||||
|
log_enabled = false
|
||||||
|
# Where to save rtt history buffer relative to manifest path.
|
||||||
|
log_path = "./logs"
|
||||||
|
|
||||||
|
[default.gdb]
|
||||||
|
# Whether or not a GDB server should be opened after flashing.
|
||||||
|
enabled = false
|
||||||
|
# The connection string in host:port format wher the GDB server will open a socket.
|
||||||
|
gdb_connection_string = "127.0.0.1:1337"
|
15
memory.x
Normal file
15
memory.x
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
MEMORY {
|
||||||
|
BOOT2 : ORIGIN = 0x10000000, LENGTH = 0x100
|
||||||
|
FLASH : ORIGIN = 0x10000100, LENGTH = 2048K - 0x100
|
||||||
|
RAM : ORIGIN = 0x20000000, LENGTH = 256K
|
||||||
|
}
|
||||||
|
|
||||||
|
EXTERN(BOOT2_FIRMWARE)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
/* ### Boot loader */
|
||||||
|
.boot2 ORIGIN(BOOT2) :
|
||||||
|
{
|
||||||
|
KEEP(*(.boot2));
|
||||||
|
} > BOOT2
|
||||||
|
} INSERT BEFORE .text;
|
4
rust-toolchain.toml
Normal file
4
rust-toolchain.toml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[toolchain]
|
||||||
|
channel = "stable"
|
||||||
|
components = ["rustfmt"]
|
||||||
|
targets = ["thumbv6m-none-eabi"]
|
129
src/main.rs
Normal file
129
src/main.rs
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
#![no_std]
|
||||||
|
#![no_main]
|
||||||
|
|
||||||
|
// Ensure we halt the program on panic (if we don't mention this crate it won't
|
||||||
|
// be linked)
|
||||||
|
use panic_halt as _;
|
||||||
|
|
||||||
|
use rp_pico as bsp;
|
||||||
|
|
||||||
|
use bsp::{
|
||||||
|
entry,
|
||||||
|
hal::{
|
||||||
|
self, pac,
|
||||||
|
pac::{interrupt, Interrupt},
|
||||||
|
prelude::*,
|
||||||
|
usb::UsbBus,
|
||||||
|
},
|
||||||
|
XOSC_CRYSTAL_FREQ,
|
||||||
|
};
|
||||||
|
|
||||||
|
use cortex_m::delay::Delay;
|
||||||
|
|
||||||
|
use usb_device::{class_prelude::*, prelude::*};
|
||||||
|
use usbd_hid::{
|
||||||
|
descriptor::{MouseReport, SerializedDescriptor},
|
||||||
|
hid_class::HIDClass,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// The USB Device Driver (shared with the interrupt).
|
||||||
|
static mut USB_DEVICE: Option<UsbDevice<UsbBus>> = None;
|
||||||
|
|
||||||
|
/// The USB Bus Driver (shared with the interrupt).
|
||||||
|
static mut USB_BUS: Option<UsbBusAllocator<UsbBus>> = None;
|
||||||
|
|
||||||
|
/// The USB Human Interface Device Driver (shared with the interrupt).
|
||||||
|
static mut USB_HID: Option<HIDClass<UsbBus>> = None;
|
||||||
|
|
||||||
|
#[entry]
|
||||||
|
fn main() -> ! {
|
||||||
|
// Grab our singleton objects
|
||||||
|
let mut pac = pac::Peripherals::take().unwrap();
|
||||||
|
let core = pac::CorePeripherals::take().unwrap();
|
||||||
|
|
||||||
|
// Set up the watchdog driver - needed by the clock setup code
|
||||||
|
let mut watchdog = hal::Watchdog::new(pac.WATCHDOG);
|
||||||
|
|
||||||
|
// Configure the clocks
|
||||||
|
let clocks = hal::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();
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
USB_BUS = Some(UsbBusAllocator::new(UsbBus::new(
|
||||||
|
pac.USBCTRL_REGS,
|
||||||
|
pac.USBCTRL_DPRAM,
|
||||||
|
clocks.usb_clock,
|
||||||
|
true,
|
||||||
|
&mut pac.RESETS,
|
||||||
|
)))
|
||||||
|
};
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
USB_HID = Some(HIDClass::new(
|
||||||
|
USB_BUS.as_ref().unwrap(),
|
||||||
|
MouseReport::desc(),
|
||||||
|
60,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
USB_DEVICE = Some(
|
||||||
|
UsbDeviceBuilder::new(USB_BUS.as_ref().unwrap(), UsbVidPid(0x046d, 0x101b))
|
||||||
|
.manufacturer("Logitech")
|
||||||
|
.product("Marathon Mouse/Performance Plus M705")
|
||||||
|
.serial_number("B14D65DA")
|
||||||
|
.device_class(0)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
pac::NVIC::unmask(Interrupt::USBCTRL_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut delay = Delay::new(core.SYST, clocks.system_clock.freq().to_Hz());
|
||||||
|
const PIXEL: i8 = 2;
|
||||||
|
const WAIT_TIME: u32 = 10000;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
mouse_move(&mut delay, WAIT_TIME, PIXEL);
|
||||||
|
mouse_move(&mut delay, 50, -PIXEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mouse_move(delay: &mut Delay, wait_time: u32, v: i8) {
|
||||||
|
delay.delay_ms(wait_time);
|
||||||
|
|
||||||
|
let rep = MouseReport {
|
||||||
|
x: 0,
|
||||||
|
y: v,
|
||||||
|
buttons: 0,
|
||||||
|
wheel: 0,
|
||||||
|
pan: 0,
|
||||||
|
};
|
||||||
|
push_mouse_movement(rep).unwrap_or(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// with interrupts disabled, to avoid a race hazard with the USB IRQ.
|
||||||
|
fn push_mouse_movement(report: MouseReport) -> Result<usize, usb_device::UsbError> {
|
||||||
|
critical_section::with(|_| unsafe { USB_HID.as_mut().map(|hid| hid.push_input(&report)) })
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[interrupt]
|
||||||
|
unsafe fn USBCTRL_IRQ() {
|
||||||
|
// Handle USB request
|
||||||
|
let usb_dev = USB_DEVICE.as_mut().unwrap();
|
||||||
|
let usb_hid = USB_HID.as_mut().unwrap();
|
||||||
|
usb_dev.poll(&mut [usb_hid]);
|
||||||
|
}
|
Loading…
Reference in a new issue