Hi @saucyboythesecond
The SAMD21's CMSIS register definintions allow you to access the registers in a number of different ways. For example lets take the TCC0 timer's CTRLA register:
Register ".reg" Suffix
The register definitions allow the entire register to be accessed using the .reg suffix.
For instance, to read the entire TCC0's CTRLA register and display it on the console as a hexidecimal number:
Serial.println(TCC0->CTRLA.reg, HEX);
However, if you wish to set or clear individual bits then it's necessary to use the OR ('|') and AND ('&') bitwise operators.
To set a bit or bitfield (more than one bit), it's necessary to do what's called a read-modify-write operation. Setting a bit/bitfield involves reading the current value of the register, bitwise ORing it with a mask of the bit/bitfield, then writing the result back to the register. This is achieved using the assignment by bitwise OR operator ("|="):
TCC0->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV16;
Note: this requires all of the TCC_CTRLA_PRESCALER_DIV16 bitfield to be cleared to 0 prior to writing. In other words, if any of the bitfields bits are already set to 1, they won't be cleared to 0.
It's also possible to set multiple bitfields in one go with the bitwise OR:
TCC0->CTRLA.reg |= TCC_CTRLA_RUNSTDBY | TCC_CTRLA_PRESCALER_DIV16;
To clear certain bits/bitfields with a read-modify-write operation, use the assignment by bitwise AND operator ("&=") together with the inverse (a.k.a bitwise NOT operator ('~')) of the bit/bitfield mask. In this case, to disable the TCC0 timer:
TCC0->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TCC0
Register ".bit" suffix
The register definitions also allow the individual register bits/bitfields to be accessed using the .bit suffix. This handy notaion dispenses with the assignment by bitwise operators.
For example to enable the TCC0 timer:
TCC0->CTRLA.bit.ENABLE = 1; // Enable TCC0
or alternatively:
TCC0->CTRLA.bit.ENABLE = TCC_CTRLA_ENABLE_Pos; // Enable TCC0
Conversely to disable TCC0:
TCC0->CTRLA.bit.ENABLE = 0; // Disable TCC0
Or set a bitfield:
TCC0->CTRLA.bit.PRESCALER = TCC_CTRLA_PRESCALER_DIV16_Val;
Note: unlike the ".reg" notation, the ".bit" suffix allows the code to both set and clear the relevant bits.
Usually I use the ".reg" notation during initialisation when bit/bitfields are already cleared to 0, as this enables multiple bits/bitfields to be bitwise ORed together in one go. I normally employ the ".bit" suffix during operation, since it automatically set/clears the relevant bit/bitfield bits as required.