Commit | Line | Data |
---|---|---|
46106f58 MM |
1 | #include "Pin.h" |
2 | ||
c5fd5b7a MM |
3 | #include "utils.h" |
4 | ||
947ae5e2 JM |
5 | Pin::Pin(){ |
6 | this->inverting= false; | |
7 | } | |
46106f58 | 8 | |
93694d6b | 9 | // Make a new pin object from a string |
93694d6b | 10 | Pin* 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 |
83 | Pin* 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 | |
96 | Pin* 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 |
110 | Pin* 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 |
124 | Pin* 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 |
138 | Pin* 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 | } |