[2.0.x] AVR: Atomic bit set and clear of upper pin ports without critical section (#10502)
* AVR: Atomic bit set and clear The critical section can be dropped, saving 3 cycles per access. Also simplified pin toggling for all ports.
This commit is contained in:
		
							parent
							
								
									02a711c4d6
								
							
						
					
					
						commit
						c1e5ebbc1e
					
				| @ -63,35 +63,29 @@ | |||||||
|  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 |  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN))) | #define _READ(IO)             TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN) | ||||||
| 
 | 
 | ||||||
| // On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed.
 | #define _WRITE_NC(IO,V) do{ \ | ||||||
|  |   if (V) SBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \ | ||||||
|  |   else   CBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \ | ||||||
|  | }while(0) | ||||||
| 
 | 
 | ||||||
| #define _WRITE_NC(IO, v)  do { if (v) {DIO ##  IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } else {DIO ##  IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); }; } while (0) | #define _WRITE_C(IO,V) do{ \ | ||||||
|  |   uint8_t port_bits = DIO ## IO ## _WPORT;                  /* Get a mask from the current port bits */ \ | ||||||
|  |   if (V) port_bits = ~port_bits;                            /* For setting bits, invert the mask */ \ | ||||||
|  |   DIO ## IO ## _RPORT = port_bits & _BV(DIO ## IO ## _PIN); /* Atomically toggle the output port bits */ \ | ||||||
|  | }while(0) | ||||||
| 
 | 
 | ||||||
| #define _WRITE_C(IO, v)   do { if (v) { \ | #define _WRITE(IO,V)          do{ if (&(DIO ## IO ## _RPORT) < (uint8_t*)0x100) _WRITE_NC(IO,V); else _WRITE_C(IO,V); }while(0) | ||||||
|                                          CRITICAL_SECTION_START; \ |  | ||||||
|                                          {DIO ##  IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \ |  | ||||||
|                                          CRITICAL_SECTION_END; \ |  | ||||||
|                                        } \ |  | ||||||
|                                        else { \ |  | ||||||
|                                          CRITICAL_SECTION_START; \ |  | ||||||
|                                          {DIO ##  IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \ |  | ||||||
|                                          CRITICAL_SECTION_END; \ |  | ||||||
|                                        } \ |  | ||||||
|                                      } \ |  | ||||||
|                                      while (0) |  | ||||||
| 
 | 
 | ||||||
| #define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0) | #define _TOGGLE(IO)           (DIO ## IO ## _RPORT = _BV(DIO ## IO ## _PIN)) | ||||||
| 
 | 
 | ||||||
| #define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0) | #define _SET_INPUT(IO)        CBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN) | ||||||
|  | #define _SET_OUTPUT(IO)       SBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN) | ||||||
| 
 | 
 | ||||||
| #define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0) | #define _GET_INPUT(IO)       !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN) | ||||||
| #define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0) | #define _GET_OUTPUT(IO)       TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN) | ||||||
| 
 | #define _GET_TIMER(IO)        DIO ## IO ## _PWM | ||||||
| #define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0) |  | ||||||
| #define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0) |  | ||||||
| #define _GET_TIMER(IO) (DIO ## IO ## _PWM) |  | ||||||
| 
 | 
 | ||||||
| #define READ(IO)              _READ(IO) | #define READ(IO)              _READ(IO) | ||||||
| #define WRITE(IO,V)           _WRITE(IO,V) | #define WRITE(IO,V)           _WRITE(IO,V) | ||||||
| @ -105,7 +99,7 @@ | |||||||
| #define GET_OUTPUT(IO)        _GET_OUTPUT(IO) | #define GET_OUTPUT(IO)        _GET_OUTPUT(IO) | ||||||
| #define GET_TIMER(IO)         _GET_TIMER(IO) | #define GET_TIMER(IO)         _GET_TIMER(IO) | ||||||
| 
 | 
 | ||||||
| #define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0) | #define OUT_WRITE(IO,V)       do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Timer and Interrupt Control |  * Timer and Interrupt Control | ||||||
|  | |||||||
| @ -59,76 +59,78 @@ | |||||||
|  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 |  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| /// Read a pin
 | // Read a pin
 | ||||||
| #define _READ(IO) ((bool)(DIO ## IO ## _WPORT -> PIO_PDSR & (MASK(DIO ## IO ## _PIN)))) | #define _READ(IO) bool(DIO ## IO ## _WPORT -> PIO_PDSR & MASK(DIO ## IO ## _PIN)) | ||||||
| 
 | 
 | ||||||
| /// Write to a pin
 | // Write to a pin
 | ||||||
| #define _WRITE_VAR(IO, v)  do { \ | #define _WRITE_VAR(IO,V) do { \ | ||||||
|   volatile Pio* port = g_APinDescription[IO].pPort; \ |   volatile Pio* port = g_APinDescription[IO].pPort; \ | ||||||
|   uint32_t mask = g_APinDescription[IO].ulPin; \ |   uint32_t mask = g_APinDescription[IO].ulPin; \ | ||||||
|   if (v) port->PIO_SODR = mask; \ |   if (V) port->PIO_SODR = mask; \ | ||||||
|   else port->PIO_CODR = mask; \ |   else port->PIO_CODR = mask; \ | ||||||
| } while(0) | } while(0) | ||||||
| 
 | 
 | ||||||
| /// Write to a pin
 | // Write to a pin
 | ||||||
| #define _WRITE(IO, v) do { \ | #define _WRITE(IO,V) do { \ | ||||||
|   volatile Pio* port = (DIO ##  IO ## _WPORT); \ |   volatile Pio* port = (DIO ##  IO ## _WPORT); \ | ||||||
|   uint32_t mask = MASK(DIO ## IO ## _PIN); \ |   uint32_t mask = MASK(DIO ## IO ## _PIN); \ | ||||||
|   if (v) port->PIO_SODR = mask; \ |   if (V) port->PIO_SODR = mask; \ | ||||||
|   else port->PIO_CODR = mask; \ |   else port->PIO_CODR = mask; \ | ||||||
| } while(0) | } while(0) | ||||||
| 
 | 
 | ||||||
| /// toggle a pin
 | // toggle a pin
 | ||||||
| #define _TOGGLE(IO) _WRITE(IO, !READ(IO)) | #define _TOGGLE(IO) _WRITE(IO, !READ(IO)) | ||||||
| 
 | 
 | ||||||
| /// set pin as input
 | // set pin as input
 | ||||||
| #define _SET_INPUT(IO)  do{ pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ | #define _SET_INPUT(IO) do{ \ | ||||||
|  |   pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ | ||||||
|   PIO_Configure(g_APinDescription[IO].pPort, PIO_INPUT, g_APinDescription[IO].ulPin, 0); \ |   PIO_Configure(g_APinDescription[IO].pPort, PIO_INPUT, g_APinDescription[IO].ulPin, 0); \ | ||||||
|                         }while(0) | }while(0) | ||||||
| /// set pin as output
 | 
 | ||||||
| #define _SET_OUTPUT(IO) do{ pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ | // set pin as output
 | ||||||
|                             PIO_Configure(g_APinDescription[IO].pPort, _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, \ | #define _SET_OUTPUT(IO) do{ \ | ||||||
|                                           g_APinDescription[IO].ulPin, g_APinDescription[IO].ulPinConfiguration); \ |   pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \ | ||||||
|  |   PIO_Configure(g_APinDescription[IO].pPort, _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, g_APinDescription[IO].ulPin, g_APinDescription[IO].ulPinConfiguration); \ | ||||||
|   g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;\ |   g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;\ | ||||||
|                         }while(0) | }while(0) | ||||||
| 
 | 
 | ||||||
| /// set pin as input with pullup mode
 | // set pin as input with pullup mode
 | ||||||
| #define _PULLUP(IO, v)  { pinMode(IO, v != LOW ? INPUT_PULLUP : INPUT); } | #define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT) | ||||||
| 
 | 
 | ||||||
| /// check if pin is an input
 | // check if pin is an input
 | ||||||
| #define _GET_INPUT(IO) | #define _GET_INPUT(IO) | ||||||
| /// check if pin is an output
 | // check if pin is an output
 | ||||||
| #define _GET_OUTPUT(IO) | #define _GET_OUTPUT(IO) | ||||||
| 
 | 
 | ||||||
| /// check if pin is a timer
 | // check if pin is a timer
 | ||||||
| #define _GET_TIMER(IO) | #define _GET_TIMER(IO) | ||||||
| 
 | 
 | ||||||
| /// Read a pin wrapper
 | // Read a pin wrapper
 | ||||||
| #define READ(IO) _READ(IO) | #define READ(IO) _READ(IO) | ||||||
| 
 | 
 | ||||||
| /// Write to a pin wrapper
 | // Write to a pin wrapper
 | ||||||
| #define WRITE_VAR(IO, v)  _WRITE_VAR(IO, v) | #define WRITE_VAR(IO,V) _WRITE_VAR(IO,V) | ||||||
| #define WRITE(IO, v)  _WRITE(IO, v) | #define WRITE(IO,V) _WRITE(IO,V) | ||||||
| 
 | 
 | ||||||
| /// toggle a pin wrapper
 | // toggle a pin wrapper
 | ||||||
| #define TOGGLE(IO) _TOGGLE(IO) | #define TOGGLE(IO) _TOGGLE(IO) | ||||||
| 
 | 
 | ||||||
| /// set pin as input wrapper
 | // set pin as input wrapper
 | ||||||
| #define SET_INPUT(IO) _SET_INPUT(IO) | #define SET_INPUT(IO) _SET_INPUT(IO) | ||||||
| /// set pin as input with pullup wrapper
 | // set pin as input with pullup wrapper
 | ||||||
| #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) | #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0) | ||||||
| /// set pin as output wrapper -  reads the pin and sets the output to that value
 | // set pin as output wrapper -  reads the pin and sets the output to that value
 | ||||||
| #define SET_OUTPUT(IO) _SET_OUTPUT(IO) | #define SET_OUTPUT(IO) _SET_OUTPUT(IO) | ||||||
| /// check if pin is an input wrapper
 | // check if pin is an input wrapper
 | ||||||
| #define GET_INPUT(IO) _GET_INPUT(IO) | #define GET_INPUT(IO) _GET_INPUT(IO) | ||||||
| /// check if pin is an output wrapper
 | // check if pin is an output wrapper
 | ||||||
| #define GET_OUTPUT(IO) _GET_OUTPUT(IO) | #define GET_OUTPUT(IO) _GET_OUTPUT(IO) | ||||||
| 
 | 
 | ||||||
| /// check if pin is a timer (wrapper)
 | // check if pin is a timer (wrapper)
 | ||||||
| #define GET_TIMER(IO) _GET_TIMER(IO) | #define GET_TIMER(IO) _GET_TIMER(IO) | ||||||
| 
 | 
 | ||||||
| // Shorthand
 | // Shorthand
 | ||||||
| #define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); } | #define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); } | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Ports and functions |  * Ports and functions | ||||||
|  | |||||||
| @ -32,23 +32,24 @@ | |||||||
| #include <libmaple/gpio.h> | #include <libmaple/gpio.h> | ||||||
| 
 | 
 | ||||||
| #define READ(IO)              (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW) | #define READ(IO)              (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW) | ||||||
| #define WRITE(IO, v)          (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)v)) | #define WRITE(IO,V)           (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)v)) | ||||||
| #define TOGGLE(IO)            (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit)) | #define TOGGLE(IO)            (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit)) | ||||||
| #define WRITE_VAR(IO, v)      WRITE(io, v) | #define WRITE_VAR(IO,V)       WRITE(io,V) | ||||||
| 
 | 
 | ||||||
| #define _GET_MODE(IO)         (gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)) | #define _GET_MODE(IO)         gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit) | ||||||
| #define _SET_MODE(IO,M)       do{ gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M); } while (0) | #define _SET_MODE(IO,M)       gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M) | ||||||
| #define _SET_OUTPUT(IO)       _SET_MODE(IO, GPIO_OUTPUT_PP) | #define _SET_OUTPUT(IO)       _SET_MODE(IO, GPIO_OUTPUT_PP) | ||||||
| 
 | 
 | ||||||
|  | #define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0) | ||||||
|  | 
 | ||||||
| #define SET_INPUT(IO)         _SET_MODE(IO, GPIO_INPUT_FLOATING) | #define SET_INPUT(IO)         _SET_MODE(IO, GPIO_INPUT_FLOATING) | ||||||
| #define SET_INPUT_PULLUP(IO)  _SET_MODE(IO, GPIO_INPUT_PU) | #define SET_INPUT_PULLUP(IO)  _SET_MODE(IO, GPIO_INPUT_PU) | ||||||
| #define SET_OUTPUT(IO)        do{ _SET_OUTPUT(IO); WRITE(IO, LOW); }while(0) | #define SET_OUTPUT(IO)        OUT_WRITE(IO,LOW) | ||||||
| 
 | 
 | ||||||
| #define GET_INPUT(IO)         (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD) | #define GET_INPUT(IO)         (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD) | ||||||
| #define GET_OUTPUT(IO)        (_GET_MODE(IO) == GPIO_OUTPUT_PP) | #define GET_OUTPUT(IO)        (_GET_MODE(IO) == GPIO_OUTPUT_PP) | ||||||
| #define GET_TIMER(IO)         (PIN_MAP[IO].timer_device != NULL) | #define GET_TIMER(IO)         (PIN_MAP[IO].timer_device != NULL) | ||||||
| 
 | 
 | ||||||
| #define OUT_WRITE(IO, v)      { _SET_OUTPUT(IO); WRITE(IO, v); } |  | ||||||
| /**
 | /**
 | ||||||
|  * TODO: Write a macro to test if PIN is PWM or not. |  * TODO: Write a macro to test if PIN is PWM or not. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -44,38 +44,46 @@ | |||||||
|  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 |  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
 | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
| #define _READ(p) ((bool)(CORE_PIN ## p ## _PINREG & CORE_PIN ## p ## _BITMASK)) | #define _READ(p) bool(CORE_PIN ## p ## _PINREG & CORE_PIN ## p ## _BITMASK) | ||||||
| #define _WRITE(p, v) do { if (v) CORE_PIN ## p ## _PORTSET = CORE_PIN ## p ## _BITMASK; \ |  | ||||||
|                             else CORE_PIN ## p ## _PORTCLEAR = CORE_PIN ## p ## _BITMASK; } while (0) |  | ||||||
| #define _TOGGLE(p)  (*(&(CORE_PIN ## p ## _PORTCLEAR)+1) = CORE_PIN ## p ## _BITMASK) |  | ||||||
| #define _SET_INPUT(p)   do { CORE_PIN ## p ## _CONFIG = PORT_PCR_MUX(1); \ |  | ||||||
|                           GPIO_BITBAND(CORE_PIN ## p ## _DDRREG , CORE_PIN ## p ## _BIT) = 0; \ |  | ||||||
|                           } while (0) |  | ||||||
| #define _SET_OUTPUT(p)  do { CORE_PIN ## p ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \ |  | ||||||
|                           GPIO_BITBAND(CORE_PIN ## p ## _DDRREG , CORE_PIN ## p ## _BIT) = 1; \ |  | ||||||
|                           } while (0) |  | ||||||
| 
 | 
 | ||||||
| //#define _PULLUP(IO, v)  { pinMode(IO, (v!=LOW ? INPUT_PULLUP : INPUT)); }
 | #define _WRITE(P,V) do{ \ | ||||||
|  |   if (V) CORE_PIN ## P ## _PORTSET = CORE_PIN ## P ## _BITMASK; \ | ||||||
|  |   else CORE_PIN ## P ## _PORTCLEAR = CORE_PIN ## P ## _BITMASK; \ | ||||||
|  | }while(0) | ||||||
| 
 | 
 | ||||||
| #define _GET_INPUT(p)   ((CORE_PIN ## p ## _DDRREG & CORE_PIN ## p ## _BITMASK) == 0) | #define _TOGGLE(P) (*(&(CORE_PIN ## P ## _PORTCLEAR)+1) = CORE_PIN ## P ## _BITMASK) | ||||||
| #define _GET_OUTPUT(p)  ((CORE_PIN ## p ## _DDRREG & CORE_PIN ## p ## _BITMASK) == 0) | 
 | ||||||
|  | #define _SET_INPUT(P) do{ \ | ||||||
|  |   CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1); \ | ||||||
|  |   GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \ | ||||||
|  | }while(0) | ||||||
|  | 
 | ||||||
|  | #define _SET_OUTPUT(P) do{ \ | ||||||
|  |   CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \ | ||||||
|  |   GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 1; \ | ||||||
|  | }while(0) | ||||||
|  | 
 | ||||||
|  | //#define _PULLUP(IO,V)  { pinMode(IO, (v!=LOW ? INPUT_PULLUP : INPUT)); }
 | ||||||
|  | 
 | ||||||
|  | #define _GET_INPUT(P)   ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) | ||||||
|  | #define _GET_OUTPUT(P)  ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0) | ||||||
| 
 | 
 | ||||||
| //#define _GET_TIMER(IO)
 | //#define _GET_TIMER(IO)
 | ||||||
| 
 | 
 | ||||||
| #define READ(IO)              _READ(IO) | #define READ(IO)              _READ(IO) | ||||||
| 
 | 
 | ||||||
| #define WRITE_VAR(IO, v)  _WRITE_VAR(IO, v) | #define WRITE_VAR(IO,V)       _WRITE_VAR(IO,V) | ||||||
| #define WRITE(IO, v)  _WRITE(IO, v) | #define WRITE(IO,V)           _WRITE(IO,V) | ||||||
| #define TOGGLE(IO)            _TOGGLE(IO) | #define TOGGLE(IO)            _TOGGLE(IO) | ||||||
| 
 | 
 | ||||||
| #define SET_INPUT(IO)         _SET_INPUT(IO) | #define SET_INPUT(IO)         _SET_INPUT(IO) | ||||||
| #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0) | #define SET_INPUT_PULLUP(IO)  do{ _SET_INPUT(IO); _WRITE(IO,HIGH); }while(0) | ||||||
| #define SET_OUTPUT(IO)        _SET_OUTPUT(IO) | #define SET_OUTPUT(IO)        _SET_OUTPUT(IO) | ||||||
| 
 | 
 | ||||||
| #define GET_INPUT(IO)         _GET_INPUT(IO) | #define GET_INPUT(IO)         _GET_INPUT(IO) | ||||||
| #define GET_OUTPUT(IO)        _GET_OUTPUT(IO) | #define GET_OUTPUT(IO)        _GET_OUTPUT(IO) | ||||||
| 
 | 
 | ||||||
| #define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); } | #define OUT_WRITE(IO,V)       do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0) | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  * Ports, functions, and pins |  * Ports, functions, and pins | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user