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

299 lines
9.5 KiB
C
Raw Normal View History

2024-09-28 14:24:04 +08:00
/****************************************************************************
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"
2024-09-28 14:24:04 +08:00
#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);
}
// val 为1时启用输入反转
void gpio_pin_iinv(uint32_t pin , uint32_t val)
2024-09-28 14:24:04 +08:00
{
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);
}
// val 为1时启用输出反转
2024-09-28 14:24:04 +08:00
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);
}
void gpio_pin_select(uint32_t pin , uint32_t func)
2024-09-28 14:24:04 +08:00
{
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);
2024-09-28 14:24:04 +08:00
}
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;
}
2025-04-12 17:17:49 +08:00
// 配置gpio输入的时候如果有gpio的func选通了这个外设则这个外设可以选择接收mtx的信号还是gpio的信号
// 指定外设输入连接的通路0通过矩阵连接1直连到gpio对于有func的那一路起作用
// offset要操作的寄存器偏移地址 val值
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// mtx sig信号到外设的输入源0通过mtx进来1常为02常为13通过mtx反向
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// mtx 信号来自哪个gpioval gpio序号
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// 找到指定信号连接的gpio序号
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// 指定gpio输出到哪个mtx sig上为255时使用gpio软控
// offset 寄存器偏移地址, val mtx sig信号id
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// 为mtx sig id绑定gpio输入是sig绑定gpio输出是gpio绑sig
2024-09-28 14:24:04 +08:00
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);
}
2025-04-12 17:17:49 +08:00
// 外设要通过mtx输出信号到gpiogpio的func必须设置为0并且id不为255
// 如果id为255则连接到gpio控制
2024-09-28 14:24:04 +08:00
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);
}
}
2025-04-12 17:17:49 +08:00
// 选择gpio到外设的信号通路mode为0时通过func连接mode为1时通过mtx连接
void gpio_module_sig_select(gpio_sig_info_t* info, uint32_t mode)
2024-09-28 14:24:04 +08:00
{
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;
}
}
}