feat(stm32:qspi): convert some u8 to enum variants
This commit is contained in:
		
							
								
								
									
										294
									
								
								embassy-stm32/src/qspi/enums.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										294
									
								
								embassy-stm32/src/qspi/enums.rs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,294 @@ | ||||
| #[allow(dead_code)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub(crate) enum QspiMode { | ||||
|     IndirectWrite, | ||||
|     IndirectRead, | ||||
|     AutoPolling, | ||||
|     MemoryMapped, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for QspiMode { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             QspiMode::IndirectWrite => 0b00, | ||||
|             QspiMode::IndirectRead => 0b01, | ||||
|             QspiMode::AutoPolling => 0b10, | ||||
|             QspiMode::MemoryMapped => 0b11, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[allow(dead_code)] | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum QspiWidth { | ||||
|     NONE, | ||||
|     SING, | ||||
|     DUAL, | ||||
|     QUAD, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for QspiWidth { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             QspiWidth::NONE => 0b00, | ||||
|             QspiWidth::SING => 0b01, | ||||
|             QspiWidth::DUAL => 0b10, | ||||
|             QspiWidth::QUAD => 0b11, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum MemorySize { | ||||
|     _1KiB, | ||||
|     _2KiB, | ||||
|     _4KiB, | ||||
|     _8KiB, | ||||
|     _16KiB, | ||||
|     _32KiB, | ||||
|     _64KiB, | ||||
|     _128KiB, | ||||
|     _256KiB, | ||||
|     _512KiB, | ||||
|     _1MiB, | ||||
|     _2MiB, | ||||
|     _4MiB, | ||||
|     _8MiB, | ||||
|     _16MiB, | ||||
|     _32MiB, | ||||
|     _64MiB, | ||||
|     _128MiB, | ||||
|     _256MiB, | ||||
|     _512MiB, | ||||
|     _1GiB, | ||||
|     _2GiB, | ||||
|     _4GiB, | ||||
|     Other(u8), | ||||
| } | ||||
|  | ||||
| impl Into<u8> for MemorySize { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             MemorySize::_1KiB => 9, | ||||
|             MemorySize::_2KiB => 10, | ||||
|             MemorySize::_4KiB => 11, | ||||
|             MemorySize::_8KiB => 12, | ||||
|             MemorySize::_16KiB => 13, | ||||
|             MemorySize::_32KiB => 14, | ||||
|             MemorySize::_64KiB => 15, | ||||
|             MemorySize::_128KiB => 16, | ||||
|             MemorySize::_256KiB => 17, | ||||
|             MemorySize::_512KiB => 18, | ||||
|             MemorySize::_1MiB => 19, | ||||
|             MemorySize::_2MiB => 20, | ||||
|             MemorySize::_4MiB => 21, | ||||
|             MemorySize::_8MiB => 22, | ||||
|             MemorySize::_16MiB => 23, | ||||
|             MemorySize::_32MiB => 24, | ||||
|             MemorySize::_64MiB => 25, | ||||
|             MemorySize::_128MiB => 26, | ||||
|             MemorySize::_256MiB => 27, | ||||
|             MemorySize::_512MiB => 28, | ||||
|             MemorySize::_1GiB => 29, | ||||
|             MemorySize::_2GiB => 30, | ||||
|             MemorySize::_4GiB => 31, | ||||
|             MemorySize::Other(val) => val, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum AddressSize { | ||||
|     _8Bit, | ||||
|     _16Bit, | ||||
|     _24bit, | ||||
|     _32bit, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for AddressSize { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             AddressSize::_8Bit => 0b00, | ||||
|             AddressSize::_16Bit => 0b01, | ||||
|             AddressSize::_24bit => 0b10, | ||||
|             AddressSize::_32bit => 0b11, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum ChipSelectHightTime { | ||||
|     _1Cycle, | ||||
|     _2Cycle, | ||||
|     _3Cycle, | ||||
|     _4Cycle, | ||||
|     _5Cycle, | ||||
|     _6Cycle, | ||||
|     _7Cycle, | ||||
|     _8Cycle, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for ChipSelectHightTime { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             ChipSelectHightTime::_1Cycle => 0, | ||||
|             ChipSelectHightTime::_2Cycle => 1, | ||||
|             ChipSelectHightTime::_3Cycle => 2, | ||||
|             ChipSelectHightTime::_4Cycle => 3, | ||||
|             ChipSelectHightTime::_5Cycle => 4, | ||||
|             ChipSelectHightTime::_6Cycle => 5, | ||||
|             ChipSelectHightTime::_7Cycle => 6, | ||||
|             ChipSelectHightTime::_8Cycle => 7, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum FIFOThresholdLevel { | ||||
|     _1Bytes, | ||||
|     _2Bytes, | ||||
|     _3Bytes, | ||||
|     _4Bytes, | ||||
|     _5Bytes, | ||||
|     _6Bytes, | ||||
|     _7Bytes, | ||||
|     _8Bytes, | ||||
|     _9Bytes, | ||||
|     _10Bytes, | ||||
|     _11Bytes, | ||||
|     _12Bytes, | ||||
|     _13Bytes, | ||||
|     _14Bytes, | ||||
|     _15Bytes, | ||||
|     _16Bytes, | ||||
|     _17Bytes, | ||||
|     _18Bytes, | ||||
|     _19Bytes, | ||||
|     _20Bytes, | ||||
|     _21Bytes, | ||||
|     _22Bytes, | ||||
|     _23Bytes, | ||||
|     _24Bytes, | ||||
|     _25Bytes, | ||||
|     _26Bytes, | ||||
|     _27Bytes, | ||||
|     _28Bytes, | ||||
|     _29Bytes, | ||||
|     _30Bytes, | ||||
|     _31Bytes, | ||||
|     _32Bytes, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for FIFOThresholdLevel { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             FIFOThresholdLevel::_1Bytes => 0, | ||||
|             FIFOThresholdLevel::_2Bytes => 1, | ||||
|             FIFOThresholdLevel::_3Bytes => 2, | ||||
|             FIFOThresholdLevel::_4Bytes => 3, | ||||
|             FIFOThresholdLevel::_5Bytes => 4, | ||||
|             FIFOThresholdLevel::_6Bytes => 5, | ||||
|             FIFOThresholdLevel::_7Bytes => 6, | ||||
|             FIFOThresholdLevel::_8Bytes => 7, | ||||
|             FIFOThresholdLevel::_9Bytes => 8, | ||||
|             FIFOThresholdLevel::_10Bytes => 9, | ||||
|             FIFOThresholdLevel::_11Bytes => 10, | ||||
|             FIFOThresholdLevel::_12Bytes => 11, | ||||
|             FIFOThresholdLevel::_13Bytes => 12, | ||||
|             FIFOThresholdLevel::_14Bytes => 13, | ||||
|             FIFOThresholdLevel::_15Bytes => 14, | ||||
|             FIFOThresholdLevel::_16Bytes => 15, | ||||
|             FIFOThresholdLevel::_17Bytes => 16, | ||||
|             FIFOThresholdLevel::_18Bytes => 17, | ||||
|             FIFOThresholdLevel::_19Bytes => 18, | ||||
|             FIFOThresholdLevel::_20Bytes => 19, | ||||
|             FIFOThresholdLevel::_21Bytes => 20, | ||||
|             FIFOThresholdLevel::_22Bytes => 21, | ||||
|             FIFOThresholdLevel::_23Bytes => 22, | ||||
|             FIFOThresholdLevel::_24Bytes => 23, | ||||
|             FIFOThresholdLevel::_25Bytes => 24, | ||||
|             FIFOThresholdLevel::_26Bytes => 25, | ||||
|             FIFOThresholdLevel::_27Bytes => 26, | ||||
|             FIFOThresholdLevel::_28Bytes => 27, | ||||
|             FIFOThresholdLevel::_29Bytes => 28, | ||||
|             FIFOThresholdLevel::_30Bytes => 29, | ||||
|             FIFOThresholdLevel::_31Bytes => 30, | ||||
|             FIFOThresholdLevel::_32Bytes => 31, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| #[derive(Copy, Clone)] | ||||
| pub enum DummyCycles { | ||||
|     _0, | ||||
|     _1, | ||||
|     _2, | ||||
|     _3, | ||||
|     _4, | ||||
|     _5, | ||||
|     _6, | ||||
|     _7, | ||||
|     _8, | ||||
|     _9, | ||||
|     _10, | ||||
|     _11, | ||||
|     _12, | ||||
|     _13, | ||||
|     _14, | ||||
|     _15, | ||||
|     _16, | ||||
|     _17, | ||||
|     _18, | ||||
|     _19, | ||||
|     _20, | ||||
|     _21, | ||||
|     _22, | ||||
|     _23, | ||||
|     _24, | ||||
|     _25, | ||||
|     _26, | ||||
|     _27, | ||||
|     _28, | ||||
|     _29, | ||||
|     _30, | ||||
|     _31, | ||||
| } | ||||
|  | ||||
| impl Into<u8> for DummyCycles { | ||||
|     fn into(self) -> u8 { | ||||
|         match self { | ||||
|             DummyCycles::_0 => 0, | ||||
|             DummyCycles::_1 => 1, | ||||
|             DummyCycles::_2 => 2, | ||||
|             DummyCycles::_3 => 3, | ||||
|             DummyCycles::_4 => 4, | ||||
|             DummyCycles::_5 => 5, | ||||
|             DummyCycles::_6 => 6, | ||||
|             DummyCycles::_7 => 7, | ||||
|             DummyCycles::_8 => 8, | ||||
|             DummyCycles::_9 => 9, | ||||
|             DummyCycles::_10 => 10, | ||||
|             DummyCycles::_11 => 11, | ||||
|             DummyCycles::_12 => 12, | ||||
|             DummyCycles::_13 => 13, | ||||
|             DummyCycles::_14 => 14, | ||||
|             DummyCycles::_15 => 15, | ||||
|             DummyCycles::_16 => 16, | ||||
|             DummyCycles::_17 => 17, | ||||
|             DummyCycles::_18 => 18, | ||||
|             DummyCycles::_19 => 19, | ||||
|             DummyCycles::_20 => 20, | ||||
|             DummyCycles::_21 => 21, | ||||
|             DummyCycles::_22 => 22, | ||||
|             DummyCycles::_23 => 23, | ||||
|             DummyCycles::_24 => 24, | ||||
|             DummyCycles::_25 => 25, | ||||
|             DummyCycles::_26 => 26, | ||||
|             DummyCycles::_27 => 27, | ||||
|             DummyCycles::_28 => 28, | ||||
|             DummyCycles::_29 => 29, | ||||
|             DummyCycles::_30 => 30, | ||||
|             DummyCycles::_31 => 31, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -1,6 +1,9 @@ | ||||
| #![macro_use] | ||||
|  | ||||
| pub mod enums; | ||||
|  | ||||
| use embassy_hal_common::{into_ref, PeripheralRef}; | ||||
| use enums::*; | ||||
|  | ||||
| use crate::dma::TransferOptions; | ||||
| use crate::gpio::sealed::AFType; | ||||
| @@ -9,37 +12,24 @@ use crate::pac::quadspi::Quadspi as Regs; | ||||
| use crate::rcc::RccPeripheral; | ||||
| use crate::{peripherals, Peripheral}; | ||||
|  | ||||
| pub struct QspiWidth; | ||||
|  | ||||
| #[allow(dead_code)] | ||||
| impl QspiWidth { | ||||
|     pub const NONE: u8 = 0b00; | ||||
|     pub const SING: u8 = 0b01; | ||||
|     pub const DUAL: u8 = 0b10; | ||||
|     pub const QUAD: u8 = 0b11; | ||||
| } | ||||
|  | ||||
| struct QspiMode; | ||||
|  | ||||
| #[allow(dead_code)] | ||||
| impl QspiMode { | ||||
|     pub const INDIRECT_WRITE: u8 = 0b00; | ||||
|     pub const INDIRECT_READ: u8 = 0b01; | ||||
|     pub const AUTO_POLLING: u8 = 0b10; | ||||
|     pub const MEMORY_MAPPED: u8 = 0b11; | ||||
| } | ||||
|  | ||||
| pub struct QspiTransaction { | ||||
|     pub iwidth: u8, | ||||
|     pub awidth: u8, | ||||
|     pub dwidth: u8, | ||||
| pub struct TransferConfig { | ||||
|     /// Instraction width (IMODE) | ||||
|     pub iwidth: QspiWidth, | ||||
|     /// Address width (ADMODE) | ||||
|     pub awidth: QspiWidth, | ||||
|     /// Data width (DMODE) | ||||
|     pub dwidth: QspiWidth, | ||||
|     /// Instruction Id | ||||
|     pub instruction: u8, | ||||
|     /// Flash memory address | ||||
|     pub address: Option<u32>, | ||||
|     pub dummy: u8, | ||||
|     /// Number of dummy cycles (DCYC) | ||||
|     pub dummy: DummyCycles, | ||||
|     /// Length of data | ||||
|     pub data_len: Option<usize>, | ||||
| } | ||||
|  | ||||
| impl Default for QspiTransaction { | ||||
| impl Default for TransferConfig { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             iwidth: QspiWidth::NONE, | ||||
| @@ -47,28 +37,34 @@ impl Default for QspiTransaction { | ||||
|             dwidth: QspiWidth::NONE, | ||||
|             instruction: 0, | ||||
|             address: None, | ||||
|             dummy: 0, | ||||
|             dummy: DummyCycles::_0, | ||||
|             data_len: None, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub struct Config { | ||||
|     pub memory_size: u8, | ||||
|     pub address_size: u8, | ||||
|     /// Flash memory size representend as 2^[0-32], as reasonable minimum 1KiB(9) was chosen. | ||||
|     /// If you need other value the whose predefined use `Other` variant. | ||||
|     pub memory_size: MemorySize, | ||||
|     /// Address size (8/16/24/32-bit) | ||||
|     pub address_size: AddressSize, | ||||
|     /// Scalar factor for generating CLK [0-255] | ||||
|     pub prescaler: u8, | ||||
|     pub fifo_threshold: u8, | ||||
|     pub cs_high_time: u8, | ||||
|     /// Number of bytes to trigger FIFO threshold flag. | ||||
|     pub fifo_threshold: FIFOThresholdLevel, | ||||
|     /// Minimum number of cycles that chip select must be high between issued commands | ||||
|     pub cs_high_time: ChipSelectHightTime, | ||||
| } | ||||
|  | ||||
| impl Default for Config { | ||||
|     fn default() -> Self { | ||||
|         Self { | ||||
|             memory_size: 0, | ||||
|             address_size: 2, | ||||
|             memory_size: MemorySize::Other(0), | ||||
|             address_size: AddressSize::_24bit, | ||||
|             prescaler: 128, | ||||
|             fifo_threshold: 16, | ||||
|             cs_high_time: 4, | ||||
|             fifo_threshold: FIFOThresholdLevel::_17Bytes, | ||||
|             cs_high_time: ChipSelectHightTime::_5Cycle, | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -143,7 +139,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|  | ||||
|         T::enable(); | ||||
|         unsafe { | ||||
|             T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold)); | ||||
|             T::REGS.cr().write(|w| w.set_fthres(config.fifo_threshold.into())); | ||||
|  | ||||
|             while T::REGS.sr().read().busy() {} | ||||
|  | ||||
| @@ -152,8 +148,8 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|                 w.set_en(true); | ||||
|             }); | ||||
|             T::REGS.dcr().write(|w| { | ||||
|                 w.set_fsize(config.memory_size); | ||||
|                 w.set_csht(config.cs_high_time); | ||||
|                 w.set_fsize(config.memory_size.into()); | ||||
|                 w.set_csht(config.cs_high_time.into()); | ||||
|                 w.set_ckmode(false); | ||||
|             }); | ||||
|         } | ||||
| @@ -171,25 +167,25 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn command(&mut self, transaction: QspiTransaction) { | ||||
|     pub fn command(&mut self, transaction: TransferConfig) { | ||||
|         unsafe { | ||||
|             T::REGS.cr().modify(|v| v.set_dmaen(false)); | ||||
|             self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); | ||||
|             self.setup_transaction(QspiMode::IndirectWrite, &transaction); | ||||
|  | ||||
|             while !T::REGS.sr().read().tcf() {} | ||||
|             T::REGS.fcr().modify(|v| v.set_ctcf(true)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn read(&mut self, buf: &mut [u8], transaction: QspiTransaction) { | ||||
|     pub fn blocking_read(&mut self, buf: &mut [u8], transaction: TransferConfig) { | ||||
|         unsafe { | ||||
|             T::REGS.cr().modify(|v| v.set_dmaen(false)); | ||||
|             self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); | ||||
|             self.setup_transaction(QspiMode::IndirectWrite, &transaction); | ||||
|  | ||||
|             if let Some(len) = transaction.data_len { | ||||
|                 let current_ar = T::REGS.ar().read().address(); | ||||
|                 T::REGS.ccr().modify(|v| { | ||||
|                     v.set_fmode(QspiMode::INDIRECT_READ); | ||||
|                     v.set_fmode(QspiMode::IndirectRead.into()); | ||||
|                 }); | ||||
|                 T::REGS.ar().write(|v| { | ||||
|                     v.set_address(current_ar); | ||||
| @@ -206,14 +202,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn write(&mut self, buf: &[u8], transaction: QspiTransaction) { | ||||
|     pub fn blocking_write(&mut self, buf: &[u8], transaction: TransferConfig) { | ||||
|         unsafe { | ||||
|             T::REGS.cr().modify(|v| v.set_dmaen(false)); | ||||
|             self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); | ||||
|             self.setup_transaction(QspiMode::IndirectWrite, &transaction); | ||||
|  | ||||
|             if let Some(len) = transaction.data_len { | ||||
|                 T::REGS.ccr().modify(|v| { | ||||
|                     v.set_fmode(QspiMode::INDIRECT_WRITE); | ||||
|                     v.set_fmode(QspiMode::IndirectWrite.into()); | ||||
|                 }); | ||||
|  | ||||
|                 for idx in 0..len { | ||||
| @@ -227,18 +223,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn read_dma(&mut self, buf: &mut [u8], transaction: QspiTransaction) | ||||
|     pub fn blocking_read_dma(&mut self, buf: &mut [u8], transaction: TransferConfig) | ||||
|     where | ||||
|         Dma: QuadDma<T>, | ||||
|     { | ||||
|         unsafe { | ||||
|             self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); | ||||
|             self.setup_transaction(QspiMode::IndirectWrite, &transaction); | ||||
|  | ||||
|             let request = self.dma.request(); | ||||
|             let options = TransferOptions::default(); | ||||
|  | ||||
|             T::REGS.ccr().modify(|v| { | ||||
|                 v.set_fmode(QspiMode::INDIRECT_READ); | ||||
|                 v.set_fmode(QspiMode::IndirectRead.into()); | ||||
|             }); | ||||
|             let current_ar = T::REGS.ar().read().address(); | ||||
|             T::REGS.ar().write(|v| { | ||||
| @@ -254,18 +250,18 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     pub fn write_dma(&mut self, buf: &[u8], transaction: QspiTransaction) | ||||
|     pub fn blocking_write_dma(&mut self, buf: &[u8], transaction: TransferConfig) | ||||
|     where | ||||
|         Dma: QuadDma<T>, | ||||
|     { | ||||
|         unsafe { | ||||
|             self.setup_transaction(QspiMode::INDIRECT_WRITE, &transaction); | ||||
|             self.setup_transaction(QspiMode::IndirectWrite, &transaction); | ||||
|  | ||||
|             let request = self.dma.request(); | ||||
|             let options = TransferOptions::default(); | ||||
|  | ||||
|             T::REGS.ccr().modify(|v| { | ||||
|                 v.set_fmode(QspiMode::INDIRECT_WRITE); | ||||
|                 v.set_fmode(QspiMode::IndirectWrite.into()); | ||||
|             }); | ||||
|  | ||||
|             self.dma | ||||
| @@ -277,7 +273,7 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fn setup_transaction(&mut self, fmode: u8, transaction: &QspiTransaction) { | ||||
|     fn setup_transaction(&mut self, fmode: QspiMode, transaction: &TransferConfig) { | ||||
|         unsafe { | ||||
|             T::REGS.fcr().modify(|v| { | ||||
|                 v.set_csmf(true); | ||||
| @@ -293,14 +289,14 @@ impl<'d, T: Instance, Dma> Qspi<'d, T, Dma> { | ||||
|             } | ||||
|  | ||||
|             T::REGS.ccr().write(|v| { | ||||
|                 v.set_fmode(fmode); | ||||
|                 v.set_imode(transaction.iwidth); | ||||
|                 v.set_fmode(fmode.into()); | ||||
|                 v.set_imode(transaction.iwidth.into()); | ||||
|                 v.set_instruction(transaction.instruction); | ||||
|                 v.set_admode(transaction.awidth); | ||||
|                 v.set_adsize(self.config.address_size); | ||||
|                 v.set_dmode(transaction.dwidth); | ||||
|                 v.set_abmode(QspiWidth::NONE); | ||||
|                 v.set_dcyc(transaction.dummy); | ||||
|                 v.set_admode(transaction.awidth.into()); | ||||
|                 v.set_adsize(self.config.address_size.into()); | ||||
|                 v.set_dmode(transaction.dwidth.into()); | ||||
|                 v.set_abmode(QspiWidth::NONE.into()); | ||||
|                 v.set_dcyc(transaction.dummy.into()); | ||||
|             }); | ||||
|  | ||||
|             if let Some(addr) = transaction.address { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user