Nut/OS  4.10.3
API Reference
gpio_nutos.c
Go to the documentation of this file.
00001 
00040 #include <arch/avr32.h>
00041 
00042 #include <stdlib.h>
00043 #include <string.h>
00044 
00045 #include <dev/gpio.h>
00046 
00047 #include <avr32/io.h>
00048 
00049 
00050 /*
00051  * Convert the external bank to the AVR32 representation.
00052  */
00053 static int get_avr32_bank(int bank)
00054 {
00055     int avr32_bank = 0;
00056 
00057     switch (bank) {
00058     default:
00059     case NUTGPIO_PORT:
00060     case NUTGPIO_PORTA:
00061         avr32_bank = 0;
00062         break;
00063     case NUTGPIO_PORTB:
00064         avr32_bank = 1;
00065         break;
00066     case NUTGPIO_PORTC:
00067         avr32_bank = 2;
00068         break;
00069     case NUTGPIO_PORTD:
00070         avr32_bank = 3;
00071         break;
00072     case NUTGPIO_PORTE:
00073         avr32_bank = 4;
00074         break;
00075     case NUTGPIO_PORTF:
00076         avr32_bank = 5;
00077         break;
00078     case NUTGPIO_PORTG:
00079         avr32_bank = 6;
00080         break;
00081     case NUTGPIO_PORTH:
00082         avr32_bank = 7;
00083         break;
00084     case NUTGPIO_PORTI:
00085         avr32_bank = 8;
00086         break;
00087     case NUTGPIO_PORTJ:
00088         avr32_bank = 9;
00089         break;
00090     case NUTGPIO_PORTK:
00091         avr32_bank = 10;
00092         break;
00093     case NUTGPIO_PORTL:
00094         avr32_bank = 11;
00095         break;
00096     }
00097 
00098     if (avr32_bank >= AVR32_GPIO_PORT_LENGTH) {
00099         avr32_bank = AVR32_GPIO_PORT_LENGTH - 1;
00100     }
00101 
00102     return (avr32_bank);
00103 }
00104 
00105 
00113 static int enable_module_pin(int avr32_bank, int mask, unsigned int function)
00114 {
00115     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00116 
00117     // Enable the correct function.
00118     switch (function) {
00119     case GPIO_CFG_PERIPHERAL0: // A function.
00120         gpio_port->pmr0c = mask;
00121         gpio_port->pmr1c = mask;
00122         break;
00123 
00124     case GPIO_CFG_PERIPHERAL1: // B function.
00125         gpio_port->pmr0s = mask;
00126         gpio_port->pmr1c = mask;
00127         break;
00128 
00129     case GPIO_CFG_PERIPHERAL2: // C function.
00130         gpio_port->pmr0c = mask;
00131         gpio_port->pmr1s = mask;
00132         break;
00133 
00134     default:
00135         return -1;
00136     }
00137 
00138     // Disable GPIO control.
00139     gpio_port->gperc = mask;
00140 
00141     return 0;
00142 }
00143 
00153 int GpioPinGet(int bank, int bit)
00154 {
00155     int avr32_bank = get_avr32_bank(bank);
00156     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00157 
00158     return (gpio_port->pvr >> (bit & 0x1F)) & 1;
00159 }
00160 
00169 void GpioPinSetLow(int bank, int bit)
00170 {
00171     int avr32_bank = get_avr32_bank(bank);
00172     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00173 
00174     gpio_port->ovrc = 1 << (bit & 0x1F);        // Value to be driven on the I/O line: 0.
00175 }
00176 
00185 void GpioPinSetHigh(int bank, int bit)
00186 {
00187     int avr32_bank = get_avr32_bank(bank);
00188     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00189 
00190     gpio_port->ovrs = 1 << (bit & 0x1F);        // Value to be driven on the I/O line: 1.
00191 }
00192 
00202 void GpioPinSet(int bank, int bit, int value)
00203 {
00204     int avr32_bank = get_avr32_bank(bank);
00205     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00206 
00207     if (value) {
00208         gpio_port->ovrs = 1 << (bit & 0x1F);    // Value to be driven on the I/O line: 1.
00209     } else {
00210         gpio_port->ovrc = 1 << (bit & 0x1F);    // Value to be driven on the I/O line: 0.
00211     }
00212 }
00213 
00221 unsigned int GpioPortGet(int bank)
00222 {
00223     int avr32_bank = get_avr32_bank(bank);
00224     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00225 
00226     return gpio_port->pvr;
00227 }
00228 
00238 void GpioPortSetLow(int bank, unsigned int mask)
00239 {
00240     int avr32_bank = get_avr32_bank(bank);
00241     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00242 
00243     gpio_port->ovrc = mask;     // Value to be driven on the I/O line: 0.
00244 }
00245 
00255 void GpioPortSetHigh(int bank, unsigned int mask)
00256 {
00257     int avr32_bank = get_avr32_bank(bank);
00258     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00259 
00260     gpio_port->ovrs = mask;     // Value to be driven on the I/O line: 1.
00261 }
00262 
00276 void GpioPortSet(int bank, unsigned int value)
00277 {
00278     int avr32_bank = get_avr32_bank(bank);
00279     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00280 
00281     gpio_port->ovr = value;
00282 }
00283 
00292 uint32_t GpioPinConfigGet(int bank, int bit)
00293 {
00294     uint32_t rc = 0;
00295     uint8_t is_gpio = 0;
00296     int avr32_bank = get_avr32_bank(bank);
00297     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00298 
00299     if ((gpio_port->gper & _BV(bit)) == 0) {
00300         rc |= GPIO_CFG_DISABLED;
00301     } else {
00302         is_gpio = 1;
00303     }
00304 
00305     if (gpio_port->oder & _BV(bit)) {
00306         rc |= GPIO_CFG_OUTPUT;
00307     }
00308 
00309     if (gpio_port->gfer & _BV(bit)) {
00310         rc |= GPIO_CFG_DEBOUNCE;
00311     }
00312 
00313     if (gpio_port->puer & _BV(bit)) {
00314         rc |= GPIO_CFG_PULLUP;
00315     }
00316 
00317     if (is_gpio == 0) {
00318         if (gpio_port->pmr1 & _BV(bit)) {
00319             if (gpio_port->pmr0 & _BV(bit)) {
00320                 rc |= GPIO_CFG_PERIPHERAL3;
00321             } else {
00322                 rc |= GPIO_CFG_PERIPHERAL2;
00323             }
00324         } else {
00325             if (gpio_port->pmr0 & _BV(bit)) {
00326                 rc |= GPIO_CFG_PERIPHERAL1;
00327             } else {
00328                 rc |= GPIO_CFG_PERIPHERAL0;
00329             }
00330         }
00331     }
00332 
00333     return rc;
00334 }
00335 
00349 int GpioPortConfigSet(int bank, unsigned int mask, uint32_t flags)
00350 {
00351 #define PERIPHERALS_MASK (GPIO_CFG_PERIPHERAL0|GPIO_CFG_PERIPHERAL1|GPIO_CFG_PERIPHERAL2|GPIO_CFG_PERIPHERAL3)
00352 
00353     int avr32_bank = get_avr32_bank(bank);
00354     volatile avr32_gpio_port_t *gpio_port = &AVR32_GPIO.port[avr32_bank];
00355 
00356     if (flags & GPIO_CFG_PULLUP) {
00357         gpio_port->puers = mask;
00358     } else {
00359         gpio_port->puerc = mask;
00360     }
00361 
00362     if (flags & GPIO_CFG_DEBOUNCE) {
00363         gpio_port->gfers = mask;
00364     } else {
00365         gpio_port->gferc = mask;
00366     }
00367 
00368     if (flags & GPIO_CFG_OUTPUT) {
00369         gpio_port->oders = mask;
00370     } else {
00371         gpio_port->oderc = mask;
00372     }
00373 
00374     if (flags & PERIPHERALS_MASK) {
00375         enable_module_pin(avr32_bank, mask, flags & PERIPHERALS_MASK);
00376     }
00377 
00378     if (flags & (GPIO_CFG_DISABLED | PERIPHERALS_MASK)) {
00379         gpio_port->gperc = mask;
00380         gpio_port->oderc = mask;
00381     } else {
00382         gpio_port->gpers = mask;
00383     }
00384 
00385 #undef PERIPHERALS_MASK
00386     return 0;
00387 }
00388 
00406 int GpioPinConfigSet(int bank, int bit, uint32_t flags)
00407 {
00408     GpioPortConfigSet(bank, _BV(bit), flags);
00409 
00410     /* Check the result. */
00411     if (GpioPinConfigGet(bank, bit) != flags) {
00412         return -1;
00413     }
00414     return 0;
00415 }
00416 
00457 int GpioRegisterIrqHandler(GPIO_SIGNAL * sig, int bit, void (*handler) (void *), void *arg)
00458 {
00459     int rc = 0;
00460 
00461     if (sig->ios_vector == 0) {
00462         /* This is the first call. Allocate the vector table. */
00463         sig->ios_vector = malloc(sizeof(GPIO_VECTOR) * 32);
00464         if (sig->ios_vector) {
00465             memset(sig->ios_vector, 0, sizeof(GPIO_VECTOR) * 32);
00466             /* Register our internal PIO interrupt service. */
00467             rc = NutRegisterIrqHandler(sig->ios_sig, sig->ios_handler, sig->ios_vector);
00468             if (rc == 0) {
00469                 rc = NutIrqEnable(sig->ios_sig);
00470             }
00471         } else {
00472             rc = -1;
00473         }
00474     }
00475     sig->ios_vector[bit].iov_handler = handler;
00476     sig->ios_vector[bit].iov_arg = arg;
00477 
00478     return rc;
00479 }
00480 
00492 int GpioIrqEnable(GPIO_SIGNAL * sig, int bit)
00493 {
00494     return (sig->ios_ctl) (NUT_IRQCTL_ENABLE, NULL, bit);
00495 }
00496 
00505 int GpioIrqDisable(GPIO_SIGNAL * sig, int bit)
00506 {
00507     return (sig->ios_ctl) (NUT_IRQCTL_DISABLE, NULL, bit);
00508 }