rpi gpio: Rework GPIO support
* GPIO calls now simplier and more correct * Set UART pins to AUX0 mode
This commit is contained in:
@@ -4,22 +4,108 @@
|
|||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Alexander von Gluck, [email protected]
|
* Alexander von Gluck, [email protected]
|
||||||
|
* Gordon Henderson, [email protected]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Define the shift up for the 3 bits per pin in each GPFSEL port
|
||||||
|
static uint8_t
|
||||||
|
kGPIOToShift[] =
|
||||||
|
{
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21, 24, 27,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Map a BCM_GPIO pin to it's control port. (GPFSEL 0-5)
|
||||||
|
static uint8_t
|
||||||
|
kGPIOToGPFSEL[] =
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
|
3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// (Word) offset to the GPIO Set registers for each GPIO pin
|
||||||
|
static uint8_t
|
||||||
|
kGPIOToGPSET[] =
|
||||||
|
{
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
// (Word) offset to the GPIO Clear registers for each GPIO pin
|
||||||
|
static uint8_t
|
||||||
|
kGPIOToGPCLR[] =
|
||||||
|
{
|
||||||
|
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||||
|
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
|
||||||
|
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||||
|
11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* At GPIO (base) (pin) state set (value)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gpio_write(addr_t base, int pin, bool value)
|
||||||
|
{
|
||||||
|
volatile addr_t *gpio = (addr_t*)base;
|
||||||
|
|
||||||
|
if (value == 1)
|
||||||
|
*(gpio + kGPIOToGPSET[pin]) = 1 << pin;
|
||||||
|
else
|
||||||
|
*(gpio + kGPIOToGPCLR[pin]) = 1 << pin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* At GPIO (base) (pin) set mode (mode)
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
gpio_mode(addr_t base, int pin, int mode)
|
||||||
|
{
|
||||||
|
int sel = kGPIOToGPFSEL[pin];
|
||||||
|
int shift = kGPIOToShift[pin];
|
||||||
|
|
||||||
|
volatile addr_t *gpio = (addr_t*)base + sel;
|
||||||
|
|
||||||
|
if (mode == GPIO_IN)
|
||||||
|
*gpio = (*gpio & ~(7 << shift));
|
||||||
|
else if (mode == GPIO_OUT)
|
||||||
|
*gpio = (*gpio & ~(7 << shift)) | (1 << shift);
|
||||||
|
else
|
||||||
|
*gpio = (*gpio & ~(7 << shift)) | (mode << shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
gpio_init()
|
gpio_init()
|
||||||
{
|
{
|
||||||
// Set up pointer to Raspberry Pi GPIO base
|
// ** Take control of ok led, and general use pins
|
||||||
gGPIOBase = (volatile unsigned *)GPIO_BASE;
|
|
||||||
|
|
||||||
// Take control of ok led and general use pins
|
|
||||||
int pin = 0;
|
int pin = 0;
|
||||||
for (pin = 16; pin <= 25; pin++) {
|
for (pin = 16; pin <= 25; pin++)
|
||||||
GPIO_IN(pin);
|
gpio_mode(GPIO_BASE, pin, GPIO_OUT);
|
||||||
GPIO_OUT(pin);
|
|
||||||
}
|
// ** Prepare UART pins for serial communication
|
||||||
|
// Set alternate function 0 on UART pins
|
||||||
|
gpio_mode(GPIO_BASE, 14, GPIO_ALT0);
|
||||||
|
gpio_mode(GPIO_BASE, 15, GPIO_ALT0);
|
||||||
|
|
||||||
|
// Pull UART pins to initial state low
|
||||||
|
gpio_write(GPIO_BASE, 14, 0);
|
||||||
|
gpio_write(GPIO_BASE, 15, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,24 +9,30 @@
|
|||||||
#define _SYSTEM_BOOT_PLATFORM_PI_GPIO_H
|
#define _SYSTEM_BOOT_PLATFORM_PI_GPIO_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
#include <arch/arm/bcm2708.h>
|
#include <arch/arm/bcm2708.h>
|
||||||
|
|
||||||
|
|
||||||
// Macros for easy GPIO pin access in loader
|
#define GPIO_IN 0
|
||||||
#define GPIO_IN(g) *(gGPIOBase + ((g)/10)) &= ~(7<<(((g)%10)*3))
|
#define GPIO_OUT 1
|
||||||
#define GPIO_OUT(g) *(gGPIOBase + ((g)/10)) |= (1<<(((g)%10)*3))
|
#define GPIO_ALT0 4
|
||||||
#define GPIO_SET(g) *(gGPIOBase + 7) = (1<<g)
|
#define GPIO_ALT1 5
|
||||||
#define GPIO_CLR(g) *(gGPIOBase + 10) = (1<<g)
|
#define GPIO_ALT2 6
|
||||||
|
#define GPIO_ALT3 7
|
||||||
|
#define GPIO_ALT4 3
|
||||||
|
#define GPIO_ALT5 2
|
||||||
|
|
||||||
|
|
||||||
volatile unsigned *gGPIOBase;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void gpio_write(addr_t base, int pin, bool value);
|
||||||
|
void gpio_mode(addr_t base, int pin, int mode);
|
||||||
|
|
||||||
void gpio_init();
|
void gpio_init();
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ pi_start(void)
|
|||||||
gpio_init();
|
gpio_init();
|
||||||
|
|
||||||
// Flick on "OK" led
|
// Flick on "OK" led
|
||||||
GPIO_CLR(16);
|
gpio_write(GPIO_BASE, 16, 0);
|
||||||
|
|
||||||
mmu_init();
|
mmu_init();
|
||||||
serial_init();
|
serial_init();
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ void
|
|||||||
uart_pl011_init_early(void)
|
uart_pl011_init_early(void)
|
||||||
{
|
{
|
||||||
// Perform special hardware UART configuration
|
// Perform special hardware UART configuration
|
||||||
|
// Raspberry Pi: Early setup handled by gpio_init in platform code
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user