Fork of Smoothie to port to mbed non-LPC targets.

Dependencies:   mbed

Fork of Smoothie by Stéphane Cachat

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?

UserRevisionLine numberNew 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 }