Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/rt685s-evk/src/bin/flexspi-storage-service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,8 @@ async fn main(_spawner: Spawner) {
rx_watermark: 0x8,
tx_watermark: 0x8,
},
);
)
.unwrap_or_else(|_| panic!("Invalid config"));

// Configure the Flexspi controller
let _ = flexspi_storage.configport.configure_flexspi(&flexspi_config); // Configure the Flexspi controller
Expand Down
148 changes: 63 additions & 85 deletions src/flexspi/nor_storage_bus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -608,15 +608,20 @@ impl BlockingNorStorageBusDriver for FlexspiNorStorageBus<'_, Blocking> {
read_buf: Option<&mut [u8]>,
write_buf: Option<&[u8]>,
) -> Result<(), NorStorageBusError> {
if cmd.data_bytes.is_some() && cmd.data_bytes.unwrap() > MAX_TRANSFER_SIZE_PER_COMMAND as u32 {
// `program_lut` expects data_bytes to be available so we bail out early if that's not the case
let Some(data_bytes) = cmd.data_bytes else {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe:

let data_bytes = cmd.data_bytes.ok_or(NorStorageBusError::StorageBusInternalError)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yeah that is cleaner, unfortunately already merged :(

return Err(NorStorageBusError::StorageBusInternalError);
};

if data_bytes > MAX_TRANSFER_SIZE_PER_COMMAND as u32 {
return Err(NorStorageBusError::StorageBusInternalError);
}

// Setup the transfer to be sent of the FlexSPI IP Port
self.setup_ip_transfer(self.command_sequence_number, cmd.addr, cmd.data_bytes);

// Program the LUT instructions for the command
self.program_lut(&cmd, self.command_sequence_number);
self.program_lut(&cmd, data_bytes, self.command_sequence_number);

// Start the transfer
self.execute_ip_cmd();
Expand Down Expand Up @@ -843,13 +848,13 @@ impl<M: Mode> FlexspiNorStorageBus<'_, M> {

cookie.next_instruction();

if cmd.cmd_ub.is_some() {
self.write_instr(cookie, cmd_mode, cmd.cmd_ub.unwrap(), bus_width);
if let Some(cmd_ub) = cmd.cmd_ub {
self.write_instr(cookie, cmd_mode, cmd_ub, bus_width);
cookie.next_instruction();
}
}

fn program_addr_instruction(&self, cmd: &NorStorageCmd, cookie: &mut LutInstrCookie) {
fn program_addr_instruction(&self, cmd: &NorStorageCmd, addr_width: u8, cookie: &mut LutInstrCookie) {
let cmd_mode = match cmd.mode {
NorStorageCmdMode::SDR => FlexSpiLutOpcode::RADDR_SDR,
NorStorageCmdMode::DDR => FlexSpiLutOpcode::RADDR_DDR,
Expand All @@ -860,7 +865,7 @@ impl<M: Mode> FlexspiNorStorageBus<'_, M> {
NorStorageBusWidth::Quad => 2,
NorStorageBusWidth::Octal => 3,
};
self.write_instr(cookie, cmd_mode, cmd.addr_width.unwrap(), bus_width);
self.write_instr(cookie, cmd_mode, addr_width, bus_width);

cookie.next_instruction();
}
Expand Down Expand Up @@ -927,7 +932,7 @@ impl<M: Mode> FlexspiNorStorageBus<'_, M> {
cookie.next_instruction();
}

fn program_lut(&self, cmd: &NorStorageCmd, seq_id: u8) {
fn program_lut(&self, cmd: &NorStorageCmd, data_bytes: u32, seq_id: u8) {
let mut cookie = LutInstrCookie {
seq_num: seq_id * 4,
instr_num: LutInstrNum::First,
Expand Down Expand Up @@ -961,19 +966,19 @@ impl<M: Mode> FlexspiNorStorageBus<'_, M> {

self.program_cmd_instruction(cmd, &mut cookie);

if cmd.addr_width.is_some() {
self.program_addr_instruction(cmd, &mut cookie);
if let Some(addr_width) = cmd.addr_width {
self.program_addr_instruction(cmd, addr_width, &mut cookie);
}

self.program_dummy_instruction_if_non_zero(cmd, &mut cookie);

if let Some(transfertype) = cmd.cmdtype {
match transfertype {
NorStorageCmdType::Read => {
self.program_read_data_instruction(cmd, &mut cookie, cmd.data_bytes.unwrap() as u8);
self.program_read_data_instruction(cmd, &mut cookie, data_bytes as u8);
}
NorStorageCmdType::Write => {
self.program_write_data_instruction(cmd, &mut cookie, cmd.data_bytes.unwrap() as u8);
self.program_write_data_instruction(cmd, &mut cookie, data_bytes as u8);
}
}
}
Expand Down Expand Up @@ -1086,7 +1091,11 @@ impl FlexspiNorStorageBus<'_, Blocking> {
.zip(0..num_rx_watermark_slot)
{
let data = self.info.regs.rfdr(slot as usize).read().bits();
chunk.copy_from_slice(&data.to_le_bytes()[..chunk.len()]);
chunk.copy_from_slice(
data.to_le_bytes()
.get(..chunk.len())
.ok_or(NorStorageBusError::StorageBusInternalError)?,
);
size -= chunk.len() as u32;
}
self.info.regs.intr().write(|w| w.iprxwa().clear_bit_by_one());
Expand Down Expand Up @@ -1130,8 +1139,8 @@ impl FlexspiNorStorageBus<'_, Blocking> {
let mut temp = 0_u32;
if chunk.len() < FIFO_SLOT_SIZE as usize {
// We cannot do copy from slice as it will cause a panic
for i in 0..chunk.len() as u32 {
temp |= (chunk[i as usize] as u32) << (i * 8);
for (i, byte) in chunk.iter().enumerate() {
temp |= (*byte as u32) << (i * 8);
}
} else {
temp = u32::from_ne_bytes(
Expand Down Expand Up @@ -1468,6 +1477,29 @@ impl FlexSpiConfigurationPort {
}

impl<'d> FlexspiNorStorageBus<'d, Blocking> {
fn new_inner<T: Instance>(_inst: Peri<'d, T>, config: FlexspiConfigPortData) -> Result<Self, NorStorageBusError> {
let valid_rx = config.rx_watermark != 0 && config.rx_watermark.is_multiple_of(8);
let valid_tx = config.tx_watermark != 0 && config.tx_watermark.is_multiple_of(8);

if valid_rx && valid_tx {
Ok(Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
})
} else {
Err(NorStorageBusError::StorageBusInternalError)
}
}

/// Create a new FlexSPI instance in blocking mode with single configuration
pub fn new_blocking_single_config<T: Instance>(
_inst: Peri<'d, T>,
Expand All @@ -1476,26 +1508,14 @@ impl<'d> FlexspiNorStorageBus<'d, Blocking> {
clk: Peri<'d, impl FlexSpiPin>,
cs: Peri<'d, impl FlexSpiPin>,
config: FlexspiConfigPortData,
) -> Self {
) -> Result<Self, NorStorageBusError> {
let flex_spi = Self::new_inner(_inst, config)?;
// Configure the pins
data0.config_pin();
data1.config_pin();
clk.config_pin();
cs.config_pin();

Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
}
Ok(flex_spi)
}

/// Create a new FlexSPI instance in blocking mode with Dual configuration
Expand All @@ -1506,25 +1526,14 @@ impl<'d> FlexspiNorStorageBus<'d, Blocking> {
clk: Peri<'d, impl FlexSpiPin>,
cs: Peri<'d, impl FlexSpiPin>,
config: FlexspiConfigPortData,
) -> Self {
) -> Result<Self, NorStorageBusError> {
let flex_spi = Self::new_inner(_inst, config)?;
// Configure the pins
data0.config_pin();
data1.config_pin();
clk.config_pin();
cs.config_pin();
Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
}
Ok(flex_spi)
}

/// Create a new FlexSPI instance in blocking mode with Quad configuration
Expand All @@ -1537,27 +1546,16 @@ impl<'d> FlexspiNorStorageBus<'d, Blocking> {
clk: Peri<'d, impl FlexSpiPin>,
cs: Peri<'d, impl FlexSpiPin>,
config: FlexspiConfigPortData,
) -> Self {
) -> Result<Self, NorStorageBusError> {
let flex_spi = Self::new_inner(_inst, config)?;
// Configure the pins
data0.config_pin();
data1.config_pin();
data2.config_pin();
data3.config_pin();
clk.config_pin();
cs.config_pin();
Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
}
Ok(flex_spi)
}

/// Create a new FlexSPI instance in blocking mode with octal configuration
Expand All @@ -1575,7 +1573,8 @@ impl<'d> FlexspiNorStorageBus<'d, Blocking> {
clk: Peri<'d, impl FlexSpiPin>,
cs: Peri<'d, impl FlexSpiPin>,
config: FlexspiConfigPortData,
) -> Self {
) -> Result<Self, NorStorageBusError> {
let flex_spi = Self::new_inner(_inst, config)?;
// Configure the pins
data0.config_pin();
data1.config_pin();
Expand All @@ -1587,36 +1586,15 @@ impl<'d> FlexspiNorStorageBus<'d, Blocking> {
data7.config_pin();
clk.config_pin();
cs.config_pin();
Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
}
Ok(flex_spi)
}

/// Create a new FlexSPI instance in blocking mode without pin configuration
pub fn new_blocking_no_pin_config<T: Instance>(_inst: Peri<'d, T>, config: FlexspiConfigPortData) -> Self {
Self {
info: T::info(),
_mode: core::marker::PhantomData,
configport: FlexSpiConfigurationPort {
info: T::info(),
device_instance: config.dev_instance,
flash_port: config.port,
},
rx_watermark: config.rx_watermark,
tx_watermark: config.tx_watermark,
command_sequence_number: DEFAULT_COMMAND_SEQUENCE_NUMBER,
phantom: core::marker::PhantomData,
}
pub fn new_blocking_no_pin_config<T: Instance>(
_inst: Peri<'d, T>,
config: FlexspiConfigPortData,
) -> Result<Self, NorStorageBusError> {
Self::new_inner(_inst, config)
}
}

Expand Down
Loading