diff --git a/cppreg_Defines.h b/cppreg_Defines.h index acd375e..3d5a254 100644 --- a/cppreg_Defines.h +++ b/cppreg_Defines.h @@ -35,25 +35,15 @@ namespace cppreg { enum class RegBitSize { b8, //!< 8-bit register. b16, //!< 16-bit register. - b32 //!< 32-bit register. + b32, //!< 32-bit register. + b64 //!< 64-bit register. }; -// //! Type alias for register and field widths. -// /** -// * This limit the implementation to a maximum size of 256 bits for any -// * register or field. -// * This corresponds to the number of bits in the a register or field. -// */ + //! Type alias field width. using FieldWidth_t = std::uint8_t; - //! Type alias for register and field offsets. - /** - * This limit the implementation to a maximum offset of 256 bits for any - * register or field. - * Given that we consider 32 bits address space and 32 bits register this - * should be enough. - */ + //! Type alias for field offset. using FieldOffset_t = std::uint8_t; diff --git a/register/Field.h b/register/Field.h index d27db10..8b8e391 100644 --- a/register/Field.h +++ b/register/Field.h @@ -170,8 +170,8 @@ namespace cppreg { >::type write() noexcept { - // For this particular we can simply forward to the non-constant - // implementation. + // For this particular we simply forward to the non-constant + // implementation because the shadow value needs to be updated. write(value); }; diff --git a/register/MergeWrite.h b/register/MergeWrite.h index e5f530f..28bd887 100644 --- a/register/MergeWrite.h +++ b/register/MergeWrite.h @@ -51,14 +51,11 @@ namespace cppreg { > class MergeWrite_tmpl { - public: - - //! Type alias to register base type. - using base_type = typename Register::type; - - private: + // Type alias to register base type. + using base_type = typename Register::type; + // Disabled for shadow value register. static_assert(!Register::shadow::value, "merge write is not available for shadow value register"); @@ -135,7 +132,16 @@ namespace cppreg { T >::type&& with() const && noexcept { + + // Check that the field belongs to the register. + static_assert(std::is_same< + typename F::parent_register, + Register + >::value, + "field is not from the same register in merge_write"); + return std::move(T::make()); + }; diff --git a/register/Register.h b/register/Register.h index 3df39b9..05653e3 100644 --- a/register/Register.h +++ b/register/Register.h @@ -25,8 +25,8 @@ namespace cppreg { /** * @tparam reg_address Register address. * @tparam reg_size Register size enum value. - * @tparam ResetValue Register reset value (0x0 if unknown). - * @tparam UseShadow shadow Boolean flag to enable shadow value. + * @tparam reset_value Register reset value (0x0 if unknown). + * @tparam use_shadow shadow Boolean flag to enable shadow value. * * This data structure will act as a container for fields and is * therefore limited to a strict minimum. It only carries information diff --git a/register/RegisterPack.h b/register/RegisterPack.h index 6325140..b0f269b 100644 --- a/register/RegisterPack.h +++ b/register/RegisterPack.h @@ -97,18 +97,18 @@ namespace internals { //! Packed register implementation. /** * @tparam RegisterPack Pack to which the register belongs. - * @tparam BitOffset Offset in bits for the register with respect to base. - * @tparam RegWidth Register width. - * @tparam ResetValue Register reset value (0x0 if unknown). - * @tparam UseShadow shadow Boolean flag to enable shadow value. + * @tparam reg_size Register size enum value. + * @tparam bit_offset Offset in bits for the register with respect to base. + * @tparam reset_value Register reset value (0x0 if unknown). + * @tparam use_shadow Boolean flag to enable shadow value. * * This implementation is intended to be used when defining a register * that belongs to a peripheral group. */ template < typename RegisterPack, - std::uint32_t bit_offset, RegBitSize reg_size, + std::uint32_t bit_offset, typename TypeTraits::type reset_value = 0x0, bool use_shadow = false > diff --git a/register/ShadowValue.h b/register/ShadowValue.h index e145787..2725bb9 100644 --- a/register/ShadowValue.h +++ b/register/ShadowValue.h @@ -20,11 +20,12 @@ namespace cppreg { //! Shadow value generic implementation. /** * @tparam Register Register type. - * @tparam UseShadow Boolean flag indicating if shadow value is required. + * @tparam use_shadow Boolean flag indicating if shadow value is required. * * This implementation is for register which do not require shadow value. */ - template struct Shadow : std::false_type {}; + template + struct Shadow : std::false_type {}; //! Shadow value implementation. diff --git a/register/Traits.h b/register/Traits.h index 20870b5..abc1b81 100644 --- a/register/Traits.h +++ b/register/Traits.h @@ -19,22 +19,6 @@ namespace cppreg { -// //! Register data type default implementation. -// /** -// * @tparam Size Register size. -// * -// * This will fail to compile if the register size is not implemented. -// */ -// template -// struct RegisterType; -// -// //!@{ Specializations based on register size. -// template <> struct RegisterType<8u> { using type = std::uint8_t; }; -// template <> struct RegisterType<16u> { using type = std::uint16_t; }; -// template <> struct RegisterType<32u> { using type = std::uint32_t; }; -// //!@} - - //! Register type traits based on size. /** * @tparam S Register size in bits. @@ -42,6 +26,9 @@ namespace cppreg { template struct TypeTraits; + + //!@{ TypeTraits specializations. + //! 8-bit specialization. template <> struct TypeTraits { using type = std::uint8_t; constexpr static const std::uint8_t bit_size = 8u; @@ -49,6 +36,7 @@ namespace cppreg { constexpr static const std::uint8_t max_field_width = 8u; constexpr static const std::uint8_t max_field_offset = 8u; }; + //! 16-bit specialization. template <> struct TypeTraits { using type = std::uint16_t; constexpr static const std::uint8_t bit_size = 16u; @@ -56,6 +44,7 @@ namespace cppreg { constexpr static const std::uint8_t max_field_width = 16u; constexpr static const std::uint8_t max_field_offset = 16u; }; + //! 32-bit specialization. template <> struct TypeTraits { using type = std::uint32_t; constexpr static const std::uint8_t bit_size = 32u; @@ -63,6 +52,15 @@ namespace cppreg { constexpr static const std::uint8_t max_field_width = 32u; constexpr static const std::uint8_t max_field_offset = 32u; }; + //! 64-bit specialization. + template <> struct TypeTraits { + using type = std::uint64_t; + constexpr static const std::uint8_t bit_size = 64u; + constexpr static const std::uint8_t byte_size = 8u; + constexpr static const std::uint8_t max_field_width = 64u; + constexpr static const std::uint8_t max_field_offset = 64u; + }; + //!@} }