Files
kunlun/driver/src/hw3/gpio_mtx.c

287 lines
8.6 KiB
C

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics Ltd. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
/* os shim includes */
#include "os_types.h"
#include "gpio_mtx.h"
#include "hw_reg_api.h"
#include "gpio_mtx_reg.h"
#include "pin_rf.h"
#include "gpio_mtx_hw.h"
#include "apb.h"
#include "iot_config.h"
#define GPIO_MTX_CHECK(a) \
if (!(a)) { \
return; \
}
#define GPIO_SEC_OFFSET GPIO02_SEC_OFFSET
#define GPIO_SEC_MASK GPIO02_SEC_MASK
#define GPIO_ODRV_OFFSET GPIO02_ODRV_OFFSET
#define GPIO_ODRV_MASK GPIO02_ODRV_MASK
#define GPIO_IINV_OFFSET GPIO02_IINV_OFFSET
#define GPIO_IINV_MASK GPIO02_IINV_MASK
#define GPIO_OINV_OFFSET GPIO02_OINV_OFFSET
#define GPIO_OINV_MASK GPIO02_OINV_MASK
#define GPIO_OPOS_OFFSET GPIO02_OPOS_OFFSET
#define GPIO_OPOS_MASK GPIO02_OPOS_MASK
#define GPIO_ONEG_OFFSET GPIO02_ONEG_OFFSET
#define GPIO_ONEG_MASK GPIO02_ONEG_MASK
#define GPIO_IPOS_OFFSET GPIO02_IPOS_OFFSET
#define GPIO_IPOS_MASK GPIO02_IPOS_MASK
#define GPIO_INEG_OFFSET GPIO02_INEG_OFFSET
#define GPIO_INEG_MASK GPIO02_INEG_MASK
#define GPIO_ORE_OFFSET GPIO02_ORE_OFFSET
#define GPIO_ORE_MASK GPIO02_ORE_MASK
#define GPIO_IRE_OFFSET GPIO02_IRE_OFFSET
#define GPIO_IRE_MASK GPIO02_IRE_MASK
#define GPIO_FUNC_SEL_OFFSET GPIO02_FUNC_SEL_OFFSET
#define GPIO_FUNC_SEL_MASK GPIO02_FUNC_SEL_MASK
#define GPIO_FUNC_WPD_OFFSET GPIO02_FUNC_WPD_OFFSET
#define GPIO_FUNC_WPD_MASK GPIO02_FUNC_WPD_MASK
#define GPIO_FUNC_WPU_OFFSET GPIO02_FUNC_WPU_OFFSET
#define GPIO_FUNC_WPU_MASK GPIO02_FUNC_WPU_MASK
#define SIG_IN_CORE_SEL_OFFSET SIG1_IN_CORE_SEL_OFFSET
#define SIG_IN_CORE_SEL_MASK SIG1_IN_CORE_SEL_MASK
#define SIG_IN_DEF_SEL_OFFSET SIG1_IN_DEF_SEL_OFFSET
#define SIG_IN_DEF_SEL_MASK SIG1_IN_DEF_SEL_MASK
#define SIG_IN_GPIO_SEL_OFFSET SIG1_IN_GPIO_SEL_OFFSET
#define SIG_IN_GPIO_SEL_MASK SIG1_IN_GPIO_SEL_MASK
#define GPIO_OUT_SEL_OFFSET GPIO0_OUT_SEL_OFFSET
#define GPIO_OUT_SEL_MASK GPIO0_OUT_SEL_MASK
#define SIG_IN_REG0 CFG_SIG0_IN_CFG_ADDR
#define SIG_IN_REG(n) (SIG_IN_REG0 + n * 4)
#define SIG_OUT_REG0 CFG_GPIO0_OUT_CFG_ADDR
#define SIG_OUT_REG(n) (SIG_OUT_REG0 + n * 4)
#define PIN_RF_READ_REG DIG_PIN_READ_REG
#define PIN_RF_WRITE_REG DIG_PIN_WRITE_REG
#define PIN_GET_OFFSET(num) ((num+1) * 4)
void IRAM_ATTR gpio_pin_wpu(uint32_t pin, uint32_t val)
{
uint32_t tmp;
uint32_t offset;
GPIO_MTX_CHECK(( pin < GPIO_PIN_COUNT));
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
REG_FIELD_SET(GPIO_FUNC_WPU, tmp, val);
PIN_RF_WRITE_REG(offset, tmp);
}
void IRAM_ATTR gpio_pin_wpd(uint32_t pin, uint32_t val)
{
uint32_t tmp;
uint32_t offset;
GPIO_MTX_CHECK(( pin < GPIO_PIN_COUNT));
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
REG_FIELD_SET(GPIO_FUNC_WPD, tmp, val);
PIN_RF_WRITE_REG(offset, tmp);
}
void gpio_pin_iinv(uint32_t pin, uint32_t val)
{
uint32_t tmp;
uint32_t offset;
GPIO_MTX_CHECK(( pin < GPIO_PIN_COUNT));
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
REG_FIELD_SET(GPIO_IINV, tmp, val);
PIN_RF_WRITE_REG(offset, tmp);
}
void gpio_pin_oinv(uint32_t pin, uint32_t val)
{
uint32_t tmp;
uint32_t offset;
GPIO_MTX_CHECK(( pin < GPIO_PIN_COUNT));
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
REG_FIELD_SET(GPIO_OINV, tmp, val);
PIN_RF_WRITE_REG(offset, tmp);
}
static_printf_def(0x10001b9e)
void gpio_pin_select(uint32_t pin , uint32_t func)
{
uint32_t tmp;
uint32_t offset;
GPIO_MTX_CHECK(( pin < GPIO_PIN_COUNT));
GPIO_MTX_CHECK(( func < PIN_FUNC_SEL_COUNT));
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
REG_FIELD_SET(GPIO_FUNC_SEL, tmp, func);
PIN_RF_WRITE_REG(offset , tmp);
sbl_printf("gpio pin=%d , fun=%d\n" , pin , func);
}
uint8_t gpio_pin_get_select(uint32_t pin)
{
uint32_t tmp;
uint32_t offset;
if (pin >= GPIO_PIN_COUNT) {
return 0xFF;
}
offset = PIN_GET_OFFSET(pin);
tmp = PIN_RF_READ_REG(offset);
return (uint8_t)REG_FIELD_GET(GPIO_FUNC_SEL, tmp);
}
uint8_t gpio_pin_func_get(uint32_t gpio)
{
return 0;
}
void IRAM_ATTR gpio_mtx_sig_in_set_core(uint32_t offset, uint32_t val)
{
uint32_t tmp;
GPIO_MTX_CHECK((val == GPIO_MTX_MODE_CORE) ||
(val == GPIO_MTX_MODE_MATRIX));
tmp = GPIO_MTX_READ_REG(offset);
REG_FIELD_SET(SIG_IN_CORE_SEL, tmp, val);
GPIO_MTX_WRITE_REG(offset, tmp);
}
void IRAM_ATTR gpio_mtx_sig_in_set_def(uint32_t offset, uint32_t val)
{
uint32_t tmp;
tmp = GPIO_MTX_READ_REG(offset);
REG_FIELD_SET(SIG_IN_DEF_SEL, tmp, val);
GPIO_MTX_WRITE_REG(offset, tmp);
}
void IRAM_ATTR gpio_mtx_sig_in_set_gpio(uint32_t offset, uint32_t val)
{
uint32_t tmp;
GPIO_MTX_CHECK((val < GPIO_PIN_COUNT));
tmp = GPIO_MTX_READ_REG(offset);
REG_FIELD_SET(SIG_IN_GPIO_SEL, tmp, val);
GPIO_MTX_WRITE_REG(offset, tmp);
}
uint8_t IRAM_ATTR gpio_mtx_sig_in_get_gpio(uint8_t sig_id)
{
uint32_t sig_addr;
uint32_t rd_gpio;
sig_addr = SIG_IN_REG(sig_id);
rd_gpio = GPIO_MTX_READ_REG(sig_addr);
return (uint8_t)REG_FIELD_GET(SIG_IN_GPIO_SEL, rd_gpio);
}
void IRAM_ATTR gpio_mtx_sig_out_set_sel(uint32_t offset, uint32_t val)
{
uint32_t tmp;
tmp = GPIO_MTX_READ_REG(offset);
REG_FIELD_SET(GPIO_OUT_SEL, tmp, val);
GPIO_MTX_WRITE_REG(offset, tmp);
}
void IRAM_ATTR gpio_mtx_sig_in(uint8_t id, uint8_t gpio, uint32_t mode)
{
uint32_t offset;
GPIO_MTX_CHECK((id < SIG_IN_COUNT));
GPIO_MTX_CHECK((gpio < GPIO_PIN_COUNT));
GPIO_MTX_CHECK( mode <= GPIO_MTX_MODE_MAX);
offset = SIG_IN_REG(id);
if (GPIO_MTX_MODE_CORE == mode) {
gpio_mtx_sig_in_set_core(offset, 1);
gpio_mtx_sig_in_set_def(offset, 0);
gpio_mtx_sig_in_set_gpio(offset, 0);
} else if (GPIO_MTX_MODE_MATRIX == mode) {
gpio_mtx_sig_in_set_core(offset, 0);
gpio_mtx_sig_in_set_def(offset, 0);
gpio_mtx_sig_in_set_gpio(offset, gpio);
}
}
void IRAM_ATTR gpio_mtx_sig_in_default(uint8_t id)
{
uint32_t offset;
offset = SIG_IN_REG(id);
gpio_mtx_sig_in_set_core(offset, 0);
gpio_mtx_sig_in_set_def(offset, 2);
}
void IRAM_ATTR gpio_mtx_sig_out(uint8_t id, uint8_t gpio)
{
uint32_t offset;
GPIO_MTX_CHECK((id < SIG_OUT_COUNT));
GPIO_MTX_CHECK((gpio < GPIO_PIN_COUNT));
offset = SIG_OUT_REG(gpio);
gpio_mtx_sig_out_set_sel(offset, id);
}
void IRAM_ATTR gpio_mtx_sig_out_default(uint8_t id, uint8_t gpio)
{
uint32_t offset;
GPIO_MTX_CHECK((gpio < GPIO_PIN_COUNT));
offset = SIG_OUT_REG(gpio);
gpio_mtx_sig_out_set_sel(offset, id);
}
void gpio_mtx_enable()
{
apb_enable(APB_GMTX);
}
void gpio_module_pin_select(gpio_sig_info_t *info)
{
int i = 0;
GPIO_MTX_CHECK(info->sig_type <= DEV_PIN_MAX);
for (i = 0; i < info->sig_type; i++) {
gpio_pin_select(info->CFG[i].gpio, info->CFG[i].func);
}
}
void gpio_module_sig_select(gpio_sig_info_t *info, uint32_t mode)
{
int i = 0;
uint8_t gpio = 0;
uint8_t inid = 0;
uint8_t outid = 0;
GPIO_MTX_CHECK(info->sig_type <= DEV_PIN_MAX);
GPIO_MTX_CHECK( mode <= GPIO_MTX_MODE_MAX);
for (i = 0; i < info->sig_type; i++) {
gpio = info->CFG[i].gpio;
inid = info->CFG[i].inid;
outid = info->CFG[i].outid;
switch(info->CFG[i].type) {
case IO_TYPE_IN: /* set sig in */
gpio_mtx_sig_in(inid, gpio, mode);
break;
case IO_TYPE_OUT: /* set sig out */
gpio_mtx_sig_out(outid, gpio);
break;
case IO_TYPE_IO: /* set sig in out */
gpio_mtx_sig_in(inid, gpio, mode);
gpio_mtx_sig_out(outid, gpio);
break;
default: break;
}
}
}