Hi @foxetera
This line sets the SWTRIG and CLKEN bits in the TC0, channel 0's CCR (Channel Control Register).
TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;
The -> operator specifies a pointer to a structure.
TC0 is defined as a pointer to an address in memory, that points to the base address of the TC0's hardware registers:
#define TC0 ((Tc *)0x40080000U) /**< \brief (TC0 ) Base Address */
Where this structure resides:
/** \brief Tc hardware registers */
#define TCCHANNEL_NUMBER 3
typedef struct {
TcChannel TC_CHANNEL[TCCHANNEL_NUMBER]; /**< \brief (Tc Offset: 0x0) channel = 0 .. 2 */
__O uint32_t TC_BCR; /**< \brief (Tc Offset: 0xC0) Block Control Register */
__IO uint32_t TC_BMR; /**< \brief (Tc Offset: 0xC4) Block Mode Register */
__O uint32_t TC_QIER; /**< \brief (Tc Offset: 0xC8) QDEC Interrupt Enable Register */
__O uint32_t TC_QIDR; /**< \brief (Tc Offset: 0xCC) QDEC Interrupt Disable Register */
__I uint32_t TC_QIMR; /**< \brief (Tc Offset: 0xD0) QDEC Interrupt Mask Register */
__I uint32_t TC_QISR; /**< \brief (Tc Offset: 0xD4) QDEC Interrupt Status Register */
__IO uint32_t TC_FMR; /**< \brief (Tc Offset: 0xD8) Fault Mode Register */
__I uint32_t Reserved1[2];
__IO uint32_t TC_WPMR; /**< \brief (Tc Offset: 0xE4) Write Protect Mode Register */
} Tc;
In your example, the TC0 pointer points to the array TC_CHANNEL[0] member in the structure above.
However, the TC_CHANNEL[0] array item is a structure itself, containg the location of various TC channel specific hardware registers:
/** \brief TcChannel hardware registers */
typedef struct {
__O uint32_t TC_CCR; /**< \brief (TcChannel Offset: 0x0) Channel Control Register */
__IO uint32_t TC_CMR; /**< \brief (TcChannel Offset: 0x4) Channel Mode Register */
__IO uint32_t TC_SMMR; /**< \brief (TcChannel Offset: 0x8) Stepper Motor Mode Register */
__I uint32_t Reserved1[1];
__I uint32_t TC_CV; /**< \brief (TcChannel Offset: 0x10) Counter Value */
__IO uint32_t TC_RA; /**< \brief (TcChannel Offset: 0x14) Register A */
__IO uint32_t TC_RB; /**< \brief (TcChannel Offset: 0x18) Register B */
__IO uint32_t TC_RC; /**< \brief (TcChannel Offset: 0x1C) Register C */
__I uint32_t TC_SR; /**< \brief (TcChannel Offset: 0x20) Status Register */
__O uint32_t TC_IER; /**< \brief (TcChannel Offset: 0x24) Interrupt Enable Register */
__O uint32_t TC_IDR; /**< \brief (TcChannel Offset: 0x28) Interrupt Disable Register */
__I uint32_t TC_IMR; /**< \brief (TcChannel Offset: 0x2C) Interrupt Mask Register */
__I uint32_t Reserved2[4];
} TcChannel;
In your example, the TC_CCR (Channel Control Register) member is determined with the structure member operator, represented by a dot "."
This line:
PIOB->PIO_ABSR |= PIO_PB25B_TIOA0;
...does a read-modify-write operation, setting the PIO_PB25B_TIOA0 bit in the PIOB->PIO_ABSR regsiter without affecting the other bits in the register.
To clear the same bit requires the bitwise ANDing of the register with the negated PIO_PB25B_TIOA0 definition:
PIOB->PIO_ABSR &= ~PIO_PB25B_TIOA0;
The SAM3X8E mircocontroller hardware register definitions on my Windows machine are located at:
C:\Users\Computer\AppData\Local\Arduino15\packages\arduino\hardware\sam\1.6.12\system\CMSIS\Device\ATMEL\sam3xa\include