Tune software spi frequency
This commit is contained in:
parent
91b49cd536
commit
51e2f5097d
32
eink_spi.hpp
32
eink_spi.hpp
@ -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()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user