diff --git a/arch/mips/src/pic32mx/pic32mx-gpio.c b/arch/mips/src/pic32mx/pic32mx-gpio.c index ecff125adf..d138984aa1 100644 --- a/arch/mips/src/pic32mx/pic32mx-gpio.c +++ b/arch/mips/src/pic32mx/pic32mx-gpio.c @@ -125,6 +125,15 @@ static inline unsigned int pic32mx_pinno(uint16_t pinset) return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); } +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +static inline unsigned int pic32mx_analog(uint16_t pinset) +{ + return ((pinset & GPIO_ANALOG_MASK) != 0); +} +#else +# define pic32mx_analog(pinset) (false) +#endif + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -145,6 +154,7 @@ int pic32mx_configgpio(uint16_t cfgset) { unsigned int port = pic32mx_portno(cfgset); unsigned int pin = pic32mx_pinno(cfgset); + uint32_t mask = (1 << pin); uintptr_t base; /* Verify that the port number is within range */ @@ -160,9 +170,14 @@ int pic32mx_configgpio(uint16_t cfgset) sched_lock(); if (pic32mx_output(cfgset)) { + /* Not analog */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + putreg32(mask, base + PIC32MX_IOPORT_ANSELCLR_OFFSET); +#endif /* It is an output; clear the corresponding bit in the TRIS register */ - putreg32(1 << pin, base + PIC32MX_IOPORT_TRISCLR_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_TRISCLR_OFFSET); /* Is it an open drain output? */ @@ -172,7 +187,7 @@ int pic32mx_configgpio(uint16_t cfgset) * the ODC register. */ - putreg32(1 << pin, base + PIC32MX_IOPORT_ODCSET_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_ODCSET_OFFSET); } else { @@ -180,7 +195,7 @@ int pic32mx_configgpio(uint16_t cfgset) * ODC register. */ - putreg32(1 << pin, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_ODCCLR_OFFSET); } /* Set the initial output value */ @@ -191,8 +206,21 @@ int pic32mx_configgpio(uint16_t cfgset) { /* It is an input; set the corresponding bit in the TRIS register. */ - putreg32(1 << pin, base + PIC32MX_IOPORT_TRISSET_OFFSET); - putreg32(1 << pin, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_TRISSET_OFFSET); + putreg32(mask, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + + /* Is it an analog input? */ + +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) + if (pic32mx_analog(cfgset)) + { + putreg32(mask, base + PIC32MX_IOPORT_ANSELSET_OFFSET); + } + else + { + putreg32(mask, base + PIC32MX_IOPORT_ANSELCLR_OFFSET); + } +#endif } sched_unlock(); diff --git a/arch/mips/src/pic32mx/pic32mx-internal.h b/arch/mips/src/pic32mx/pic32mx-internal.h index 7ba2d239f6..0af09a40c4 100644 --- a/arch/mips/src/pic32mx/pic32mx-internal.h +++ b/arch/mips/src/pic32mx/pic32mx-internal.h @@ -59,7 +59,7 @@ /* GPIO settings used in the configport, readport, writeport, etc. * * General encoding: - * MMxV IIDx RRRx PPPP + * MMAV IIDx RRRx PPPP */ #define GPIO_MODE_SHIFT (14) /* Bits 14-15: I/O mode */ @@ -68,6 +68,12 @@ # define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* 10 Normal output */ # define GPIO_OPENDRAN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */ +#if defined(CHIP_PIC32MX1) || defined(CHIP_PIC32MX2) +#define GPIO_ANALOG_MASK (1 << 13) /* Bit 13: Analog */ +# define GPIO_ANALOG (1 << 13) +# define GPIO_DIGITAL (0) +#endif + #define GPIO_VALUE_MASK (1 << 12) /* Bit 12: Initial output value */ # define GPIO_VALUE_ONE (1 << 12) # define GPIO_VALUE_ZERO (0)