Compare commits
4 commits
main
...
hardware-r
Author | SHA1 | Date | |
---|---|---|---|
4aa116e32d | |||
395d8b3cdb | |||
255a24b5fe | |||
031613e59f |
10 changed files with 182 additions and 13 deletions
26
.github/workflows/ci.yml
vendored
Normal file
26
.github/workflows/ci.yml
vendored
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
name: Cargo Build Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: windows-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
- name: Update rust to nightly
|
||||||
|
run: rustup update nightly && rustup default nightly && rustup target add x86_64-pc-windows-gnu
|
||||||
|
- name: Check for errors
|
||||||
|
run: cargo check
|
||||||
|
- name: Build with release profile
|
||||||
|
run: cargo build --release
|
||||||
|
- name: Archive output from build
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: build
|
||||||
|
path: target/x86_64-pc-windows-gnu/release/*.dll
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
debug/
|
||||||
|
target/
|
||||||
|
Cargo.lock
|
58
Cargo.lock
generated
58
Cargo.lock
generated
|
@ -2,6 +2,64 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg-if"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ftdi-mpsse"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa7cfcda69930a8d2fdcdd7ffb9234fe4c79a8c73934ed4904327d77bfb5078a"
|
||||||
|
dependencies = [
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libftd2xx"
|
||||||
|
version = "0.32.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f20d68b3138aaabb97edc3db8ed8f418d60f8abd2a7d8220d562906fb38ff08e"
|
||||||
|
dependencies = [
|
||||||
|
"ftdi-mpsse",
|
||||||
|
"libftd2xx-ffi",
|
||||||
|
"log",
|
||||||
|
"paste",
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "libftd2xx-ffi"
|
||||||
|
version = "0.8.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "40bed7f53ea45282e0e4f1361d1a8094e62abe0ccfd9a6dbf7e3db932b2789ce"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "log"
|
||||||
|
version = "0.4.22"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paste"
|
||||||
|
version = "1.0.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wacca-led"
|
name = "wacca-led"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"libftd2xx",
|
||||||
|
]
|
||||||
|
|
|
@ -13,3 +13,4 @@ default-target="x86_64-pc-windows-gnu"
|
||||||
crate-type = ["cdylib"]
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
libftd2xx = "0.32.5"
|
41
src/lib.rs
41
src/lib.rs
|
@ -2,7 +2,9 @@
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::net::{SocketAddr, UdpSocket};
|
use std::net::{SocketAddr, UdpSocket};
|
||||||
use std::sync::OnceLock;
|
use std::sync::OnceLock;
|
||||||
use std::convert::TryFrom;
|
|
||||||
|
mod output;
|
||||||
|
mod rgb;
|
||||||
|
|
||||||
struct RGB {
|
struct RGB {
|
||||||
red: u8,
|
red: u8,
|
||||||
|
@ -18,7 +20,7 @@ impl IntoIterator for RGB {
|
||||||
IntoIterator::into_iter([self.red, self.green, self.blue])
|
IntoIterator::into_iter([self.red, self.green, self.blue])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static SOCKET: OnceLock<UdpSocket> = OnceLock::new();
|
static SOCKET: OnceLock<output::sockets> = OnceLock::new();
|
||||||
|
|
||||||
fn flatten<T, const N: usize>(v: Vec<Vec<[T; N]>>) -> Vec<T> {
|
fn flatten<T, const N: usize>(v: Vec<Vec<[T; N]>>) -> Vec<T> {
|
||||||
v.into_iter().flatten().flatten().collect()
|
v.into_iter().flatten().flatten().collect()
|
||||||
|
@ -35,8 +37,19 @@ pub extern fn USBIntLED_getVersion() -> i64 {
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn USBIntLED_Init() -> bool {
|
pub extern fn USBIntLED_Init() -> bool {
|
||||||
println!("Init");
|
println!("Init");
|
||||||
let _ = SOCKET.set(UdpSocket::bind("0.0.0.0:0").unwrap());
|
// let _ = SOCKET.set(UdpSocket::bind("0.0.0.0:0").unwrap());
|
||||||
return true;
|
// let mut e = output::udprealtime::output {
|
||||||
|
// socket: Some(UdpSocket::bind("0.0.0.0:0").unwrap())
|
||||||
|
// };
|
||||||
|
let ok = match output::udprealtime::Output::create(SocketAddr::from(([127, 0, 0, 1], 21324))) {
|
||||||
|
Ok(e) => { match SOCKET.set(output::sockets::udprealtime(e)) {
|
||||||
|
Ok(_) => true,
|
||||||
|
Err(_) => false,
|
||||||
|
}},
|
||||||
|
Err(e) => { println!("{:?}",e); false },
|
||||||
|
};
|
||||||
|
// e.init();
|
||||||
|
return ok
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -47,28 +60,30 @@ pub extern fn USBIntLED_Terminate() -> bool {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn USBIntLED_set(_a1: i64, a2: usize) {
|
pub extern fn USBIntLED_set(_a1: i64, a2: usize) {
|
||||||
let mut header: Vec<u8> = vec![2, 2];
|
// let mut header: Vec<u8> = vec![2, 2];
|
||||||
let mut leds: Vec<RGB> = Vec::new();
|
let mut leds: Vec<rgb::RGB> = Vec::new();
|
||||||
for i in (3..1920).step_by(4) {
|
for i in (3..1920).step_by(4) {
|
||||||
let n: u32 = unsafe { ptr::read((a2+i) as *const u32) };
|
let n: u32 = unsafe { ptr::read((a2+i) as *const u32) };
|
||||||
let a: [u8; 4] =n.to_le_bytes();
|
let a: [u8; 4] =n.to_le_bytes();
|
||||||
leds.push(RGB {
|
leds.push(rgb::RGB {
|
||||||
red: a[1],
|
red: a[1],
|
||||||
green: a[2],
|
green: a[2],
|
||||||
blue: a[3],
|
blue: a[3],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let addr = SocketAddr::from(([100, 64, 0, 79], 21324));
|
// let addr = SocketAddr::from(([100, 64, 0, 79], 21324));
|
||||||
let mut flattened: Vec<u8> = leds.into_iter().flatten().collect();
|
// let mut flattened: Vec<u8> = leds.into_iter().flatten().collect();
|
||||||
header.append(&mut flattened);
|
// header.append(&mut flattened);
|
||||||
match SOCKET.get() {
|
match SOCKET.get() {
|
||||||
Some(socket) => {
|
Some(socket) => {
|
||||||
let sock: UdpSocket = socket.try_clone().unwrap();
|
// let sock: UdpSocket = socket.try_clone().unwrap();
|
||||||
let _ = sock.send_to(&header, addr);
|
// let _ = sock.send_to(&header, addr);
|
||||||
|
socket.send(&leds);
|
||||||
|
// output::sockets::udprealtime(*socket).send(leds)
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
println!("Socket hasn't been initialized yet")
|
println!("Socket hasn't been initialized yet")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
0
src/output/d2xx.rs
Normal file
0
src/output/d2xx.rs
Normal file
15
src/output/mod.rs
Normal file
15
src/output/mod.rs
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
pub mod udprealtime;
|
||||||
|
use crate::rgb;
|
||||||
|
pub enum sockets {
|
||||||
|
udprealtime(udprealtime::Output)
|
||||||
|
}
|
||||||
|
|
||||||
|
impl sockets {
|
||||||
|
pub fn send(&self, leds: &Vec<rgb::RGB>) -> bool {
|
||||||
|
match self {
|
||||||
|
sockets::udprealtime(s) => {
|
||||||
|
s.send(&leds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
0
src/output/serial.rs
Normal file
0
src/output/serial.rs
Normal file
31
src/output/udprealtime.rs
Normal file
31
src/output/udprealtime.rs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
use std::net::{SocketAddr, UdpSocket};
|
||||||
|
use crate::rgb;
|
||||||
|
|
||||||
|
pub struct Output {
|
||||||
|
pub socket: UdpSocket,
|
||||||
|
pub target: SocketAddr
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Output {
|
||||||
|
// pub fn init(&mut self) -> bool {
|
||||||
|
// self.socket =
|
||||||
|
// return true;
|
||||||
|
// }
|
||||||
|
pub fn create(addr: SocketAddr) -> Result<Output, &'static str> {
|
||||||
|
let socket = match UdpSocket::bind("0.0.0.0:0") {
|
||||||
|
Ok(socket) => socket,
|
||||||
|
Err(_) => todo!(),
|
||||||
|
};
|
||||||
|
return Ok(Output {
|
||||||
|
socket: socket,
|
||||||
|
target: addr,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
pub fn send(&self, leds: &Vec<rgb::RGB>) -> bool {
|
||||||
|
let mut header: Vec<u8> = vec![2, 2];
|
||||||
|
let mut flattened: Vec<u8> = rgb::serialize(&leds);
|
||||||
|
header.append(&mut flattened);
|
||||||
|
let _ = &self.socket.send_to(&header, &self.target);
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
20
src/rgb.rs
Normal file
20
src/rgb.rs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RGB {
|
||||||
|
pub red: u8,
|
||||||
|
pub green: u8,
|
||||||
|
pub blue: u8
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoIterator for RGB {
|
||||||
|
type Item = u8;
|
||||||
|
type IntoIter = std::array::IntoIter<u8, 3>;
|
||||||
|
|
||||||
|
fn into_iter(self) -> Self::IntoIter {
|
||||||
|
IntoIterator::into_iter([self.red, self.green, self.blue])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize(s: &Vec<RGB>) -> Vec<u8> {
|
||||||
|
let p = s.clone();
|
||||||
|
p.into_iter().flatten().collect()
|
||||||
|
}
|
Loading…
Reference in a new issue