Arduino Pin Library  v4.2.0
An easy to use Arduino library for fast and simultaneous operations on Arduino I/O pins.
Pin.h
Go to the documentation of this file.
1 
14 #include "Arduino.h"
15 
16 #pragma once
17 
18 #define DDR_HIGH (*_DDR |= _offset)
19 #define DDR_TOGGLE (*_DDR ^= _offset)
20 #define DDR_LOW (*_DDR &= _ioffset)
21 
22 #define PORT_HIGH (*_PORT |= _offset)
23 #define PORT_TOGGLE (*_PORT ^= _offset)
24 #define PORT_LOW (*_PORT &= _ioffset)
25 
26 #define DDR_ON (*_DDR & _offset)
27 #define DDR_OFF (*_DDR | _ioffset)
28 
29 #define PORT_ON (*_PORT & _offset)
30 #define PORT_OFF (*_PORT | _ioffset)
31 
32 #define PIN_ON (*_PIN & _offset)
33 #define PIN_OFF (*_PIN | _ioffset)
34 
35 
40 class Pin {
41  public:
45  Pin() {
46  _number = 0;
47  _offset = digitalPinToBitMask(_number);
48  _ioffset = ~_offset;
49  _timer = digitalPinToTimer(_number);
50  _PIN = portInputRegister(digitalPinToPort(_number));
51  _PORT = portOutputRegister(digitalPinToPort(_number));
52  _DDR = portModeRegister(digitalPinToPort(_number));
53  }
54 
60  Pin(uint8_t number) {
61  _number = number;
62  _offset = digitalPinToBitMask(_number);
63  _ioffset = ~_offset;
64  _timer = digitalPinToTimer(_number);
65  _PIN = portInputRegister(digitalPinToPort(_number));
66  _PORT = portOutputRegister(digitalPinToPort(_number));
67  _DDR = portModeRegister(digitalPinToPort(_number));
68  }
69 
82  Pin(uint8_t number, uint8_t offset, uint8_t timer, volatile uint8_t* PIN, volatile uint8_t* PORT, volatile uint8_t* DDR) {
83  _number = number;
84  _offset = offset;
85  _ioffset = ~_offset;
86  _timer = timer;
87  _PIN = PIN;
88  _PORT = PORT;
89  _DDR = DDR;
90  }
91 
97  operator bool() const {
98  return bool(PIN_ON);
99  }
100 
106  Pin& operator =(uint8_t state) {
107  uint8_t oldSREG = SREG;
108  cli();
109  if (state == LOW) {
110  PORT_LOW;
111  } else {
112  PORT_HIGH;
113  }
114  SREG = oldSREG;
115 
116  return *this;
117  }
118 
124  uint8_t getNumber() {
125  return _number;
126  }
127 
133  uint8_t getOffset() {
134  return _offset;
135  }
136 
142  uint8_t getInverseOffset() {
143  return _ioffset;
144  }
145 
151  uint8_t getTimer() {
152  return _timer;
153  }
154 
160  volatile uint8_t* getPIN() {
161  return _PIN;
162  }
163 
169  volatile uint8_t* getPORT() {
170  return _PORT;
171  }
172 
178  volatile uint8_t* getDDR() {
179  return _DDR;
180  }
181 
187  uint8_t getMode() {
188  if (DDR_ON) {
189  return OUTPUT;
190  } else {
191  return INPUT;
192  }
193  }
194 
200  uint8_t getState() {
201  if (PORT_ON) {
202  return HIGH;
203  } else {
204  return LOW;
205  }
206  }
207 
213  uint8_t getValue() {
214  if (PIN_ON) {
215  return HIGH;
216  } else {
217  return LOW;
218  }
219  }
220 
226  uint16_t getAnalogValue() {
227  return analogRead(_number);
228  }
229 
236  void set(uint8_t mode, uint8_t state) {
237  uint8_t oldSREG = SREG;
238  cli();
239  if (mode == INPUT) {
240  DDR_LOW;
241  } else {
242  DDR_HIGH;
243  }
244  if (state == LOW) {
245  PORT_LOW;
246  } else {
247  PORT_HIGH;
248  }
249  SREG = oldSREG;
250  }
251 
257  void setMode(uint8_t mode) {
258  uint8_t oldSREG = SREG;
259  cli();
260  if (mode == INPUT) {
261  DDR_LOW;
262  } else {
263  DDR_HIGH;
264  }
265  SREG = oldSREG;
266  }
267 
273  void setState(uint8_t state) {
274  uint8_t oldSREG = SREG;
275  cli();
276  if (state == LOW) {
277  PORT_LOW;
278  } else {
279  PORT_HIGH;
280  }
281  SREG = oldSREG;
282  }
283 
287  void setInput() {
288  uint8_t oldSREG = SREG;
289  cli();
290  DDR_LOW;
291  SREG = oldSREG;
292  }
293 
297  void setPullupOn() {
298  uint8_t oldSREG = SREG;
299  cli();
300  PORT_HIGH;
301  SREG = oldSREG;
302  }
303 
307  void setPullupOff() {
308  uint8_t oldSREG = SREG;
309  cli();
310  PORT_LOW;
311  SREG = oldSREG;
312  }
313 
318  uint8_t oldSREG = SREG;
319  cli();
320  DDR_LOW;
321  PORT_HIGH;
322  SREG = oldSREG;
323  }
324 
329  uint8_t oldSREG = SREG;
330  cli();
331  DDR_LOW;
332  PORT_LOW;
333  SREG = oldSREG;
334  }
335 
339  void setOutput() {
340  uint8_t oldSREG = SREG;
341  cli();
342  DDR_HIGH;
343  SREG = oldSREG;
344  }
345 
349  void setHigh() {
350  uint8_t oldSREG = SREG;
351  cli();
352  PORT_HIGH;
353  SREG = oldSREG;
354  }
355 
359  void setLow() {
360  uint8_t oldSREG = SREG;
361  cli();
362  PORT_LOW;
363  SREG = oldSREG;
364  }
365 
369  void setOutputHigh() {
370  uint8_t oldSREG = SREG;
371  cli();
372  DDR_HIGH;
373  PORT_HIGH;
374  SREG = oldSREG;
375  }
376 
380  void setOutputLow() {
381  uint8_t oldSREG = SREG;
382  cli();
383  DDR_HIGH;
384  PORT_LOW;
385  SREG = oldSREG;
386  }
387 
393  void setDutyCycle(int value) {
394  analogWrite(_number,value);
395  }
396 
400  void toggleMode() {
401  uint8_t oldSREG = SREG;
402  cli();
403  DDR_TOGGLE;
404  SREG = oldSREG;
405  }
406 
410  void toggleState() {
411  uint8_t oldSREG = SREG;
412  cli();
413  PORT_TOGGLE;
414  SREG = oldSREG;
415  }
416 
424  volatile unsigned int rcTimer(volatile unsigned int count) {
425  /*
426  pin.setInput();
427  for (; count > 0; count--) {
428  if ((pin.getValue() == HIGH) || (count == 0)) {
429  pin.setOutput();
430  return count;
431  }
432  }
433  */
434 
435  uint8_t status;
436  asm volatile (
437  // Save interupt status and disable interupts
438  "in %[status], __SREG__ \n\t" // Store current interupt status in variable 's'
439  "cli \n\t" // Disable interupts
440 
441  // Set Pin to input mode to start charging capacitor
442  "ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
443  "and __tmp_reg__, %[_ioffset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
444  "st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the DDR register
445 
446  // Count time before Pin becomes high
447  "loop%=: \n\t" // Label for looping
448  "ld __tmp_reg__,%a[_PIN] \n\t" // Load the PIN register into r0 (__tmp_reg__)
449  "and __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
450  "brne end%= \n\t" // End the loop if r0 (__tmp_reg__) is not equal to zero by branching to label 'end'
451  "dec %[count] \n\t" // Decrement the value of 'count' by one
452  "brne loop%= \n\t" // If the value of 'count' is not equal to zero continue the loop by branching to label 'loop'
453 
454  // Done counting
455  "end%=: \n\t" // Label for ending loop
456  // Set Pin to output mode to start discharging capacitor
457  "ld __tmp_reg__, %a[_DDR] \n\t" // Load the DDR register into r0 (__tmp_reg__)
458  "or __tmp_reg__, %[_offset] \n\t" // Apply the bit mask (offset) to r0 (__tmp_reg__)
459  "st %a[_DDR], __tmp_reg__ \n\t" // Store r0 (__tmp_reg__) in the PORT register
460 
461  // Restore interupt status
462  "out __SREG__, %[status] \n\t" // Load interupt status from variable 's'
463 
464  // Outputs
465  :
466  [count] "+r" (count), // The value the counter was at when the pin went high
467  [status] "=&r" (status) // The interupt status
468 
469  // Inputs
470  :
471  [_DDR] "e" (_DDR), // The address of the DDR register for the pin
472  [_PIN] "e" (_PIN), // The address of the PIN register for the pin
473  [_offset] "r" (_offset), // The bit mask used to access pin in registers
474  [_ioffset] "r" (_ioffset) // The inverse bit mask used to access pin in registers
475  );
476 
477  return count;
478  }
479 
480  private:
481  uint8_t _number;
482  uint8_t _offset;
483  uint8_t _ioffset;
484  uint8_t _timer;
485  volatile uint8_t* _PIN;
486  volatile uint8_t* _PORT;
487  volatile uint8_t* _DDR;
488 };
void setInputPullupOff()
Set the pin mode to input and the pin pullup resistor to off.
Definition: Pin.h:328
uint8_t getState()
Get the state of the pin from the PORT register.
Definition: Pin.h:200
uint8_t getNumber()
Get the pin number.
Definition: Pin.h:124
#define DDR_ON
Get the DDR register for the pin (HIGH, LOW)
Definition: Pin.h:26
void setHigh()
Set the pin output to HIGH.
Definition: Pin.h:349
uint8_t getInverseOffset()
Get the inverse pin offset.
Definition: Pin.h:142
Class for fast operations on Arduino I/O pins.
Definition: Pin.h:40
void setDutyCycle(int value)
Set the PWM duty cycle.
Definition: Pin.h:393
#define PIN_ON
Get the PIN register for the pin (HIGH, LOW)
Definition: Pin.h:32
volatile uint8_t * getPIN()
Get a pointer to the PIN register.
Definition: Pin.h:160
#define DDR_LOW
Set the DDR register to LOW for the pin.
Definition: Pin.h:20
uint16_t getAnalogValue()
Get the analog value of the pin.
Definition: Pin.h:226
#define PORT_ON
Get the PORT register for the pin (HIGH, LOW)
Definition: Pin.h:29
void setPullupOff()
Set the pin pullup resistor to off.
Definition: Pin.h:307
void setInputPullupOn()
Set the pin mode to input and the pin pullup resistor to on.
Definition: Pin.h:317
Pin & operator=(uint8_t state)
Set the pin state.
Definition: Pin.h:106
#define PORT_TOGGLE
Set the PORT register to the inverse for the pin.
Definition: Pin.h:23
void setOutput()
Set the pin mode to output.
Definition: Pin.h:339
void setOutputHigh()
Set the pin mode to output and the pin output to HIGH.
Definition: Pin.h:369
void setMode(uint8_t mode)
Set the pin mode.
Definition: Pin.h:257
volatile uint8_t * getPORT()
Get a pointer to the PORT register.
Definition: Pin.h:169
void setLow()
Set the pin output to LOW.
Definition: Pin.h:359
#define DDR_HIGH
Set the DDR register to HIGH for the pin.
Definition: Pin.h:18
#define PORT_HIGH
Set the PORT register to HIGH for the pin.
Definition: Pin.h:22
void setPullupOn()
Set the pin pullup resistor to on.
Definition: Pin.h:297
void setOutputLow()
Set the pin mode to output and the pin output to LOW.
Definition: Pin.h:380
uint8_t getValue()
Get the value of the pin from the PIN register.
Definition: Pin.h:213
void toggleMode()
Toggle the pin mode (OUTPUT -> INPUT, INPUT -> OUTPUT)
Definition: Pin.h:400
void toggleState()
Toggle the pin state (HIGH -> LOW, LOW -> HIGH)
Definition: Pin.h:410
uint8_t getOffset()
Get the pin offset.
Definition: Pin.h:133
Pin()
Default constructor.
Definition: Pin.h:45
#define PORT_LOW
Set the PORT register to LOW for the pin.
Definition: Pin.h:24
volatile uint8_t * getDDR()
Get a pointer to the DDR register.
Definition: Pin.h:178
void setInput()
Set the pin mode to input.
Definition: Pin.h:287
Pin(uint8_t number)
Arduino supported board constructor.
Definition: Pin.h:60
Pin(uint8_t number, uint8_t offset, uint8_t timer, volatile uint8_t *PIN, volatile uint8_t *PORT, volatile uint8_t *DDR)
Custom board constructor.
Definition: Pin.h:82
uint8_t getMode()
Get the mode of the pin from the DDR register.
Definition: Pin.h:187
void setState(uint8_t state)
Set the pin state.
Definition: Pin.h:273
uint8_t getTimer()
Get the pin timer.
Definition: Pin.h:151
#define DDR_TOGGLE
Set the DDR register to the inverse for the pin.
Definition: Pin.h:19
volatile unsigned int rcTimer(volatile unsigned int count)
Set the pin mode to input and decrement a counter until the pin goes HIGH or the counter reaches 0 th...
Definition: Pin.h:424