diff --git a/boards/pic32-clicker/include/board.h b/boards/pic32-clicker/include/board.h index 03cd42931e80..ef202c6c85a4 100644 --- a/boards/pic32-clicker/include/board.h +++ b/boards/pic32-clicker/include/board.h @@ -33,8 +33,6 @@ extern "C" { #endif -#include "vendor/p32mx470f512h.h" - /** * @brief Set how many increments of the count register per uS * needed by the timer code. diff --git a/boards/pic32-wifire/include/board.h b/boards/pic32-wifire/include/board.h index 12c43d320f3e..487c849ecece 100644 --- a/boards/pic32-wifire/include/board.h +++ b/boards/pic32-wifire/include/board.h @@ -32,8 +32,6 @@ extern "C" { #endif -#include "vendor/p32mz2048efg100.h" - /** * @brief Set how many increments of the count register per uS * needed by the timer code. diff --git a/cpu/mips_pic32_common/include/periph_cpu_common.h b/cpu/mips_pic32_common/include/periph_cpu_common.h index 0d9690161bf9..b87a17ec8769 100644 --- a/cpu/mips_pic32_common/include/periph_cpu_common.h +++ b/cpu/mips_pic32_common/include/periph_cpu_common.h @@ -22,6 +22,8 @@ #ifndef PERIPH_CPU_COMMON_H #define PERIPH_CPU_COMMON_H +#include "cpu.h" + #ifdef __cplusplus extern "C" { #endif @@ -43,10 +45,20 @@ extern "C" { */ #define CPUID_LEN (4U) +#ifndef DOXYGEN +/** + * @brief Overwrite the default gpio_t type definition + * @{ + */ +#define HAVE_GPIO_T +typedef uint32_t gpio_t; +/** @} */ +#endif + /** * @brief Override GPIO pin selection macro */ -#define GPIO_PIN(x,y) ((x << 4) | (y & 0xf)) +#define GPIO_PIN(x, y) (((_PORTB_BASE_ADDRESS & 0xFFFFF000) + (x << 8)) | y) /** * @brief Available ports on the PIC32 family diff --git a/cpu/mips_pic32_common/periph/gpio.c b/cpu/mips_pic32_common/periph/gpio.c index 21d5bb226d99..5f6fa6ea5139 100644 --- a/cpu/mips_pic32_common/periph/gpio.c +++ b/cpu/mips_pic32_common/periph/gpio.c @@ -19,115 +19,58 @@ * @} */ -#include -#include +#include "cpu.h" #include "periph/gpio.h" -#include "board.h" - -#define GPIO_PIN_NO(PIN) (1 << ((PIN) & 0xf)) -#define GPIO_PORT(PIN) ((PIN) >> 4) - -#define LATx(P) (base_address[P].gpio[0x10/0x4]) -#define LATxCLR(P) (base_address[P].gpio[0x14/0x4]) -#define LATxSET(P) (base_address[P].gpio[0x18/0x4]) -#define LATxINV(P) (base_address[P].gpio[0x1C/0x4]) -#define PORTx(P) (base_address[P].gpio[0x0]) -#define CNPUxCLR(P) (base_address[P].gpio[0x34/0x4]) -#define CNPUxSET(P) (base_address[P].gpio[0x38/0x4]) -#define CNPDxCLR(P) (base_address[P].gpio[0x44/0x4]) -#define CNPDxSET(P) (base_address[P].gpio[0x48/0x4]) -#define ODCxCLR(P) (base_address[P].gpio[0x24/0x4]) -#define ODCxSET(P) (base_address[P].gpio[0x28/0x4]) -#define ANSELxCLR(P) (base_address[P].ansel[0x04/0x4]) -#define TRISxCLR(P) (base_address[P].tris[0x04/0x4]) -#define TRISxSET(P) (base_address[P].tris[0x08/0x4]) - -typedef struct PIC32_GPIO_tag { - volatile uint32_t* gpio; - volatile uint32_t* ansel; - volatile uint32_t* tris; -} PIC32_GPIO_T; - -static PIC32_GPIO_T base_address[] = { -#ifdef _PORTA_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTA_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELA, - .tris = (volatile uint32_t*)&TRISA - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTB_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTB_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELB, - .tris = (volatile uint32_t*)&TRISB - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTC_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTC_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELC, - .tris = (volatile uint32_t*)&TRISC - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTD_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTD_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELD, - .tris = (volatile uint32_t*)&TRISD - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTE_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTE_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELE, - .tris = (volatile uint32_t*)&TRISE - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTF_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTF_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELF, - .tris = (volatile uint32_t*)&TRISF - }, -#else - {0 , 0, 0}, -#endif -#ifdef _PORTG_BASE_ADDRESS - { - .gpio = (volatile uint32_t*)_PORTG_BASE_ADDRESS, - .ansel = (volatile uint32_t*)&ANSELG, - .tris = (volatile uint32_t*)&TRISG - }, -#else - {0 , 0, 0}, -#endif -}; - -static inline int check_valid_port(uint8_t port) +#include "periph_conf.h" + +#define LATx(P) ((P)[0x30/0x4]) +#define LATxCLR(P) ((P)[0x34/0x4]) +#define LATxSET(P) ((P)[0x38/0x4]) +#define LATxINV(P) ((P)[0x3C/0x4]) +#define PORTx(P) ((P)[0x20/0x4]) +#define CNPUxCLR(P) ((P)[0x54/0x4]) +#define CNPUxSET(P) ((P)[0x58/0x4]) +#define CNPDxCLR(P) ((P)[0x64/0x4]) +#define CNPDxSET(P) ((P)[0x68/0x4]) +#define ODCxCLR(P) ((P)[0x44/0x4]) +#define ODCxSET(P) ((P)[0x48/0x4]) +#define ANSELxCLR(P) ((P)[0x04/0x4]) +#define TRISxCLR(P) ((P)[0x14/0x4]) +#define TRISxSET(P) ((P)[0x18/0x4]) + +/** + * @brief Extract the port base address from the given pin identifier + */ +static inline volatile unsigned int * _port(gpio_t pin) +{ + return (volatile unsigned int *)(pin & ~(0xff)); +} + +/** + * @brief Extract the port number form the given identifier + * + * The port number is extracted by looking at bits 8, 9, 10, 11 of the base + * register addresses. + */ +static inline int _port_num(gpio_t pin) +{ + return ((pin >> 8) & 0x0f); +} + +/** + * @brief Extract the pin number from the last 4 bit of the pin identifier + */ +static inline int _pin_num(gpio_t pin) { - return port < ARRAY_SIZE(base_address) - && base_address[port].gpio != NULL; + return (pin & 0x0f); } int gpio_init(gpio_t pin, gpio_mode_t mode) { - uint8_t port = GPIO_PORT(pin); - uint32_t pin_no = GPIO_PIN_NO(pin); + volatile unsigned int * port = _port(pin); + int pin_num = _pin_num(pin); uint8_t output = 0, pu = 0, pd = 0, od = 0; - assert(check_valid_port(port)); - switch (mode) { case GPIO_IN: break; @@ -137,7 +80,6 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) case GPIO_IN_PU: pu = 1; break; - case GPIO_OD_PU: pu = 1; case GPIO_OD: @@ -147,57 +89,49 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) break; } - ANSELxCLR(port) = pin_no; /* Configure GPIO as digital */ + ANSELxCLR(port) = 1U << pin_num; /* Configure GPIO as digital */ if (pu) - CNPUxSET(port) = pin_no; + CNPUxSET(port) = 1U << pin_num; else - CNPUxCLR(port) = pin_no; + CNPUxCLR(port) = 1U << pin_num; if (pd) - CNPDxSET(port) = pin_no; + CNPDxSET(port) = 1U << pin_num; else - CNPDxCLR(port) = pin_no; + CNPDxCLR(port) = 1U << pin_num; if (od) - ODCxSET(port) = pin_no; + ODCxSET(port) = 1U << pin_num; else - ODCxCLR(port) = pin_no; + ODCxCLR(port) = 1U << pin_num; if (output) - TRISxCLR(port) = pin_no; + TRISxCLR(port) = 1U << pin_num; else - TRISxSET(port) = pin_no; + TRISxSET(port) = 1U << pin_num; return 0; } int gpio_read(gpio_t pin) { - assert(check_valid_port(GPIO_PORT(pin))); - - return PORTx(GPIO_PORT(pin)) & GPIO_PIN_NO(pin); + return PORTx(_port(pin)) & (1U << _pin_num(pin)); } void gpio_set(gpio_t pin) { - assert(check_valid_port(GPIO_PORT(pin))); - - LATxSET(GPIO_PORT(pin)) = GPIO_PIN_NO(pin); + LATxSET(_port(pin)) = 1U << _pin_num(pin); } void gpio_clear(gpio_t pin) { - assert(check_valid_port(GPIO_PORT(pin))); - - LATxCLR(GPIO_PORT(pin)) = GPIO_PIN_NO(pin); + LATxCLR(_port(pin)) = 1U << _pin_num(pin); } void gpio_toggle(gpio_t pin) { - assert(check_valid_port(GPIO_PORT(pin))); - - LATxINV(GPIO_PORT(pin)) = GPIO_PIN_NO(pin); + LATxINV(_port(pin)) = 1U << _pin_num(pin); } void gpio_write(gpio_t pin, int value)