PIO support for RPi Pico
This commit is contained in:
		| @@ -26,6 +26,7 @@ time-driver = [] | |||||||
| rom-func-cache = [] | rom-func-cache = [] | ||||||
| intrinsics = [] | intrinsics = [] | ||||||
| rom-v2-intrinsics = [] | rom-v2-intrinsics = [] | ||||||
|  | pio = ["dep:pio", "dep:pio-proc"] | ||||||
|  |  | ||||||
| # Enable nightly-only features | # Enable nightly-only features | ||||||
| nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] | nightly = ["embassy-executor/nightly", "embedded-hal-1", "embedded-hal-async", "embassy-embedded-hal/nightly", "dep:embassy-usb-driver", "dep:embedded-io"] | ||||||
| @@ -64,3 +65,10 @@ embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["un | |||||||
| embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true} | embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9", optional = true} | ||||||
| embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true} | embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true} | ||||||
| embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true} | embedded-hal-nb = { version = "=1.0.0-alpha.1", optional = true} | ||||||
|  |  | ||||||
|  | paste = "1.0" | ||||||
|  | pio-proc = {version= "0.2", optional = true} | ||||||
|  | pio = {version= "0.2", optional = true} | ||||||
|  |  | ||||||
|  | [patch.crates-io] | ||||||
|  | pio = {git = "https://github.com/rp-rs/pio-rs.git"} | ||||||
| @@ -48,6 +48,21 @@ pub enum Pull { | |||||||
|     Down, |     Down, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /// Drive strength of an output | ||||||
|  | #[derive(Debug, Eq, PartialEq)] | ||||||
|  | pub enum Drive { | ||||||
|  |     _2mA, | ||||||
|  |     _4mA, | ||||||
|  |     _8mA, | ||||||
|  |     _12mA, | ||||||
|  | } | ||||||
|  | /// Slew rate of an output | ||||||
|  | #[derive(Debug, Eq, PartialEq)] | ||||||
|  | pub enum SlewRate { | ||||||
|  |     Fast, | ||||||
|  |     Slow, | ||||||
|  | } | ||||||
|  |  | ||||||
| /// A GPIO bank with up to 32 pins. | /// A GPIO bank with up to 32 pins. | ||||||
| #[derive(Debug, Eq, PartialEq)] | #[derive(Debug, Eq, PartialEq)] | ||||||
| pub enum Bank { | pub enum Bank { | ||||||
| @@ -459,7 +474,7 @@ impl<'d, T: Pin> Flex<'d, T> { | |||||||
|     #[inline] |     #[inline] | ||||||
|     pub fn set_pull(&mut self, pull: Pull) { |     pub fn set_pull(&mut self, pull: Pull) { | ||||||
|         unsafe { |         unsafe { | ||||||
|             self.pin.pad_ctrl().write(|w| { |             self.pin.pad_ctrl().modify(|w| { | ||||||
|                 w.set_ie(true); |                 w.set_ie(true); | ||||||
|                 match pull { |                 match pull { | ||||||
|                     Pull::Up => w.set_pue(true), |                     Pull::Up => w.set_pue(true), | ||||||
| @@ -470,6 +485,31 @@ impl<'d, T: Pin> Flex<'d, T> { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /// Set the pin's drive strength. | ||||||
|  |     #[inline] | ||||||
|  |     pub fn set_drive_strength(&mut self, strength: Drive) { | ||||||
|  |         unsafe { | ||||||
|  |             self.pin.pad_ctrl().modify(|w| { | ||||||
|  |                 w.set_drive(match strength { | ||||||
|  |                     Drive::_2mA => pac::pads::vals::Drive::_2MA, | ||||||
|  |                     Drive::_4mA => pac::pads::vals::Drive::_4MA, | ||||||
|  |                     Drive::_8mA => pac::pads::vals::Drive::_8MA, | ||||||
|  |                     Drive::_12mA => pac::pads::vals::Drive::_12MA, | ||||||
|  |                 }); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Set the pin's slew rate. | ||||||
|  |     #[inline] | ||||||
|  |     pub fn set_slew_rate(&mut self, slew_rate: SlewRate) { | ||||||
|  |         unsafe { | ||||||
|  |             self.pin.pad_ctrl().modify(|w| { | ||||||
|  |                 w.set_slewfast(slew_rate == SlewRate::Fast); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /// Put the pin into input mode. |     /// Put the pin into input mode. | ||||||
|     /// |     /// | ||||||
|     /// The pull setting is left unchanged. |     /// The pull setting is left unchanged. | ||||||
|   | |||||||
| @@ -12,6 +12,12 @@ pub mod dma; | |||||||
| pub mod gpio; | pub mod gpio; | ||||||
| pub mod i2c; | pub mod i2c; | ||||||
| pub mod interrupt; | pub mod interrupt; | ||||||
|  |  | ||||||
|  | #[cfg(feature = "pio")] | ||||||
|  | pub mod pio; | ||||||
|  | #[cfg(feature = "pio")] | ||||||
|  | pub mod pio_instr_util; | ||||||
|  |  | ||||||
| pub mod rom_data; | pub mod rom_data; | ||||||
| pub mod rtc; | pub mod rtc; | ||||||
| pub mod spi; | pub mod spi; | ||||||
| @@ -102,6 +108,9 @@ embassy_hal_common::peripherals! { | |||||||
|     FLASH, |     FLASH, | ||||||
|  |  | ||||||
|     ADC, |     ADC, | ||||||
|  |  | ||||||
|  |     PIO0, | ||||||
|  |     PIO1, | ||||||
| } | } | ||||||
|  |  | ||||||
| #[link_section = ".boot2"] | #[link_section = ".boot2"] | ||||||
|   | |||||||
							
								
								
									
										1250
									
								
								embassy-rp/src/pio.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1250
									
								
								embassy-rp/src/pio.rs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										90
									
								
								embassy-rp/src/pio_instr_util.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								embassy-rp/src/pio_instr_util.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,90 @@ | |||||||
|  | use pio::{InSource, InstructionOperands, JmpCondition, OutDestination, SetDestination}; | ||||||
|  |  | ||||||
|  | use crate::pio::PioStateMachine; | ||||||
|  |  | ||||||
|  | pub fn set_x<SM: PioStateMachine>(sm: &mut SM, value: u32) { | ||||||
|  |     const OUT: u16 = InstructionOperands::OUT { | ||||||
|  |         destination: OutDestination::X, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.push_tx(value); | ||||||
|  |     sm.exec_instr(OUT); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn get_x<SM: PioStateMachine>(sm: &mut SM) -> u32 { | ||||||
|  |     const IN: u16 = InstructionOperands::IN { | ||||||
|  |         source: InSource::X, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.exec_instr(IN); | ||||||
|  |     sm.pull_rx() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn set_y<SM: PioStateMachine>(sm: &mut SM, value: u32) { | ||||||
|  |     const OUT: u16 = InstructionOperands::OUT { | ||||||
|  |         destination: OutDestination::Y, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.push_tx(value); | ||||||
|  |     sm.exec_instr(OUT); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn get_y<SM: PioStateMachine>(sm: &mut SM) -> u32 { | ||||||
|  |     const IN: u16 = InstructionOperands::IN { | ||||||
|  |         source: InSource::Y, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.exec_instr(IN); | ||||||
|  |  | ||||||
|  |     sm.pull_rx() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn set_pindir<SM: PioStateMachine>(sm: &mut SM, data: u8) { | ||||||
|  |     let set: u16 = InstructionOperands::SET { | ||||||
|  |         destination: SetDestination::PINDIRS, | ||||||
|  |         data, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.exec_instr(set); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn set_pin<SM: PioStateMachine>(sm: &mut SM, data: u8) { | ||||||
|  |     let set: u16 = InstructionOperands::SET { | ||||||
|  |         destination: SetDestination::PINS, | ||||||
|  |         data, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.exec_instr(set); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn set_out_pin<SM: PioStateMachine>(sm: &mut SM, data: u32) { | ||||||
|  |     const OUT: u16 = InstructionOperands::OUT { | ||||||
|  |         destination: OutDestination::PINS, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.push_tx(data); | ||||||
|  |     sm.exec_instr(OUT); | ||||||
|  | } | ||||||
|  | pub fn set_out_pindir<SM: PioStateMachine>(sm: &mut SM, data: u32) { | ||||||
|  |     const OUT: u16 = InstructionOperands::OUT { | ||||||
|  |         destination: OutDestination::PINDIRS, | ||||||
|  |         bit_count: 32, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.push_tx(data); | ||||||
|  |     sm.exec_instr(OUT); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pub fn exec_jmp<SM: PioStateMachine>(sm: &mut SM, to_addr: u8) { | ||||||
|  |     let jmp: u16 = InstructionOperands::JMP { | ||||||
|  |         address: to_addr, | ||||||
|  |         condition: JmpCondition::Always, | ||||||
|  |     } | ||||||
|  |     .encode(); | ||||||
|  |     sm.exec_instr(jmp); | ||||||
|  | } | ||||||
| @@ -9,7 +9,7 @@ license = "MIT OR Apache-2.0" | |||||||
| embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | ||||||
| embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | ||||||
| embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | ||||||
| embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver"] } | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio"] } | ||||||
| embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | ||||||
| embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] } | embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "pool-16"] } | ||||||
| embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | ||||||
| @@ -34,6 +34,11 @@ embedded-io = { version = "0.4.0", features = ["async", "defmt"] } | |||||||
| embedded-storage = { version = "0.3" } | embedded-storage = { version = "0.3" } | ||||||
| static_cell = "1.0.0" | static_cell = "1.0.0" | ||||||
| log = "0.4" | log = "0.4" | ||||||
|  | pio-proc = "0.2" | ||||||
|  | pio = "0.2" | ||||||
|  |  | ||||||
| [profile.release] | [profile.release] | ||||||
| debug = true | debug = true | ||||||
|  |  | ||||||
|  | [patch.crates-io] | ||||||
|  | pio = {git = "https://github.com/rp-rs/pio-rs.git"} | ||||||
							
								
								
									
										105
									
								
								examples/rp/src/bin/pio_async.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								examples/rp/src/bin/pio_async.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | |||||||
|  | #![no_std] | ||||||
|  | #![no_main] | ||||||
|  | #![feature(type_alias_impl_trait)] | ||||||
|  | use defmt::info; | ||||||
|  | use embassy_executor::Spawner; | ||||||
|  | use embassy_rp::gpio::{AnyPin, Pin}; | ||||||
|  | use embassy_rp::pio::{Pio0, PioPeripherial, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2}; | ||||||
|  | use embassy_rp::pio_instr_util; | ||||||
|  | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
|  | #[embassy_executor::task] | ||||||
|  | async fn pio_task_sm0(mut sm: PioStateMachineInstance<Pio0, Sm0>, pin: AnyPin) { | ||||||
|  |     // Setup sm0 | ||||||
|  |  | ||||||
|  |     // Send data serially to pin | ||||||
|  |     let prg = pio_proc::pio_asm!( | ||||||
|  |         ".origin 16", | ||||||
|  |         "set pindirs, 1", | ||||||
|  |         ".wrap_target", | ||||||
|  |         "out pins,1 [19]", | ||||||
|  |         ".wrap", | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     let origin = prg.program.origin.unwrap_or(0); | ||||||
|  |     let out_pin = sm.make_pio_pin(pin); | ||||||
|  |     let pio_pins = [&out_pin]; | ||||||
|  |     sm.set_out_pins(&pio_pins); | ||||||
|  |     sm.write_instr(origin as usize, &prg.program.code); | ||||||
|  |     pio_instr_util::exec_jmp(&mut sm, origin); | ||||||
|  |     sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); | ||||||
|  |     sm.set_set_range(0, 1); | ||||||
|  |     sm.set_wrap(prg.program.wrap.source + origin, prg.program.wrap.target + origin); | ||||||
|  |     sm.set_autopull(true); | ||||||
|  |     sm.set_out_shift_dir(ShiftDirection::Left); | ||||||
|  |  | ||||||
|  |     sm.set_enable(true); | ||||||
|  |  | ||||||
|  |     let mut v = 0x0f0caffa; | ||||||
|  |     loop { | ||||||
|  |         sm.wait_push(v).await; | ||||||
|  |         v ^= 0xffff; | ||||||
|  |         info!("Pushed {:032b} to FIFO", v); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[embassy_executor::task] | ||||||
|  | async fn pio_task_sm1(mut sm: PioStateMachineInstance<Pio0, Sm1>) { | ||||||
|  |     // Setupm sm1 | ||||||
|  |  | ||||||
|  |     // Read 0b10101 repeatedly until ISR is full | ||||||
|  |     let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); | ||||||
|  |  | ||||||
|  |     let origin = prg.program.origin.unwrap_or(0); | ||||||
|  |     sm.write_instr(origin as usize, &prg.program.code); | ||||||
|  |     pio_instr_util::exec_jmp(&mut sm, origin); | ||||||
|  |     sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | ||||||
|  |     sm.set_set_range(0, 0); | ||||||
|  |     sm.set_wrap(prg.program.wrap.source + origin, prg.program.wrap.target + origin); | ||||||
|  |     sm.set_autopush(true); | ||||||
|  |     sm.set_in_shift_dir(ShiftDirection::Right); | ||||||
|  |     sm.set_enable(true); | ||||||
|  |     loop { | ||||||
|  |         let rx = sm.wait_pull().await; | ||||||
|  |         info!("Pulled {:032b} from FIFO", rx); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[embassy_executor::task] | ||||||
|  | async fn pio_task_sm2(mut sm: PioStateMachineInstance<Pio0, Sm2>) { | ||||||
|  |     // Setup sm2 | ||||||
|  |  | ||||||
|  |     // Repeatedly trigger IRQ 3 | ||||||
|  |     let prg = pio_proc::pio_asm!( | ||||||
|  |         ".origin 0", | ||||||
|  |         ".wrap_target", | ||||||
|  |         "set x,10", | ||||||
|  |         "delay:", | ||||||
|  |         "jmp x-- delay [15]", | ||||||
|  |         "irq 3 [15]", | ||||||
|  |         ".wrap", | ||||||
|  |     ); | ||||||
|  |     let origin = prg.program.origin.unwrap_or(0); | ||||||
|  |  | ||||||
|  |     sm.write_instr(origin as usize, &prg.program.code); | ||||||
|  |     sm.set_wrap(prg.program.wrap.source + origin, prg.program.wrap.target + origin); | ||||||
|  |     pio_instr_util::exec_jmp(&mut sm, origin); | ||||||
|  |     sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | ||||||
|  |     sm.set_enable(true); | ||||||
|  |     loop { | ||||||
|  |         sm.wait_irq(3).await; | ||||||
|  |         info!("IRQ trigged"); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[embassy_executor::main] | ||||||
|  | async fn main(spawner: Spawner) { | ||||||
|  |     let p = embassy_rp::init(Default::default()); | ||||||
|  |     let pio = p.PIO0; | ||||||
|  |  | ||||||
|  |     let (_, sm0, sm1, sm2, ..) = pio.split(); | ||||||
|  |  | ||||||
|  |     spawner.spawn(pio_task_sm0(sm0, p.PIN_0.degrade())).unwrap(); | ||||||
|  |     spawner.spawn(pio_task_sm1(sm1)).unwrap(); | ||||||
|  |     spawner.spawn(pio_task_sm2(sm2)).unwrap(); | ||||||
|  | } | ||||||
							
								
								
									
										67
									
								
								examples/rp/src/bin/pio_dma.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								examples/rp/src/bin/pio_dma.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | |||||||
|  | #![no_std] | ||||||
|  | #![no_main] | ||||||
|  | #![feature(type_alias_impl_trait)] | ||||||
|  | use defmt::info; | ||||||
|  | use embassy_executor::Spawner; | ||||||
|  | use embassy_futures::join::join; | ||||||
|  | use embassy_rp::pio::{PioPeripherial, PioStateMachine, ShiftDirection}; | ||||||
|  | use embassy_rp::{pio_instr_util, Peripheral}; | ||||||
|  | use {defmt_rtt as _, panic_probe as _}; | ||||||
|  |  | ||||||
|  | fn swap_nibbles(v: u32) -> u32 { | ||||||
|  |     let v = (v & 0x0f0f_0f0f) << 4 | (v & 0xf0f0_f0f0) >> 4; | ||||||
|  |     let v = (v & 0x00ff_00ff) << 8 | (v & 0xff00_ff00) >> 8; | ||||||
|  |     (v & 0x0000_ffff) << 16 | (v & 0xffff_0000) >> 16 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #[embassy_executor::main] | ||||||
|  | async fn main(_spawner: Spawner) { | ||||||
|  |     let p = embassy_rp::init(Default::default()); | ||||||
|  |     let pio = p.PIO0; | ||||||
|  |     let (_, mut sm, ..) = pio.split(); | ||||||
|  |  | ||||||
|  |     let prg = pio_proc::pio_asm!( | ||||||
|  |         ".origin 0", | ||||||
|  |         "set pindirs,1", | ||||||
|  |         ".wrap_target", | ||||||
|  |         "set y,7", | ||||||
|  |         "loop:", | ||||||
|  |         "out x,4", | ||||||
|  |         "in x,4", | ||||||
|  |         "jmp y--, loop", | ||||||
|  |         ".wrap", | ||||||
|  |     ); | ||||||
|  |  | ||||||
|  |     let origin = prg.program.origin.unwrap_or(0); | ||||||
|  |     sm.write_instr(origin as usize, &prg.program.code); | ||||||
|  |     pio_instr_util::exec_jmp(&mut sm, origin); | ||||||
|  |     sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); | ||||||
|  |     sm.set_wrap(prg.program.wrap.source + origin, prg.program.wrap.target + origin); | ||||||
|  |     sm.set_autopull(true); | ||||||
|  |     sm.set_autopush(true); | ||||||
|  |     sm.set_pull_threshold(32); | ||||||
|  |     sm.set_push_threshold(32); | ||||||
|  |     sm.set_out_shift_dir(ShiftDirection::Right); | ||||||
|  |     sm.set_in_shift_dir(ShiftDirection::Left); | ||||||
|  |  | ||||||
|  |     sm.set_enable(true); | ||||||
|  |  | ||||||
|  |     let mut dma_out_ref = p.DMA_CH0.into_ref(); | ||||||
|  |     let mut dma_in_ref = p.DMA_CH1.into_ref(); | ||||||
|  |     let mut dout = [0x12345678u32; 29]; | ||||||
|  |     for i in 1..dout.len() { | ||||||
|  |         dout[i] = (dout[i - 1] & 0x0fff_ffff) * 13 + 7; | ||||||
|  |     } | ||||||
|  |     let mut din = [0u32; 29]; | ||||||
|  |     loop { | ||||||
|  |         join( | ||||||
|  |             sm.dma_push(dma_out_ref.reborrow(), &dout), | ||||||
|  |             sm.dma_pull(dma_in_ref.reborrow(), &mut din), | ||||||
|  |         ) | ||||||
|  |         .await; | ||||||
|  |         for i in 0..din.len() { | ||||||
|  |             assert_eq!(din[i], swap_nibbles(dout[i])); | ||||||
|  |         } | ||||||
|  |         info!("Swapped {} words", dout.len()); | ||||||
|  |     } | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user