|
@@ -74,12 +74,18 @@ namespace utl { |
|
|
private:
|
|
|
private:
|
|
|
//! \name SPI implementation specific functions
|
|
|
//! \name SPI implementation specific functions
|
|
|
//!@{
|
|
|
//!@{
|
|
|
template <spi::cpol C =CPOL> constexpr bool clkHigh () { return !static_cast<bool>(C); }
|
|
|
|
|
|
template <spi::cpol C =CPOL> constexpr bool clkLow () { return static_cast<bool>(C); }
|
|
|
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
use_if_t <(B == spi::bitOrder::LSB_First), void> shift (byte_t& b) { b <<=1; }
|
|
|
use_if_t <(B == spi::bitOrder::LSB_First), void> shift (byte_t& b) { b <<=1; }
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
use_if_t <(B == spi::bitOrder::MSB_First), void> shift (byte_t& b) { b >>=1; }
|
|
|
use_if_t <(B == spi::bitOrder::MSB_First), void> shift (byte_t& b) { b >>=1; }
|
|
|
|
|
|
template <spi::cpol C =CPOL> static constexpr bool clkHigh () {
|
|
|
|
|
|
return !static_cast<bool>(C);
|
|
|
|
|
|
}
|
|
|
|
|
|
template <spi::cpol C =CPOL> static constexpr bool clkLow () {
|
|
|
|
|
|
return static_cast<bool>(C);
|
|
|
|
|
|
}
|
|
|
|
|
|
static constexpr bool clkH_ {clkHigh()};
|
|
|
|
|
|
static constexpr bool clkL_ {clkLow()};
|
|
|
//!}
|
|
|
//!}
|
|
|
|
|
|
|
|
|
/*!
|
|
|
/*!
|
|
@@ -110,9 +116,13 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::LOW), byte_t> _tx_data_impl (byte_t out);
|
|
|
use_if_t <(C == spi::cpha::LOW), byte_t> _tx_data_impl (byte_t out);
|
|
|
template <spi::cpha C =CPHA>
|
|
|
template <spi::cpha C =CPHA>
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t> _tx_data_impl (byte_t out);
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t> _tx_data_impl (byte_t out);
|
|
|
|
|
|
//!@}
|
|
|
|
|
|
|
|
|
|
|
|
//! Data members
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
private:
|
|
|
uint32_t nsec_; //!< half period of SPI bus
|
|
|
uint32_t nsec_; //!< half period of SPI bus
|
|
|
//!@}
|
|
|
|
|
|
|
|
|
//! @}
|
|
|
};
|
|
|
};
|
|
|
|
|
|
|
|
|
/*!
|
|
|
/*!
|
|
@@ -127,14 +137,14 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::LOW), byte_t>
|
|
|
use_if_t <(C == spi::cpha::LOW), byte_t>
|
|
|
spi_bb_i<impl_t, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
spi_bb_i<impl_t, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
byte_t in {};
|
|
|
byte_t in {};
|
|
|
SCLK (clkLow());
|
|
|
|
|
|
|
|
|
SCLK (clkL_);
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
MOSI (out & bit); // Out at preceding clock trailing edge
|
|
|
MOSI (out & bit); // Out at preceding clock trailing edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkHigh()); // Leading edge
|
|
|
|
|
|
|
|
|
SCLK (clkH_); // Leading edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at leading clock edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at leading clock edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkLow()); // Trailing edge
|
|
|
|
|
|
|
|
|
SCLK (clkL_); // Trailing edge
|
|
|
}
|
|
|
}
|
|
|
return in;
|
|
|
return in;
|
|
|
}
|
|
|
}
|
|
@@ -151,13 +161,13 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t>
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t>
|
|
|
spi_bb_i<impl_t, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
spi_bb_i<impl_t, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
byte_t in {};
|
|
|
byte_t in {};
|
|
|
SCLK (clkLow());
|
|
|
|
|
|
|
|
|
SCLK (clkL_);
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkHigh()); // Leading edge
|
|
|
|
|
|
|
|
|
SCLK (clkH_); // Leading edge
|
|
|
MOSI (out & bit); // Out at leading clock edge
|
|
|
MOSI (out & bit); // Out at leading clock edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkLow()); // Trailing edge
|
|
|
|
|
|
|
|
|
SCLK (clkL_); // Trailing edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at trailing clock edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at trailing clock edge
|
|
|
}
|
|
|
}
|
|
|
return in;
|
|
|
return in;
|
|
@@ -196,12 +206,18 @@ namespace utl { |
|
|
private:
|
|
|
private:
|
|
|
//! \name SPI implementation specific functions
|
|
|
//! \name SPI implementation specific functions
|
|
|
//!@{
|
|
|
//!@{
|
|
|
template <spi::cpol C =CPOL> constexpr bool clkHigh () { return !static_cast<bool>(C); }
|
|
|
|
|
|
template <spi::cpol C =CPOL> constexpr bool clkLow () { return static_cast<bool>(C); }
|
|
|
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
use_if_t <(B == spi::bitOrder::LSB_First), void> shift (byte_t& b) { b <<=1; }
|
|
|
use_if_t <(B == spi::bitOrder::LSB_First), void> shift (byte_t& b) { b <<=1; }
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
template <spi::bitOrder B =BitOrder> constexpr
|
|
|
use_if_t <(B == spi::bitOrder::MSB_First), void> shift (byte_t& b) { b >>=1; }
|
|
|
use_if_t <(B == spi::bitOrder::MSB_First), void> shift (byte_t& b) { b >>=1; }
|
|
|
|
|
|
template <spi::cpol C =CPOL> static constexpr bool clkHigh () {
|
|
|
|
|
|
return !static_cast<bool>(C);
|
|
|
|
|
|
}
|
|
|
|
|
|
template <spi::cpol C =CPOL> static constexpr bool clkLow () {
|
|
|
|
|
|
return static_cast<bool>(C);
|
|
|
|
|
|
}
|
|
|
|
|
|
static constexpr bool clkH_ {clkHigh()};
|
|
|
|
|
|
static constexpr bool clkL_ {clkLow()};
|
|
|
//!}
|
|
|
//!}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -228,9 +244,13 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::LOW), byte_t> _tx_data_impl (byte_t out);
|
|
|
use_if_t <(C == spi::cpha::LOW), byte_t> _tx_data_impl (byte_t out);
|
|
|
template <spi::cpha C =CPHA>
|
|
|
template <spi::cpha C =CPHA>
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t> _tx_data_impl (byte_t out);
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t> _tx_data_impl (byte_t out);
|
|
|
|
|
|
//!@}
|
|
|
|
|
|
|
|
|
|
|
|
//! Data members
|
|
|
|
|
|
//! @{
|
|
|
|
|
|
private:
|
|
|
uint32_t nsec_; //!< half period of SPI bus
|
|
|
uint32_t nsec_; //!< half period of SPI bus
|
|
|
//!@}
|
|
|
|
|
|
|
|
|
//! @}
|
|
|
};
|
|
|
};
|
|
|
|
|
|
|
|
|
/*!
|
|
|
/*!
|
|
@@ -245,14 +265,14 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::LOW), byte_t>
|
|
|
use_if_t <(C == spi::cpha::LOW), byte_t>
|
|
|
spi_bb_i<virtual_tag, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
spi_bb_i<virtual_tag, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
byte_t in {};
|
|
|
byte_t in {};
|
|
|
SCLK (clkLow());
|
|
|
|
|
|
|
|
|
SCLK (clkL_);
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
MOSI (out & bit); // Out at preceding clock trailing edge
|
|
|
MOSI (out & bit); // Out at preceding clock trailing edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkHigh()); // Leading edge
|
|
|
|
|
|
|
|
|
SCLK (clkH_); // Leading edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at leading clock edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at leading clock edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkLow()); // Trailing edge
|
|
|
|
|
|
|
|
|
SCLK (clkL_); // Trailing edge
|
|
|
}
|
|
|
}
|
|
|
return in;
|
|
|
return in;
|
|
|
}
|
|
|
}
|
|
@@ -269,13 +289,13 @@ namespace utl { |
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t>
|
|
|
use_if_t <(C == spi::cpha::HIGH), byte_t>
|
|
|
spi_bb_i<virtual_tag, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
spi_bb_i<virtual_tag, CPOL, CPHA, BitOrder>::_tx_data_impl (byte_t out) {
|
|
|
byte_t in {};
|
|
|
byte_t in {};
|
|
|
SCLK (clkLow());
|
|
|
|
|
|
|
|
|
SCLK (clkL_);
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
for (uint8_t bit {static_cast<uint8_t>(BitOrder)} ; bit ; shift (bit)) {
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkHigh()); // Leading edge
|
|
|
|
|
|
|
|
|
SCLK (clkH_); // Leading edge
|
|
|
MOSI (out & bit); // Out at leading clock edge
|
|
|
MOSI (out & bit); // Out at leading clock edge
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
delay (nsec_); // Half cycle delay
|
|
|
SCLK (clkLow()); // Trailing edge
|
|
|
|
|
|
|
|
|
SCLK (clkL_); // Trailing edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at trailing clock edge
|
|
|
in |= (MISO ()) ? bit : 0; // In at trailing clock edge
|
|
|
}
|
|
|
}
|
|
|
return in;
|
|
|
return in;
|
|
|