diff --git a/Project/game/src/lib.rs b/Project/game/src/lib.rs index 312e5f6..8496569 100644 --- a/Project/game/src/lib.rs +++ b/Project/game/src/lib.rs @@ -7,7 +7,13 @@ use arduboy_rust::prelude::*; #[allow(dead_code)] const arduboy: Arduboy2 = Arduboy2::new(); +extern "C" { + #[link_name = "arduino_serial_begin"] + fn serial_begin(serial: c_ulong); + // #[link_name = "arduino_serial_println_chars"] + // fn serial_println_chars(cstr: *const c_char); +} // Progmem data // dynamic ram variables @@ -19,6 +25,7 @@ pub unsafe extern "C" fn setup() { arduboy.begin(); arduboy.set_frame_rate(30); arduboy.clear(); + serial_begin(9600) } // The loop() function repeats forever after setup() is done @@ -29,5 +36,7 @@ pub unsafe extern "C" fn loop_() { if !arduboy.next_frame() { return; } + serial::print("velo\0"); + //serial_println_chars(b"hallo\0" as *const [u8] as *const i8); arduboy.display(); } diff --git a/arduboy-rust/Wrapper-Project/platformio.ini b/arduboy-rust/Wrapper-Project/platformio.ini index 881bf39..c4a6130 100644 --- a/arduboy-rust/Wrapper-Project/platformio.ini +++ b/arduboy-rust/Wrapper-Project/platformio.ini @@ -13,6 +13,7 @@ platform = atmelavr board = arduboy framework = arduino + build_flags = -L lib -l libgame diff --git a/arduboy-rust/Wrapper-Project/src/library/arduino/arduino_serial_export.h b/arduboy-rust/Wrapper-Project/src/library/arduino/arduino_serial_export.h new file mode 100644 index 0000000..c33e5e7 --- /dev/null +++ b/arduboy-rust/Wrapper-Project/src/library/arduino/arduino_serial_export.h @@ -0,0 +1,41 @@ +#include + +extern "C" +{ + void arduino_serial_begin(uint8_t serial) + { + Serial.begin(serial); + } + void arduino_serial_println_chars(const char *cstr) + { + Serial.println(cstr); + } + size_t arduino_serial_println_chars_progmem(const char *cstr) + { + return Serial.println(reinterpret_cast(cstr)); + } + size_t arduino_serial_print_char(char c) + { + return Serial.println(c); + } + size_t arduino_serial_print_int(int n, int base) + { + return Serial.println(n, base); + } + size_t arduino_serial_print_long(long n, int base) + { + return Serial.println(n, base); + } + size_t arduino_serial_print_unsigned_char(unsigned char n, int base) + { + return Serial.println(n, base); + } + size_t arduino_serial_print_unsigned_int(unsigned int n, int base) + { + return Serial.println(n, base); + } + size_t arduino_serial_print_unsigned_long(unsigned long n, int base) + { + return Serial.println(n, base); + } +} \ No newline at end of file diff --git a/arduboy-rust/Wrapper-Project/src/main.h b/arduboy-rust/Wrapper-Project/src/main.h index 3c69329..dceaaee 100644 --- a/arduboy-rust/Wrapper-Project/src/main.h +++ b/arduboy-rust/Wrapper-Project/src/main.h @@ -26,3 +26,5 @@ ArdVoice ardvoice; #if defined(EEPROM_Library) #include "./library/arduino/eeprom_export.h" #endif + +#include "./library/arduino/arduino_serial_export.h" diff --git a/arduboy-rust/src/lib.rs b/arduboy-rust/src/lib.rs index 24ca35f..05fd881 100644 --- a/arduboy-rust/src/lib.rs +++ b/arduboy-rust/src/lib.rs @@ -37,3 +37,4 @@ pub use crate::library::arduboy_tone::{self, ArduboyTones}; pub use crate::library::ardvoice::{self, ArdVoice}; pub use crate::library::eeprom::{EEPROM, EEPROMBYTE}; pub use crate::library::{arduino, c, sprites}; +pub mod serial_print; diff --git a/arduboy-rust/src/prelude.rs b/arduboy-rust/src/prelude.rs index 3b903d6..6eb7602 100644 --- a/arduboy-rust/src/prelude.rs +++ b/arduboy-rust/src/prelude.rs @@ -21,6 +21,7 @@ pub use crate::library::sprites; pub use crate::print::*; pub use crate::{ f, get_ardvoice_tone_addr, get_sprite_addr, get_string_addr, get_tones_addr, progmem, + serial_print as serial, }; use core::cmp; pub use core::ffi::{ diff --git a/arduboy-rust/src/serial_print.rs b/arduboy-rust/src/serial_print.rs new file mode 100644 index 0000000..8aa4afe --- /dev/null +++ b/arduboy-rust/src/serial_print.rs @@ -0,0 +1,178 @@ +//! This is the Module to interact in a save way with the Arduino Serial C++ library. +//! +//! You will need to uncomment the Arduino_Serial_Library in the import_config.h file. +use crate::prelude::Pstring; +use core::ffi::{c_char, c_int, c_long, c_size_t, c_uchar, c_uint, c_ulong}; + +use crate::print::Base; + +extern "C" { + #[link_name = "arduino_serial_begin"] + fn serial_begin(serial: c_ulong); + #[link_name = "arduino_serial_println_chars"] + fn print_chars(cstr: *const c_char); + #[doc(hidden)] + #[link_name = "arduino_serial_println_chars_progmem"] + fn print_chars_progmem(pstring: *const c_char); + // #[link_name = "arduino_serial_print_char"] + // fn print_char(c: c_char) -> c_size_t; + #[doc(hidden)] + #[link_name = "arduino_serial_print_int"] + fn print_int(n: c_int, base: c_int) -> c_size_t; + #[doc(hidden)] + #[link_name = "arduino_serial_print_long"] + fn print_long(n: c_long, base: c_int) -> c_size_t; + #[doc(hidden)] + #[link_name = "arduino_serial_print_unsigned_char"] + fn print_unsigned_char(n: c_uchar, base: c_int) -> c_size_t; + #[doc(hidden)] + #[link_name = "arduino_serial_print_unsigned_int"] + fn print_unsigned_int(n: c_uint, base: c_int) -> c_size_t; + #[doc(hidden)] + #[link_name = "arduino_serial_print_unsigned_long"] + fn print_unsigned_long(n: c_ulong, base: c_int) -> c_size_t; +} +///The Arduino Serial Print class is available for writing text to the screen buffer. +/// +///In the same manner as the Arduino arduboy.print(), etc., functions. +/// +/// +///Example +/// ``` +/// let value: i16 = 42; +/// +/// serial::print(b"Hello World\n\0"[..]); // Prints "Hello World" and then sets the +/// // text cursor to the start of the next line +/// serial::print(f!(b"Hello World\n")); // Prints "Hello World" but does not use the 2kb ram +/// serial::print(value); // Prints "42" +/// serial::print("\n\0"); // Sets the text cursor to the start of the next line +/// serial::print("hello world") // Prints normal [&str] +/// ``` +pub fn print(x: impl SerialPrintable) { + x.print() +} +/// Set the Baud rate for the serial monitor +/// +/// ### Example +/// ``` +/// serial::begin(9600) +/// ``` +pub fn begin(baud_rates: u32) { + unsafe { serial_begin(baud_rates) } +} +pub trait SerialPrintable +where + Self: Sized, +{ + type Parameters; + + fn print_2(self, params: Self::Parameters); + fn default_parameters() -> Self::Parameters; + + fn print(self) { + self.print_2(Self::default_parameters()); + } +} + +impl SerialPrintable for i16 { + type Parameters = Base; + + fn print_2(self, params: Self::Parameters) { + unsafe { + print_int(self, params as c_int); + } + } + + fn default_parameters() -> Self::Parameters { + Base::Dec + } +} + +impl SerialPrintable for u16 { + type Parameters = Base; + + fn print_2(self, params: Self::Parameters) { + unsafe { + print_unsigned_int(self, params as c_int); + } + } + + fn default_parameters() -> Self::Parameters { + Base::Dec + } +} + +impl SerialPrintable for i32 { + type Parameters = Base; + + fn print_2(self, params: Self::Parameters) { + unsafe { + print_long(self, params as c_int); + } + } + + fn default_parameters() -> Self::Parameters { + Base::Dec + } +} + +impl SerialPrintable for u32 { + type Parameters = Base; + + fn print_2(self, params: Self::Parameters) { + unsafe { + print_unsigned_long(self, params as c_int); + } + } + + fn default_parameters() -> Self::Parameters { + Base::Dec + } +} + +impl SerialPrintable for &[u8] { + type Parameters = (); + + fn print_2(self, _params: Self::Parameters) { + unsafe { + print_chars(self as *const [u8] as *const i8); + } + } + + fn default_parameters() -> Self::Parameters {} +} + +impl SerialPrintable for &str { + type Parameters = (); + + fn print_2(self, _params: Self::Parameters) { + unsafe { + print_chars(self.as_bytes() as *const [u8] as *const i8); + } + } + + fn default_parameters() -> Self::Parameters {} +} +impl SerialPrintable for crate::heapless::String { + type Parameters = (); + + fn print_2(self, _params: Self::Parameters) { + unsafe { + print_chars(self.as_bytes() as *const [u8] as *const i8); + } + } + + fn default_parameters() -> Self::Parameters {} +} + +impl SerialPrintable for Pstring { + type Parameters = (); + + fn print_2(self, _params: Self::Parameters) { + unsafe { + print_chars_progmem(self.pointer); + } + } + + fn default_parameters() -> Self::Parameters {} +} diff --git a/run.bat b/run.bat index 62e2677..dfca76d 100644 --- a/run.bat +++ b/run.bat @@ -5,7 +5,8 @@ set option=%1 if [%option%]==[] ( powershell -Command "cargo build -p game --release; cp ./target/arduboy/release/libgame.a ./arduboy-rust/Wrapper-Project/lib/libgame.a; cd arduboy-rust/Wrapper-Project/; pio run -v -t upload; cp ./.pio/build/arduboy/firmware.hex ./build/game.hex; pio run -t clean; rm lib/libgame.a; cd ../../" goto :eof -) else if %option%==doc ( +) +if %option%==doc ( powershell -Command "cargo doc -p arduboy-rust; rm -r ./docs/doc/; cp -r ./target/arduboy/doc ./docs/" goto :eof ) else if %option%==eeprom-byte (