Pin: code cleanup, no functionality changes
[clinton/Smoothieware.git] / src / libs / Pin.cpp
CommitLineData
46106f58
MM
1#include "Pin.h"
2
c5fd5b7a
MM
3#include "utils.h"
4
947ae5e2
JM
5Pin::Pin(){
6 this->inverting= false;
7}
46106f58 8
93694d6b 9// Make a new pin object from a string
93694d6b 10Pin* Pin::from_string(std::string value){
46106f58 11 LPC_GPIO_TypeDef* gpios[5] ={LPC_GPIO0,LPC_GPIO1,LPC_GPIO2,LPC_GPIO3,LPC_GPIO4};
c5fd5b7a
MM
12
13 // cs is the current position in the string
14 const char* cs = value.c_str();
15 // cn is the position of the next char after the number we just read
16 char* cn = NULL;
17
82e2eaae 18 // grab first integer as port. pointer to first non-digit goes in cn
c5fd5b7a 19 this->port_number = strtol(cs, &cn, 10);
82e2eaae 20 // if cn > cs then strtol read at least one digit
93694d6b 21 if ((cn > cs) && (port_number <= 4)){
82e2eaae 22 // translate port index into something useful
46106f58 23 this->port = gpios[(unsigned int) this->port_number];
82e2eaae 24 // if the char after the first integer is a . then we should expect a pin index next
93694d6b 25 if (*cn == '.'){
82e2eaae 26 // move pointer to first digit (hopefully) of pin index
c5fd5b7a 27 cs = ++cn;
947ae5e2 28
82e2eaae 29 // grab pin index.
c5fd5b7a 30 this->pin = strtol(cs, &cn, 10);
947ae5e2 31
82e2eaae 32 // if strtol read some numbers, cn will point to the first non-digit
2d14aa61 33 if ((cn > cs) && (pin < 32)){
c5fd5b7a
MM
34 this->port->FIOMASK &= ~(1 << this->pin);
35
947ae5e2
JM
36 // now check for modifiers:-
37 // ! = invert pin
38 // o = set pin to open drain
39 // ^ = set pin to pull up
40 // v = set pin to pull down
1d7df31d
JM
41 // - = set pin to no pull up or down
42 // @ = set pin to repeater mode
2d14aa61 43 for (;*cn;cn++) {
947ae5e2
JM
44 switch(*cn) {
45 case '!':
46 this->inverting = true;
47 break;
48 case 'o':
49 as_open_drain();
50 break;
51 case '^':
52 pull_up();
53 break;
54 case 'v':
55 pull_down();
56 break;
1d7df31d
JM
57 case '-':
58 pull_none();
59 break;
60 case '@':
61 as_repeater();
62 break;
947ae5e2 63 default:
cfd9dc69
MM
64 // skip any whitespace following the pin index
65 if (!is_whitespace(*cn))
2d14aa61 66 return this;
947ae5e2 67 }
947ae5e2 68 }
c5fd5b7a
MM
69 return this;
70 }
71 }
46106f58 72 }
c5fd5b7a 73
82e2eaae 74 // from_string failed. TODO: some sort of error
c5fd5b7a
MM
75 port_number = 0;
76 port = gpios[0];
77 pin = 255;
78 inverting = false;
46106f58
MM
79 return this;
80}
81
93694d6b
AW
82// Configure this pin as OD
83Pin* Pin::as_open_drain(){
46106f58
MM
84 if (this->pin >= 32) return this;
85 if( this->port_number == 0 ){ LPC_PINCON->PINMODE_OD0 |= (1<<this->pin); }
86 if( this->port_number == 1 ){ LPC_PINCON->PINMODE_OD1 |= (1<<this->pin); }
87 if( this->port_number == 2 ){ LPC_PINCON->PINMODE_OD2 |= (1<<this->pin); }
88 if( this->port_number == 3 ){ LPC_PINCON->PINMODE_OD3 |= (1<<this->pin); }
89 if( this->port_number == 4 ){ LPC_PINCON->PINMODE_OD4 |= (1<<this->pin); }
2b7aefce
JM
90 pull_none(); // no pull up by default
91 return this;
92}
93
1d7df31d
JM
94
95// Configure this pin as a repeater
96Pin* Pin::as_repeater(){
97 if (this->pin >= 32) return this;
98 // Set the two bits for this pin as 01
99 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE0 &= ~(2<<( this->pin *2)); }
100 if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE1 &= ~(2<<((this->pin-16)*2)); }
101 if( this->port_number == 1 && this->pin < 16 ){ LPC_PINCON->PINMODE2 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE2 &= ~(2<<( this->pin *2)); }
102 if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE3 &= ~(2<<((this->pin-16)*2)); }
103 if( this->port_number == 2 && this->pin < 16 ){ LPC_PINCON->PINMODE4 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE4 &= ~(2<<( this->pin *2)); }
104 if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE7 &= ~(2<<((this->pin-16)*2)); }
105 if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (1<<( this->pin*2)); LPC_PINCON->PINMODE9 &= ~(2<<((this->pin-16)*2)); }
106 return this;
107}
d4ee6ee2 108
2b7aefce
JM
109// Configure this pin as no pullup or pulldown
110Pin* Pin::pull_none(){
d4ee6ee2
JM
111 if (this->pin >= 32) return this;
112 // Set the two bits for this pin as 10
113 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE0 &= ~(1<<( this->pin *2)); }
114 if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE1 &= ~(1<<((this->pin-16)*2)); }
115 if( this->port_number == 1 && this->pin < 16 ){ LPC_PINCON->PINMODE2 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE2 &= ~(1<<( this->pin *2)); }
116 if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE3 &= ~(1<<((this->pin-16)*2)); }
117 if( this->port_number == 2 && this->pin < 16 ){ LPC_PINCON->PINMODE4 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE4 &= ~(1<<( this->pin *2)); }
118 if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE7 &= ~(1<<((this->pin-16)*2)); }
119 if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (2<<( this->pin*2)); LPC_PINCON->PINMODE9 &= ~(1<<((this->pin-16)*2)); }
120 return this;
46106f58
MM
121}
122
93694d6b
AW
123// Configure this pin as a pullup
124Pin* Pin::pull_up(){
46106f58
MM
125 if (this->pin >= 32) return this;
126 // Set the two bits for this pin as 00
127 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 &= ~(3<<( this->pin *2)); }
128 if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 &= ~(3<<((this->pin-16)*2)); }
129 if( this->port_number == 1 && this->pin < 16 ){ LPC_PINCON->PINMODE2 &= ~(3<<( this->pin *2)); }
130 if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 &= ~(3<<((this->pin-16)*2)); }
131 if( this->port_number == 2 && this->pin < 16 ){ LPC_PINCON->PINMODE4 &= ~(3<<( this->pin *2)); }
132 if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 &= ~(3<<((this->pin-16)*2)); }
133 if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 &= ~(3<<((this->pin-16)*2)); }
134 return this;
135}
136
93694d6b
AW
137// Configure this pin as a pulldown
138Pin* Pin::pull_down(){
46106f58
MM
139 if (this->pin >= 32) return this;
140 // Set the two bits for this pin as 11
141 if( this->port_number == 0 && this->pin < 16 ){ LPC_PINCON->PINMODE0 |= (3<<( this->pin *2)); }
142 if( this->port_number == 0 && this->pin >= 16 ){ LPC_PINCON->PINMODE1 |= (3<<((this->pin-16)*2)); }
143 if( this->port_number == 1 && this->pin < 16 ){ LPC_PINCON->PINMODE2 |= (3<<( this->pin *2)); }
144 if( this->port_number == 1 && this->pin >= 16 ){ LPC_PINCON->PINMODE3 |= (3<<((this->pin-16)*2)); }
145 if( this->port_number == 2 && this->pin < 16 ){ LPC_PINCON->PINMODE4 |= (3<<( this->pin *2)); }
146 if( this->port_number == 3 && this->pin >= 16 ){ LPC_PINCON->PINMODE7 |= (3<<((this->pin-16)*2)); }
147 if( this->port_number == 4 && this->pin >= 16 ){ LPC_PINCON->PINMODE9 |= (3<<((this->pin-16)*2)); }
148 return this;
149}