com: A 1-wire interface rework
This commit is contained in:
parent
ab729c5c81
commit
de4eb2cf09
@ -26,19 +26,28 @@
|
|||||||
#include <utl/meta/sfinae.h>
|
#include <utl/meta/sfinae.h>
|
||||||
#include <utl/com/_1wire_id.h>
|
#include <utl/com/_1wire_id.h>
|
||||||
|
|
||||||
#include <gsl/span>
|
|
||||||
using gsl::span;
|
|
||||||
|
|
||||||
namespace utl {
|
namespace utl {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \ingroup Communication
|
* \ingroup Communication
|
||||||
* \brief Abstract base class interface for 1-wire bus
|
* \brief Abstract base class interface for 1-wire bus
|
||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name Friend API to provide common functionality to all specializations
|
||||||
|
*/
|
||||||
|
namespace _1wire_i_det {
|
||||||
|
template <typename _T> byte_t _touch (_T& obj, byte_t out, typename _T::Speed s);
|
||||||
|
template <typename _T> void _match (_T& obj, _1wire_id_t& id, typename _T::Speed s);
|
||||||
|
template <typename _T> void _match_n_ovdr (_T& obj, _1wire_id_t& id);
|
||||||
|
template <typename _T> void _skip (_T& obj, typename _T::Speed s);
|
||||||
|
template <typename _T> void _skip_n_ovdr (_T& obj);
|
||||||
|
template <typename _T> _1wire_id_t _first (_T& obj, typename _T::Speed s, bool alarm);
|
||||||
|
template <typename _T> _1wire_id_t _next (_T& obj, typename _T::Speed s, bool alarm);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Template base class for 1-wire communication interface using CRTP
|
* Template base class for 1-wire communication interface using CRTP
|
||||||
@ -73,11 +82,11 @@ namespace utl {
|
|||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
private:
|
private:
|
||||||
Speed speed () { return impl().speed(); } //!< Get the 1-wire bus speed
|
Speed speed () const { return impl().speed(); } //!< Get the 1-wire bus speed
|
||||||
void speed (Speed s) { return impl().speed(s); } //!< Set the 1-wire bus speed
|
void speed (Speed s) { return impl().speed(s); } //!< Set the 1-wire bus speed
|
||||||
bool bit () { return impl().bit(); } //!< Read a bit from the 1-Wire bus, return it and provide the recovery time.
|
//! Write a bit to the 1-Wire bus, return response/write status and provide the recovery time.
|
||||||
bool bit (bool b) { return impl().bit(b); } //!< Write a bit to the 1-Wire bus, return write status and provide the recovery time.
|
bool bit (bool b) { return impl().bit(b); }
|
||||||
bool _reset () { return impl()._reset(); } //!< Generate a 1-wire reset and return the operation status
|
bool _reset (Speed s){ return impl()._reset(s); } //!< Generate a 1-wire reset and return the operation status
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -94,18 +103,13 @@ namespace utl {
|
|||||||
CMD_ALARM_SEARCH = 0xEC,
|
CMD_ALARM_SEARCH = 0xEC,
|
||||||
CMD_SEARCH_ROM = 0xF0
|
CMD_SEARCH_ROM = 0xF0
|
||||||
};
|
};
|
||||||
template <typename _T> friend bool _1wire_i_reset (_T&, typename _T::Speed);
|
template <typename _T> friend byte_t _1wire_i_det::_touch (_T&, byte_t, typename _T::Speed);
|
||||||
template <typename _T> friend byte_t _1wire_i_rw (_T&, byte_t, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_match (_T& obj, _1wire_id_t& id, typename _T::Speed s);
|
||||||
template <typename _T> friend byte_t _1wire_i_rx (_T&, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_match_n_ovdr (_T& obj, _1wire_id_t& id);
|
||||||
template <typename _T> friend size_t _1wire_i_rx (_T&, span<byte_t>, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_skip (_T& obj, typename _T::Speed s);
|
||||||
template <typename _T> friend size_t _1wire_i_tx (_T&, byte_t, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_skip_n_ovdr (_T& obj);
|
||||||
template <typename _T> friend size_t _1wire_i_tx (_T&, const span<byte_t>, typename _T::Speed);
|
template <typename _T> friend _1wire_id_t _1wire_i_det::_first (_T&, typename _T::Speed, bool);
|
||||||
template <typename _T> friend void _1wire_i_match (_T& obj, _1wire_id_t& id, typename _T::Speed s);
|
template <typename _T> friend _1wire_id_t _1wire_i_det::_next (_T&, typename _T::Speed, bool);
|
||||||
template <typename _T> friend void _1wire_i_match_n_ovdr (_T& obj, _1wire_id_t& id);
|
|
||||||
template <typename _T> friend void _1wire_i_skip (_T& obj, typename _T::Speed s);
|
|
||||||
template <typename _T> friend void _1wire_i_skip_n_ovdr (_T& obj);
|
|
||||||
template <typename _T> friend _1wire_id_t _1wire_i_first (_T&, typename _T::Speed, bool);
|
|
||||||
template <typename _T> friend _1wire_id_t _1wire_i_next (_T&, typename _T::Speed, bool);
|
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -121,39 +125,75 @@ namespace utl {
|
|||||||
* \arg 0 Fail
|
* \arg 0 Fail
|
||||||
* \arg 1 Success
|
* \arg 1 Success
|
||||||
*/
|
*/
|
||||||
bool reset (Speed s) { return _1wire_i_reset (*this, s); };
|
bool reset (Speed s = Speed::STD) {
|
||||||
//! Read a byte from 1-Wire bus
|
return _reset (s);
|
||||||
//! @param s The bus speed
|
}
|
||||||
//! @return The received byte
|
|
||||||
byte_t read (Speed s) { return _1wire_i_rx (*this, s); }
|
|
||||||
//! Read a span of bytes from 1-wire bus
|
|
||||||
//! \param data Ref to data span
|
|
||||||
//! \param s The speed to use
|
|
||||||
//! \return The number of received bytes
|
|
||||||
size_t read (span<byte_t> data, Speed s) { return _1wire_i_rx (*this, data, s); }
|
|
||||||
//! \brief Write a byte to 1-Wire bus
|
|
||||||
//! \param b The byte to write
|
|
||||||
//! \param s Bus speed to use
|
|
||||||
//! \return The number of transmitted bytes
|
|
||||||
size_t write (byte_t byte, Speed s) { return _1wire_i_tx (*this, byte, s); }
|
|
||||||
//! \brief Write a span of bytes to 1-wire bus
|
|
||||||
//! \param data Ref to data span
|
|
||||||
//! \param s Bus speed to use
|
|
||||||
//! \return The number of transmitted bytes
|
|
||||||
size_t write (const span<byte_t> data, Speed s) { return _1wire_i_tx (*this, data, s); }
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* Transmit a byte to 1-Wire bus and read the response
|
||||||
* Write a byte to 1-Wire bus and read the response
|
* \param out The byte to write
|
||||||
* \param b The byte to write
|
|
||||||
* \param s Bus speed to use
|
* \param s Bus speed to use
|
||||||
* \return The byte received.
|
* \return The byte received.
|
||||||
*/
|
*/
|
||||||
byte_t rw (byte_t b, Speed s) { return _1wire_i_rw (*this, b, s); }
|
byte_t tx_data (byte_t out, Speed s = Speed::STD) {
|
||||||
|
return _1wire_i_det::_touch (*this, out, s);
|
||||||
|
}
|
||||||
|
|
||||||
void match (_1wire_id_t& id, Speed s) { _1wire_i_match (*this, id, s); }
|
/*!
|
||||||
void match_n_ovdr (_1wire_id_t& id) { _1wire_i_match_n_ovdr (*this, id); }
|
* Transmit a number of bytes to 1-wire bus and read the response
|
||||||
void skip (Speed s) { _1wire_i_skip (*this, s); }
|
* \param out Pointer to data to transmit
|
||||||
void skip_n_ovdr () { _1wire_i_skip_n_ovdr (*this); }
|
* \param in Pointer to data to store
|
||||||
|
* \param n Number of bytes
|
||||||
|
* \param s Speed to use
|
||||||
|
* \return The number of transmitted bytes
|
||||||
|
*/
|
||||||
|
size_t tx_data (const byte_t *out, byte_t *in, size_t n, Speed s = Speed::STD);
|
||||||
|
/*!
|
||||||
|
* Receive a byte from 1-Wire bus while transmitting 0xFF
|
||||||
|
* \param s Bus speed to use
|
||||||
|
* \return The byte received.
|
||||||
|
*/
|
||||||
|
byte_t rx_data (Speed s = Speed::STD) {
|
||||||
|
return _1wire_i_det::_touch (*this, 0xFF, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Receive a number of bytes from 1-wire bus while transmitting 0xFFs
|
||||||
|
* \param in Pointer to data to store
|
||||||
|
* \param n Number of bytes
|
||||||
|
* \param s Speed to use
|
||||||
|
* \return The number of transmitted bytes
|
||||||
|
*/
|
||||||
|
size_t rx_data (byte_t *in, size_t n, Speed s = Speed::STD);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Send match rom command
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
* \param s The speed to use for the command
|
||||||
|
*/
|
||||||
|
void match (_1wire_id_t& id, Speed s = Speed::STD) {
|
||||||
|
_1wire_i_det::_match (*this, id, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Match and overdrive sequence
|
||||||
|
* \param obj The object from which we call private members
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
*/
|
||||||
|
void match_n_ovdr (_1wire_id_t& id) {
|
||||||
|
_1wire_i_det::_match_n_ovdr (*this, id);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Send skip command to the bus
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
*/
|
||||||
|
void skip (Speed s = Speed::STD) {
|
||||||
|
_1wire_i_det::_skip (*this, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Send the Skip and Overdrive sequence
|
||||||
|
*/
|
||||||
|
void skip_n_ovdr () {
|
||||||
|
_1wire_i_det::_skip_n_ovdr (*this);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
@ -164,7 +204,9 @@ namespace utl {
|
|||||||
* \return ID The romID
|
* \return ID The romID
|
||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
_1wire_id_t first (Speed s, bool alarm =false) { return _1wire_i_first (*this, s, alarm); }
|
_1wire_id_t first (Speed s = Speed::STD, bool alarm =false) {
|
||||||
|
return _1wire_i_det::_first (*this, s, alarm);
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* 'next' operation, to search on the 1-Wire for the next device.
|
* 'next' operation, to search on the 1-Wire for the next device.
|
||||||
@ -175,10 +217,11 @@ namespace utl {
|
|||||||
* \return ID The romID
|
* \return ID The romID
|
||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
_1wire_id_t next (Speed s, bool alarm =false) { return _1wire_i_next (*this, s, alarm); }
|
_1wire_id_t next (Speed s = Speed::STD, bool alarm =false) {
|
||||||
|
return _1wire_i_det::_next (*this, s, alarm);
|
||||||
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
_1wire_id_t dec_ {_1wire_id_t::nullDev()}; /*!<
|
_1wire_id_t dec_ {_1wire_id_t::nullDev()}; /*!<
|
||||||
* Hold the algorithm's select bit when a discrepancy
|
* Hold the algorithm's select bit when a discrepancy
|
||||||
@ -194,7 +237,19 @@ namespace utl {
|
|||||||
_1wire_id_t cur_ {_1wire_id_t::nullDev()}; //! Current rom discrepancy state
|
_1wire_id_t cur_ {_1wire_id_t::nullDev()}; //! Current rom discrepancy state
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename _I>
|
||||||
|
size_t _1wire_i<_I>::tx_data (const byte_t *out, byte_t *in, size_t n, Speed s){
|
||||||
|
for (size_t nn {n} ; nn ; --nn)
|
||||||
|
*in++ = tx_data (*out++, s);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename _I>
|
||||||
|
size_t _1wire_i<_I>::rx_data(byte_t *in, size_t n, Speed s) {
|
||||||
|
for (size_t nn {n} ; nn ; --nn)
|
||||||
|
*in++ = tx_data (0xFF, s);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
@ -226,11 +281,11 @@ namespace utl {
|
|||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
private:
|
private:
|
||||||
virtual Speed speed () =0; //!< Get the 1-wire bus speed
|
virtual Speed speed () const =0; //!< Get the 1-wire bus speed
|
||||||
virtual void speed (Speed) =0; //!< Set the 1-wire bus speed
|
virtual void speed (Speed) =0; //!< Set the 1-wire bus speed
|
||||||
virtual bool bit () =0; //!< Read a bit from the 1-Wire bus, return it and provide the recovery time.
|
virtual bool bit () =0; //!< Read a bit from the 1-Wire bus, return it and provide the recovery time.
|
||||||
virtual bool bit (bool) =0; //!< Write a bit to the 1-Wire bus, return write status and provide the recovery time.
|
virtual bool bit (bool) =0; //!< Write a bit to the 1-Wire bus, return write status and provide the recovery time.
|
||||||
virtual bool _reset () =0; //!< Generate a 1-wire reset and return the operation status
|
virtual bool _reset (Speed) =0; //!< Generate a 1-wire reset and return the operation status
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -247,18 +302,13 @@ namespace utl {
|
|||||||
CMD_ALARM_SEARCH = 0xEC,
|
CMD_ALARM_SEARCH = 0xEC,
|
||||||
CMD_SEARCH_ROM = 0xF0
|
CMD_SEARCH_ROM = 0xF0
|
||||||
};
|
};
|
||||||
template <typename _T> friend bool _1wire_i_reset (_T&, typename _T::Speed);
|
template <typename _T> friend byte_t _1wire_i_det::_touch (_T&, byte_t, typename _T::Speed);
|
||||||
template <typename _T> friend byte_t _1wire_i_rw (_T&, byte_t, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_match (_T& obj, _1wire_id_t& id, typename _T::Speed s);
|
||||||
template <typename _T> friend byte_t _1wire_i_rx (_T&, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_match_n_ovdr (_T& obj, _1wire_id_t& id);
|
||||||
template <typename _T> friend size_t _1wire_i_rx (_T&, span<byte_t>, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_skip (_T& obj, typename _T::Speed s);
|
||||||
template <typename _T> friend size_t _1wire_i_tx (_T&, byte_t, typename _T::Speed);
|
template <typename _T> friend void _1wire_i_det::_skip_n_ovdr (_T& obj);
|
||||||
template <typename _T> friend size_t _1wire_i_tx (_T&, const span<byte_t>, typename _T::Speed);
|
template <typename _T> friend _1wire_id_t _1wire_i_det::_first (_T&, typename _T::Speed, bool);
|
||||||
template <typename _T> friend void _1wire_i_match (_T& obj, _1wire_id_t& id, typename _T::Speed s);
|
template <typename _T> friend _1wire_id_t _1wire_i_det::_next (_T&, typename _T::Speed, bool);
|
||||||
template <typename _T> friend void _1wire_i_match_n_ovdr (_T& obj, _1wire_id_t& id);
|
|
||||||
template <typename _T> friend void _1wire_i_skip (_T& obj, typename _T::Speed s);
|
|
||||||
template <typename _T> friend void _1wire_i_skip_n_ovdr (_T& obj);
|
|
||||||
template <typename _T> friend _1wire_id_t _1wire_i_first (_T&, typename _T::Speed, bool);
|
|
||||||
template <typename _T> friend _1wire_id_t _1wire_i_next (_T&, typename _T::Speed, bool);
|
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -274,39 +324,75 @@ namespace utl {
|
|||||||
* \arg 0 Fail
|
* \arg 0 Fail
|
||||||
* \arg 1 Success
|
* \arg 1 Success
|
||||||
*/
|
*/
|
||||||
bool reset (Speed s) { return _1wire_i_reset (*this, s); };
|
bool reset (Speed s = Speed::STD) {
|
||||||
//! Read a byte from 1-Wire bus
|
return _reset (s);
|
||||||
//! @param s The bus speed
|
}
|
||||||
//! @return The received byte
|
|
||||||
byte_t read (Speed s) { return _1wire_i_rx (*this, s); }
|
|
||||||
//! Read a span of bytes from 1-wire bus
|
|
||||||
//! \param data Ref to data span
|
|
||||||
//! \param s The speed to use
|
|
||||||
//! \return The number of received bytes
|
|
||||||
size_t read (span<byte_t> data, Speed s) { return _1wire_i_rx (*this, data, s); }
|
|
||||||
//! \brief Write a byte to 1-Wire bus
|
|
||||||
//! \param b The byte to write
|
|
||||||
//! \param s Bus speed to use
|
|
||||||
//! \return The number of transmitted bytes
|
|
||||||
size_t write (byte_t byte, Speed s) { return _1wire_i_tx (*this, byte, s); }
|
|
||||||
//! \brief Write a span of bytes to 1-wire bus
|
|
||||||
//! \param data Ref to data span
|
|
||||||
//! \param s Bus speed to use
|
|
||||||
//! \return The number of transmitted bytes
|
|
||||||
size_t write (const span<byte_t> data, Speed s) { return _1wire_i_tx (*this, data, s); }
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* Transmit a byte to 1-Wire bus and read the response
|
||||||
* Write a byte to 1-Wire bus and read the response
|
* \param out The byte to write
|
||||||
* \param b The byte to write
|
|
||||||
* \param s Bus speed to use
|
* \param s Bus speed to use
|
||||||
* \return The byte received.
|
* \return The byte received.
|
||||||
*/
|
*/
|
||||||
byte_t rw (byte_t b, Speed s) { return _1wire_i_rw (*this, b, s); }
|
byte_t tx_data (byte_t out, Speed s = Speed::STD) {
|
||||||
|
return _1wire_i_det::_touch (*this, out, s);
|
||||||
|
}
|
||||||
|
|
||||||
void match (_1wire_id_t& id, Speed s) { _1wire_i_match (*this, id, s); }
|
/*!
|
||||||
void match_n_ovdr (_1wire_id_t& id) { _1wire_i_match_n_ovdr (*this, id); }
|
* Transmit a number of bytes to 1-wire bus and read the response
|
||||||
void skip (Speed s) { _1wire_i_skip (*this, s); }
|
* \param out Pointer to data to transmit
|
||||||
void skip_n_ovdr () { _1wire_i_skip_n_ovdr (*this); }
|
* \param in Pointer to data to store
|
||||||
|
* \param n Number of bytes
|
||||||
|
* \param s Speed to use
|
||||||
|
* \return The number of transmitted bytes
|
||||||
|
*/
|
||||||
|
size_t tx_data (const byte_t *out, byte_t *in, size_t n, Speed s = Speed::STD);
|
||||||
|
/*!
|
||||||
|
* Receive a byte from 1-Wire bus while transmitting 0xFF
|
||||||
|
* \param s Bus speed to use
|
||||||
|
* \return The byte received.
|
||||||
|
*/
|
||||||
|
byte_t rx_data (Speed s = Speed::STD) {
|
||||||
|
return _1wire_i_det::_touch (*this, 0xFF, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Receive a number of bytes from 1-wire bus while transmitting 0xFFs
|
||||||
|
* \param in Pointer to data to store
|
||||||
|
* \param n Number of bytes
|
||||||
|
* \param s Speed to use
|
||||||
|
* \return The number of transmitted bytes
|
||||||
|
*/
|
||||||
|
size_t rx_data (byte_t *in, size_t n, Speed s = Speed::STD);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* Send match rom command
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
* \param s The speed to use for the command
|
||||||
|
*/
|
||||||
|
void match (_1wire_id_t& id, Speed s = Speed::STD) {
|
||||||
|
_1wire_i_det::_match (*this, id, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Match and overdrive sequence
|
||||||
|
* \param obj The object from which we call private members
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
*/
|
||||||
|
void match_n_ovdr (_1wire_id_t& id) {
|
||||||
|
_1wire_i_det::_match_n_ovdr (*this, id);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Send skip command to the bus
|
||||||
|
* \param id The ID to select on the bus
|
||||||
|
*/
|
||||||
|
void skip (Speed s = Speed::STD) {
|
||||||
|
_1wire_i_det::_skip (*this, s);
|
||||||
|
}
|
||||||
|
/*!
|
||||||
|
* Send the Skip and Overdrive sequence
|
||||||
|
*/
|
||||||
|
void skip_n_ovdr () {
|
||||||
|
_1wire_i_det::_skip_n_ovdr (*this);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
@ -317,7 +403,9 @@ namespace utl {
|
|||||||
* \return ID The romID
|
* \return ID The romID
|
||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
_1wire_id_t first (Speed s, bool alarm =false) { return _1wire_i_first (*this, s, alarm); }
|
_1wire_id_t first (Speed s = Speed::STD, bool alarm =false) {
|
||||||
|
return _1wire_i_det::_first (*this, s, alarm);
|
||||||
|
}
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* 'next' operation, to search on the 1-Wire for the next device.
|
* 'next' operation, to search on the 1-Wire for the next device.
|
||||||
@ -328,10 +416,11 @@ namespace utl {
|
|||||||
* \return ID The romID
|
* \return ID The romID
|
||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
_1wire_id_t next (Speed s, bool alarm =false) { return _1wire_i_next (*this, s, alarm); }
|
_1wire_id_t next (Speed s = Speed::STD, bool alarm =false) {
|
||||||
|
return _1wire_i_det::_next (*this, s, alarm);
|
||||||
|
}
|
||||||
//!@}
|
//!@}
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
_1wire_id_t dec_ {_1wire_id_t::nullDev()}; /*!<
|
_1wire_id_t dec_ {_1wire_id_t::nullDev()}; /*!<
|
||||||
* Hold the algorithm's select bit when a discrepancy
|
* Hold the algorithm's select bit when a discrepancy
|
||||||
@ -348,27 +437,24 @@ namespace utl {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*!
|
size_t _1wire_i<virtual_tag>::tx_data (const byte_t *out, byte_t *in, size_t n, Speed s){
|
||||||
* \name Friend API to provide common functionality to all specializations
|
for (size_t nn {n} ; nn ; --nn)
|
||||||
*/
|
*in++ = tx_data (*out++, s);
|
||||||
//!@{
|
return n;
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief
|
|
||||||
* Generate a 1-wire reset
|
|
||||||
* \param obj The object from which we call private members
|
|
||||||
* \param s Bus speed
|
|
||||||
* \return The status of the operation
|
|
||||||
* \arg 0 Fail
|
|
||||||
* \arg 1 Success
|
|
||||||
*/
|
|
||||||
template <typename _T>
|
|
||||||
bool _1wire_i_reset (_T& obj, typename _T::Speed s) {
|
|
||||||
if (obj.speed () != s)
|
|
||||||
obj.speed (s);
|
|
||||||
return obj._reset ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t _1wire_i<virtual_tag>::rx_data(byte_t *in, size_t n, Speed s) {
|
||||||
|
for (size_t nn {n} ; nn ; --nn)
|
||||||
|
*in++ = tx_data (0xFF, s);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name Friend API to provide common functionality to all specializations
|
||||||
|
*/
|
||||||
|
//!@{
|
||||||
|
namespace _1wire_i_det {
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Write a byte to 1-Wire bus and read the response
|
* Write a byte to 1-Wire bus and read the response
|
||||||
@ -378,7 +464,7 @@ namespace utl {
|
|||||||
* \return The byte received.
|
* \return The byte received.
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
byte_t _1wire_i_rw (_T& obj, byte_t b, typename _T::Speed s) {
|
byte_t _touch (_T& obj, byte_t out, typename _T::Speed s) {
|
||||||
byte_t ret {0};
|
byte_t ret {0};
|
||||||
|
|
||||||
// Select speed once
|
// Select speed once
|
||||||
@ -386,90 +472,16 @@ namespace utl {
|
|||||||
obj.speed (s);
|
obj.speed (s);
|
||||||
for (uint8_t i =8; i>0 ; --i) {
|
for (uint8_t i =8; i>0 ; --i) {
|
||||||
ret >>= 1;
|
ret >>= 1;
|
||||||
if ((b & 0x01) != 0) ret |= (obj.bit ()) ? 0x80 : 0x00;
|
ret |= (obj.bit (out & 0x01)) ? 0x80 : 0x00;
|
||||||
else obj.bit (0);
|
out >>= 1;
|
||||||
b >>= 1;
|
|
||||||
/*^
|
/*^
|
||||||
* If the bit is 1 we use the read sequence, as it has the same
|
* We shift bits to right as LSB comes first and mask it to MSB
|
||||||
* waveform with write-1 and we get the slave response
|
* If we need to read we have to write 1
|
||||||
* If the bit is 0, we can not read the slave response so we just write-0
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*!
|
|
||||||
* \brief Read a byte from 1-Wire bus
|
|
||||||
* \param obj The object from which we call private members
|
|
||||||
* \param s Bus speed to use
|
|
||||||
* \return The byte received.
|
|
||||||
*/
|
|
||||||
template <typename _T>
|
|
||||||
byte_t _1wire_i_rx (_T& obj, typename _T::Speed s) {
|
|
||||||
byte_t byte {0};
|
|
||||||
// Select speed once
|
|
||||||
if (obj.speed () != s)
|
|
||||||
obj.speed (s);
|
|
||||||
for (uint8_t i =8; i>0 ; --i) {
|
|
||||||
// shift bits to right as LSB comes first and mask it to MSB
|
|
||||||
byte >>= 1;
|
|
||||||
byte |= (obj.bit ()) ? 0x80 : 0x00;
|
|
||||||
}
|
|
||||||
return byte;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Read a span of bytes from 1-Wire bus
|
|
||||||
* \param obj The object from which we call private members
|
|
||||||
* \param data Reference to byte span
|
|
||||||
* \param s Bus speed to use
|
|
||||||
* \return The number of received bytes. Actual return data.size()
|
|
||||||
*/
|
|
||||||
template <typename _T>
|
|
||||||
size_t _1wire_i_rx (_T& obj, span<byte_t> data, typename _T::Speed s) {
|
|
||||||
// Select speed once
|
|
||||||
if (obj.speed () != s)
|
|
||||||
obj.speed (s);
|
|
||||||
for (byte_t& byte : data) {
|
|
||||||
byte = 0;
|
|
||||||
for (uint8_t i =8; i>0 ; --i) {
|
|
||||||
// shift bits to right as LSB comes first and mask it to MSB
|
|
||||||
byte >>= 1;
|
|
||||||
byte |= (obj.bit ()) ? 0x80 : 0x00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return data.size();
|
|
||||||
}
|
|
||||||
/*!
|
|
||||||
* \brief Write a byte to 1-Wire bus
|
|
||||||
* \param obj The object from which we call private members
|
|
||||||
* \param byte The byte to write
|
|
||||||
* \param s Bus speed to use
|
|
||||||
* \return The number of transmitted bytes. So "1" of "0"
|
|
||||||
*/
|
|
||||||
template <typename _T>
|
|
||||||
size_t _1wire_i_tx (_T& obj, byte_t byte, typename _T::Speed s) {
|
|
||||||
return (_1wire_i_rw (obj, byte, s) == byte) ? 1 : 0;
|
|
||||||
}
|
|
||||||
/*!
|
|
||||||
* \brief Write a byte to 1-Wire bus
|
|
||||||
* \param obj The object from which we call private members
|
|
||||||
* \param data Reference to byte span
|
|
||||||
* \param s Bus speed to use
|
|
||||||
* \return The number of transmitted bytes.
|
|
||||||
* \note
|
|
||||||
* The procedure breaks on first transmission error
|
|
||||||
*/
|
|
||||||
template <typename _T>
|
|
||||||
size_t _1wire_i_tx (_T& obj, const span<byte_t> data, typename _T::Speed s) {
|
|
||||||
size_t ret {0};
|
|
||||||
for (byte_t byte : data) {
|
|
||||||
if (_1wire_i_rw (obj, byte, s) == byte)
|
|
||||||
++ret;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Send match rom command
|
* Send match rom command
|
||||||
@ -478,10 +490,10 @@ namespace utl {
|
|||||||
* \param s The speed to use for the command
|
* \param s The speed to use for the command
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
void _1wire_i_match (_T& obj, _1wire_id_t& id, typename _T::Speed s) {
|
void _match (_T& obj, _1wire_id_t& id, typename _T::Speed s) {
|
||||||
_1wire_i_tx (obj, (s == _T::Speed::STD) ? _T::CMD_MATCH : _T::CMD_OVDR_MATCH, s);
|
_touch (obj, (s == _T::Speed::STD) ? _T::CMD_MATCH : _T::CMD_OVDR_MATCH, s);
|
||||||
for (uint8_t& b : id)
|
for (uint8_t& b : id)
|
||||||
_1wire_i_tx (obj, b, s);
|
_touch (obj, b, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -490,10 +502,10 @@ namespace utl {
|
|||||||
* \param id The ID to select on the bus
|
* \param id The ID to select on the bus
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
void _1wire_i_match_n_ovdr (_T& obj, _1wire_id_t& id) {
|
void _match_n_ovdr (_T& obj, _1wire_id_t& id) {
|
||||||
_1wire_i_tx (obj, _T::CMD_MATCH, _T::Speed::STD);
|
_touch (obj, _T::CMD_MATCH, _T::Speed::STD);
|
||||||
for (uint8_t& b : id)
|
for (uint8_t& b : id)
|
||||||
_1wire_i_tx (obj, b, _T::Speed::OVDR);
|
_touch (obj, b, _T::Speed::OVDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -502,8 +514,8 @@ namespace utl {
|
|||||||
* \param id The ID to select on the bus
|
* \param id The ID to select on the bus
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
void _1wire_i_skip (_T& obj, typename _T::Speed s) {
|
void _skip (_T& obj, typename _T::Speed s) {
|
||||||
_1wire_i_tx (obj, (s == _T::Speed::STD) ? _T::CMD_SKIP : _T::CMD_SKIP, s);
|
_touch (obj, (s == _T::Speed::STD) ? _T::CMD_SKIP : _T::CMD_SKIP, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -511,8 +523,8 @@ namespace utl {
|
|||||||
* \param obj The object from which we call private members
|
* \param obj The object from which we call private members
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
void _1wire_i_skip_n_ovdr (_T& obj) {
|
void _skip_n_ovdr (_T& obj) {
|
||||||
_1wire_i_tx (obj, _T::CMD_OVDR_SKIP, _T::Speed::STD);
|
_touch (obj, _T::CMD_OVDR_SKIP, _T::Speed::STD);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -525,9 +537,9 @@ namespace utl {
|
|||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
_1wire_id_t _1wire_i_first (_T& obj, typename _T::Speed s, bool alarm) {
|
_1wire_id_t _first (_T& obj, typename _T::Speed s, bool alarm) {
|
||||||
obj.dec_ = obj.pos_ = obj.cur_ = _1wire_id_t::nullDev();
|
obj.dec_ = obj.pos_ = obj.cur_ = _1wire_id_t::nullDev();
|
||||||
return _1wire_i_next (obj, s, alarm);
|
return _next (obj, s, alarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -541,7 +553,7 @@ namespace utl {
|
|||||||
* \arg nullDev Indicate no [more] device[s]
|
* \arg nullDev Indicate no [more] device[s]
|
||||||
*/
|
*/
|
||||||
template <typename _T>
|
template <typename _T>
|
||||||
_1wire_id_t _1wire_i_next (_T& obj, typename _T::Speed s, bool alarm) {
|
_1wire_id_t _next (_T& obj, typename _T::Speed s, bool alarm) {
|
||||||
uint8_t b, bxx; // bit helper vars
|
uint8_t b, bxx; // bit helper vars
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
_1wire_id_t ID;
|
_1wire_id_t ID;
|
||||||
@ -558,15 +570,19 @@ namespace utl {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Issue search command
|
// Issue search command
|
||||||
if (alarm) obj.write (_T::CMD_ALARM_SEARCH, s);
|
if (alarm) obj.tx_data (_T::CMD_ALARM_SEARCH, s);
|
||||||
else obj.write (_T::CMD_SEARCH_ROM, s);
|
else obj.tx_data (_T::CMD_SEARCH_ROM, s);
|
||||||
|
|
||||||
|
// Select speed once
|
||||||
|
if (obj.speed () != s)
|
||||||
|
obj.speed (s);
|
||||||
|
|
||||||
// traverse entire RomID from LSB to MSB
|
// traverse entire RomID from LSB to MSB
|
||||||
for (i =0 ; i<64 ; ++i) {
|
for (i =0 ; i<64 ; ++i) {
|
||||||
// Get response pair bits
|
// Get response pair bits
|
||||||
bxx = obj.bit (); // bit
|
bxx = obj.bit (1); // bit
|
||||||
bxx <<= 1;
|
bxx <<= 1;
|
||||||
bxx |= obj.bit (); // complementary bit
|
bxx |= obj.bit (1); // complementary bit
|
||||||
|
|
||||||
if (bxx == 0x00) {
|
if (bxx == 0x00) {
|
||||||
// 00 - We have discrepancy
|
// 00 - We have discrepancy
|
||||||
@ -621,7 +637,8 @@ namespace utl {
|
|||||||
|
|
||||||
return ID;
|
return ID;
|
||||||
}
|
}
|
||||||
//!@}
|
} // namespace _1wire_i_det
|
||||||
|
//!@}
|
||||||
|
|
||||||
|
|
||||||
#if defined _utl_have_concepts
|
#if defined _utl_have_concepts
|
||||||
@ -638,9 +655,8 @@ namespace utl {
|
|||||||
// typename T::Command;
|
// typename T::Command;
|
||||||
// Methods
|
// Methods
|
||||||
{t.reset(s)} -> bool;
|
{t.reset(s)} -> bool;
|
||||||
{t.read(s)} -> byte_t;
|
{t.tx_data(1)} -> byte_t;
|
||||||
{t.write(0, s)} -> size_t;
|
{t.rx_data(s)} -> byte_t;
|
||||||
{t.rw(0, s)} -> byte_t;
|
|
||||||
t.match(id, s);
|
t.match(id, s);
|
||||||
t.match_n_ovdr(id);
|
t.match_n_ovdr(id);
|
||||||
t.skip(s);
|
t.skip(s);
|
||||||
@ -649,16 +665,12 @@ namespace utl {
|
|||||||
{t.next(s)} -> _1wire_id_t;
|
{t.next(s)} -> _1wire_id_t;
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
namespace _1wire_i_cnpt {
|
namespace _1wire_i_det {
|
||||||
using std::declval;
|
using std::declval;
|
||||||
|
|
||||||
template <class _Tp> using try_reset_t = decltype (declval<_Tp>().reset (declval<typename _Tp::Speed>()));
|
template <class _Tp> using try_reset_t = decltype (declval<_Tp>().reset (declval<typename _Tp::Speed>()));
|
||||||
template <class _Tp> using try_rw_t = decltype (declval<_Tp>().rw (declval<byte_t>(), declval<typename _Tp::Speed>()));
|
template <class _Tp> using try_rx1_t = decltype (declval<_Tp>().rx_data (declval<typename _Tp::Speed>()));
|
||||||
template <class _Tp> using try_rx1_t = decltype (declval<_Tp>().read (declval<typename _Tp::Speed>()));
|
template <class _Tp> using try_tx1_t = decltype (declval<_Tp>().tx_data (declval<byte_t>(), declval<typename _Tp::Speed>()));
|
||||||
template <class _Tp> using try_rx2_t = decltype (declval<_Tp>().read (declval<span<byte_t>>(), declval<typename _Tp::Speed>()));
|
|
||||||
template <class _Tp> using try_tx1_t = decltype (declval<_Tp>().write (declval<byte_t>(), declval<typename _Tp::Speed>()));
|
|
||||||
template <class _Tp> using try_tx2_t = decltype (declval<_Tp>().write (declval<const span<byte_t>>(), declval<typename _Tp::Speed>()));
|
|
||||||
|
|
||||||
|
|
||||||
template <class _Tp> using try_match_t = decltype (declval<_Tp>().match (declval<_1wire_id_t&>(), declval<typename _Tp::Speed>()));
|
template <class _Tp> using try_match_t = decltype (declval<_Tp>().match (declval<_1wire_id_t&>(), declval<typename _Tp::Speed>()));
|
||||||
template <class _Tp> using try_match_n_ovdr_t = decltype (declval<_Tp>().match_n_ovdr (declval<_1wire_id_t&>()));
|
template <class _Tp> using try_match_n_ovdr_t = decltype (declval<_Tp>().match_n_ovdr (declval<_1wire_id_t&>()));
|
||||||
@ -678,11 +690,10 @@ namespace utl {
|
|||||||
// typename _Tp::Speed,
|
// typename _Tp::Speed,
|
||||||
// typename _Tp::Command,
|
// typename _Tp::Command,
|
||||||
use_if_same_t <try_reset_t <_Tp>, bool>,
|
use_if_same_t <try_reset_t <_Tp>, bool>,
|
||||||
use_if_same_t <try_rw_t <_Tp>, byte_t>,
|
|
||||||
use_if_same_t <try_rx1_t <_Tp>, byte_t>,
|
use_if_same_t <try_rx1_t <_Tp>, byte_t>,
|
||||||
use_if_same_t <try_rx2_t <_Tp>, size_t>,
|
//use_if_same_t <try_rx2_t <_Tp>, size_t>,
|
||||||
use_if_same_t <try_tx1_t <_Tp>, size_t>,
|
use_if_same_t <try_tx1_t <_Tp>, byte_t>,
|
||||||
use_if_same_t <try_tx2_t <_Tp>, size_t>,
|
//use_if_same_t <try_tx2_t <_Tp>, size_t>,
|
||||||
use_if_same_t <try_match_t<_Tp>, void>,
|
use_if_same_t <try_match_t<_Tp>, void>,
|
||||||
use_if_same_t <try_match_n_ovdr_t<_Tp>, void>,
|
use_if_same_t <try_match_n_ovdr_t<_Tp>, void>,
|
||||||
use_if_same_t <try_skip_t<_Tp>, void>,
|
use_if_same_t <try_skip_t<_Tp>, void>,
|
||||||
@ -691,7 +702,7 @@ namespace utl {
|
|||||||
use_if_same_t <try_next_t <_Tp>, _1wire_id_t>
|
use_if_same_t <try_next_t <_Tp>, _1wire_id_t>
|
||||||
> //!^ SFINAE may apply
|
> //!^ SFINAE may apply
|
||||||
> : true_ {};
|
> : true_ {};
|
||||||
}
|
} // namespace _1wire_i_det
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* Value meta-programming function for 1-wire interface checking
|
* Value meta-programming function for 1-wire interface checking
|
||||||
@ -699,7 +710,7 @@ namespace utl {
|
|||||||
* \return True if _Tp is a 1-wire interface
|
* \return True if _Tp is a 1-wire interface
|
||||||
*/
|
*/
|
||||||
template <typename _Tp>
|
template <typename _Tp>
|
||||||
constexpr bool _1wire_c = _1wire_i_cnpt::is_1wire_<_Tp>::value;
|
constexpr bool _1wire_c = _1wire_i_det::is_1wire_<_Tp>::value;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//!@}
|
//!@}
|
||||||
|
@ -3,9 +3,9 @@
|
|||||||
* \brief
|
* \brief
|
||||||
* A 1-wire implementation using a microprocessor's uart for bit timing
|
* A 1-wire implementation using a microprocessor's uart for bit timing
|
||||||
* \note
|
* \note
|
||||||
* This 1-wire implementation is based on MCU UART io functionality. In order
|
* This 1-wire implementation is based on MCU UART functionality. The implementation
|
||||||
* to work it needs:
|
* expects:
|
||||||
* 1) A Open drain tx and floating(or pull-up) rx UART pin configuration with both pins
|
* 1) An Open drain tx and a floating(or pull-up) rx UART pin configuration with both pins
|
||||||
* connected to the 1-wire bus wire
|
* connected to the 1-wire bus wire
|
||||||
* 2) A Transmit/receive function even in blocking/polling mode
|
* 2) A Transmit/receive function even in blocking/polling mode
|
||||||
* 3) A baudrate set function
|
* 3) A baudrate set function
|
||||||
@ -70,19 +70,13 @@ namespace utl {
|
|||||||
* \note
|
* \note
|
||||||
* In order for the implementation to have the following as private members
|
* In order for the implementation to have the following as private members
|
||||||
* it also need to declare this class as friend
|
* it also need to declare this class as friend
|
||||||
* for ex:
|
|
||||||
* class Foo : public _1wire_uart<Foo> {
|
|
||||||
* friend _1wire_uart<Foo>;
|
|
||||||
* byte_t UART_RW (byte_t byte);
|
|
||||||
* void UART_BR (uint32_t br);
|
|
||||||
* // ...
|
|
||||||
* };
|
|
||||||
*/
|
*/
|
||||||
//!@{
|
//!@{
|
||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Implementers's (driver) read-write function. We use the following USART configuration.
|
* Implementers's (driver) read-write function. We expect the following
|
||||||
|
* USART configuration:
|
||||||
* - Word Length = 8 Bits
|
* - Word Length = 8 Bits
|
||||||
* - Stop Bit = One Stop bit
|
* - Stop Bit = One Stop bit
|
||||||
* - Parity = No parity
|
* - Parity = No parity
|
||||||
@ -114,55 +108,22 @@ namespace utl {
|
|||||||
};
|
};
|
||||||
Speed _speed {Speed::STD};
|
Speed _speed {Speed::STD};
|
||||||
|
|
||||||
Speed speed () { return _speed; } //!< Get the 1-wire bus speed
|
Speed speed () const { return _speed; } //!< Get the 1-wire bus speed
|
||||||
void speed (Speed s); //!< Set the 1-wire bus speed
|
void speed (Speed s); //!< Set the 1-wire bus speed
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Read a bit from the 1-Wire bus, return it and provide
|
* Send a 1-Wire write bit and read the response
|
||||||
* the recovery time.
|
|
||||||
*
|
*
|
||||||
* --- - - - - - - - - - - - - - - - - ------
|
* Write 1 --- --------------------------------------
|
||||||
* Read \ / X X X X X X X X X X X X X X X /
|
* Read 0/1 \ /
|
||||||
* ---- - - - - - - - - - - - - - - - -
|
|
||||||
* RS: | | | | | | | | | | |
|
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
|
||||||
* < ------------- 87/11 usec ------------->
|
|
||||||
* ^
|
|
||||||
* |
|
|
||||||
* Master sample
|
|
||||||
*
|
|
||||||
* 8 bits, no parity, 1 stop
|
|
||||||
* standard: BR: 115200
|
|
||||||
* Overdrive: BR: 921600
|
|
||||||
* TX: 0xFF
|
|
||||||
* RX: {1 - 0xFF, 0 - [0x00 - 0xFE] }
|
|
||||||
*
|
|
||||||
* \return The answer
|
|
||||||
* \arg 0 Read 0
|
|
||||||
* \arg 1 Read 1 (This is also returned on transition error).
|
|
||||||
*/
|
|
||||||
bool bit () {
|
|
||||||
return (impl().UART_RW (0xFF) < 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief
|
|
||||||
* Send a 1-Wire write bit
|
|
||||||
* 8 bits, no parity, 1 stop
|
|
||||||
* standard: BR: 115200
|
|
||||||
* Overdrive: BR: 921600
|
|
||||||
*
|
|
||||||
* --- --------------------------------------
|
|
||||||
* Write 1 \ /
|
|
||||||
* ----
|
* ----
|
||||||
* RS: | | | | | | | | | | |
|
* RS: | | | | | | | | | | |
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
* TX: 0xFF RX: 0xFF
|
* TX: 0xFF RX: 0xFF->1, less->0
|
||||||
*
|
*
|
||||||
* --- ------
|
* Write 0 --- ------
|
||||||
* Write 0 \ /
|
* Read 0 \ /
|
||||||
* -------------------------------------
|
* -------------------------------------
|
||||||
* RS: | | | | | | | | | | |
|
* RS: | | | | | | | | | | |
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
@ -170,15 +131,17 @@ namespace utl {
|
|||||||
* TX: 0x00 RX: 0x00
|
* TX: 0x00 RX: 0x00
|
||||||
*
|
*
|
||||||
* \param b The bit to send
|
* \param b The bit to send
|
||||||
* \return Status of the operation
|
* \return The response
|
||||||
* \arg 0 Fail
|
|
||||||
* \arg 1 Success
|
|
||||||
*/
|
*/
|
||||||
bool bit (bool b) {
|
bool bit (bool b) {
|
||||||
uint8_t w = (b) ? 0xFF : 0x00; // Select write frame to send
|
if (b)
|
||||||
return (w == impl().UART_RW (w)); // Return status
|
return (UART_RW (0xFF) < 0xFF) ? 0 : 1;
|
||||||
|
else {
|
||||||
|
UART_RW (0x00);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool _reset ();
|
bool _reset (Speed s);
|
||||||
//!@}
|
//!@}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,15 +155,14 @@ namespace utl {
|
|||||||
template <typename Impl_t>
|
template <typename Impl_t>
|
||||||
void _1wire_uart_i<Impl_t>::speed (Speed s) {
|
void _1wire_uart_i<Impl_t>::speed (Speed s) {
|
||||||
switch (_speed = s) {
|
switch (_speed = s) {
|
||||||
case Speed::STD: impl().UART_BR (BR_STD); break;
|
case Speed::STD: UART_BR (BR_STD); break;
|
||||||
case Speed::OVDR: impl().UART_BR (BR_OVR); break;
|
case Speed::OVDR: UART_BR (BR_OVR); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Generate a 1-wire reset
|
* Generate a 1-wire reset
|
||||||
*
|
|
||||||
* --- ---- - - - -------
|
* --- ---- - - - -------
|
||||||
* Reset \ / \ X X X /
|
* Reset \ / \ X X X /
|
||||||
* -------------------- - - - -
|
* -------------------- - - - -
|
||||||
@ -208,12 +170,7 @@ namespace utl {
|
|||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
* < ---------- 1024/174 usec ------------->
|
* < ---------- 1024/174 usec ------------->
|
||||||
*
|
*
|
||||||
* 8 bits, no parity, 1 stop
|
* TX: (STD)0xF0, (OVDR)0xF8 RX: less if present
|
||||||
* Standard: Overdrive :
|
|
||||||
* BR: 9600, BR: 57600
|
|
||||||
* TX: 0xF0, TX: 0xF8
|
|
||||||
* RX: 0xF0 not present RX: 0xF8 not present
|
|
||||||
* less if present less if present
|
|
||||||
*
|
*
|
||||||
* \param t Timing
|
* \param t Timing
|
||||||
* \return The status of the operation
|
* \return The status of the operation
|
||||||
@ -221,9 +178,9 @@ namespace utl {
|
|||||||
* \arg 1 Success
|
* \arg 1 Success
|
||||||
*/
|
*/
|
||||||
template <typename Impl_t>
|
template <typename Impl_t>
|
||||||
bool _1wire_uart_i<Impl_t>::_reset () {
|
bool _1wire_uart_i<Impl_t>::_reset (Speed s) {
|
||||||
// Select frame to send
|
// Select frame to send
|
||||||
uint8_t w = (_speed == Speed::STD) ? 0xF0 : 0xF8;
|
uint8_t w = ((_speed = s) == Speed::STD) ? 0xF0 : 0xF8;
|
||||||
// Select baudrate
|
// Select baudrate
|
||||||
impl().UART_BR ((_speed == Speed::STD) ? BR_STD_RST : BR_OVR_RST);
|
impl().UART_BR ((_speed == Speed::STD) ? BR_STD_RST : BR_OVR_RST);
|
||||||
// Send frame and check the result
|
// Send frame and check the result
|
||||||
@ -259,7 +216,8 @@ namespace utl {
|
|||||||
private:
|
private:
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Implementers's (driver) read-write function. We use the following USART configuration.
|
* Implementers's (driver) read-write function. We use the following
|
||||||
|
* USART configuration:
|
||||||
* - Word Length = 8 Bits
|
* - Word Length = 8 Bits
|
||||||
* - Stop Bit = One Stop bit
|
* - Stop Bit = One Stop bit
|
||||||
* - Parity = No parity
|
* - Parity = No parity
|
||||||
@ -291,55 +249,22 @@ namespace utl {
|
|||||||
};
|
};
|
||||||
Speed _speed {Speed::STD};
|
Speed _speed {Speed::STD};
|
||||||
|
|
||||||
Speed speed () { return _speed; } //!< Get the 1-wire bus speed
|
Speed speed () const { return _speed; } //!< Get the 1-wire bus speed
|
||||||
void speed (Speed s); //!< Set the 1-wire bus speed
|
void speed (Speed s); //!< Set the 1-wire bus speed
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Read a bit from the 1-Wire bus, return it and provide
|
* Send a 1-Wire write bit and read the response
|
||||||
* the recovery time.
|
|
||||||
*
|
*
|
||||||
* --- - - - - - - - - - - - - - - - - ------
|
* Write 1 --- --------------------------------------
|
||||||
* Read \ / X X X X X X X X X X X X X X X /
|
* Read 0/1 \ /
|
||||||
* ---- - - - - - - - - - - - - - - - -
|
|
||||||
* RS: | | | | | | | | | | |
|
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
|
||||||
* < ------------- 87/11 usec ------------->
|
|
||||||
* ^
|
|
||||||
* |
|
|
||||||
* Master sample
|
|
||||||
*
|
|
||||||
* 8 bits, no parity, 1 stop
|
|
||||||
* standard: BR: 115200
|
|
||||||
* Overdrive: BR: 921600
|
|
||||||
* TX: 0xFF
|
|
||||||
* RX: {1 - 0xFF, 0 - [0x00 - 0xFE] }
|
|
||||||
*
|
|
||||||
* \return The answer
|
|
||||||
* \arg 0 Read 0
|
|
||||||
* \arg 1 Read 1 (This is also returned on transition error).
|
|
||||||
*/
|
|
||||||
bool bit () {
|
|
||||||
return (UART_RW (0xFF) < 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief
|
|
||||||
* Send a 1-Wire write bit
|
|
||||||
* 8 bits, no parity, 1 stop
|
|
||||||
* standard: BR: 115200
|
|
||||||
* Overdrive: BR: 921600
|
|
||||||
*
|
|
||||||
* --- --------------------------------------
|
|
||||||
* Write 1 \ /
|
|
||||||
* ----
|
* ----
|
||||||
* RS: | | | | | | | | | | |
|
* RS: | | | | | | | | | | |
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
* TX: 0xFF RX: 0xFF
|
* TX: 0xFF RX: 0xFF->1, less->0
|
||||||
*
|
*
|
||||||
* --- ------
|
* Write 0 --- ------
|
||||||
* Write 0 \ /
|
* Read 0 \ /
|
||||||
* -------------------------------------
|
* -------------------------------------
|
||||||
* RS: | | | | | | | | | | |
|
* RS: | | | | | | | | | | |
|
||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
@ -347,15 +272,17 @@ namespace utl {
|
|||||||
* TX: 0x00 RX: 0x00
|
* TX: 0x00 RX: 0x00
|
||||||
*
|
*
|
||||||
* \param b The bit to send
|
* \param b The bit to send
|
||||||
* \return Status of the operation
|
* \return The response
|
||||||
* \arg 0 Fail
|
|
||||||
* \arg 1 Success
|
|
||||||
*/
|
*/
|
||||||
bool bit (bool b) {
|
bool bit (bool b) {
|
||||||
uint8_t w = (b) ? 0xFF : 0x00; // Select write frame to send
|
if (b)
|
||||||
return (w == UART_RW (w)); // Return status
|
return (UART_RW (0xFF) < 0xFF) ? 0 : 1;
|
||||||
|
else {
|
||||||
|
UART_RW (0x00);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
bool _reset ();
|
bool _reset (Speed s);
|
||||||
//!@}
|
//!@}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -376,7 +303,6 @@ namespace utl {
|
|||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
* Generate a 1-wire reset
|
* Generate a 1-wire reset
|
||||||
*
|
|
||||||
* --- ---- - - - -------
|
* --- ---- - - - -------
|
||||||
* Reset \ / \ X X X /
|
* Reset \ / \ X X X /
|
||||||
* -------------------- - - - -
|
* -------------------- - - - -
|
||||||
@ -384,21 +310,16 @@ namespace utl {
|
|||||||
* bit: ST 0 1 2 3 4 5 6 7 SP
|
* bit: ST 0 1 2 3 4 5 6 7 SP
|
||||||
* < ---------- 1024/174 usec ------------->
|
* < ---------- 1024/174 usec ------------->
|
||||||
*
|
*
|
||||||
* 8 bits, no parity, 1 stop
|
* TX: (STD)0xF0, (OVDR)0xF8 RX: less if present
|
||||||
* Standard: Overdrive :
|
|
||||||
* BR: 9600, BR: 57600
|
|
||||||
* TX: 0xF0, TX: 0xF8
|
|
||||||
* RX: 0xF0 not present RX: 0xF8 not present
|
|
||||||
* less if present less if present
|
|
||||||
*
|
*
|
||||||
* \param t Timing
|
* \param t Timing
|
||||||
* \return The status of the operation
|
* \return The status of the operation
|
||||||
* \arg 0 Fail
|
* \arg 0 Fail
|
||||||
* \arg 1 Success
|
* \arg 1 Success
|
||||||
*/
|
*/
|
||||||
bool _1wire_uart_i<virtual_tag>::_reset () {
|
bool _1wire_uart_i<virtual_tag>::_reset (Speed s) {
|
||||||
// Select frame to send
|
// Select frame to send
|
||||||
uint8_t w = (_speed == Speed::STD) ? 0xF0 : 0xF8;
|
uint8_t w = ((_speed = s) == Speed::STD) ? 0xF0 : 0xF8;
|
||||||
// Select baudrate
|
// Select baudrate
|
||||||
UART_BR ((_speed == Speed::STD) ? BR_STD_RST : BR_OVR_RST);
|
UART_BR ((_speed == Speed::STD) ? BR_STD_RST : BR_OVR_RST);
|
||||||
// Send frame and check the result
|
// Send frame and check the result
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*!
|
/*!
|
||||||
* \file utl/container/id.h
|
* \file utl/container/id.h
|
||||||
* \brief A container for device ID's
|
* \brief A container for device IDs
|
||||||
*
|
*
|
||||||
* Copyright (C) 2018 Christos Choutouridis
|
* Copyright (C) 2018 Christos Choutouridis
|
||||||
*
|
*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user