From ab9078ab3f48801512aa3d6f301d274f1c597038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Proch=C3=A1zka?= Date: Sat, 20 Sep 2025 23:04:18 +0200 Subject: [PATCH] Added command for generating the kopyto --- README.md | 30 ++++++++++++++++-------------- src/args.rs | 18 ++++++++++++++---- src/main.rs | 26 +++++++++++++++++++++++++- 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 54df0ab..e2db1d6 100644 --- a/README.md +++ b/README.md @@ -2,31 +2,33 @@ ## Installation instructions -No need to clone this repo manually. You'll just need to install the Rust toolchain. +No need to clone this repo manually. You'll just need to install the Rust toolchain and SDCC. ```bash # All OSes cargo install --git https://git.zumepro.cz/michal.prochazka/tulflash ``` -## Flashing Intel HEX binaries +## Running the example program + +```bash +# Generate the example program (only needed to run once): +tulflash example + +# Compile, flash and monitor the example program: +tulflash run example.c: + +# note: `tulflash run example.c` is the thing as `tulflash write --cmd "sdcc example.c" --monitor example.ihx` +``` + +If the flash fails, try to add `--slow` before `run` (should not be needed though). + +## Manually flashing Intel HEX binaries ```bash # All OSes, automatically detects the correct serial port tulflash write ``` -If the flash fails, try to add `--slow` before `write` (should not be needed though). - The tool also allows reading and erasing the chip, figure that out on your own if you need that (although `tulflash --help` might guide you if you ask it nicely). -## Example program - -You'll need to clone this repo (or just [download the file](example.c)) and install SDCC: - -```bash -tulflash run example.c - -# Same thing as `tulflash write --cmd "sdcc example.c" --monitor example.ihx` -``` - diff --git a/src/args.rs b/src/args.rs index a558e2c..12d797e 100644 --- a/src/args.rs +++ b/src/args.rs @@ -24,7 +24,8 @@ pub enum ArgCommand { Write(ArgWrite), Erase(ArgErase), Monitor(ArgMonitor), - Run(ArgRun) + Run(ArgRun), + Example(ArgExample) } #[derive(FromArgs)] @@ -90,6 +91,11 @@ pub struct ArgWrite { #[argp(subcommand, name = "erase")] pub struct ArgErase {} +#[derive(FromArgs)] +#[argp(description = "Opens the serial monitor.")] +#[argp(subcommand, name = "monitor")] +pub struct ArgMonitor {} + #[derive(FromArgs)] #[argp(description = "Handy shorthand for `write --cmd \"sdcc \" --monitor `.")] #[argp(subcommand, name = "run")] @@ -100,9 +106,13 @@ pub struct ArgRun { } #[derive(FromArgs)] -#[argp(description = "Opens the serial monitor.")] -#[argp(subcommand, name = "monitor")] -pub struct ArgMonitor {} +#[argp(description = "Generates a \"stub\" C file for the TUL výukový přípravek™.")] +#[argp(subcommand, name = "example")] +pub struct ArgExample { + #[argp(positional)] + #[argp(description = "Path to the source C file to be generated.")] + pub path: Option +} pub fn parse() -> Args { let args: Args = argp::parse_args_or_exit(argp::DEFAULT); diff --git a/src/main.rs b/src/main.rs index 8bb7b5f..5a01d89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -272,9 +272,32 @@ fn run_chip(args: ArgRun, target: &mut PhysicalTarget) -> Result<(), Error> { }, target) } +fn gen_example(args: ArgExample) -> Result<(), Error> { + let path = PathBuf::from(args.path.unwrap_or(OsString::from("example.c"))); + + if path.try_exists()? { + Err(Error::other("File already exists"))? + } + + std::fs::write(&path, include_bytes!("../example.c"))?; + + let path = path.to_string_lossy(); + println!("Example source code generated to `{}`.", path); + println!("Execute `tulflash run \"{}\"` to run it.", path); + Ok(()) +} + fn main() { let args = args::parse(); + if let ArgCommand::Example(args) = args.command { + if let Err(err) = gen_example(args) { + println!("Error generating example source code: {}", err); + } + + return + } + let start = SystemTime::now(); let port = args.port.or_else(|| { @@ -300,7 +323,8 @@ fn main() { ArgCommand::Write(args) => write_chip(args, &mut target), ArgCommand::Erase(args) => erase_chip(args, &mut target), ArgCommand::Monitor(args) => monitor_chip(args, &mut target), - ArgCommand::Run(args) => run_chip(args, &mut target) + ArgCommand::Run(args) => run_chip(args, &mut target), + ArgCommand::Example(_) => unreachable!() }; if let Err(err) = res {