diff --git a/src/macros.h b/src/macros.h
new file mode 100644
index 0000000000000000000000000000000000000000..939eae1e85624a861fc603a84781d1b0bb12e8a5
--- /dev/null
+++ b/src/macros.h
@@ -0,0 +1,48 @@
+/*
+ * macros.h
+ *
+ * Created: 2021-11-04 14:11:05
+ *  Author: benra10
+ */ 
+
+
+#ifndef MACROS_H_
+#define MACROS_H_
+
+// Macros for writing to I/O:
+// There are many ways to write to PORT registers.
+// Method 1. Simplest PORT method. Example for setting PA20 on PORTA. Note PORT_PA20 and not PIN_PA20
+//		PORTA.OUTSET.reg = PORT_PA20
+// Method 2. Quicker method of PORT. Not sure if it is much faster than method 1 but it is more "compatible" with method nr 3.
+//		port_nr is in this case 0 for PORTA, 1 for PORTB and so on.
+//		PORT->Group[port_nr].OUTSET.reg = PORT_PA20
+// Method nr 3. Much quicker method that uses the direct access IOBUS. (If any optimization is enabled, otherwise difference is smaller).
+//		PORT_IOBUS->Group[port_nr].OUTSET.reg = PORT_PA20
+// Drawback is that for using IOBUS the constant sampling of used pins (in groups of 8) must be enabled.
+// This consumes some power.
+// Recommendation: Use method nr 2 and 3. Nr 2 if need to use minimum of power and 3 if need for maximal speed.
+// Note: Data sheet says that only Data Output Value, Data Input Value and Pin Direction registers can be accessed through IOBUS operation.
+// But practically test has shown that all PORT register can be accessed. For example PINCFG.
+// Read more here about writing to ports:
+// https://electronics.stackexchange.com/questions/139117/atmels-arm-programming-without-asf
+// https://community.atmel.com/forum/getting-started-arm-3
+// https://www.avrfreaks.net/forum/considerations-using-iobus-port-access
+
+#define PORT_SET_PIN(port_nr,port_pin)								PORT_IOBUS->Group[port_nr].OUTSET.reg = port_pin		// Set to 1; Time with 40MHz is 190nsec
+#define PORT_CLR_PIN(port_nr,port_pin)								PORT_IOBUS->Group[port_nr].OUTCLR.reg = port_pin		// Set to 0
+#define PORT_TOGGLE_PIN(port_nr,port_pin)							PORT_IOBUS->Group[port_nr].OUTTGL.reg = port_pin		// Toggle pin
+#define PORT_OUTPUT_PIN(port_nr,port_pin)							PORT_IOBUS->Group[port_nr].DIRSET.reg =  port_pin		// Set pin to output
+#define PORT_INPUT_PIN(port_nr,port_pin)							PORT_IOBUS->Group[port_nr].DIRCLR.reg =  port_pin		// port.DIRCLR.reg = pin			// Set pin to input
+#define PORT_INPUT_PIN_EN(port_nr,port_pin)						PORT->Group[port_nr].PINCFG[port_pin].bit.INEN = 1	// Enable input buffer (needed to be able to read a pin)
+#define PORT_READ_PIN(port_nr,port_pin)								PORT_IOBUS->Group[port_nr].IN[port_pin]							// Read a pin
+#define PORT_READ(port_nr)														PORT->Group[port_nr].IN.reg													// Read a port
+#define PORT_SET_CTRLSAMPLING(port_nr,port_pin)				PORT->Group[port_nr].CTRL.reg |= port_pin;					// Enable continuous sampling of a pin group (always in groups of 8)
+#define PORT_CLR_CTRLSAMPLING(port_nr,port_pin)				PORT->Group[port_nr].CTRL.reg &= ~port_pin;					// Remove continuous sampling of a pin group
+#define PORT_PULL_PIN_EN(port_nr,port_pin)						PORT->Group[port_nr].PINCFG[port_pin].PULLEN=1			// Enable pull on a pin (Typ 40 kohm). Data value defines pull-up (1) or pull-down (0). Not on PA24 and PA25
+#define PORT_PULL_PIN_DIS(port_nr,port_pin)						PORT->Group[port_nr].PINCFG[port_pin].PULLEN=0			// Disable pull on a pin
+#define PORT_PULL_PIN_DRIVE_STRONG(port_nr,port_pin)	PORT->Group[port_nr].PINCFG[port_pin].DRVSTR=1			// Enable strong drive strength on a pin. (~3mA, twice for VCC=3.6V). Not on PA24 and PA25
+#define PORT_PULL_PIN_DRIVE_WEAK(port_nr,port_pin)		PORT->Group[port_nr].PINCFG[port_pin].DRVSTR=1			// Disable strong drive strength on a pin. (~1mA, twice for VCC=3.6V)
+
+// Tip: Example of other register or variable fiddling: SYSCTRL->VREG.bit.RUNSTDBY = 1
+
+#endif /* MACROS_H_ */
\ No newline at end of file