build: W600-SDK importiert, Firmware-Build und Hello am EVK
Docker-Build mit gcc-arm-none-eabi 4.9-2014q4 (statt Homebrew-Cask) verwendet, Dockerfile/tools/docker.sh dafür aus Task 13 vorgezogen. cmake/sdk.cmake schont gcc 4.9 (kennt -fcommon/-Wno-error=... nicht). Zwei zusätzliche SDK-Stubs (EarlyInit, pre_gpio_config) in src/sys/sdk_stubs.c ergänzt, siehe sdk/PATCHES.md.
This commit is contained in:
@@ -0,0 +1,411 @@
|
||||
/**
|
||||
* @file wm_gpio.c
|
||||
*
|
||||
* @brief GPIO Driver Module
|
||||
*
|
||||
* @author dave
|
||||
*
|
||||
* Copyright (c) 2014 Winner Microelectronics Co., Ltd.
|
||||
*/
|
||||
#include "wm_gpio.h"
|
||||
#include "wm_regs.h"
|
||||
#include "wm_irq.h"
|
||||
#include "wm_osal.h"
|
||||
#include "tls_common.h"
|
||||
|
||||
struct gpio_irq_context{
|
||||
tls_gpio_irq_callback callback;
|
||||
void *arg;
|
||||
};
|
||||
|
||||
|
||||
static struct gpio_irq_context gpio_context[WM_IO_PB_30 - WM_IO_PA_00 + 1] = {{0,0}};
|
||||
|
||||
|
||||
void GPIOA_IRQHandler(void)
|
||||
{
|
||||
u8 i = 0;
|
||||
u8 found = 0;
|
||||
u32 reg = 0;
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_MIS);
|
||||
|
||||
for (i = 0; i <= WM_IO_PA_15; i++)
|
||||
{
|
||||
if (reg & BIT(i))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (NULL != gpio_context[i].callback)
|
||||
gpio_context[i].callback(gpio_context[i].arg);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void GPIOB_IRQHandler(void)
|
||||
{
|
||||
u8 i = 0;
|
||||
u8 found = 0;
|
||||
u32 reg = 0;
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_MIS + TLS_IO_AB_OFFSET);
|
||||
|
||||
|
||||
for (i = WM_IO_PB_00; i <= WM_IO_PB_31; i++)
|
||||
{
|
||||
if (reg & BIT(i - WM_IO_PB_00))
|
||||
{
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found)
|
||||
{
|
||||
if (NULL != gpio_context[i].callback)
|
||||
gpio_context[i].callback(gpio_context[i].arg);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to config gpio function
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
* @param[in] dir gpio direction
|
||||
* @param[in] attr gpio attribute
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note
|
||||
* All gpio's attribute can only be set as WM_GPIO_ATTR_FLOATING or WM_GPIO_ATTR_PULLHIGH on W600/W60X.
|
||||
*/
|
||||
void tls_gpio_cfg(enum tls_io_name gpio_pin, enum tls_gpio_dir dir, enum tls_gpio_attr attr)
|
||||
{
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
/* enable gpio function */
|
||||
tls_io_cfg_set(gpio_pin, WM_IO_OPT5_GPIO);
|
||||
|
||||
/* gpio direction */
|
||||
if (WM_GPIO_DIR_OUTPUT == dir)
|
||||
{
|
||||
tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) | BIT(pin)); /* 1 set output */
|
||||
}
|
||||
else if (WM_GPIO_DIR_INPUT == dir)
|
||||
{
|
||||
tls_reg_write32(HR_GPIO_DIR + offset, tls_reg_read32(HR_GPIO_DIR + offset) & (~BIT(pin))); /* 0 set input */
|
||||
}
|
||||
|
||||
/* gpio pull attribute */
|
||||
if (WM_GPIO_ATTR_FLOATING == attr)
|
||||
{
|
||||
tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) | BIT(pin)); /* 1 disable pull */
|
||||
}
|
||||
else if (WM_GPIO_ATTR_PULLHIGH == attr)
|
||||
{
|
||||
tls_reg_write32(HR_GPIO_PULL_EN + offset, tls_reg_read32(HR_GPIO_PULL_EN + offset) & (~BIT(pin))); /* 0 enable pull */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to read gpio status
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
*
|
||||
* @retval 0 low level
|
||||
* @retval 1 high level
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
u8 tls_gpio_read(enum tls_io_name gpio_pin)
|
||||
{
|
||||
u32 reg_en;
|
||||
u32 reg;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
|
||||
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
|
||||
reg = tls_reg_read32(HR_GPIO_DATA + offset);
|
||||
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
|
||||
if(reg & (0x1 << pin))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to modify gpio status
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
* @param[in] value power level
|
||||
* 0: low level
|
||||
* 1: high level
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_gpio_write(enum tls_io_name gpio_pin, u8 value)
|
||||
{
|
||||
u32 cpu_sr = 0;
|
||||
u32 reg;
|
||||
u32 reg_en;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
|
||||
cpu_sr = tls_os_set_critical();
|
||||
|
||||
reg_en = tls_reg_read32(HR_GPIO_DATA_EN + offset);
|
||||
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en | (1 << pin));
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_DATA + offset);
|
||||
if(value)
|
||||
tls_reg_write32(HR_GPIO_DATA + offset, reg | (1 << pin)); /* write high */
|
||||
else
|
||||
tls_reg_write32(HR_GPIO_DATA + offset, reg & (~(1 << pin)));/* write low */
|
||||
|
||||
tls_reg_write32(HR_GPIO_DATA_EN + offset, reg_en);
|
||||
|
||||
tls_os_release_critical(cpu_sr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to config gpio interrupt
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
* @param[in] mode interrupt trigger type
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_gpio_irq_enable(enum tls_io_name gpio_pin, enum tls_gpio_irq_trig mode)
|
||||
{
|
||||
u32 reg;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
u8 vec_no;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
vec_no = GPIOB_INT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
vec_no = GPIO_INT;
|
||||
}
|
||||
switch(mode)
|
||||
{
|
||||
case WM_GPIO_IRQ_TRIG_RISING_EDGE:
|
||||
reg = tls_reg_read32(HR_GPIO_IS + offset);
|
||||
reg &= (~(0x1 << pin));
|
||||
tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IBE + offset);
|
||||
reg &= (~(0x1 << pin));
|
||||
tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IEV + offset);
|
||||
reg |= (0x1 << pin);
|
||||
tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 1 rising edge trigger */
|
||||
break;
|
||||
case WM_GPIO_IRQ_TRIG_FALLING_EDGE:
|
||||
reg = tls_reg_read32(HR_GPIO_IS + offset);
|
||||
reg &= (~(0x1 << pin));
|
||||
tls_reg_write32(HR_GPIO_IS + offset, reg); /* 0 edge trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IBE + offset);
|
||||
reg &= (~(0x1 << pin));
|
||||
tls_reg_write32(HR_GPIO_IBE + offset, reg); /* 0 edge trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IEV + offset);
|
||||
reg &= (~(0x1 << pin));
|
||||
tls_reg_write32(HR_GPIO_IEV + offset, reg); /* 0 falling edge trigger */
|
||||
break;
|
||||
case WM_GPIO_IRQ_TRIG_DOUBLE_EDGE:
|
||||
reg = tls_reg_read32(HR_GPIO_IS + offset);
|
||||
tls_reg_write32(HR_GPIO_IS + offset, reg & (~(0x1 << pin))); /* 0 edge trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IBE + offset);
|
||||
tls_reg_write32(HR_GPIO_IBE + offset, reg | (0x1 << pin)); /* 1 double edge trigger */
|
||||
break;
|
||||
case WM_GPIO_IRQ_TRIG_HIGH_LEVEL:
|
||||
reg = tls_reg_read32(HR_GPIO_IS + offset);
|
||||
tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IEV + offset);
|
||||
tls_reg_write32(HR_GPIO_IEV + offset, reg | (0x1 << pin)); /* 1 high level trigger */
|
||||
break;
|
||||
case WM_GPIO_IRQ_TRIG_LOW_LEVEL:
|
||||
reg = tls_reg_read32(HR_GPIO_IS + offset);
|
||||
tls_reg_write32(HR_GPIO_IS + offset, reg | (0x1 << pin)); /* 1 level trigger */
|
||||
reg = tls_reg_read32(HR_GPIO_IEV + offset);
|
||||
tls_reg_write32(HR_GPIO_IEV + offset, reg & (~(0x1 << pin))); /* 0 low level trigger */
|
||||
break;
|
||||
}
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_IE + offset);
|
||||
reg |= (0x1 << pin);
|
||||
tls_reg_write32(HR_GPIO_IE + offset, reg); /* enable interrupt */
|
||||
tls_irq_enable(vec_no);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to disable gpio interrupt
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_gpio_irq_disable(enum tls_io_name gpio_pin)
|
||||
{
|
||||
u32 reg;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_IE + offset);
|
||||
tls_reg_write32(HR_GPIO_IE + offset, reg & (~(0x1 << pin))); /* disable interrupt */
|
||||
tls_irq_disable(GPIO_INT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to get gpio interrupt status
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
*
|
||||
* @retval 0 no interrupt happened
|
||||
* @retval 1 interrupt happened
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
u8 tls_get_gpio_irq_status(enum tls_io_name gpio_pin)
|
||||
{
|
||||
u32 reg;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_RIS + offset);
|
||||
if(reg & (0x1 << pin))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to clear gpio interrupt flag
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*/
|
||||
void tls_clr_gpio_irq_status(enum tls_io_name gpio_pin)
|
||||
{
|
||||
u32 reg;
|
||||
u8 pin;
|
||||
u16 offset;
|
||||
|
||||
if (gpio_pin >= WM_IO_PB_00)
|
||||
{
|
||||
pin = gpio_pin - WM_IO_PB_00;
|
||||
offset = TLS_IO_AB_OFFSET;
|
||||
}
|
||||
else
|
||||
{
|
||||
pin = gpio_pin;
|
||||
offset = 0;
|
||||
}
|
||||
|
||||
reg = tls_reg_read32(HR_GPIO_IC + offset);
|
||||
tls_reg_write32(HR_GPIO_IC + offset, reg | (0x1 << pin)); /* 1 clear interrupt status */
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief This function is used to register gpio interrupt
|
||||
*
|
||||
* @param[in] gpio_pin gpio pin num
|
||||
* @param[in] callback the gpio interrupt call back function
|
||||
* @param[in] arg parammeter for the callback
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note
|
||||
* gpio callback function is called in interrupt,
|
||||
* so can not operate the critical data in the callback fuuction,
|
||||
* recommendation to send messages to other tasks to operate it.
|
||||
*/
|
||||
void tls_gpio_isr_register(enum tls_io_name gpio_pin,
|
||||
tls_gpio_irq_callback callback,
|
||||
void *arg)
|
||||
{
|
||||
gpio_context[gpio_pin].callback = callback;
|
||||
gpio_context[gpio_pin].arg = arg;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user