required low-level debugging
This commit is contained in:
@ -26,6 +26,8 @@ use embedded_hal::spi::{Mode, MODE_0};
|
||||
// FIFO has a depth of 16.
|
||||
const FILL_DEPTH: usize = 12;
|
||||
|
||||
pub const BMSTART_BMSTOP_MASK: u32 = 1 << 31;
|
||||
|
||||
pub const DEFAULT_CLK_DIV: u16 = 2;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
@ -369,6 +371,8 @@ pub struct SpiConfig {
|
||||
/// the BMSTOP bit is set on a dataword. A frame is defined as CSn being active for the
|
||||
/// duration of multiple data words. Defaults to true.
|
||||
pub blockmode: bool,
|
||||
/// This enables the stalling of the SPI SCK if in blockmode and the FIFO is empty.
|
||||
pub bmstall: bool,
|
||||
/// By default, configure SPI for master mode (ms == false)
|
||||
ms: bool,
|
||||
/// Slave output disable. Useful if separate GPIO pins or decoders are used for CS control
|
||||
@ -384,6 +388,7 @@ impl Default for SpiConfig {
|
||||
Self {
|
||||
init_mode: MODE_0,
|
||||
blockmode: true,
|
||||
bmstall: true,
|
||||
// Default value is definitely valid.
|
||||
clk: SpiClkConfig::from_div(DEFAULT_CLK_DIV).unwrap(),
|
||||
ms: Default::default(),
|
||||
@ -623,6 +628,7 @@ where
|
||||
clk,
|
||||
init_mode,
|
||||
blockmode,
|
||||
bmstall,
|
||||
ms,
|
||||
slave_output_disable,
|
||||
loopback_mode,
|
||||
@ -647,6 +653,7 @@ where
|
||||
w.ms().bit(ms);
|
||||
w.mdlycap().bit(master_delayer_capture);
|
||||
w.blockmode().bit(blockmode);
|
||||
w.bmstall().bit(bmstall);
|
||||
unsafe { w.ss().bits(0) }
|
||||
});
|
||||
spi.clkprescale()
|
||||
@ -850,15 +857,15 @@ where
|
||||
|
||||
/// Sends a word to the slave
|
||||
#[inline(always)]
|
||||
fn send_blocking(&self, word: Word) {
|
||||
fn send_blocking(&self, data: u32) {
|
||||
// TODO: Upper limit for wait cycles to avoid complete hangups?
|
||||
while self.spi.status().read().tnf().bit_is_clear() {}
|
||||
self.send(word)
|
||||
self.send(data)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn send(&self, word: Word) {
|
||||
self.spi.data().write(|w| unsafe { w.bits(word.into()) });
|
||||
fn send(&self, data: u32) {
|
||||
self.spi.data().write(|w| unsafe { w.bits(data) });
|
||||
}
|
||||
|
||||
/// Read a word from the slave. Must be preceeded by a [`send`](Self::send) call
|
||||
@ -905,7 +912,11 @@ where
|
||||
// Fill the first half of the write FIFO
|
||||
let mut current_write_idx = 0;
|
||||
for _ in 0..core::cmp::min(FILL_DEPTH, words.len()) {
|
||||
self.send_blocking(words[current_write_idx]);
|
||||
if current_write_idx == words.len() - 1 {
|
||||
self.send_blocking(words[current_write_idx].into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(words[current_write_idx].into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if self.blockmode {
|
||||
@ -921,7 +932,11 @@ where
|
||||
// Fill the first half of the write FIFO
|
||||
let mut current_write_idx = 0;
|
||||
for _ in 0..core::cmp::min(FILL_DEPTH, send_len) {
|
||||
self.send_blocking(self.fill_word);
|
||||
if current_write_idx == send_len - 1 {
|
||||
self.send_blocking(self.fill_word.into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(self.fill_word.into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if self.blockmode {
|
||||
@ -992,14 +1007,18 @@ where
|
||||
let mut current_read_idx = 0;
|
||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_fill_words(words.len());
|
||||
loop {
|
||||
if current_write_idx < words.len() {
|
||||
self.send_blocking(self.fill_word);
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if current_read_idx < words.len() {
|
||||
words[current_read_idx] = self.read_blocking();
|
||||
current_read_idx += 1;
|
||||
}
|
||||
if current_write_idx < words.len() {
|
||||
if current_write_idx == words.len() - 1 {
|
||||
self.send_blocking(self.fill_word.into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(self.fill_word.into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if current_read_idx >= words.len() && current_write_idx >= words.len() {
|
||||
break;
|
||||
}
|
||||
@ -1011,7 +1030,11 @@ where
|
||||
// self.transfer_preparation(words)?;
|
||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(words);
|
||||
while current_write_idx < words.len() {
|
||||
self.send_blocking(words[current_write_idx]);
|
||||
if current_write_idx == words.len() - 1 {
|
||||
self.send_blocking(words[current_write_idx].into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(words[current_write_idx].into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
// Ignore received words.
|
||||
if self.spi.status().read().rne().bit_is_set() {
|
||||
@ -1027,7 +1050,11 @@ where
|
||||
let mut current_write_idx = self.initial_send_fifo_pumping_with_words(write);
|
||||
while current_read_idx < read.len() || current_write_idx < write.len() {
|
||||
if current_write_idx < write.len() {
|
||||
self.send_blocking(write[current_write_idx]);
|
||||
if current_write_idx == write.len() - 1 {
|
||||
self.send_blocking(write[current_write_idx].into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(write[current_write_idx].into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if current_read_idx < read.len() {
|
||||
@ -1046,7 +1073,11 @@ where
|
||||
|
||||
while current_read_idx < words.len() || current_write_idx < words.len() {
|
||||
if current_write_idx < words.len() {
|
||||
self.send_blocking(words[current_write_idx]);
|
||||
if current_write_idx == words.len() - 1 {
|
||||
self.send_blocking(words[current_write_idx].into() | BMSTART_BMSTOP_MASK);
|
||||
} else {
|
||||
self.send_blocking(words[current_write_idx].into());
|
||||
}
|
||||
current_write_idx += 1;
|
||||
}
|
||||
if current_read_idx < words.len() && current_read_idx < current_write_idx {
|
||||
|
Reference in New Issue
Block a user