2 * Copyright (c) 2014, Texas Instruments Incorporated
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
9 * * Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
12 * * Redistributions in binary form must reproduce the above copyright
\r
13 * notice, this list of conditions and the following disclaimer in the
\r
14 * documentation and/or other materials provided with the distribution.
\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of
\r
17 * its contributors may be used to endorse or promote products derived
\r
18 * from this software without specific prior written permission.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
32 //*****************************************************************************
\r
34 // gpio.c - Driver for the gpio Module.
\r
36 //*****************************************************************************
\r
38 //*****************************************************************************
\r
40 //! \addtogroup gpio_api gpio
\r
43 //*****************************************************************************
\r
45 #include "inc/hw_regaccess.h"
\r
46 #include "inc/hw_memmap.h"
\r
48 #if defined(__MSP430_HAS_PORT1_R__) || defined(__MSP430_HAS_PORT2_R__) || \
\r
49 defined(__MSP430_HAS_PORTA_R__)
\r
54 static const uint16_t GPIO_PORT_TO_BASE[] = {
\r
56 #if defined(__MSP430_HAS_PORT1_R__)
\r
57 __MSP430_BASEADDRESS_PORT1_R__,
\r
58 #elif defined(__MSP430_HAS_PORT1__)
\r
59 __MSP430_BASEADDRESS_PORT1__,
\r
63 #if defined(__MSP430_HAS_PORT2_R__)
\r
64 __MSP430_BASEADDRESS_PORT2_R__,
\r
65 #elif defined(__MSP430_HAS_PORT2__)
\r
66 __MSP430_BASEADDRESS_PORT2__,
\r
70 #if defined(__MSP430_HAS_PORT3_R__)
\r
71 __MSP430_BASEADDRESS_PORT3_R__,
\r
72 #elif defined(__MSP430_HAS_PORT3__)
\r
73 __MSP430_BASEADDRESS_PORT3__,
\r
77 #if defined(__MSP430_HAS_PORT4_R__)
\r
78 __MSP430_BASEADDRESS_PORT4_R__,
\r
79 #elif defined(__MSP430_HAS_PORT4__)
\r
80 __MSP430_BASEADDRESS_PORT4__,
\r
84 #if defined(__MSP430_HAS_PORT5_R__)
\r
85 __MSP430_BASEADDRESS_PORT5_R__,
\r
86 #elif defined(__MSP430_HAS_PORT5__)
\r
87 __MSP430_BASEADDRESS_PORT5__,
\r
91 #if defined(__MSP430_HAS_PORT6_R__)
\r
92 __MSP430_BASEADDRESS_PORT6_R__,
\r
93 #elif defined(__MSP430_HAS_PORT6__)
\r
94 __MSP430_BASEADDRESS_PORT6__,
\r
98 #if defined(__MSP430_HAS_PORT7_R__)
\r
99 __MSP430_BASEADDRESS_PORT7_R__,
\r
100 #elif defined(__MSP430_HAS_PORT7__)
\r
101 __MSP430_BASEADDRESS_PORT7__,
\r
105 #if defined(__MSP430_HAS_PORT8_R__)
\r
106 __MSP430_BASEADDRESS_PORT8_R__,
\r
107 #elif defined(__MSP430_HAS_PORT8__)
\r
108 __MSP430_BASEADDRESS_PORT8__,
\r
112 #if defined(__MSP430_HAS_PORT9_R__)
\r
113 __MSP430_BASEADDRESS_PORT9_R__,
\r
114 #elif defined(__MSP430_HAS_PORT9__)
\r
115 __MSP430_BASEADDRESS_PORT9__,
\r
119 #if defined(__MSP430_HAS_PORT10_R__)
\r
120 __MSP430_BASEADDRESS_PORT10_R__,
\r
121 #elif defined(__MSP430_HAS_PORT10__)
\r
122 __MSP430_BASEADDRESS_PORT10__,
\r
126 #if defined(__MSP430_HAS_PORT11_R__)
\r
127 __MSP430_BASEADDRESS_PORT11_R__,
\r
128 #elif defined(__MSP430_HAS_PORT11__)
\r
129 __MSP430_BASEADDRESS_PORT11__,
\r
134 #if defined(__MSP430_HAS_PORTJ_R__)
\r
135 __MSP430_BASEADDRESS_PORTJ_R__
\r
136 #elif defined(__MSP430_HAS_PORTJ__)
\r
137 __MSP430_BASEADDRESS_PORTJ__
\r
143 void GPIO_setAsOutputPin(uint8_t selectedPort,
\r
144 uint16_t selectedPins) {
\r
145 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
148 if(baseAddress == 0xFFFF)
\r
154 // Shift by 8 if port is even (upper 8-bits)
\r
155 if((selectedPort & 1) ^ 1)
\r
157 selectedPins <<= 8;
\r
160 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
161 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
162 HWREG16(baseAddress + OFS_PADIR) |= selectedPins;
\r
167 void GPIO_setAsInputPin(uint8_t selectedPort,
\r
168 uint16_t selectedPins) {
\r
169 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
172 if(baseAddress == 0xFFFF)
\r
178 // Shift by 8 if port is even (upper 8-bits)
\r
179 if((selectedPort & 1) ^ 1)
\r
181 selectedPins <<= 8;
\r
184 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
185 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
186 HWREG16(baseAddress + OFS_PADIR) &= ~selectedPins;
\r
187 HWREG16(baseAddress + OFS_PAREN) &= ~selectedPins;
\r
190 void GPIO_setAsPeripheralModuleFunctionOutputPin(uint8_t selectedPort,
\r
191 uint16_t selectedPins
\r
194 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
197 if(baseAddress == 0xFFFF)
\r
203 // Shift by 8 if port is even (upper 8-bits)
\r
204 if((selectedPort & 1) ^ 1)
\r
206 selectedPins <<= 8;
\r
209 HWREG16(baseAddress + OFS_PADIR) |= selectedPins;
\r
212 case GPIO_PRIMARY_MODULE_FUNCTION:
\r
213 HWREG16(baseAddress + OFS_PASEL0) |= selectedPins;
\r
214 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
216 case GPIO_SECONDARY_MODULE_FUNCTION:
\r
217 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
218 HWREG16(baseAddress + OFS_PASEL1) |= selectedPins;
\r
220 case GPIO_TERNARY_MODULE_FUNCTION:
\r
221 HWREG16(baseAddress + OFS_PASEL0) |= selectedPins;
\r
222 HWREG16(baseAddress + OFS_PASEL1) |= selectedPins;
\r
227 void GPIO_setAsPeripheralModuleFunctionInputPin(uint8_t selectedPort,
\r
228 uint16_t selectedPins
\r
231 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
234 if(baseAddress == 0xFFFF)
\r
240 // Shift by 8 if port is even (upper 8-bits)
\r
241 if((selectedPort & 1) ^ 1)
\r
243 selectedPins <<= 8;
\r
246 HWREG16(baseAddress + OFS_PADIR) &= ~selectedPins;
\r
249 case GPIO_PRIMARY_MODULE_FUNCTION:
\r
250 HWREG16(baseAddress + OFS_PASEL0) |= selectedPins;
\r
251 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
253 case GPIO_SECONDARY_MODULE_FUNCTION:
\r
254 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
255 HWREG16(baseAddress + OFS_PASEL1) |= selectedPins;
\r
257 case GPIO_TERNARY_MODULE_FUNCTION:
\r
258 HWREG16(baseAddress + OFS_PASEL0) |= selectedPins;
\r
259 HWREG16(baseAddress + OFS_PASEL1) |= selectedPins;
\r
264 void GPIO_setOutputHighOnPin(uint8_t selectedPort,
\r
265 uint16_t selectedPins) {
\r
266 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
269 if(baseAddress == 0xFFFF)
\r
275 // Shift by 8 if port is even (upper 8-bits)
\r
276 if((selectedPort & 1) ^ 1)
\r
278 selectedPins <<= 8;
\r
281 HWREG16(baseAddress + OFS_PAOUT) |= selectedPins;
\r
284 void GPIO_setOutputLowOnPin(uint8_t selectedPort,
\r
285 uint16_t selectedPins) {
\r
286 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
289 if(baseAddress == 0xFFFF)
\r
295 // Shift by 8 if port is even (upper 8-bits)
\r
296 if((selectedPort & 1) ^ 1)
\r
298 selectedPins <<= 8;
\r
301 HWREG16(baseAddress + OFS_PAOUT) &= ~selectedPins;
\r
304 void GPIO_toggleOutputOnPin(uint8_t selectedPort,
\r
305 uint16_t selectedPins) {
\r
306 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
309 if(baseAddress == 0xFFFF)
\r
315 // Shift by 8 if port is even (upper 8-bits)
\r
316 if((selectedPort & 1) ^ 1)
\r
318 selectedPins <<= 8;
\r
321 HWREG16(baseAddress + OFS_PAOUT) ^= selectedPins;
\r
324 void GPIO_setAsInputPinWithPullDownResistor(uint8_t selectedPort,
\r
325 uint16_t selectedPins) {
\r
326 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
329 if(baseAddress == 0xFFFF)
\r
335 // Shift by 8 if port is even (upper 8-bits)
\r
336 if((selectedPort & 1) ^ 1)
\r
338 selectedPins <<= 8;
\r
341 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
342 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
344 HWREG16(baseAddress + OFS_PADIR) &= ~selectedPins;
\r
345 HWREG16(baseAddress + OFS_PAREN) |= selectedPins;
\r
346 HWREG16(baseAddress + OFS_PAOUT) &= ~selectedPins;
\r
349 void GPIO_setAsInputPinWithPullUpResistor(uint8_t selectedPort,
\r
350 uint16_t selectedPins) {
\r
351 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
354 if(baseAddress == 0xFFFF)
\r
360 // Shift by 8 if port is even (upper 8-bits)
\r
361 if((selectedPort & 1) ^ 1)
\r
363 selectedPins <<= 8;
\r
366 HWREG16(baseAddress + OFS_PASEL0) &= ~selectedPins;
\r
367 HWREG16(baseAddress + OFS_PASEL1) &= ~selectedPins;
\r
368 HWREG16(baseAddress + OFS_PADIR) &= ~selectedPins;
\r
369 HWREG16(baseAddress + OFS_PAREN) |= selectedPins;
\r
370 HWREG16(baseAddress + OFS_PAOUT) |= selectedPins;
\r
373 uint8_t GPIO_getInputPinValue(uint8_t selectedPort,
\r
374 uint16_t selectedPins) {
\r
375 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
378 if(baseAddress == 0xFFFF)
\r
384 // Shift by 8 if port is even (upper 8-bits)
\r
385 if((selectedPort & 1) ^ 1)
\r
387 selectedPins <<= 8;
\r
390 uint16_t inputPinValue = HWREG16(baseAddress + OFS_PAIN) & (selectedPins);
\r
392 if(inputPinValue > 0)
\r
394 return (GPIO_INPUT_PIN_HIGH);
\r
396 return (GPIO_INPUT_PIN_LOW);
\r
399 void GPIO_enableInterrupt(uint8_t selectedPort,
\r
400 uint16_t selectedPins) {
\r
401 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
404 if(baseAddress == 0xFFFF)
\r
410 // Shift by 8 if port is even (upper 8-bits)
\r
411 if((selectedPort & 1) ^ 1)
\r
413 selectedPins <<= 8;
\r
416 HWREG16(baseAddress + OFS_PAIE) |= selectedPins;
\r
419 void GPIO_disableInterrupt(uint8_t selectedPort,
\r
420 uint16_t selectedPins) {
\r
421 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
424 if(baseAddress == 0xFFFF)
\r
430 // Shift by 8 if port is even (upper 8-bits)
\r
431 if((selectedPort & 1) ^ 1)
\r
433 selectedPins <<= 8;
\r
436 HWREG16(baseAddress + OFS_PAIE) &= ~selectedPins;
\r
439 uint16_t GPIO_getInterruptStatus(uint8_t selectedPort,
\r
440 uint16_t selectedPins) {
\r
441 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
444 if(baseAddress == 0xFFFF)
\r
450 // Shift by 8 if port is even (upper 8-bits)
\r
451 if((selectedPort & 1) ^ 1)
\r
453 selectedPins <<= 8;
\r
456 return (HWREG16(baseAddress + OFS_PAIFG) & selectedPins);
\r
459 void GPIO_clearInterrupt(uint8_t selectedPort,
\r
460 uint16_t selectedPins) {
\r
461 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
464 if(baseAddress == 0xFFFF)
\r
470 // Shift by 8 if port is even (upper 8-bits)
\r
471 if((selectedPort & 1) ^ 1)
\r
473 selectedPins <<= 8;
\r
476 HWREG16(baseAddress + OFS_PAIFG) &= ~selectedPins;
\r
479 void GPIO_selectInterruptEdge(uint8_t selectedPort,
\r
480 uint16_t selectedPins,
\r
481 uint8_t edgeSelect) {
\r
482 uint16_t baseAddress = GPIO_PORT_TO_BASE[selectedPort];
\r
485 if(baseAddress == 0xFFFF)
\r
491 // Shift by 8 if port is even (upper 8-bits)
\r
492 if((selectedPort & 1) ^ 1)
\r
494 selectedPins <<= 8;
\r
497 if(GPIO_LOW_TO_HIGH_TRANSITION == edgeSelect)
\r
499 HWREG16(baseAddress + OFS_PAIES) &= ~selectedPins;
\r
503 HWREG16(baseAddress + OFS_PAIES) |= selectedPins;
\r
508 //*****************************************************************************
\r
510 //! Close the doxygen group for gpio_api
\r
513 //*****************************************************************************
\r