Skip to content

Commit

Permalink
Merge pull request #6829 from francois-berder-imgtec/periph-gpio
Browse files Browse the repository at this point in the history
PIC32: Add GPIO peripheral
  • Loading branch information
miri64 committed Apr 19, 2017
2 parents a884640 + 74a999a commit 2e6520d
Show file tree
Hide file tree
Showing 15 changed files with 276 additions and 11 deletions.
1 change: 1 addition & 0 deletions boards/pic32-clicker/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_gpio
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart

Expand Down
1 change: 0 additions & 1 deletion boards/pic32-clicker/clicker.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include "periph/uart.h"
#include "bitarithm.h"
#include "board.h"
#include "periph_conf.h"

extern void dummy(void);

Expand Down
2 changes: 2 additions & 0 deletions boards/pic32-clicker/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#ifndef BOARD_H
#define BOARD_H

#include "periph_conf.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
2 changes: 2 additions & 0 deletions boards/pic32-clicker/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#ifndef PERIPH_CONF_H
#define PERIPH_CONF_H

#include "periph_cpu.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
1 change: 1 addition & 0 deletions boards/pic32-wifire/Makefile.features
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Put defined MCU peripherals here (in alphabetical order)
FEATURES_PROVIDED += periph_gpio
FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart

Expand Down
2 changes: 2 additions & 0 deletions boards/pic32-wifire/include/board.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#ifndef _BOARD_H_
#define _BOARD_H_

#include "periph_conf.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
2 changes: 2 additions & 0 deletions boards/pic32-wifire/include/periph_conf.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#ifndef _PERIPH_CONF_H_
#define _PERIPH_CONF_H_

#include "periph_cpu.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down
1 change: 0 additions & 1 deletion boards/pic32-wifire/wifire.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "periph/uart.h"
#include "bitarithm.h"
#include "board.h"
#include "periph_conf.h"

extern void dummy(void);

Expand Down
9 changes: 2 additions & 7 deletions cpu/mips_pic32_common/Makefile.include
Original file line number Diff line number Diff line change
@@ -1,7 +1,2 @@
# depends on mips32r2_common
USEMODULE += mips32r2_common

export MIPS32R2_COMMON = $(RIOTCPU)/mips32r2_common/

export INCLUDES = $(MIPS32R2_COMMON)include
include $(MIPS32R2_COMMON)Makefile.include
export INCLUDES += -I$(RIOTCPU)/mips32r2_common/include \
-I$(RIOTCPU)/mips_pic32_common/include
48 changes: 48 additions & 0 deletions cpu/mips_pic32_common/include/periph_cpu_common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright(C) 2017, Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/

/**
* @ingroup cpu_mips_pic32_common
* @{
*
* @file
* @brief CPU specific definitions for internal peripheral handling
*
* @author Francois Berder <francois.berder@imgtec.com>
*/

#ifndef PERIPH_CPU_COMMON_H
#define PERIPH_CPU_COMMON_H

#ifdef __cplusplus
extern "C" {
#endif

#define GPIO_PIN(x,y) ((x << 4) | (y & 0xf))

/**
* @brief Available ports on the PIC32 family
*/
enum {
PORT_A = 0, /**< port A */
PORT_B = 1, /**< port B */
PORT_C = 2, /**< port C */
PORT_D = 3, /**< port D */
PORT_E = 4, /**< port E */
PORT_F = 5, /**< port F */
PORT_G = 6, /**< port G */
};

#ifdef __cplusplus
}
#endif

#endif /* PERIPH_CPU_COMMON_H */
/** @} */
212 changes: 212 additions & 0 deletions cpu/mips_pic32_common/periph/gpio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
/*
* Copyright(C) 2017 Imagination Technologies Limited and/or its
* affiliated group companies.
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/

#include <assert.h>
#include <stdint.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)
{
return port < (sizeof(base_address)/sizeof(base_address[0]))
&& base_address[port].gpio != 0;
}

int gpio_init(gpio_t pin, gpio_mode_t mode)
{
uint8_t port = GPIO_PORT(pin);
uint32_t pin_no = GPIO_PIN_NO(pin);
uint8_t output = 0, pu = 0, pd = 0, od = 0;

assert(check_valid_port(port));

switch (mode) {
case GPIO_IN:
break;
case GPIO_IN_PD:
pd = 1;
break;
case GPIO_IN_PU:
pu = 1;
break;

case GPIO_OD_PU:
pu = 1;
case GPIO_OD:
od = 1;
case GPIO_OUT:
output = 1;
break;
}

ANSELxCLR(port) = pin_no; /* Configure GPIO as digital */

if (pu)
CNPUxSET(port) = pin_no;
else
CNPUxCLR(port) = pin_no;

if (pd)
CNPDxSET(port) = pin_no;
else
CNPDxCLR(port) = pin_no;

if (od)
ODCxSET(port) = pin_no;
else
ODCxCLR(port) = pin_no;

if (output)
TRISxCLR(port) = pin_no;
else
TRISxSET(port) = pin_no;

return 0;
}

int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
gpio_cb_t cb, void *arg)
{
(void)pin;
(void)mode;
(void)flank;
(void)cb;
(void)arg;

/* TODO: Not implemented yet */

return -1;
}

int gpio_read(gpio_t pin)
{
assert(check_valid_port(GPIO_PORT(pin)));

return PORTx(GPIO_PORT(pin)) & GPIO_PIN_NO(pin);
}

void gpio_set(gpio_t pin)
{
assert(check_valid_port(GPIO_PORT(pin)));

LATxSET(GPIO_PORT(pin)) = GPIO_PIN_NO(pin);
}

void gpio_clear(gpio_t pin)
{
assert(check_valid_port(GPIO_PORT(pin)));

LATxCLR(GPIO_PORT(pin)) = GPIO_PIN_NO(pin);
}

void gpio_toggle(gpio_t pin)
{
assert(check_valid_port(GPIO_PORT(pin)));

LATxINV(GPIO_PORT(pin)) = GPIO_PIN_NO(pin);
}

void gpio_write(gpio_t pin, int value)
{
if (value)
gpio_set(pin);
else
gpio_clear(pin);
}
1 change: 1 addition & 0 deletions cpu/mips_pic32mx/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export APP_START=0x80000000
export ROMABLE = 1

include $(RIOTMAKE)/arch/mips.inc.mk
include $(RIOTCPU)/mips_pic32_common/Makefile.include

# define build specific options
export CFLAGS += -march=m4k -DSKIP_COPY_TO_RAM
Expand Down
2 changes: 1 addition & 1 deletion cpu/mips_pic32mx/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
*/

/* This file must exist to get timer code to build */
#include "periph_cpu_common.h"

#ifdef __cplusplus
extern "C" {
Expand Down
1 change: 1 addition & 0 deletions cpu/mips_pic32mz/Makefile.include
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export APP_START=0x80000000
export ROMABLE = 1

include $(RIOTMAKE)/arch/mips.inc.mk
include $(RIOTCPU)/mips_pic32_common/Makefile.include

# define build specific options
export CFLAGS += -march=m5101 -mmicromips -DSKIP_COPY_TO_RAM
Expand Down
2 changes: 1 addition & 1 deletion cpu/mips_pic32mz/include/periph_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
*
*/

/* This file must exist to get timer code to build */
#include "periph_cpu_common.h"

#ifdef __cplusplus
extern "C" {
Expand Down

0 comments on commit 2e6520d

Please sign in to comment.