?? bug in samd51 EIC header file - Page 1
Forum section: electronics / general

author: snarkysparky
author_rank: Frequent Contributor
timestamp: November 09, 2023, 02:26:16 pm
content: I doubt its a bug really but i just don't understand.I am trying to enable EXTINT11. The bitfields in the header file#define EIC_INTENSET_EXTINT_Pos 0 /**< \brief (EIC_INTENSET) External Interrupt Enable */#define EIC_INTENSET_EXTINT_Msk (_U_(0xFFFF) << EIC_INTENSET_EXTINT_Pos)#define EIC_INTENSET_EXTINT(value) (EIC_INTENSET_EXTINT_Msk & ((value) << EIC_INTENSET_EXTINT_Pos))#define EIC_INTENSET_MASK _U_(0x0000FFFF) /**< \brief (EIC_INTENSET) MASK Register */soREG_EIC_INTENSET = EIC_INTENSET_EXTINT(11); // write 11 into register ? not correct according to data sheet. To enable EXTINT11 need to write 1 << 11 into registerdatasheet ->Bits 15:0 – EXTINT[15:0] External Interrupt EnableThe bit x of EXTINT enables the interrupt associated with the EXTINTx pin.Writing a '0' to bit x has no effect.Writing a '1' to bit x will set the External Interrupt Enable bit x, which enables the external interrupt EXTINTx.so I need to doREG_EIC_INTENSET |= 1 << 11;AMI wrongThanks

author: eutectique
author_rank: Frequent Contributor
timestamp: November 09, 2023, 02:36:14 pm
content: Without a specific macro for EXTINT11:REG_EIC_INTENSET |= EIC_INTENSET_EXTINT(1u<<11);

author: cv007
author_rank: Frequent Contributor
timestamp: November 09, 2023, 09:13:41 pm
content: With these header monsters, everything is a define so you have to keep to their system of define/macro usage-This would be an example of the part you are missing, in the device header which specifies its pins-Code:#define PIN_PA11A_EIC_EXTINT11 _L_(11) /**< \brief EIC signal: EXTINT11 on PA11 mux A */#define MUX_PA11A_EIC_EXTINT11 _L_(0)#define PINMUX_PA11A_EIC_EXTINT11 ((PIN_PA11A_EIC_EXTINT11 << 16) | MUX_PA11A_EIC_EXTINT11)#define PORT_PA11A_EIC_EXTINT11 (_UL_(1) << 11)#define PIN_PA11A_EIC_EXTINT_NUM _L_(11) /**< \brief EIC signal: PIN_PA11 External Interrupt Line */#define PIN_PA27A_EIC_EXTINT11 _L_(27) /**< \brief EIC signal: EXTINT11 on PA27 mux A */#define MUX_PA27A_EIC_EXTINT11 _L_(0)#define PINMUX_PA27A_EIC_EXTINT11 ((PIN_PA27A_EIC_EXTINT11 << 16) | MUX_PA27A_EIC_EXTINT11)#define PORT_PA27A_EIC_EXTINT11 (_UL_(1) << 27)#define PIN_PA27A_EIC_EXTINT_NUM _L_(11) /**< \brief EIC signal: PIN_PA27 External Interrupt Line */#define PIN_PB11A_EIC_EXTINT11 _L_(43) /**< \brief EIC signal: EXTINT11 on PB11 mux A */#define MUX_PB11A_EIC_EXTINT11 _L_(0)#define PINMUX_PB11A_EIC_EXTINT11 ((PIN_PB11A_EIC_EXTINT11 << 16) | MUX_PB11A_EIC_EXTINT11)#define PORT_PB11A_EIC_EXTINT11 (_UL_(1) << 11)So now you code becomes-REG_EIC_INTENSET = EIC_INTENSET_EXTINT(PORT_PB11A_EIC_EXTINT11); //or whatever EXT11 pin you wantedThe EIC_INTENSET_EXTINT_Pos define simply specifies the location of all these bits in the register (0). The macro will mask off the relevant bits and shift your BITMASK value into the relevant bit position (0).QuoteThat would be wrong also. You do not want |= on these type of registers (you want just =). Whether it actually matters or not in this case (I do not know), the purpose of these set/clr registers is to get an atomic write. With |=, you lose that and may potentially mess with other bits due to the read (using the read values to write, instead of just dealing with only the bit(s) you wanted to set).

author: ataradov
author_rank: Super Contributor
timestamp: November 09, 2023, 09:46:34 pm
content: This is not really a bug. Those files are auto-generated and the generator does not know the type of the field, so the macros universally take the value you want to write. If this value needs to be a shifted bit, then it it on you to shift it. This also lets you set multiple bits at the same time.And this is not specific to EIC, it applies to all the peripherals.This also means that there will be macros generated that make no logical sense too.

author: SiliconWizard
author_rank: Super Contributor
timestamp: November 10, 2023, 01:34:32 am
content: Yes, they are all built on the same principle and it is quite simple. They encode bit fields with masks and bit positions. (Others prefer using real bit fields in structs, although they are known not to be quite portable - but it usually doesn't matter in practice.) So, as ataradov said, these macros don't do anyting else than this. They don't further encode bit fields (although there may be some other macros that do this, you'll have to look, SAMD header files are quite long.)