提交 ff10eaed 编写于 作者: B bigmagic

[bsp/raspi3-64]fix gpio drvier

上级 dc47abf4
......@@ -146,7 +146,7 @@ CONFIG_RT_USING_SERIAL=y
# CONFIG_RT_SERIAL_USING_DMA is not set
CONFIG_RT_SERIAL_RB_BUFSZ=64
# CONFIG_RT_USING_CAN is not set
# CONFIG_RT_USING_HWTIMER is not set
CONFIG_RT_USING_HWTIMER=y
# CONFIG_RT_USING_CPUTIME is not set
# CONFIG_RT_USING_I2C is not set
CONFIG_RT_USING_PIN=y
......@@ -465,7 +465,9 @@ CONFIG_BSP_USING_UART=y
CONFIG_RT_USING_UART1=y
CONFIG_BSP_USING_PIN=y
CONFIG_BSP_USING_CORETIMER=y
# CONFIG_BSP_USING_SYSTIMER is not set
CONFIG_BSP_USING_SYSTIMER=y
CONFIG_RT_USING_SYSTIMER1=y
# CONFIG_RT_USING_SYSTIMER3 is not set
# CONFIG_BSP_USING_I2C is not set
# CONFIG_BSP_USING_SPI is not set
# CONFIG_BSP_USING_WDT is not set
......
......@@ -5,7 +5,6 @@ from building import *
cwd = GetCurrentDir()
src = Split('''
board.c
bcm283x.c
drv_uart.c
''')
CPPPATH = [cwd]
......
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-07-29 zdzn first version
*/
#include "bcm283x.h"
rt_uint32_t bcm283x_peri_read(volatile rt_ubase_t addr)
{
rt_uint32_t ret;
__sync_synchronize();
ret = HWREG32(addr);
__sync_synchronize();
return ret;
}
rt_uint32_t bcm283x_peri_read_nb(volatile rt_ubase_t addr)
{
return HWREG32(addr);
}
void bcm283x_peri_write(volatile rt_ubase_t addr, rt_uint32_t value)
{
__sync_synchronize();
HWREG32(addr) = value;
__sync_synchronize();
}
void bcm283x_peri_write_nb(volatile rt_ubase_t addr, rt_uint32_t value)
{
HWREG32(addr) = value;
}
void bcm283x_peri_set_bits(volatile rt_ubase_t addr, rt_uint32_t value, rt_uint32_t mask)
{
rt_uint32_t v = bcm283x_peri_read(addr);
v = (v & ~mask) | (value & mask);
bcm283x_peri_write(addr, v);
}
void bcm283x_gpio_fsel(rt_uint8_t pin, rt_uint8_t mode)
{
volatile rt_ubase_t addr = (BCM283X_GPIO_BASE + BCM283X_GPIO_GPFSEL0 + (pin / 10) * 4);
rt_uint8_t shift = (pin % 10) * 3;
rt_uint32_t mask = BCM283X_GPIO_FSEL_MASK << shift;
rt_uint32_t value = mode << shift;
bcm283x_peri_set_bits(addr, value, mask);
}
void bcm283x_gpio_set(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPSET0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
bcm283x_peri_write(addr, 1 << shift);
}
void bcm283x_gpio_clr(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPCLR0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
bcm283x_peri_write(addr, 1 << shift);
}
rt_uint8_t bcm283x_gpio_lev(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM2835_GPIO_GPLEV0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = bcm283x_peri_read(addr);
return (value & (1 << shift)) ? HIGH : LOW;
}
rt_uint8_t bcm283x_gpio_eds(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = bcm283x_peri_read(addr);
return (value & (1 << shift)) ? HIGH : LOW;
}
/* Write a 1 to clear the bit in EDS */
void bcm283x_gpio_set_eds(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_write(addr, value);
}
/* Rising edge detect enable */
void bcm283x_gpio_ren(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_ren(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPREN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* Falling edge detect enable */
void bcm283x_gpio_fen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_fen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPFEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* High detect enable */
void bcm283x_gpio_hen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_hen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPHEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* Low detect enable */
void bcm283x_gpio_len(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_len(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPLEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* Async rising edge detect enable */
void bcm283x_gpio_aren(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_aren(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAREN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* Async falling edge detect enable */
void bcm283x_gpio_afen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, value, value);
}
void bcm283x_gpio_clr_afen(rt_uint8_t pin)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPAFEN0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
rt_uint32_t value = 1 << shift;
bcm283x_peri_set_bits(addr, 0, value);
}
/* Set pullup/down */
void bcm283x_gpio_pud(rt_uint8_t pud)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUD;
bcm283x_peri_write(addr, pud);
}
/* Pullup/down clock
// Clocks the value of pud into the GPIO pin
*/
void bcm283x_gpio_pudclk(rt_uint8_t pin, rt_uint8_t on)
{
volatile rt_ubase_t addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPPUDCLK0 + (pin / 32) * 4;
rt_uint8_t shift = pin % 32;
bcm283x_peri_write(addr, (on? 1 : 0) << shift);
}
void bcm283x_gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud)
{
bcm283x_gpio_pud(pud);
bcm283x_clo_delayMicros(10);
bcm283x_gpio_pudclk(pin, 1);
bcm283x_clo_delayMicros(10);
bcm283x_gpio_pud(BCM283X_GPIO_PUD_OFF);
bcm283x_gpio_pudclk(pin, 0);
}
void bcm283x_gpio_write(rt_uint8_t pin, rt_uint8_t val)
{
if (val)
bcm283x_gpio_set(pin);
else
bcm283x_gpio_clr(pin);
}
rt_uint64_t bcm283x_st_read(void)
{
volatile rt_ubase_t addr;
rt_uint32_t hi, lo;
rt_uint64_t st;
addr = BCM283X_ST_BASE + BCM283X_ST_CHI;
hi = bcm283x_peri_read(addr);
addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
lo = bcm283x_peri_read(addr);
addr = BCM283X_ST_BASE + BCM283X_ST_CHI;
st = bcm283x_peri_read(addr);
/* Test for overflow */
if (st == hi)
{
rt_kprintf(">> 1crash???\n");
st <<= 32;
st += lo;
rt_kprintf(">> 2crash!!!\n");
}
else
{
st <<= 32;
addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
st += bcm283x_peri_read(addr);
}
return st;
}
/* microseconds */
void bcm283x_delayMicroseconds(rt_uint64_t micros)
{
rt_uint64_t start;
start = bcm283x_st_read();
rt_kprintf("bcm283x_st_read result: %d\n", start);
/* Not allowed to access timer registers (result is not as precise)*/
if (start==0)
return;
bcm283x_st_delay(start, micros);
}
void bcm283x_clo_delayMicros(rt_uint32_t micros)
{
volatile rt_uint32_t addr;
rt_uint32_t compare;
addr = BCM283X_ST_BASE + BCM283X_ST_CLO;
compare = bcm283x_peri_read(addr) + micros;
while(bcm283x_peri_read(addr) < compare);
}
void bcm283x_st_delay(rt_uint64_t offset_micros, rt_uint64_t micros)
{
rt_uint64_t compare = offset_micros + micros;
while(bcm283x_st_read() < compare);
}
/* Read an number of bytes from I2C */
rt_uint8_t bcm283x_i2c_read(rt_uint32_t base, rt_uint8_t* buf, rt_uint32_t len)
{
volatile rt_uint32_t dlen = base + BCM283X_BSC_DLEN;
volatile rt_uint32_t fifo = base + BCM283X_BSC_FIFO;
volatile rt_uint32_t status = base + BCM283X_BSC_S;
volatile rt_uint32_t control = base + BCM283X_BSC_C;
rt_uint32_t remaining = len;
rt_uint32_t i = 0;
rt_uint8_t reason = BCM283X_I2C_REASON_OK;
/* Clear FIFO */
bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
/* Clear Status */
bcm283x_peri_write_nb(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
/* Set Data Length */
bcm283x_peri_write_nb(dlen, len);
/* Start read */
bcm283x_peri_write_nb(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST | BCM283X_BSC_C_READ);
/* wait for transfer to complete */
while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE))
{
/* we must empty the FIFO as it is populated and not use any delay */
while (remaining && bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD)
{
/* Read from FIFO, no barrier */
buf[i] = bcm283x_peri_read_nb(fifo);
i++;
remaining--;
}
}
/* transfer has finished - grab any remaining stuff in FIFO */
while (remaining && (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_RXD))
{
/* Read from FIFO, no barrier */
buf[i] = bcm283x_peri_read_nb(fifo);
i++;
remaining--;
}
/* Received a NACK */
if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
{
reason = BCM283X_I2C_REASON_ERROR_NACK;
}
/* Received Clock Stretch Timeout */
else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
{
reason = BCM283X_I2C_REASON_ERROR_CLKT;
}
/* Not all data is received */
else if (remaining)
{
reason = BCM283X_I2C_REASON_ERROR_DATA;
}
bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
return reason;
}
int bcm283x_i2c_begin(int no)
{
if (0 == no)
{
bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_ALT0); /* SDA */
bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_ALT0); /* SCL */
}
else
{
bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_ALT0); /* SDA */
bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_ALT0); /* SCL */
}
return 0;
}
void bcm283x_i2c_end(int no)
{
if (0 == no)
{
bcm283x_gpio_fsel(BCM_GPIO_PIN_0, BCM283X_GPIO_FSEL_INPT); /* SDA */
bcm283x_gpio_fsel(BCM_GPIO_PIN_1, BCM283X_GPIO_FSEL_INPT); /* SCL */
}
else
{
bcm283x_gpio_fsel(BCM_GPIO_PIN_2, BCM283X_GPIO_FSEL_INPT); /* SDA */
bcm283x_gpio_fsel(BCM_GPIO_PIN_3, BCM283X_GPIO_FSEL_INPT); /* SCL */
}
}
void bcm283x_i2c_setSlaveAddress(int no, rt_uint8_t saddr)
{
volatile rt_uint32_t addr;
if (0 == no)
addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_A;
else
addr = PER_BASE + BCM283X_BSC1_BASE + BCM283X_BSC_A;
bcm283x_peri_write(addr, saddr);
}
void bcm283x_i2c_setClockDivider(int no, rt_uint16_t divider)
{
volatile rt_uint32_t addr;
if (0 == no)
addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV;
else
addr = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DIV;
bcm283x_peri_write(addr, divider);
}
void bcm283x_i2c_set_baudrate(int no, rt_uint32_t baudrate)
{
rt_uint32_t divider;
divider = (BCM283X_CORE_CLK_HZ / baudrate) & 0xFFFE;
bcm283x_i2c_setClockDivider(no, (rt_uint16_t)divider);
}
/* Writes an number of bytes to I2C */
rt_uint8_t bcm283x_i2c_write(rt_uint32_t base, const rt_uint8_t * buf, rt_uint32_t len)
{
volatile rt_uint32_t dlen = base + BCM283X_BSC_DLEN;
volatile rt_uint32_t fifo = base + BCM283X_BSC_FIFO;
volatile rt_uint32_t status = base + BCM283X_BSC_S;
volatile rt_uint32_t control = base + BCM283X_BSC_C;
rt_uint32_t remaining = len;
rt_uint32_t i = 0;
rt_uint8_t reason = BCM283X_I2C_REASON_OK;
/* Clear FIFO */
bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
/* Clear Status */
bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
/* Set Data Length */
bcm283x_peri_write(dlen, len);
/* pre populate FIFO with max buffer */
while(remaining && (i < BCM283X_BSC_FIFO_SIZE))
{
bcm283x_peri_write_nb(fifo, buf[i]);
i++;
remaining--;
}
/* Enable device and start transfer */
bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST);
/* Transfer is over when BCM2835_BSC_S_DONE */
while(!(bcm283x_peri_read(status) & BCM283X_BSC_S_DONE))
{
while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_TXD))
{
/* Write to FIFO */
bcm283x_peri_write(fifo, buf[i]);
i++;
remaining--;
}
}
/* Received a NACK */
if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
{
reason = BCM283X_I2C_REASON_ERROR_NACK;
}
/* Received Clock Stretch Timeout */
else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
{
reason = BCM283X_I2C_REASON_ERROR_CLKT;
}
/* Not all data is sent */
else if (remaining)
{
reason = BCM283X_I2C_REASON_ERROR_DATA;
}
bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
return reason;
}
rt_uint8_t bcm283x_i2c_write_read_rs(char* cmds, rt_uint32_t cmds_len, char* buf, rt_uint32_t buf_len)
{
volatile rt_uint32_t dlen = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_DLEN;
volatile rt_uint32_t fifo = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_FIFO;
volatile rt_uint32_t status = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_S;
volatile rt_uint32_t control = PER_BASE + BCM283X_BSC0_BASE + BCM283X_BSC_C;
rt_uint32_t remaining = cmds_len;
rt_uint32_t i = 0;
rt_uint8_t reason = BCM283X_I2C_REASON_OK;
/* Clear FIFO */
bcm283x_peri_set_bits(control, BCM283X_BSC_C_CLEAR_1, BCM283X_BSC_C_CLEAR_1);
/* Clear Status */
bcm283x_peri_write(status, BCM283X_BSC_S_CLKT | BCM283X_BSC_S_ERR | BCM283X_BSC_S_DONE);
/* Set Data Length */
bcm283x_peri_write(dlen, cmds_len);
/* pre populate FIFO with max buffer */
while(remaining && (i < BCM283X_BSC_FIFO_SIZE))
{
bcm283x_peri_write_nb(fifo, cmds[i]);
i++;
remaining--;
}
/* Enable device and start transfer */
bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST);
/* poll for transfer has started (way to do repeated start, from BCM2835 datasheet) */
while (!(bcm283x_peri_read(status) & BCM283X_BSC_S_TA))
{
/* Linux may cause us to miss entire transfer stage */
if (bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE)
break;
}
remaining = buf_len;
i = 0;
/* Send a repeated start with read bit set in address */
bcm283x_peri_write(dlen, buf_len);
bcm283x_peri_write(control, BCM283X_BSC_C_I2CEN | BCM283X_BSC_C_ST | BCM283X_BSC_C_READ);
/* Wait for write to complete and first byte back. */
bcm283x_clo_delayMicros(100);
/* wait for transfer to complete */
while (!(bcm283x_peri_read_nb(status) & BCM283X_BSC_S_DONE))
{
/* we must empty the FIFO as it is populated and not use any delay */
while (remaining && bcm283x_peri_read(status) & BCM283X_BSC_S_RXD)
{
/* Read from FIFO, no barrier */
buf[i] = bcm283x_peri_read_nb(fifo);
i++;
remaining--;
}
}
/* transfer has finished - grab any remaining stuff in FIFO */
while (remaining && (bcm283x_peri_read(status) & BCM283X_BSC_S_RXD))
{
/* Read from FIFO */
buf[i] = bcm283x_peri_read(fifo);
i++;
remaining--;
}
/* Received a NACK */
if (bcm283x_peri_read(status) & BCM283X_BSC_S_ERR)
{
reason = BCM283X_I2C_REASON_ERROR_NACK;
}
/* Received Clock Stretch Timeout */
else if (bcm283x_peri_read(status) & BCM283X_BSC_S_CLKT)
{
reason = BCM283X_I2C_REASON_ERROR_CLKT;
}
/* Not all data is sent */
else if (remaining)
{
reason = BCM283X_I2C_REASON_ERROR_DATA;
}
bcm283x_peri_set_bits(control, BCM283X_BSC_S_DONE, BCM283X_BSC_S_DONE);
return reason;
}
此差异已折叠。
......@@ -17,6 +17,7 @@
#include "cp15.h"
#include "mmu.h"
#include "raspi.h"
#ifdef BSP_USING_CORETIMER
static rt_uint64_t timerStep;
......
......@@ -13,10 +13,6 @@
#include <stdint.h>
#include <rthw.h>
#include <bcm283x.h>
#define __REG32 HWREG32
extern unsigned char __bss_start;
extern unsigned char __bss_end;
......
......@@ -10,62 +10,8 @@
#include "raspi.h"
#include "drv_gpio.h"
#ifdef BSP_USING_PIN
struct rpi_pin_index
{
rt_uint8_t phy_id;
rt_uint8_t bcm_id;
rt_uint8_t signal_name;
rt_uint8_t magic;
};
//raspi phy id and bcm id
static struct rpi_pin_index phypin_index[] =
{
{0, 0, 0, 0},
{1, 0, 0, 0},
{2, 0, 0, 0},
{3, BCM_GPIO_PIN_2, RPI_SDA1, PIN_MAGIC},
{4, 0, 0, 0},
{5, BCM_GPIO_PIN_3, RPI_SCL1, PIN_MAGIC},
{6, 0, 0, 0},
{7, BCM_GPIO_PIN_4, RPI_GPIO_GCLK, PIN_MAGIC},
{8, BCM_GPIO_PIN_14, RPI_TXD0, PIN_MAGIC},
{9, 0, 0, 0},
{10, BCM_GPIO_PIN_15, RPI_RXD0, PIN_MAGIC},
{11, BCM_GPIO_PIN_17, RPI_GPIO_GEN0, PIN_MAGIC},
{12, BCM_GPIO_PIN_18, RPI_GPIO_GEN1, PIN_MAGIC},
{13, BCM_GPIO_PIN_27, RPI_GPIO_GEN2, PIN_MAGIC},
{14, 0, 0, 0},
{15, BCM_GPIO_PIN_22, RPI_GPIO_GEN3, PIN_MAGIC},
{16, BCM_GPIO_PIN_23, RPI_GPIO_GEN4, PIN_MAGIC},
{17, 0, 0, 0},
{18, BCM_GPIO_PIN_24, RPI_GPIO_GEN5, PIN_MAGIC},
{19, BCM_GPIO_PIN_10, RPI_SPI_MOSI, PIN_MAGIC},
{20, 0, 0, 0},
{21, BCM_GPIO_PIN_9, RPI_SPI_MISO, PIN_MAGIC},
{22, BCM_GPIO_PIN_25, RPI_GPIO_GEN6, PIN_MAGIC},
{23, BCM_GPIO_PIN_11, RPI_SPI_SCLK, PIN_MAGIC},
{24, BCM_GPIO_PIN_8, RPI_SPI_CE0_N, PIN_MAGIC},
{25, 0, 0, 0},
{26, BCM_GPIO_PIN_7, RPI_SPI_CE1_N, PIN_MAGIC},
{27, BCM_GPIO_PIN_0, RPI_SDA0, PIN_MAGIC},
{28, BCM_GPIO_PIN_1, RPI_SCL0, PIN_MAGIC},
{29, BCM_GPIO_PIN_5, RPI_CAM_CLK, PIN_MAGIC},
{30, 0, 0, 0},
{31, BCM_GPIO_PIN_6, RPI_LAN_RUN, PIN_MAGIC},
{32, BCM_GPIO_PIN_12, 0, PIN_MAGIC},
{33, BCM_GPIO_PIN_13, 0, PIN_MAGIC},
{34, 0, 0, 0},
{35, BCM_GPIO_PIN_19, 0, PIN_MAGIC},
{36, BCM_GPIO_PIN_16, RPI_STATUS_LED_N, PIN_MAGIC},
{37, BCM_GPIO_PIN_26, 0, PIN_MAGIC},
{38, BCM_GPIO_PIN_20, 0, PIN_MAGIC},
{39, 0, 0, 0},
{40, BCM_GPIO_PIN_21, RPI_CAM_GPIO, PIN_MAGIC},
};
#ifdef BSP_USING_PIN
/*
* gpio_int[0] for BANK0 (pins 0-27)
* gpio_int[1] for BANK1 (pins 28-45)
......@@ -73,286 +19,262 @@ static struct rpi_pin_index phypin_index[] =
*/
static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_IRQ_NUM];
int gpio_set_func(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t func)
void gpio_set_pud(rt_uint8_t pin, rt_uint8_t pud)
{
RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
if (func & 0x8)
{
rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__);
return RT_EINVAL;
}
rt_uint8_t num = pin / 32;
rt_uint8_t shift = pin % 32;
BCM283X_GPIO_GPPUD = pud;
DELAY_MICROS(10);
BCM283X_GPIO_GPPUDCLK(num) = 1 << shift;
DELAY_MICROS(10);
BCM283X_GPIO_GPPUD = BCM283X_GPIO_PUD_OFF;
BCM283X_GPIO_GPPUDCLK(num) = 0 << shift;
}
switch(func)
{
case 0x00:
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP);
break;
case 0x01:
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x02:
bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x03:
bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN);
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x04:
bcm283x_gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF);
bcm283x_gpio_fsel(pin, BCM283X_GPIO_FSEL_OUTP);
break;
}
static void gpio_ack_irq(int irq, bcm_gpio_pin pin)
{
rt_uint32_t data;
data = IRQ_PEND2;
data &= (0x0 << (irq - 32));
IRQ_PEND2 = data;
return RT_EOK;
data = IRQ_DISABLE2;
data |= (0x1 << (irq - 32));
IRQ_DISABLE2 = data;
}
int gpio_set_value(enum gpio_code code, enum bcm_gpio_pin pin, rt_uint8_t value)
void gpio_irq_disable(rt_uint8_t index, bcm_gpio_pin pin)
{
int irq = 0;
rt_uint32_t reg_value;
rt_uint8_t irq_type;
irq = IRQ_GPIO0 + index;
RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
gpio_ack_irq(irq, pin);
irq_type = _g_gpio_irq_tbl[index].irq_type[pin];
rt_uint8_t shift = pin % 32;
rt_uint32_t mask = 1 << shift;
if (value & 0xE)
switch (irq_type)
{
rt_kprintf("[line]:%d There is a warning with parameter input", __LINE__);
return RT_EINVAL;
case PIN_IRQ_MODE_RISING:
reg_value = BCM283X_GPIO_GPREN(pin /32);
BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
break;
case PIN_IRQ_MODE_FALLING:
reg_value = BCM283X_GPIO_GPFEN(pin /32);
BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
break;
case PIN_IRQ_MODE_RISING_FALLING:
reg_value = BCM283X_GPIO_GPAREN(pin /32);
BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
reg_value = BCM283X_GPIO_GPAFEN(pin /32);
BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
break;
case PIN_IRQ_MODE_HIGH_LEVEL:
reg_value = BCM283X_GPIO_GPHEN(pin /32);
BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
break;
case PIN_IRQ_MODE_LOW_LEVEL:
reg_value = BCM283X_GPIO_GPLEN(pin /32);
BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_LOW & mask);
break;
}
bcm283x_gpio_write(pin, value);
return RT_EOK;
}
int gpio_get_value(enum gpio_code code, enum bcm_gpio_pin pin)
void gpio_irq_enable(rt_uint8_t index, bcm_gpio_pin pin)
{
rt_uint8_t data;
RT_ASSERT((GPIO_CODE_PHY <= code) && (code < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
rt_uint32_t offset;
rt_uint32_t data;
data = bcm283x_gpio_lev(pin);
return data;
}
offset = pin;
if (index == 0)
offset = IRQ_GPIO0 - 32;
else if (index == 1)
offset = IRQ_GPIO1 - 32;
else
offset = IRQ_GPIO2 - 32;
void gpio_set_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
{
RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
data = IRQ_ENABLE2;
data |= 0x1 << offset;
IRQ_ENABLE2 = data;
rt_uint8_t index;
if (pin <= 27)
{
index = 0;
}
else if (pin <= 45)
{
index = 1;
}
else{
index = 2;
}
_g_gpio_irq_tbl[index].irq_cb[pin] = irq_cb;
_g_gpio_irq_tbl[index].irq_arg[pin] = irq_arg;
}
void gpio_set_irq_type(enum gpio_code port, enum bcm_gpio_pin pin, rt_uint8_t irq_type)
static void raspi_pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
{
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
RT_ASSERT(!(mode & 0x8));
RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
rt_uint8_t index;
if (pin <= 27)
{
index = 0;
}
else if (pin <= 45)
switch (mode)
{
index = 1;
}
else{
index = 2;
}
_g_gpio_irq_tbl[index].irq_type[pin] = irq_type;
switch(irq_type)
{
case 0x00:
bcm283x_gpio_ren(pin);
case PIN_MODE_OUTPUT:
GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP);
break;
case 0x01:
bcm283x_gpio_fen(pin);
case PIN_MODE_INPUT:
GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x02:
bcm283x_gpio_aren(pin);
bcm283x_gpio_afen(pin);
case PIN_MODE_INPUT_PULLUP:
gpio_set_pud(pin, BCM283X_GPIO_PUD_UP);
GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x03:
bcm283x_gpio_hen(pin);
case PIN_MODE_INPUT_PULLDOWN:
gpio_set_pud(pin, BCM283X_GPIO_PUD_DOWN);
GPIO_FSEL(pin, BCM283X_GPIO_FSEL_INPT);
break;
case 0x04:
bcm283x_gpio_len(pin);
case PIN_MODE_OUTPUT_OD:
gpio_set_pud(pin, BCM283X_GPIO_PUD_OFF);
GPIO_FSEL(pin, BCM283X_GPIO_FSEL_OUTP);
break;
}
}
static void gpio_ack_irq(int irq, enum bcm_gpio_pin pin)
static void raspi_pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
rt_uint32_t data;
data = IRQ_PEND2;
data &= (0x0 << (irq - 32));
IRQ_PEND2 = data;
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
RT_ASSERT(!(value & 0xE));
if (value)
BCM283X_GPIO_GPSET(pin / 32) |= (1 << (pin %32));
else
BCM283X_GPIO_GPCLR(pin / 32) |= (0 << (pin %32));
data = IRQ_DISABLE2;
data |= (0x1 << (irq - 32));
IRQ_DISABLE2 = data;
}
void gpio_irq_disable(enum gpio_code port, enum bcm_gpio_pin pin)
static int raspi_pin_read(struct rt_device *device, rt_base_t pin)
{
rt_uint8_t index;
int irq = 0;
RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
return (BCM2835_GPIO_GPLEV(pin / 32) & (1 << (pin % 32)))? PIN_HIGH : PIN_LOW;
}
static rt_err_t raspi_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
rt_uint8_t index;
rt_uint32_t reg_value;
if (pin <= 27)
{
index = 0;
irq = IRQ_GPIO0;
}else if (pin <= 45){
else if (pin <= 45)
index = 1;
irq = IRQ_GPIO1;
}else{
else
index = 2;
irq = IRQ_GPIO2;
}
_g_gpio_irq_tbl[index].irq_cb[pin] = hdr;
_g_gpio_irq_tbl[index].irq_arg[pin] = args;
_g_gpio_irq_tbl[index].irq_type[pin] = mode;
gpio_ack_irq(irq, pin);
rt_uint8_t irq_type = _g_gpio_irq_tbl[index].irq_type[pin];
rt_uint8_t shift = pin % 32;
rt_uint32_t mask = 1 << shift;
switch(irq_type)
switch (mode)
{
case 0x00:
bcm283x_gpio_clr_ren(pin);
case PIN_IRQ_MODE_RISING:
reg_value = BCM283X_GPIO_GPREN(pin /32);
BCM283X_GPIO_GPREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
break;
case 0x01:
bcm283x_gpio_clr_fen(pin);
case PIN_IRQ_MODE_FALLING:
reg_value = BCM283X_GPIO_GPFEN(pin /32);
BCM283X_GPIO_GPFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
break;
case 0x02:
bcm283x_gpio_clr_aren(pin);
bcm283x_gpio_clr_afen(pin);
case PIN_IRQ_MODE_RISING_FALLING:
reg_value = BCM283X_GPIO_GPAREN(pin /32);
BCM283X_GPIO_GPAREN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
reg_value = BCM283X_GPIO_GPAFEN(pin /32);
BCM283X_GPIO_GPAFEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
break;
case 0x03:
bcm283x_gpio_clr_hen(pin);
case PIN_IRQ_MODE_HIGH_LEVEL:
reg_value = BCM283X_GPIO_GPHEN(pin /32);
BCM283X_GPIO_GPHEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
break;
case 0x04:
bcm283x_gpio_clr_len(pin);
case PIN_IRQ_MODE_LOW_LEVEL:
reg_value = BCM283X_GPIO_GPLEN(pin /32);
BCM283X_GPIO_GPLEN(pin /32) = (reg_value & ~ mask) | (PIN_HIGH & mask);
break;
}
return RT_EOK;
}
void gpio_clear_irq_callback(enum gpio_code port, enum bcm_gpio_pin pin)
static rt_err_t raspi_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
rt_uint8_t index;
gpio_irq_disable(port, pin);
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
rt_uint8_t index;
if (pin <= 27)
{
index = 0;
}
else if (pin <= 45)
{
index = 1;
}
else
{
index = 2;
}
gpio_irq_disable(index, pin);
_g_gpio_irq_tbl[index].irq_cb[pin] = RT_NULL;
_g_gpio_irq_tbl[index].irq_arg[pin] = RT_NULL;
_g_gpio_irq_tbl[index].irq_type[pin] = RT_NULL;
return RT_EOK;
}
void gpio_irq_enable(enum gpio_code port, enum bcm_gpio_pin pin)
rt_err_t raspi_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_NULL));
rt_uint32_t offset;
rt_uint32_t data;
RT_ASSERT((GPIO_CODE_PHY < port) && (port < GPIO_CODE_NUM));
RT_ASSERT((BCM_GPIO_PIN_0 <= pin) && (pin < BCM_GPIO_PIN_53));
offset = pin;
rt_uint8_t index;
if (pin <= 27)
{
offset = IRQ_GPIO0 - 32;
}
index = 0;
else if (pin <= 45)
{
offset = IRQ_GPIO1 - 32;
}
index = 1;
else
{
offset = IRQ_GPIO2 - 32;
}
index = 2;
data = IRQ_ENABLE2;
data |= 0x1 << offset;
IRQ_ENABLE2 = data;
if (enabled)
gpio_irq_enable(index, pin);
else
gpio_irq_disable(index, pin);
return RT_EOK;
}
//gpio_int[0] for BANK0 (pins 0-27)
//gpio_int[1] for BANK1 (pins 28-45)
//gpio_int[2] for BANK2 (pins 46-53)
static void gpio_irq_handler(int irq, void *param)
{
struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
rt_uint32_t pin;
rt_uint32_t addr;
rt_uint32_t value;
rt_uint32_t tmpvalue;
if (irq == IRQ_GPIO0)
{
/* 0~27 */
addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0; // 0~31
value = bcm283x_peri_read(addr);
value = BCM283X_GPIO_GPEDS(0);
value &= 0x0fffffff;
pin = 0;
BCM283X_GPIO_GPEDS(0) = 0;
}
else if (irq == IRQ_GPIO1)
{
/* 28-45 */
addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS0;
tmpvalue = bcm283x_peri_read(addr);
tmpvalue = BCM283X_GPIO_GPEDS(0);
tmpvalue &= (~0x0fffffff);
addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1;
value = bcm283x_peri_read(addr);
value = BCM283X_GPIO_GPEDS(1);
value &= 0x3fff;
value = (value<<4) | tmpvalue;
pin = 28;
BCM283X_GPIO_GPEDS(0) = 0;
BCM283X_GPIO_GPEDS(1) = 0;
}
else if (irq == IRQ_GPIO2)
{
/* 46-53 */
addr = BCM283X_GPIO_BASE + BCM283X_GPIO_GPEDS1;
value = bcm283x_peri_read(addr);
value = BCM283X_GPIO_GPEDS(1);
value &= (~0x3fff);
value &= 0xff600000;
pin = 46;
BCM283X_GPIO_GPEDS(1) = 0;
}
bcm283x_peri_write(addr,0);
while (value)
{
if ((value & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
......@@ -365,90 +287,14 @@ static void gpio_irq_handler(int irq, void *param)
}
}
static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_base_t mode)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return;
}
gpio_set_func(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode);
}
static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return;
}
gpio_set_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id, value);
}
static int pin_read(struct rt_device *device, rt_base_t pin)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return 0;
}
return gpio_get_value(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
}
static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return RT_ERROR;
}
gpio_set_irq_callback(GPIO_CODE_BCM , phypin_index[pin].bcm_id, hdr, args);
gpio_set_irq_type(GPIO_CODE_BCM, phypin_index[pin].bcm_id, mode);
return RT_EOK;
}
static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return RT_ERROR;
}
gpio_clear_irq_callback(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
return RT_EOK;
}
rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
{
if ((pin > PIN_NUM(phypin_index)) || (phypin_index[pin].magic != PIN_MAGIC))
{
rt_kprintf("pin:%d value wrongful", pin);
return RT_ERROR;
}
if (enabled)
gpio_irq_enable(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
else
gpio_irq_disable(GPIO_CODE_BCM, phypin_index[pin].bcm_id);
return RT_EOK;
}
static const struct rt_pin_ops ops =
{
pin_mode,
pin_write,
pin_read,
pin_attach_irq,
pin_detach_irq,
pin_irq_enable,
raspi_pin_mode,
raspi_pin_write,
raspi_pin_read,
raspi_pin_attach_irq,
raspi_pin_detach_irq,
raspi_pin_irq_enable,
};
#endif
......@@ -456,7 +302,6 @@ int rt_hw_gpio_init(void)
{
#ifdef BSP_USING_PIN
rt_device_pin_register("gpio", &ops, RT_NULL);
#endif
/* install ISR */
rt_hw_interrupt_install(IRQ_GPIO0, gpio_irq_handler, &_g_gpio_irq_tbl[0], "gpio0_irq");
......@@ -467,6 +312,7 @@ int rt_hw_gpio_init(void)
rt_hw_interrupt_install(IRQ_GPIO2, gpio_irq_handler, &_g_gpio_irq_tbl[2], "gpio2_irq");
rt_hw_interrupt_umask(IRQ_GPIO2);
#endif
return 0;
}
......
......@@ -11,19 +11,20 @@
#ifndef __DRV_GPIO_H__
#define __DRV_GPIO_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <rtdebug.h>
#include <rtdbg.h>
#include "interrupt.h"
#include "bcm283x.h"
#include "raspi.h"
#include "board.h"
#include "interrupt.h"
#define GPIO_IRQ_NUM 3
#define IRQ_GPIO0 49
#define IRQ_GPIO1 50
#define IRQ_GPIO2 51
#define IRQ_GPIO3 52
struct gpio_irq_def
{
void *irq_arg[32];
......
......@@ -8,58 +8,60 @@
* 2019-07-29 zdzn first version
*/
#include <rtthread.h>
#include <rtdevice.h>
#include "bcm283x.h"
#include "drv_timer.h"
#include <drivers/hwtimer.h>
#include "cp15.h"
#include "interrupt.h"
#include "raspi.h"
static void rt_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state)
#ifdef BSP_USING_SYSTIMER
static void raspi_systimer_init(rt_hwtimer_t *hwtimer, rt_uint32_t state)
{
if (state == 0)
hwtimer->ops->stop(hwtimer);
}
static rt_err_t rt_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
static rt_err_t raspi_systimer_start(rt_hwtimer_t *hwtimer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
{
rt_err_t result = RT_EOK;
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
int timer_id = timer->timer_id;
if (mode == HWTIMER_MODE_PERIOD)
timer->cnt = cnt;
else
timer->cnt = 0;
__DSB();
__sync_synchronize();
if (timer_id == 1)
{
rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_1);
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
STIMER_C1 = STIMER_CLO + cnt;
}
else if (timer_id == 3)
{
rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_3);
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
STIMER_C3 = STIMER_CLO + cnt;
}
else
result = -RT_ERROR;
__DSB();
__sync_synchronize();
return result;
}
static void rt_systimer_stop(rt_hwtimer_t *hwtimer)
static void raspi_systimer_stop(rt_hwtimer_t *hwtimer)
{
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
int timer_id = timer->timer_id;
if (timer_id == 1)
rt_hw_interrupt_mask(IRQ_SYSTIMER_MATCH_1);
rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_1);
else if (timer_id == 3)
rt_hw_interrupt_mask(IRQ_SYSTIMER_MATCH_3);
rt_hw_interrupt_mask(IRQ_SYSTEM_TIMER_3);
}
static rt_err_t rt_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
static rt_err_t raspi_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
{
/* The frequency value is an immutable value. */
if (cmd == HWTIMER_CTRL_FREQ_SET)
......@@ -72,23 +74,17 @@ static rt_err_t rt_systimer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg
}
}
const static struct rt_hwtimer_ops systimer_ops =
{
rt_systimer_init,
rt_systimer_start,
rt_systimer_stop,
RT_NULL,
rt_systimer_ctrl
};
void rt_device_systimer_isr(int vector, void *param)
{
rt_hwtimer_t *hwtimer = (rt_hwtimer_t *) param;
rt_systimer_t *timer = (rt_systimer_t *)hwtimer->parent.user_data;
RT_ASSERT(timer != RT_NULL);
int timer_id = timer->timer_id;
__DSB();
__sync_synchronize();
if (timer_id == 1)
{
STIMER_CS = 0x2;
......@@ -99,15 +95,29 @@ void rt_device_systimer_isr(int vector, void *param)
STIMER_CS = 0x8;
STIMER_C3 = STIMER_CLO + timer->cnt;
}
__DSB();
__sync_synchronize();
rt_device_hwtimer_isr(hwtimer);
}
#ifdef RT_USING_SYSTIMER1
static struct rt_hwtimer_device _hwtimer1;
static rt_systimer_t _systimer1;
#endif
#ifdef RT_USING_SYSTIMER3
static struct rt_hwtimer_device _hwtimer3;
static struct rt_systimer_device _systimer1;
static struct rt_systimer_device _systimer3;
static rt_systimer_t _systimer3;
#endif
const static struct rt_hwtimer_ops systimer_ops =
{
raspi_systimer_init,
raspi_systimer_start,
raspi_systimer_stop,
RT_NULL,
raspi_systimer_ctrl
};
static const struct rt_hwtimer_info _info =
{
......@@ -117,15 +127,20 @@ static const struct rt_hwtimer_info _info =
HWTIMER_CNTMODE_UP /* count mode (inc/dec) */
};
#endif
int rt_hw_systimer_init(void)
{
#ifdef BSP_USING_SYSTIMER
#ifdef RT_USING_SYSTIMER1
_systimer1.timer_id =1;
_hwtimer1.ops = &systimer_ops;
_hwtimer1.info = &_info;
rt_device_hwtimer_register(&_hwtimer1, "timer1",&_systimer1);
rt_hw_interrupt_install(IRQ_SYSTIMER_MATCH_1, rt_device_systimer_isr, &_hwtimer1, "systimer1");
rt_hw_interrupt_umask(IRQ_SYSTIMER_MATCH_1);
rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_1, rt_device_systimer_isr, &_hwtimer1, "systimer1");
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_1);
#endif
#ifdef RT_USING_SYSTIMER3
......@@ -133,9 +148,12 @@ int rt_hw_systimer_init(void)
_hwtimer3.ops = &systimer_ops;
_hwtimer3.info = &_info;
rt_device_hwtimer_register(&_hwtimer3, "timer3",&_systimer3);
rt_hw_interrupt_install(IRQ_SYSTIMER_MATCH_3, rt_device_systimer_isr, &_hwtimer3, "systimer3");
rt_hw_interrupt_install(IRQ_SYSTEM_TIMER_3, rt_device_systimer_isr, &_hwtimer3, "systimer3");
rt_hw_interrupt_umask(IRQ_SYSTEM_TIMER_3);
#endif
#endif
return 0;
}
INIT_DEVICE_EXPORT(rt_hw_systimer_init);
......@@ -12,11 +12,10 @@
#include <rtthread.h>
#include <rtdevice.h>
#include "raspi.h"
#include "board.h"
#include "drv_uart.h"
#include <rtdevice.h>
#define AUX_BASE (0x3F000000 + 0x215000)
struct hw_uart_device
......@@ -34,20 +33,19 @@ static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_co
if (uart->hw_base == AUX_BASE)
{
rt_uint32_t value;
rt_uint32_t value;
/* GPIO function set */
value = GPIO_GPFSEL1;
value &= ~(7<<12); /* GPIO14 */
value |= 2<<12 ; /* ALT5 */
value &= ~(7<<15); /* GPIO15 */
value |= 2<<15 ; /* ALT5 */
GPIO_GPFSEL1 = value;
/* PullUD disable */
GPIO_GPPUD = 0;
GPIO_GPPUDCLK0 = (1 << 14) | (1 << 15);
GPIO_GPPUDCLK0 = 0;
value = BCM283X_GPIO_GPFSEL(1);
value &= ~(7 << 12); /* GPIO14 */
value |= 2 << 12 ; /* ALT5 */
value &= ~(7 << 15); /* GPIO15 */
value |= 2 << 15 ; /* ALT5 */
BCM283X_GPIO_GPFSEL(1) = value;
BCM283X_GPIO_GPPUD = 0;
BCM283X_GPIO_GPPUDCLK(0) = (1 << 14) | (1 << 15);
BCM283X_GPIO_GPPUDCLK(0) = 0;
AUX_ENABLES(uart->hw_base) = 1; /* Enable UART1 */
AUX_MU_IER_REG(uart->hw_base) = 0; /* Disable interrupt */
......
......@@ -101,6 +101,7 @@
#define RT_PIPE_BUFSZ 512
#define RT_USING_SERIAL
#define RT_SERIAL_RB_BUFSZ 64
#define RT_USING_HWTIMER
#define RT_USING_PIN
#define RT_USING_SDIO
#define RT_SDIO_STACK_SIZE 2048
......@@ -193,6 +194,8 @@
#define RT_USING_UART1
#define BSP_USING_PIN
#define BSP_USING_CORETIMER
#define BSP_USING_SYSTIMER
#define RT_USING_SYSTIMER1
#define BSP_USING_SDIO
#define BSP_USING_SDIO0
......
......@@ -11,7 +11,6 @@
#ifndef __CP15_H__
#define __CP15_H__
#include "bcm283x.h"
#ifndef __STATIC_FORCEINLINE
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
#endif
......
......@@ -12,12 +12,12 @@
*/
#include <rthw.h>
#include <board.h>
#include <rtthread.h>
#include "cp15.h"
#include "armv8.h"
#include <board.h>
#include "interrupt.h"
#define MAX_HANDLERS 72
......
......@@ -14,6 +14,8 @@
#include <rthw.h>
#include <board.h>
#include "raspi.h"
#define INT_IRQ 0x00
#define INT_FIQ 0x01
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册