Tune software spi frequency

This commit is contained in:
BlackMark 2022-06-02 23:15:22 +02:00
parent 91b49cd536
commit 51e2f5097d

View File

@ -15,17 +15,26 @@ namespace eink {
template <io::P SclPin, io::P SdaPin, io::P CsPin, io::P DcPin, std::uint32_t Freq = 100'000> template <io::P SclPin, io::P SdaPin, io::P CsPin, io::P DcPin, std::uint32_t Freq = 100'000>
class Spi { class Spi {
template <std::uint32_t StaticClockCycles>
static constexpr double calcClockDelay() static constexpr double calcClockDelay()
{ {
// TODO: Verify static clock cycles constexpr auto maxFrequency = F_CPU / StaticClockCycles;
constexpr auto staticClockCycles = 10;
constexpr auto maxFrequency = F_CPU / staticClockCycles;
static_assert(Freq <= maxFrequency, "SPI frequency not achievable using selected clock speed"); static_assert(Freq <= maxFrequency, "SPI frequency not achievable using selected clock speed");
constexpr auto staticDelay = (1.0 * 1000 * 1000 / maxFrequency); constexpr auto staticDelay = (1.0 * 1000 * 1000 / maxFrequency);
const auto delayUs = ((1.0 * 1000 * 1000 / Freq) - staticDelay) / 2; const auto delayUs = ((1.0 * 1000 * 1000 / Freq) - staticDelay) / 2;
return (delayUs > 0 ? delayUs : 0); return (delayUs > 0 ? delayUs : 0);
} }
static constexpr double calcWriteClockDelay()
{
return calcClockDelay<8>();
}
static constexpr double calcReadClockDelay()
{
return calcClockDelay<5>();
}
static constexpr auto THREE_WIRE_SPI = (DcPin == io::P::NONE); static constexpr auto THREE_WIRE_SPI = (DcPin == io::P::NONE);
public: public:
@ -42,7 +51,7 @@ class Spi {
sm_dc.dir(io::Dir::OUT); sm_dc.dir(io::Dir::OUT);
} }
static void write(const word_t data, const bool command = true) static void write(word_t data, const bool command = true)
{ {
constexpr auto numBits = THREE_WIRE_SPI ? 9 : 8; constexpr auto numBits = THREE_WIRE_SPI ? 9 : 8;
@ -66,10 +75,10 @@ class Spi {
sm_sda = data >> bitPos & 1; sm_sda = data >> bitPos & 1;
_delay_us(DELAY_US); _delay_us(WRITE_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
_delay_us(DELAY_US); _delay_us(WRITE_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
}, },
std::make_index_sequence<numBits>{}); std::make_index_sequence<numBits>{});
@ -85,9 +94,9 @@ class Spi {
if constexpr (THREE_WIRE_SPI) { if constexpr (THREE_WIRE_SPI) {
sm_sda = true; sm_sda = true;
_delay_us(DELAY_US); _delay_us(READ_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
_delay_us(DELAY_US); _delay_us(READ_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
} }
@ -102,13 +111,13 @@ class Spi {
[&](const auto idx) { [&](const auto idx) {
constexpr auto bitPos = numBits - idx.value - 1; constexpr auto bitPos = numBits - idx.value - 1;
_delay_us(DELAY_US); _delay_us(READ_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
const auto receivedBit = sm_sda.read(); const auto receivedBit = sm_sda.read();
res |= word_t{receivedBit} << bitPos; res |= word_t{receivedBit} << bitPos;
_delay_us(DELAY_US); _delay_us(READ_DELAY_US);
sm_scl.toggle(); sm_scl.toggle();
}, },
std::make_index_sequence<numBits>{}); std::make_index_sequence<numBits>{});
@ -129,7 +138,8 @@ class Spi {
static io::Pin<CsPin> sm_cs; static io::Pin<CsPin> sm_cs;
static io::Pin<DcPin> sm_dc; static io::Pin<DcPin> sm_dc;
static constexpr auto DELAY_US = calcClockDelay(); static constexpr auto WRITE_DELAY_US = calcWriteClockDelay();
static constexpr auto READ_DELAY_US = calcReadClockDelay();
static inline std::uint8_t disableInterrupts() static inline std::uint8_t disableInterrupts()
{ {