mirror of
https://github.com/sendyne/cppreg.git
synced 2026-01-19 04:52:08 +00:00
BUG FIX IN MERGER WRITE IMPLEMENTATION FOR NON CONSTANT VALUES
* For write-only registers the merge write implementation for non-constant values was properly updating the cache value. * Unnecessary `inline` have been removed.
This commit is contained in:
@@ -58,7 +58,7 @@ namespace cppreg {
|
||||
* @return The content of the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -71,7 +71,7 @@ namespace cppreg {
|
||||
* @return The content of the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -111,7 +111,7 @@ namespace cppreg {
|
||||
* @param value Value to be written to the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
@@ -127,7 +127,7 @@ namespace cppreg {
|
||||
* @param value Value to be written to the register field.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
@@ -170,7 +170,7 @@ namespace cppreg {
|
||||
* @param mmio_device Pointer to the register memory device.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -184,7 +184,7 @@ namespace cppreg {
|
||||
* @param mmio_device Pointer to the register memory device.
|
||||
*/
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -207,7 +207,7 @@ namespace cppreg {
|
||||
* @return The value at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static T read(const MMIO_t& mmio_device) noexcept {
|
||||
static T read(const MMIO_t& mmio_device) noexcept {
|
||||
return RegisterRead<MMIO_t, T, mask, offset>::read(mmio_device);
|
||||
};
|
||||
|
||||
@@ -227,7 +227,7 @@ namespace cppreg {
|
||||
* @param value Value to be written at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, mask, offset>::write(mmio_device, value);
|
||||
};
|
||||
@@ -244,7 +244,7 @@ namespace cppreg {
|
||||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, offset, value>
|
||||
::write(mmio_device);
|
||||
};
|
||||
@@ -256,7 +256,7 @@ namespace cppreg {
|
||||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void set(MMIO_t& mmio_device)
|
||||
static void set(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, mask>
|
||||
::write(mmio_device);
|
||||
@@ -270,7 +270,7 @@ namespace cppreg {
|
||||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void clear(MMIO_t& mmio_device)
|
||||
static void clear(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, ~mask>
|
||||
::write(mmio_device);
|
||||
@@ -284,7 +284,7 @@ namespace cppreg {
|
||||
* @param mmio_device Pointer to register mapped memory.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void toggle(MMIO_t& mmio_device)
|
||||
static void toggle(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
mmio_device = static_cast<T>((mmio_device) ^ mask);
|
||||
};
|
||||
@@ -305,8 +305,7 @@ namespace cppreg {
|
||||
* @param value Value to be written at the field location.
|
||||
*/
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
static void write(MMIO_t& mmio_device, const T value) noexcept {
|
||||
|
||||
// For write-only fields we can only write to the whole register.
|
||||
RegisterWrite<MMIO_t, T, type_mask<T>::value, 0u>::write(
|
||||
@@ -326,7 +325,7 @@ namespace cppreg {
|
||||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
|
||||
// For write-only fields we can only write to the whole register.
|
||||
RegisterWriteConstant<
|
||||
|
||||
@@ -89,7 +89,7 @@ namespace cppreg {
|
||||
/**
|
||||
* @return Field value.
|
||||
*/
|
||||
inline static type read() noexcept {
|
||||
static type read() noexcept {
|
||||
return policy::template read<MMIO_t, type, mask, offset>(
|
||||
parent_register::ro_mem_device()
|
||||
);
|
||||
@@ -100,7 +100,7 @@ namespace cppreg {
|
||||
* @param value Value to be written to the field.
|
||||
*/
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<!has_shadow, T>::type value)
|
||||
noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset>(
|
||||
@@ -114,7 +114,7 @@ namespace cppreg {
|
||||
* @param value Value to be written to the field.
|
||||
*/
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<has_shadow, T>::type value)
|
||||
noexcept {
|
||||
|
||||
@@ -140,14 +140,14 @@ namespace cppreg {
|
||||
* field and uses the constant write implementation.
|
||||
*/
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset, value>(
|
||||
parent_register::rw_mem_device()
|
||||
);
|
||||
@@ -161,14 +161,14 @@ namespace cppreg {
|
||||
* field and uses the constant write implementation.
|
||||
*/
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
|
||||
// For this particular we simply forward to the non-constant
|
||||
// implementation because the shadow value needs to be updated.
|
||||
@@ -180,7 +180,7 @@ namespace cppreg {
|
||||
/**
|
||||
* This method will set all bits in the field.
|
||||
*/
|
||||
inline static void set() noexcept {
|
||||
static void set() noexcept {
|
||||
policy::template
|
||||
set<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
@@ -189,7 +189,7 @@ namespace cppreg {
|
||||
/**
|
||||
* This method will clear all bits in the field.
|
||||
*/
|
||||
inline static void clear() noexcept {
|
||||
static void clear() noexcept {
|
||||
policy::template
|
||||
clear<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
@@ -198,7 +198,7 @@ namespace cppreg {
|
||||
/**
|
||||
* This method will toggle all bits in the field.
|
||||
*/
|
||||
inline static void toggle() noexcept {
|
||||
static void toggle() noexcept {
|
||||
policy::template
|
||||
toggle<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
@@ -207,7 +207,7 @@ namespace cppreg {
|
||||
/**
|
||||
* @return `true` if all the bits are set to 1, `false` otherwise.
|
||||
*/
|
||||
inline static bool is_set() noexcept {
|
||||
static bool is_set() noexcept {
|
||||
return (Field::read() == (mask >> offset));
|
||||
};
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace cppreg {
|
||||
/**
|
||||
* @return `true` if all the bits are set to 0, `false` otherwise.
|
||||
*/
|
||||
inline static bool is_clear() noexcept {
|
||||
static bool is_clear() noexcept {
|
||||
return (Field::read() == 0u);
|
||||
};
|
||||
|
||||
|
||||
@@ -68,13 +68,13 @@ namespace cppreg {
|
||||
constexpr static const base_type _combined_mask = mask;
|
||||
|
||||
// Default constructor.
|
||||
MergeWrite_tmpl() {};
|
||||
MergeWrite_tmpl() = default;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//! Instantiation method.
|
||||
inline static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
|
||||
//!@{ Non-copyable and non-moveable.
|
||||
MergeWrite_tmpl(const MergeWrite_tmpl&) = delete;
|
||||
@@ -88,7 +88,7 @@ namespace cppreg {
|
||||
/**
|
||||
* This is where the write happens.
|
||||
*/
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
|
||||
// Get memory pointer.
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
@@ -124,7 +124,6 @@ namespace cppreg {
|
||||
F::mask)
|
||||
>
|
||||
>
|
||||
inline
|
||||
typename std::enable_if<
|
||||
(internals::check_overflow<
|
||||
typename Register::type, new_value, (F::mask >> F::offset)
|
||||
@@ -196,7 +195,7 @@ namespace cppreg {
|
||||
/**
|
||||
* This is where the write happens.
|
||||
*/
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
|
||||
// Get memory pointer.
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
@@ -221,8 +220,8 @@ namespace cppreg {
|
||||
* @return A reference to the current merge write data.
|
||||
*/
|
||||
template <typename F>
|
||||
inline MergeWrite<Register, _combined_mask | F::mask> with
|
||||
(const base_type value) && noexcept {
|
||||
MergeWrite<Register, _combined_mask | F::mask>
|
||||
with(const base_type value) && noexcept {
|
||||
|
||||
// Check that the field belongs to the register.
|
||||
static_assert(std::is_same<
|
||||
@@ -232,12 +231,8 @@ namespace cppreg {
|
||||
"field is not from the same register in merge_write");
|
||||
|
||||
// Update accumulated value.
|
||||
F::policy::template write<
|
||||
base_type,
|
||||
base_type,
|
||||
F::mask,
|
||||
F::offset
|
||||
>(_accumulated_value, value);
|
||||
_accumulated_value = (_accumulated_value & ~F::mask)
|
||||
| ((value << F::offset) & F::mask);
|
||||
|
||||
return
|
||||
std::move(
|
||||
@@ -256,7 +251,8 @@ namespace cppreg {
|
||||
|
||||
// Private default constructor.
|
||||
constexpr MergeWrite() : _accumulated_value(0u) {};
|
||||
constexpr MergeWrite(const base_type v) : _accumulated_value(v) {};
|
||||
constexpr explicit MergeWrite(const base_type v) :
|
||||
_accumulated_value(v) {};
|
||||
|
||||
// Accumulated value.
|
||||
base_type _accumulated_value;
|
||||
|
||||
@@ -84,7 +84,7 @@ namespace cppreg {
|
||||
* @return A merge write data structure to chain further writes.
|
||||
*/
|
||||
template <typename F>
|
||||
inline static MergeWrite<typename F::parent_register, F::mask>
|
||||
static MergeWrite<typename F::parent_register, F::mask>
|
||||
merge_write(const typename F::type value) noexcept {
|
||||
return
|
||||
MergeWrite<typename F::parent_register, F::mask>
|
||||
@@ -107,7 +107,7 @@ namespace cppreg {
|
||||
value
|
||||
>
|
||||
>
|
||||
inline static
|
||||
static
|
||||
typename std::enable_if<
|
||||
internals::check_overflow<
|
||||
type, value, (F::mask >> F::offset)
|
||||
|
||||
@@ -83,7 +83,7 @@ namespace cppreg {
|
||||
/**
|
||||
* @return A reference to the writable register memory.
|
||||
*/
|
||||
inline static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
@@ -92,7 +92,7 @@ namespace cppreg {
|
||||
/**
|
||||
* @return A reference to the read-only register memory.
|
||||
*/
|
||||
inline static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
@@ -166,7 +166,7 @@ namespace cppreg {
|
||||
* This will call Op for the range [start, end).
|
||||
*/
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {
|
||||
static void apply() noexcept {
|
||||
Func().template operator()<start>();
|
||||
if (start < end)
|
||||
for_loop<start + 1ul, end>::template apply<Func>();
|
||||
@@ -184,7 +184,7 @@ namespace cppreg {
|
||||
* use lambda [](auto index) { index.value will be the loop index};
|
||||
*/
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {
|
||||
static void apply(Op&& f) noexcept {
|
||||
if (start < end) {
|
||||
f(std::integral_constant<std::size_t, start>{});
|
||||
for_loop<start + 1ul, end>::apply(std::forward<Op>(f));
|
||||
@@ -196,10 +196,10 @@ namespace cppreg {
|
||||
template <std::size_t end>
|
||||
struct for_loop<end, end> {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {};
|
||||
static void apply() noexcept {};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {};
|
||||
static void apply(Op&& f) noexcept {};
|
||||
#endif // __cplusplus 201402L
|
||||
};
|
||||
|
||||
|
||||
@@ -109,14 +109,14 @@ namespace cppreg {
|
||||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
return static_cast<T>((mmio_device & mask) >> offset);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static T read(
|
||||
static T read(
|
||||
const MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -128,7 +128,7 @@ namespace cppreg {
|
||||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
@@ -138,7 +138,7 @@ namespace cppreg {
|
||||
);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
T value,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
@@ -153,7 +153,7 @@ namespace cppreg {
|
||||
constexpr static const bool is_trivial =
|
||||
(mask == type_mask<T>::value) && (offset == 0u);
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<!is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -162,7 +162,7 @@ namespace cppreg {
|
||||
);
|
||||
};
|
||||
template <typename U = void>
|
||||
inline static void write(
|
||||
static void write(
|
||||
MMIO_t& mmio_device,
|
||||
typename std::enable_if<is_trivial, U*>::type = nullptr
|
||||
) noexcept {
|
||||
@@ -171,45 +171,44 @@ namespace cppreg {
|
||||
};
|
||||
struct read_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static T read(const MMIO_t& mmio_device) noexcept {
|
||||
static T read(const MMIO_t& mmio_device) noexcept {
|
||||
return RegisterRead<MMIO_t, T, mask, offset>::read(mmio_device);
|
||||
};
|
||||
};
|
||||
struct read_write : read_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, mask, offset>::write(mmio_device, value);
|
||||
};
|
||||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, offset, value>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void set(MMIO_t& mmio_device)
|
||||
static void set(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, mask>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void clear(MMIO_t& mmio_device)
|
||||
static void clear(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
RegisterWriteConstant<MMIO_t, T, mask, 0u, ~mask>
|
||||
::write(mmio_device);
|
||||
};
|
||||
template <typename MMIO_t, typename T, T mask>
|
||||
inline static void toggle(MMIO_t& mmio_device)
|
||||
static void toggle(MMIO_t& mmio_device)
|
||||
noexcept {
|
||||
mmio_device = static_cast<T>((mmio_device) ^ mask);
|
||||
};
|
||||
};
|
||||
struct write_only {
|
||||
template <typename MMIO_t, typename T, T mask, FieldOffset_t offset>
|
||||
inline static void write(MMIO_t& mmio_device,
|
||||
const T value) noexcept {
|
||||
static void write(MMIO_t& mmio_device, const T value) noexcept {
|
||||
RegisterWrite<MMIO_t, T, type_mask<T>::value, 0u>::write(
|
||||
mmio_device, ((value << offset) & mask)
|
||||
);
|
||||
@@ -217,7 +216,7 @@ namespace cppreg {
|
||||
template <
|
||||
typename MMIO_t, typename T, T mask, FieldOffset_t offset, T value
|
||||
>
|
||||
inline static void write(MMIO_t& mmio_device) noexcept {
|
||||
static void write(MMIO_t& mmio_device) noexcept {
|
||||
RegisterWriteConstant<
|
||||
MMIO_t, T, type_mask<T>::value, 0u, ((value << offset) & mask)
|
||||
>
|
||||
@@ -281,15 +280,15 @@ namespace cppreg {
|
||||
constexpr static const base_type _accumulated_value =
|
||||
((value << offset) & mask);
|
||||
constexpr static const base_type _combined_mask = mask;
|
||||
MergeWrite_tmpl() {};
|
||||
MergeWrite_tmpl() = default;
|
||||
public:
|
||||
inline static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
static MergeWrite_tmpl make() noexcept { return {}; };
|
||||
MergeWrite_tmpl(const MergeWrite_tmpl&) = delete;
|
||||
MergeWrite_tmpl& operator=(const MergeWrite_tmpl&) = delete;
|
||||
MergeWrite_tmpl& operator=(MergeWrite_tmpl&&) = delete;
|
||||
MergeWrite_tmpl operator=(MergeWrite_tmpl) = delete;
|
||||
MergeWrite_tmpl(MergeWrite_tmpl&&) = delete;
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
Register::rw_mem_device();
|
||||
RegisterWriteConstant<
|
||||
@@ -311,7 +310,6 @@ namespace cppreg {
|
||||
F::mask)
|
||||
>
|
||||
>
|
||||
inline
|
||||
typename std::enable_if<
|
||||
(internals::check_overflow<
|
||||
typename Register::type, new_value, (F::mask >> F::offset)
|
||||
@@ -345,7 +343,7 @@ namespace cppreg {
|
||||
MergeWrite(const MergeWrite&) = delete;
|
||||
MergeWrite& operator=(const MergeWrite&) = delete;
|
||||
MergeWrite& operator=(MergeWrite&&) = delete;
|
||||
inline void done() const && noexcept {
|
||||
void done() const && noexcept {
|
||||
typename Register::MMIO_t& mmio_device =
|
||||
Register::rw_mem_device();
|
||||
RegisterWrite<
|
||||
@@ -356,19 +354,15 @@ namespace cppreg {
|
||||
>::write(mmio_device, _accumulated_value);
|
||||
};
|
||||
template <typename F>
|
||||
inline MergeWrite<Register, _combined_mask | F::mask> with
|
||||
(const base_type value) && noexcept {
|
||||
MergeWrite<Register, _combined_mask | F::mask>
|
||||
with(const base_type value) && noexcept {
|
||||
static_assert(std::is_same<
|
||||
typename F::parent_register,
|
||||
Register
|
||||
>::value,
|
||||
"field is not from the same register in merge_write");
|
||||
F::policy::template write<
|
||||
base_type,
|
||||
base_type,
|
||||
F::mask,
|
||||
F::offset
|
||||
>(_accumulated_value, value);
|
||||
_accumulated_value = (_accumulated_value & ~F::mask)
|
||||
| ((value << F::offset) & F::mask);
|
||||
return
|
||||
std::move(
|
||||
MergeWrite<Register, (_combined_mask | F::mask)>
|
||||
@@ -379,7 +373,8 @@ namespace cppreg {
|
||||
static_assert(!Register::shadow::value,
|
||||
"merge write is not available for shadow value register");
|
||||
constexpr MergeWrite() : _accumulated_value(0u) {};
|
||||
constexpr MergeWrite(const base_type v) : _accumulated_value(v) {};
|
||||
constexpr explicit MergeWrite(const base_type v) :
|
||||
_accumulated_value(v) {};
|
||||
base_type _accumulated_value;
|
||||
};
|
||||
}
|
||||
@@ -410,7 +405,7 @@ namespace cppreg {
|
||||
return *(reinterpret_cast<const MMIO_t* const>(base_address));
|
||||
};
|
||||
template <typename F>
|
||||
inline static MergeWrite<typename F::parent_register, F::mask>
|
||||
static MergeWrite<typename F::parent_register, F::mask>
|
||||
merge_write(const typename F::type value) noexcept {
|
||||
return
|
||||
MergeWrite<typename F::parent_register, F::mask>
|
||||
@@ -426,7 +421,7 @@ namespace cppreg {
|
||||
value
|
||||
>
|
||||
>
|
||||
inline static
|
||||
static
|
||||
typename std::enable_if<
|
||||
internals::check_overflow<
|
||||
type, value, (F::mask >> F::offset)
|
||||
@@ -482,11 +477,11 @@ namespace cppreg {
|
||||
RegisterPack::size_in_bytes,
|
||||
reg_size
|
||||
>;
|
||||
inline static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
static typename base_reg::MMIO_t& rw_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
inline static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
static const typename base_reg::MMIO_t& ro_mem_device() noexcept {
|
||||
return mem_map_t::array[bit_offset
|
||||
/ TypeTraits<reg_size>::bit_size];
|
||||
};
|
||||
@@ -521,14 +516,14 @@ namespace cppreg {
|
||||
template <std::size_t start, std::size_t end>
|
||||
struct for_loop {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {
|
||||
static void apply() noexcept {
|
||||
Func().template operator()<start>();
|
||||
if (start < end)
|
||||
for_loop<start + 1ul, end>::template apply<Func>();
|
||||
};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {
|
||||
static void apply(Op&& f) noexcept {
|
||||
if (start < end) {
|
||||
f(std::integral_constant<std::size_t, start>{});
|
||||
for_loop<start + 1ul, end>::apply(std::forward<Op>(f));
|
||||
@@ -539,10 +534,10 @@ namespace cppreg {
|
||||
template <std::size_t end>
|
||||
struct for_loop<end, end> {
|
||||
template <typename Func>
|
||||
inline static void apply() noexcept {};
|
||||
static void apply() noexcept {};
|
||||
#if __cplusplus >= 201402L
|
||||
template <typename Op>
|
||||
inline static void apply(Op&& f) noexcept {};
|
||||
static void apply(Op&& f) noexcept {};
|
||||
#endif
|
||||
};
|
||||
template <typename IndexedPack>
|
||||
@@ -577,13 +572,13 @@ namespace cppreg {
|
||||
value,
|
||||
(mask >> offset)
|
||||
> {};
|
||||
inline static type read() noexcept {
|
||||
static type read() noexcept {
|
||||
return policy::template read<MMIO_t, type, mask, offset>(
|
||||
parent_register::ro_mem_device()
|
||||
);
|
||||
};
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<!has_shadow, T>::type value)
|
||||
noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset>(
|
||||
@@ -592,7 +587,7 @@ namespace cppreg {
|
||||
);
|
||||
};
|
||||
template <typename T = type>
|
||||
inline static void
|
||||
static void
|
||||
write(const typename std::enable_if<has_shadow, T>::type value)
|
||||
noexcept {
|
||||
RegisterWrite<type, type, mask, offset>
|
||||
@@ -603,45 +598,45 @@ namespace cppreg {
|
||||
);
|
||||
};
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
!has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
policy::template write<MMIO_t, type, mask, offset, value>(
|
||||
parent_register::rw_mem_device()
|
||||
);
|
||||
};
|
||||
template <type value, typename T = void>
|
||||
inline static
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type
|
||||
write() noexcept {
|
||||
static void write(
|
||||
typename std::enable_if<
|
||||
has_shadow
|
||||
&&
|
||||
check_overflow<value>::value,
|
||||
T
|
||||
>::type* = nullptr
|
||||
) noexcept {
|
||||
write(value);
|
||||
};
|
||||
inline static void set() noexcept {
|
||||
static void set() noexcept {
|
||||
policy::template
|
||||
set<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static void clear() noexcept {
|
||||
static void clear() noexcept {
|
||||
policy::template
|
||||
clear<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static void toggle() noexcept {
|
||||
static void toggle() noexcept {
|
||||
policy::template
|
||||
toggle<MMIO_t, type, mask>(parent_register::rw_mem_device());
|
||||
};
|
||||
inline static bool is_set() noexcept {
|
||||
static bool is_set() noexcept {
|
||||
return (Field::read() == (mask >> offset));
|
||||
};
|
||||
inline static bool is_clear() noexcept {
|
||||
static bool is_clear() noexcept {
|
||||
return (Field::read() == 0u);
|
||||
};
|
||||
static_assert(parent_register::size >= width,
|
||||
|
||||
Reference in New Issue
Block a user