Add basic project structure

This commit is contained in:
hodasemi 2023-03-19 16:19:56 +01:00
parent 39f71fed04
commit b5c607fa3a
8 changed files with 285 additions and 0 deletions

29
.cargo/config.toml Normal file
View 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
View file

@ -0,0 +1,2 @@
/target
Cargo.lock

8
.vscode/settings.json vendored Normal file
View 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
View 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
View 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
View 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
View file

@ -0,0 +1,4 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["thumbv6m-none-eabi"]

129
src/main.rs Normal file
View 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]);
}