Skip to content

Commit

Permalink
Got some frames moving
Browse files Browse the repository at this point in the history
  • Loading branch information
DDRBoxman committed Oct 13, 2023
1 parent 3e86a88 commit 7d97d21
Show file tree
Hide file tree
Showing 10 changed files with 504 additions and 91 deletions.
264 changes: 262 additions & 2 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions cappy3ds/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ image = "0.24.7"
libusb1-sys = "0.6.4"
libc = "0.2.148"
itertools = "0.11.0"
simple-error = "0.3.0"

174 changes: 92 additions & 82 deletions cappy3ds/src/capture/katsukitty/mod.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,15 @@
use bytes::{buf, Buf, BufMut, BytesMut};
use memchr::memmem;
use rust_embed::RustEmbed;
use std::ffi::c_void;
use std::io::Write;
use std::ptr;
use std::slice;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Mutex};
use std::time::Duration;
use std::{ffi, fs, path, slice};
use std::{thread, time};
extern crate libusb1_sys as usbffi;
use bytes::BytesMut;
use simple_error::SimpleError;

use rusb::{
Context, Device, DeviceDescriptor, DeviceHandle, Direction, Recipient, RequestType, Result,
TransferType, UsbContext,
};
use rusb::{Device, DeviceDescriptor, DeviceHandle, UsbContext};

mod fpga;
mod fx2;
Expand All @@ -25,57 +20,56 @@ mod parse;
#[folder = "resources/Katsukity/"]
struct Katsukity;

pub fn do_capture() {
pub fn connect<T: UsbContext>(context: &mut T) -> Result<DeviceHandle<T>, SimpleError> {
let firmware = Katsukity::get("firm.bin").unwrap();
let bitstream = Katsukity::get("bitstream.bin").unwrap();

let vid = 0x0752;
let pid = 0x8613;

match Context::new() {
Ok(mut context) => {
let mut flashed_fx2 = false;
match open_device(&mut context, vid, pid) {
Some((mut device, device_desc, mut handle)) => {
println!("Opened {:04x}:{:04x}", vid, pid);
fx2::send_firmware(&mut handle, firmware.data.to_vec());
flashed_fx2 = true;
}
None => println!("could not find FX2 device {:04x}:{:04x}", vid, pid),
}
let mut flashed_fx2 = false;
match open_device(context, vid, pid) {
Some((mut device, device_desc, mut handle)) => {
println!("Opened {:04x}:{:04x}", vid, pid);
fx2::send_firmware(&mut handle, firmware.data.to_vec());
flashed_fx2 = true;
}
None => {
println!("could not find FX2 device");
}
}

if flashed_fx2 {
println!("Waiting for second interface");
let sleep_time = time::Duration::from_millis(5000);
thread::sleep(sleep_time);
// todo: loop with device check instead of sleeping
}
if flashed_fx2 {
println!("Waiting for second interface");
let sleep_time = time::Duration::from_millis(5000);
thread::sleep(sleep_time);
// todo: loop with device check instead of sleeping
}

match open_device(&mut context, 0x0752, 0xf2c0) {
Some((mut device, device_desc, mut handle)) => {
println!("Opened secondary device");
match handle.claim_interface(0) {
Ok(_) => {}
Err(err) => panic!("could not claim second device: {}", err),
}

// bleh apparently relesase runs fast enough to break this
// add in some sleeps
//if fpga::check_fpga_programmed(&mut handle) {
//} else {
fpga::read_eeprom(&mut handle);
fpga::configure_fpga(&mut handle, bitstream.data.to_vec());
fpga::configure_port(&mut handle);
//}

fpga::fifo_start(&mut handle);

bulk_read(&mut handle);
}
None => println!("secondary device missing, firmware upload failed?"),
match open_device(context, 0x0752, 0xf2c0) {
Some((mut device, device_desc, mut handle)) => {
println!("Opened secondary device");
match handle.claim_interface(0) {
Ok(_) => {}
Err(err) => panic!("could not claim second device: {}", err),
}

// bleh apparently relesase runs fast enough to break this
// add in some sleeps
//if fpga::check_fpga_programmed(&mut handle) {
//} else {
fpga::read_eeprom(&mut handle);
fpga::configure_fpga(&mut handle, bitstream.data.to_vec());
fpga::configure_port(&mut handle);
//}

fpga::fifo_start(&mut handle);

Ok(handle)
}
Err(e) => panic!("could not initialize libusb: {}", e),
None => Err(SimpleError::new(
"secondary device missing, firmware upload failed?",
)),
}
}

Expand Down Expand Up @@ -106,7 +100,17 @@ fn open_device<T: UsbContext>(
None
}

extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::libusb_transfer) {
pub fn do_capture<T: UsbContext, F>(handle: &mut DeviceHandle<T>, data_callback: F)
where
F: Fn(&[i16], BytesMut, BytesMut),
{
bulk_read(handle, data_callback);
}

extern "system" fn transfer_finished<T: UsbContext, F>(transfer_ptr: *mut usbffi::libusb_transfer)
where
F: Fn(&[i16], BytesMut, BytesMut),
{
let transfer: &mut usbffi::libusb_transfer = unsafe { &mut *transfer_ptr };

let user_data = transfer.user_data;
Expand All @@ -122,9 +126,9 @@ extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::l

let start = memmem::find(s, &[0x33, 0xCC, 0x00, 0x00]);

let bulk_transfer = user_data as *mut BulkTransfer;
let handler = user_data as *mut Arc<Mutex<CaptureHandler<F>>>;

let mut handler = unsafe { (*bulk_transfer).capture_handler.lock().unwrap() };
let mut handler = unsafe { (*handler).lock().unwrap() };

let current_buffer = handler.current_buffer;
let frame_buffer_len = handler.buffers[current_buffer].len();
Expand All @@ -140,15 +144,28 @@ extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::l
local_end = start;
}
} else if frame_buffer_len == 0 {
// Wait for us to get the frame start code
wait = true;
}

// if we don't need to wait for a new frame to start
if !wait {
// Move the data into the frame buffer
handler.buffers[current_buffer].extend(&s[local_offset..local_end]);

if let Some(start) = start {
if frame_buffer_len > 0 {
//println!("{:}", frame_buffer_len);
// parse since we have a frame
let (upper_buffer, lower_buffer, sound_buffer) =
parse::split_capture_buffer(&handler.buffers[current_buffer]);

let (_, short, _) = unsafe { sound_buffer.align_to::<i16>() };
(handler.data_callback)(
short,
parse::rgb565_to_rgb(&upper_buffer),
parse::rgb565_to_rgb(&lower_buffer),
);

handler.current_buffer += 1;
if handler.current_buffer >= NUM_BUFFERS {
handler.current_buffer = 0;
Expand All @@ -169,11 +186,13 @@ extern "system" fn transfer_finished<T: UsbContext>(transfer_ptr: *mut usbffi::l
}
}

struct CaptureHandler {
buffers: Vec<Vec<u8>>,
#[derive(Debug)]
struct CaptureHandler<F> {
buffers: Vec<BytesMut>,
current_buffer: usize,
new_frame: bool,
should_stop: AtomicBool,
data_callback: F,
}

const NUM_BUFFERS: usize = 20;
Expand All @@ -188,43 +207,34 @@ const FRAM_BUFFER_SIZE: usize = 720 * 248 * 2;

const TRANSFER_SIZE: usize = 0x4000;

impl CaptureHandler {
fn new() -> Self {
let mut buffers = Vec::<Vec<u8>>::with_capacity(NUM_BUFFERS);
impl<F> CaptureHandler<F>
where
F: Fn(&[i16], BytesMut, BytesMut),
{
fn new(data_callback: F) -> Self {
let mut buffers = Vec::<BytesMut>::with_capacity(NUM_BUFFERS);

for i in 0..NUM_BUFFERS {
buffers.push(Vec::<u8>::with_capacity(FRAM_BUFFER_SIZE));
buffers.push(BytesMut::with_capacity(FRAM_BUFFER_SIZE));
}

Self {
new_frame: false,
current_buffer: 0,
buffers,
should_stop: AtomicBool::new(false),
data_callback,
}
}
}

struct BulkTransfer {
//lib_usb_transfer: *mut usbffi::libusb_transfer,
capture_handler: Arc<Mutex<CaptureHandler>>,
}

impl BulkTransfer {
fn new(capture_handler: Arc<Mutex<CaptureHandler>>) -> Self {
/* let transfer;
unsafe {
// transfer = usbffi::libusb_alloc_transfer(0);
}*/

Self { capture_handler }
}
}

fn bulk_read<T: UsbContext>(handle: &mut DeviceHandle<T>) {
fn bulk_read<T: UsbContext, F>(handle: &mut DeviceHandle<T>, data_callback: F)
where
F: Fn(&[i16], BytesMut, BytesMut),
{
println!("Starting Bulk Read");

let capture_handler = Arc::new(Mutex::new(CaptureHandler::new()));
let capture_handler = Arc::new(Mutex::new(CaptureHandler::new(data_callback)));

let should_stop = Arc::new(AtomicBool::new(false));
let stop_internal = Arc::clone(&should_stop);
Expand Down Expand Up @@ -252,9 +262,9 @@ fn bulk_read<T: UsbContext>(handle: &mut DeviceHandle<T>) {

for _n in 0..10 {
let mut in_buf = [0u8; TRANSFER_SIZE];
let transfer = Box::new(BulkTransfer::new(capture_handler.clone()));
let capture_handler = Box::new(capture_handler.clone());

let raw_transfer = Box::into_raw(transfer) as *mut c_void;
let raw_transfer = Box::into_raw(capture_handler) as *mut c_void;

//transfers.push(transfer);

Expand All @@ -269,7 +279,7 @@ fn bulk_read<T: UsbContext>(handle: &mut DeviceHandle<T>) {
0x82,
in_buf.as_mut_ptr(),
TRANSFER_SIZE.try_into().unwrap(),
transfer_finished::<T> as _,
transfer_finished::<T, F> as _,
raw_transfer,
1000,
);
Expand All @@ -281,7 +291,7 @@ fn bulk_read<T: UsbContext>(handle: &mut DeviceHandle<T>) {
loop {
let current_buffer = capture_handler.lock().unwrap().current_buffer;
if current_buffer >= NUM_BUFFERS - 10 {
break;
//break;
}
//let ten_millis = time::Duration::from_millis(1);
//thread::sleep(ten_millis);
Expand Down
2 changes: 1 addition & 1 deletion cappy3ds/src/capture/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod katsukitty;
pub mod katsukitty;
48 changes: 48 additions & 0 deletions cappy3ds/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1,49 @@
mod capture;

use bytes::BytesMut;
use rusb::Context;

pub struct Cappy3ds<F> {
data_callback: F,
usb_context: Option<rusb::Context>,
device_handle: Option<rusb::DeviceHandle<rusb::Context>>,
}

impl<F> Cappy3ds<F>
where
F: Fn(&[i16], BytesMut, BytesMut),
{
pub fn new(data_callback: F) -> Self
where
F: Fn(&[i16], BytesMut, BytesMut),
{
Self {
data_callback,
usb_context: None,
device_handle: None,
}
}

pub fn connect(&mut self) {
match Context::new() {
Ok(mut context) => match capture::katsukitty::connect(&mut context) {
Ok(handle) => {
self.device_handle = Some(handle);
self.usb_context = Some(context);
}
Err(err) => {
println!("{}", err);
todo!();
}
},
Err(e) => {
println!("could not initialize libusb: {}", e);
todo!();
}
}
}

pub fn do_capture(self) {
capture::katsukitty::do_capture(&mut self.device_handle.unwrap(), self.data_callback);
}
}
2 changes: 1 addition & 1 deletion cappy3ds/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
mod capture;

fn main() {
capture::katsukitty::do_capture();
//capture::katsukitty::do_capture();
}
5 changes: 5 additions & 0 deletions cappy3ds_render/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ wgpu = "0.17"
raw-window-handle = "0.5.2"
image = "0.24.7"
futures = "0.3.28"
cpal = "0.15.2"
cappy3ds = { path = "../cappy3ds" }
ringbuf = "0.3.3"
simple-error = "0.3.0"
bytes = "1.5.0"

[lib]
name = "cappy3ds_render"
Expand Down
Binary file added cappy3ds_render/resources/test/upper_5.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 7d97d21

Please sign in to comment.