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