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