소스 검색

[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.
Eduardo José Tagle 6 년 전
부모
커밋
c1e5ebbc1e
4개의 변경된 파일113개의 추가작업 그리고 108개의 파일을 삭제
  1. 27
    33
      Marlin/src/HAL/HAL_AVR/fastio_AVR.h
  2. 47
    45
      Marlin/src/HAL/HAL_DUE/fastio_Due.h
  3. 7
    6
      Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h
  4. 32
    24
      Marlin/src/HAL/HAL_TEENSY35_36/fastio_Teensy.h

+ 27
- 33
Marlin/src/HAL/HAL_AVR/fastio_AVR.h 파일 보기

@@ -63,49 +63,43 @@
63 63
  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
64 64
  */
65 65
 
66
-#define _READ(IO) ((bool)(DIO ## IO ## _RPORT & _BV(DIO ## IO ## _PIN)))
66
+#define _READ(IO)             TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN)
67 67
 
68
-// On some boards pins > 0x100 are used. These are not converted to atomic actions. A critical section is needed.
68
+#define _WRITE_NC(IO,V) do{ \
69
+  if (V) SBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \
70
+  else   CBI(DIO ## IO ## _WPORT, DIO ## IO ## _PIN); \
71
+}while(0)
69 72
 
70
-#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)
73
+#define _WRITE_C(IO,V) do{ \
74
+  uint8_t port_bits = DIO ## IO ## _WPORT;                  /* Get a mask from the current port bits */ \
75
+  if (V) port_bits = ~port_bits;                            /* For setting bits, invert the mask */ \
76
+  DIO ## IO ## _RPORT = port_bits & _BV(DIO ## IO ## _PIN); /* Atomically toggle the output port bits */ \
77
+}while(0)
71 78
 
72
-#define _WRITE_C(IO, v)   do { if (v) { \
73
-                                         CRITICAL_SECTION_START; \
74
-                                         {DIO ##  IO ## _WPORT |= _BV(DIO ## IO ## _PIN); } \
75
-                                         CRITICAL_SECTION_END; \
76
-                                       } \
77
-                                       else { \
78
-                                         CRITICAL_SECTION_START; \
79
-                                         {DIO ##  IO ## _WPORT &= ~_BV(DIO ## IO ## _PIN); } \
80
-                                         CRITICAL_SECTION_END; \
81
-                                       } \
82
-                                     } \
83
-                                     while (0)
79
+#define _WRITE(IO,V)          do{ if (&(DIO ## IO ## _RPORT) < (uint8_t*)0x100) _WRITE_NC(IO,V); else _WRITE_C(IO,V); }while(0)
84 80
 
85
-#define _WRITE(IO, v) do { if (&(DIO ## IO ## _RPORT) >= (uint8_t *)0x100) {_WRITE_C(IO, v); } else {_WRITE_NC(IO, v); }; } while (0)
81
+#define _TOGGLE(IO)           (DIO ## IO ## _RPORT = _BV(DIO ## IO ## _PIN))
86 82
 
87
-#define _TOGGLE(IO) do {DIO ## IO ## _RPORT ^= _BV(DIO ## IO ## _PIN); } while (0)
83
+#define _SET_INPUT(IO)        CBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
84
+#define _SET_OUTPUT(IO)       SBI(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
88 85
 
89
-#define _SET_INPUT(IO) do {DIO ## IO ## _DDR &= ~_BV(DIO ## IO ## _PIN); } while (0)
90
-#define _SET_OUTPUT(IO) do {DIO ## IO ## _DDR |= _BV(DIO ## IO ## _PIN); } while (0)
86
+#define _GET_INPUT(IO)       !TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
87
+#define _GET_OUTPUT(IO)       TEST(DIO ## IO ## _DDR, DIO ## IO ## _PIN)
88
+#define _GET_TIMER(IO)        DIO ## IO ## _PWM
91 89
 
92
-#define _GET_INPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) == 0)
93
-#define _GET_OUTPUT(IO) ((DIO ## IO ## _DDR & _BV(DIO ## IO ## _PIN)) != 0)
94
-#define _GET_TIMER(IO) (DIO ## IO ## _PWM)
90
+#define READ(IO)              _READ(IO)
91
+#define WRITE(IO,V)           _WRITE(IO,V)
92
+#define TOGGLE(IO)            _TOGGLE(IO)
95 93
 
96
-#define READ(IO) _READ(IO)
97
-#define WRITE(IO,V) _WRITE(IO,V)
98
-#define TOGGLE(IO) _TOGGLE(IO)
94
+#define SET_INPUT(IO)         _SET_INPUT(IO)
95
+#define SET_INPUT_PULLUP(IO)  do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
96
+#define SET_OUTPUT(IO)        _SET_OUTPUT(IO)
99 97
 
100
-#define SET_INPUT(IO) _SET_INPUT(IO)
101
-#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
102
-#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
98
+#define GET_INPUT(IO)         _GET_INPUT(IO)
99
+#define GET_OUTPUT(IO)        _GET_OUTPUT(IO)
100
+#define GET_TIMER(IO)         _GET_TIMER(IO)
103 101
 
104
-#define GET_INPUT(IO) _GET_INPUT(IO)
105
-#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
106
-#define GET_TIMER(IO) _GET_TIMER(IO)
107
-
108
-#define OUT_WRITE(IO, v) do{ SET_OUTPUT(IO); WRITE(IO, v); }while(0)
102
+#define OUT_WRITE(IO,V)       do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
109 103
 
110 104
 /**
111 105
  * Timer and Interrupt Control

+ 47
- 45
Marlin/src/HAL/HAL_DUE/fastio_Due.h 파일 보기

@@ -48,7 +48,7 @@
48 48
 #define USEABLE_HARDWARE_PWM(p) ((2 <= p) && (p <= 13))
49 49
 
50 50
 #ifndef MASK
51
-  #define MASK(PIN)  (1 << PIN)
51
+  #define MASK(PIN) (1 << PIN)
52 52
 #endif
53 53
 
54 54
 /**
@@ -59,76 +59,78 @@
59 59
  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
60 60
  */
61 61
 
62
-/// Read a pin
63
-#define _READ(IO) ((bool)(DIO ## IO ## _WPORT -> PIO_PDSR & (MASK(DIO ## IO ## _PIN))))
62
+// Read a pin
63
+#define _READ(IO) bool(DIO ## IO ## _WPORT -> PIO_PDSR & MASK(DIO ## IO ## _PIN))
64 64
 
65
-/// Write to a pin
66
-#define _WRITE_VAR(IO, v)  do { \
65
+// Write to a pin
66
+#define _WRITE_VAR(IO,V) do { \
67 67
   volatile Pio* port = g_APinDescription[IO].pPort; \
68 68
   uint32_t mask = g_APinDescription[IO].ulPin; \
69
-  if (v) port->PIO_SODR = mask; \
69
+  if (V) port->PIO_SODR = mask; \
70 70
   else port->PIO_CODR = mask; \
71 71
 } while(0)
72 72
 
73
-/// Write to a pin
74
-#define _WRITE(IO, v) do { \
73
+// Write to a pin
74
+#define _WRITE(IO,V) do { \
75 75
   volatile Pio* port = (DIO ##  IO ## _WPORT); \
76 76
   uint32_t mask = MASK(DIO ## IO ## _PIN); \
77
-  if (v) port->PIO_SODR = mask; \
77
+  if (V) port->PIO_SODR = mask; \
78 78
   else port->PIO_CODR = mask; \
79 79
 } while(0)
80 80
 
81
-/// toggle a pin
82
-#define _TOGGLE(IO)  _WRITE(IO, !READ(IO))
81
+// toggle a pin
82
+#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
83 83
 
84
-/// set pin as input
85
-#define _SET_INPUT(IO)  do{ pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
86
-                            PIO_Configure(g_APinDescription[IO].pPort, PIO_INPUT, g_APinDescription[IO].ulPin, 0); \
87
-                        }while(0)
88
-/// set pin as output
89
-#define _SET_OUTPUT(IO) do{ pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
90
-                            PIO_Configure(g_APinDescription[IO].pPort, _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, \
91
-                                          g_APinDescription[IO].ulPin, g_APinDescription[IO].ulPinConfiguration); \
92
-                            g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;\
93
-                        }while(0)
84
+// set pin as input
85
+#define _SET_INPUT(IO) do{ \
86
+  pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
87
+  PIO_Configure(g_APinDescription[IO].pPort, PIO_INPUT, g_APinDescription[IO].ulPin, 0); \
88
+}while(0)
94 89
 
95
-/// set pin as input with pullup mode
96
-#define _PULLUP(IO, v)  { pinMode(IO, v != LOW ? INPUT_PULLUP : INPUT); }
90
+// set pin as output
91
+#define _SET_OUTPUT(IO) do{ \
92
+  pmc_enable_periph_clk(g_APinDescription[IO].ulPeripheralId); \
93
+  PIO_Configure(g_APinDescription[IO].pPort, _READ(IO) ? PIO_OUTPUT_1 : PIO_OUTPUT_0, g_APinDescription[IO].ulPin, g_APinDescription[IO].ulPinConfiguration); \
94
+  g_pinStatus[IO] = (g_pinStatus[IO] & 0xF0) | PIN_STATUS_DIGITAL_OUTPUT;\
95
+}while(0)
97 96
 
98
-/// check if pin is an input
97
+// set pin as input with pullup mode
98
+#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
99
+
100
+// check if pin is an input
99 101
 #define _GET_INPUT(IO)
100
-/// check if pin is an output
102
+// check if pin is an output
101 103
 #define _GET_OUTPUT(IO)
102 104
 
103
-/// check if pin is a timer
105
+// check if pin is a timer
104 106
 #define _GET_TIMER(IO)
105 107
 
106
-/// Read a pin wrapper
107
-#define READ(IO)  _READ(IO)
108
+// Read a pin wrapper
109
+#define READ(IO) _READ(IO)
108 110
 
109
-/// Write to a pin wrapper
110
-#define WRITE_VAR(IO, v)  _WRITE_VAR(IO, v)
111
-#define WRITE(IO, v)  _WRITE(IO, v)
111
+// Write to a pin wrapper
112
+#define WRITE_VAR(IO,V) _WRITE_VAR(IO,V)
113
+#define WRITE(IO,V) _WRITE(IO,V)
112 114
 
113
-/// toggle a pin wrapper
114
-#define TOGGLE(IO)  _TOGGLE(IO)
115
+// toggle a pin wrapper
116
+#define TOGGLE(IO) _TOGGLE(IO)
115 117
 
116
-/// set pin as input wrapper
117
-#define SET_INPUT(IO)  _SET_INPUT(IO)
118
-/// set pin as input with pullup wrapper
118
+// set pin as input wrapper
119
+#define SET_INPUT(IO) _SET_INPUT(IO)
120
+// set pin as input with pullup wrapper
119 121
 #define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
120
-/// set pin as output wrapper -  reads the pin and sets the output to that value
121
-#define SET_OUTPUT(IO)  _SET_OUTPUT(IO)
122
-/// check if pin is an input wrapper
123
-#define GET_INPUT(IO)  _GET_INPUT(IO)
124
-/// check if pin is an output wrapper
125
-#define GET_OUTPUT(IO)  _GET_OUTPUT(IO)
122
+// set pin as output wrapper -  reads the pin and sets the output to that value
123
+#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
124
+// check if pin is an input wrapper
125
+#define GET_INPUT(IO) _GET_INPUT(IO)
126
+// check if pin is an output wrapper
127
+#define GET_OUTPUT(IO) _GET_OUTPUT(IO)
126 128
 
127
-/// check if pin is a timer (wrapper)
128
-#define GET_TIMER(IO)  _GET_TIMER(IO)
129
+// check if pin is a timer (wrapper)
130
+#define GET_TIMER(IO) _GET_TIMER(IO)
129 131
 
130 132
 // Shorthand
131
-#define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); }
133
+#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); }
132 134
 
133 135
 /**
134 136
  * Ports and functions

+ 7
- 6
Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h 파일 보기

@@ -32,23 +32,24 @@
32 32
 #include <libmaple/gpio.h>
33 33
 
34 34
 #define READ(IO)              (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
35
-#define WRITE(IO, v)          (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)v))
35
+#define WRITE(IO,V)           (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)v))
36 36
 #define TOGGLE(IO)            (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
37
-#define WRITE_VAR(IO, v)      WRITE(io, v)
37
+#define WRITE_VAR(IO,V)       WRITE(io,V)
38 38
 
39
-#define _GET_MODE(IO)         (gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit))
40
-#define _SET_MODE(IO,M)       do{ gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M); } while (0)
39
+#define _GET_MODE(IO)         gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)
40
+#define _SET_MODE(IO,M)       gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M)
41 41
 #define _SET_OUTPUT(IO)       _SET_MODE(IO, GPIO_OUTPUT_PP)
42 42
 
43
+#define OUT_WRITE(IO,V)       do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
44
+
43 45
 #define SET_INPUT(IO)         _SET_MODE(IO, GPIO_INPUT_FLOATING)
44 46
 #define SET_INPUT_PULLUP(IO)  _SET_MODE(IO, GPIO_INPUT_PU)
45
-#define SET_OUTPUT(IO)        do{ _SET_OUTPUT(IO); WRITE(IO, LOW); }while(0)
47
+#define SET_OUTPUT(IO)        OUT_WRITE(IO,LOW)
46 48
 
47 49
 #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)
48 50
 #define GET_OUTPUT(IO)        (_GET_MODE(IO) == GPIO_OUTPUT_PP)
49 51
 #define GET_TIMER(IO)         (PIN_MAP[IO].timer_device != NULL)
50 52
 
51
-#define OUT_WRITE(IO, v)      { _SET_OUTPUT(IO); WRITE(IO, v); }
52 53
 /**
53 54
  * TODO: Write a macro to test if PIN is PWM or not.
54 55
  */

+ 32
- 24
Marlin/src/HAL/HAL_TEENSY35_36/fastio_Teensy.h 파일 보기

@@ -30,7 +30,7 @@
30 30
 #define _FASTIO_TEENSY_H
31 31
 
32 32
 #ifndef MASK
33
-  #define MASK(PIN)  (1 << PIN)
33
+  #define MASK(PIN) (1 << PIN)
34 34
 #endif
35 35
 
36 36
 #define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
@@ -44,38 +44,46 @@
44 44
  * Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
45 45
  */
46 46
 
47
-#define _READ(p) ((bool)(CORE_PIN ## p ## _PINREG & CORE_PIN ## p ## _BITMASK))
48
-#define _WRITE(p, v) do { if (v) CORE_PIN ## p ## _PORTSET = CORE_PIN ## p ## _BITMASK; \
49
-                            else CORE_PIN ## p ## _PORTCLEAR = CORE_PIN ## p ## _BITMASK; } while (0)
50
-#define _TOGGLE(p)  (*(&(CORE_PIN ## p ## _PORTCLEAR)+1) = CORE_PIN ## p ## _BITMASK)
51
-#define _SET_INPUT(p)   do { CORE_PIN ## p ## _CONFIG = PORT_PCR_MUX(1); \
52
-                          GPIO_BITBAND(CORE_PIN ## p ## _DDRREG , CORE_PIN ## p ## _BIT) = 0; \
53
-                          } while (0)
54
-#define _SET_OUTPUT(p)  do { CORE_PIN ## p ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \
55
-                          GPIO_BITBAND(CORE_PIN ## p ## _DDRREG , CORE_PIN ## p ## _BIT) = 1; \
56
-                          } while (0)
47
+#define _READ(p) bool(CORE_PIN ## p ## _PINREG & CORE_PIN ## p ## _BITMASK)
57 48
 
58
-//#define _PULLUP(IO, v)  { pinMode(IO, (v!=LOW ? INPUT_PULLUP : INPUT)); }
49
+#define _WRITE(P,V) do{ \
50
+  if (V) CORE_PIN ## P ## _PORTSET = CORE_PIN ## P ## _BITMASK; \
51
+  else CORE_PIN ## P ## _PORTCLEAR = CORE_PIN ## P ## _BITMASK; \
52
+}while(0)
59 53
 
60
-#define _GET_INPUT(p)   ((CORE_PIN ## p ## _DDRREG & CORE_PIN ## p ## _BITMASK) == 0)
61
-#define _GET_OUTPUT(p)  ((CORE_PIN ## p ## _DDRREG & CORE_PIN ## p ## _BITMASK) == 0)
54
+#define _TOGGLE(P) (*(&(CORE_PIN ## P ## _PORTCLEAR)+1) = CORE_PIN ## P ## _BITMASK)
55
+
56
+#define _SET_INPUT(P) do{ \
57
+  CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1); \
58
+  GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 0; \
59
+}while(0)
60
+
61
+#define _SET_OUTPUT(P) do{ \
62
+  CORE_PIN ## P ## _CONFIG = PORT_PCR_MUX(1)|PORT_PCR_SRE|PORT_PCR_DSE; \
63
+  GPIO_BITBAND(CORE_PIN ## P ## _DDRREG , CORE_PIN ## P ## _BIT) = 1; \
64
+}while(0)
65
+
66
+//#define _PULLUP(IO,V)  { pinMode(IO, (v!=LOW ? INPUT_PULLUP : INPUT)); }
67
+
68
+#define _GET_INPUT(P)   ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0)
69
+#define _GET_OUTPUT(P)  ((CORE_PIN ## P ## _DDRREG & CORE_PIN ## P ## _BITMASK) == 0)
62 70
 
63 71
 //#define _GET_TIMER(IO)
64 72
 
65
-#define READ(IO)  _READ(IO)
73
+#define READ(IO)              _READ(IO)
66 74
 
67
-#define WRITE_VAR(IO, v)  _WRITE_VAR(IO, v)
68
-#define WRITE(IO, v)  _WRITE(IO, v)
69
-#define TOGGLE(IO)  _TOGGLE(IO)
75
+#define WRITE_VAR(IO,V)       _WRITE_VAR(IO,V)
76
+#define WRITE(IO,V)           _WRITE(IO,V)
77
+#define TOGGLE(IO)            _TOGGLE(IO)
70 78
 
71
-#define SET_INPUT(IO)  _SET_INPUT(IO)
72
-#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
73
-#define SET_OUTPUT(IO)  _SET_OUTPUT(IO)
79
+#define SET_INPUT(IO)         _SET_INPUT(IO)
80
+#define SET_INPUT_PULLUP(IO)  do{ _SET_INPUT(IO); _WRITE(IO,HIGH); }while(0)
81
+#define SET_OUTPUT(IO)        _SET_OUTPUT(IO)
74 82
 
75
-#define GET_INPUT(IO)  _GET_INPUT(IO)
76
-#define GET_OUTPUT(IO)  _GET_OUTPUT(IO)
83
+#define GET_INPUT(IO)         _GET_INPUT(IO)
84
+#define GET_OUTPUT(IO)        _GET_OUTPUT(IO)
77 85
 
78
-#define OUT_WRITE(IO, v) { SET_OUTPUT(IO); WRITE(IO, v); }
86
+#define OUT_WRITE(IO,V)       do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
79 87
 
80 88
 /**
81 89
  * Ports, functions, and pins

Loading…
취소
저장