Skip to content
Snippets Groups Projects
Commit e0f0c766 authored by Bengt Ragnemalm's avatar Bengt Ragnemalm
Browse files

Added macros.h

parent dc237b82
No related branches found
No related tags found
No related merge requests found
/*
* 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment