Files
kunlun/app/chaokongbao/app_dev_drv/mcp_io_drv.c
2024-09-28 14:24:04 +08:00

284 lines
6.5 KiB
C

/****************************************************************************
*
* Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. 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.
*
* ****************************************************************************/
#include "iot_errno.h"
#include "iot_app_api.h"
#include "iot_i2c_api.h"
#include "mcp_io_drv.h"
#include "iot_io_api.h"
#include "os_utils_api.h"
#include "iot_gpio_api.h"
iot_i2c_module_cfg_t g_cfg;
static uint32_t mcp_write_command(uint8_t reg, uint8_t val)
{
uint8_t ret;
char buf[3];
buf[0] = reg;
buf[1] = val;
ret = iot_i2c_write(g_cfg.port, MCP_SLAVER_ADDR, buf, 2);
os_delay(100);
//iot_cus_printf("\nMCP : WRITE REG#%02x, DATA#%02x", 0xFF & ((int)reg), 0xFF & ((int)val));
return (ERR_OK == ret) ? ERR_OK : ERR_FAIL;
}
uint32_t mcp_read_command(uint8_t reg, uint8_t *data, uint8_t len)
{
uint8_t ret;
char buf[3];
buf[0] = reg;
ret = iot_i2c_write(g_cfg.port, MCP_SLAVER_ADDR, buf, 1);
os_delay(10);
if (ERR_OK != ret) {
return ERR_FAIL;
}
ret = iot_i2c_read(g_cfg.port, MCP_SLAVER_ADDR, (char *)data, len);
os_delay(100);
if (ERR_OK != ret) {
iot_cus_printf("\nMCP : READ REG#%02x , TIMEOUT", 0xFF & ((int)reg));
return ERR_FAIL;
}
// iot_cus_printf("\nMCP : READ REG#%02x, DATA#%02x", 0xFF & ((int)reg), 0xFF & ((int)*data));
return ERR_OK;
}
uint32_t mcp_gpio_get_value(uint32_t gpio)
{
uint32_t ret;
uint8_t data;
if (!MCP_GPIO_VALID(gpio)) {
return ERR_FAIL;
}
ret = mcp_read_command(GPIO(gpio), &data, 1);
if (ERR_OK != ret) {
return ERR_FAIL;
}
return MCP_IO_GET(data, gpio);
}
uint32_t mcp_gpio_set_value(uint32_t gpio, uint32_t val)
{
uint32_t ret;
uint8_t data;
if (!MCP_GPIO_VALID(gpio)) {
return ERR_FAIL;
}
ret = mcp_read_command(GPIO(gpio), &data, 1);
if (ERR_OK != ret) {
return ERR_FAIL;
}
if (0 == val) {
MCP_IO_CLEAR(data, gpio);
} else {
MCP_IO_SET(data, gpio);
}
ret = mcp_write_command(GPIO(gpio), data);
if (ERR_OK != ret) {
return ERR_FAIL;
}
return ERR_OK;
}
uint32_t mcp_gpio_set_dir(uint32_t gpio, uint32_t dir)
{
uint32_t ret;
uint8_t data;
if (!MCP_GPIO_VALID(gpio)) {
return ERR_FAIL;
}
ret = mcp_read_command(IODIR(gpio), &data, 1);
if (ERR_OK != ret) {
return ERR_FAIL;
}
if (MCP_GPIO_INPUT == dir) {
MCP_IO_SET(data, gpio);
} else {
MCP_IO_CLEAR(data, gpio);
}
ret = mcp_write_command(IODIR(gpio), data);
if (ERR_OK != ret) {
return ERR_FAIL;
}
return ERR_OK;
}
uint32_t mcp_gpio_set_interrupt(uint32_t gpio, uint32_t enable, uint32_t mode)
{
uint32_t ret;
uint8_t gpinten, defval, intcon;
if ((!MCP_GPIO_VALID(gpio)
|| (enable && (MCP_GPIO_RAISING != mode) && (MCP_GPIO_FALLING != mode)
&& (MCP_GPIO_BOTH_EDGE != mode)))) {
return ERR_FAIL;
}
ret = mcp_read_command(GPINTEN(gpio), &gpinten, 1);
if (enable) {
ret |= mcp_read_command(DEFVAL(gpio), &defval, 1);
ret |= mcp_read_command(INTCON(gpio), &intcon, 1);
}
if (ERR_OK != ret) {
return ERR_FAIL;
}
if (enable) {
MCP_IO_SET(gpinten, gpio);
if (MCP_GPIO_RAISING == mode) {
MCP_IO_SET(intcon, gpio);
MCP_IO_CLEAR(defval, gpio);
} else if (MCP_GPIO_FALLING == mode) {
MCP_IO_SET(intcon, gpio);
MCP_IO_SET(defval, gpio);
} else {
MCP_IO_CLEAR(intcon, gpio);
}
ret = mcp_write_command(DEFVAL(gpio), defval);
ret |= mcp_write_command(INTCON(gpio), intcon);
if (ERR_OK != ret) {
return ERR_FAIL;
}
} else {
MCP_IO_CLEAR(gpinten, gpio);
}
ret = mcp_write_command(GPINTEN(gpio), gpinten);
if (ERR_OK != ret) {
return ERR_FAIL;
}
return ERR_OK;
}
uint32_t mcp_gpio_get_int_gpio(void)
{
uint32_t port, final_pend = 0;
uint8_t intcap[MCP_GPMAX], intf, int_flag = 0;
for (port = 0; port < MCP_GPMAX; port++) {
mcp_read_command(INTF(port * MCP_MAX_GPIO_NUM_PER_PORT), &intf, 1);
if (intf) {
int_flag = 1; /* Walk all port, no break. */
}
}
if (0 == int_flag) {
return 0;
}
/* Read GPIO or INTCAP will clear the interrupt satus. */
for (port = 0; port < MCP_GPMAX; port++) {
mcp_read_command(INTCAP(port * MCP_MAX_GPIO_NUM_PER_PORT), &intcap[port], 1);
}
for (port = MCP_GPMAX; port > 0; port--) {
final_pend <<= (8 * sizeof(intcap[0]));
final_pend |= intcap[port - 1];
}
return final_pend;
}
uint32_t mcp_gpio_set_pullup(uint32_t gpio, uint32_t enable)
{
uint32_t ret;
uint8_t data;
if (!MCP_GPIO_VALID(gpio)) {
return ERR_FAIL;
}
ret = mcp_read_command(GPPU(gpio), &data, 1);
if (ERR_OK != ret) {
return ERR_FAIL;
}
if (enable) {
MCP_IO_SET(data, gpio);
} else {
MCP_IO_CLEAR(data, gpio);
}
ret = mcp_write_command(GPPU(gpio), data);
if (ERR_OK != ret) {
return ERR_FAIL;
}
return ERR_OK;
}
uint32_t mcp_init(void)
{
g_cfg.port = IOT_I2C_PORT_0;
g_cfg.nack_wait_num = 10;
g_cfg.baud = 400;
g_cfg.gpio.scl = MCP_SCL_GPIO;
g_cfg.gpio.sda = MCP_SDA_GPIO;
if ((ERR_OK != iot_gpio_open_as_output(g_cfg.gpio.scl))
|| (ERR_OK != iot_gpio_open_as_output(g_cfg.gpio.sda)))
{
return ERR_FAIL;
}
iot_gpio_set_pull_mode(g_cfg.gpio.scl, GPIO_PULL_UP);
iot_gpio_set_pull_mode(g_cfg.gpio.sda, GPIO_PULL_UP);
if (ERR_OK != iot_i2c_module_init(&g_cfg))
{
iot_gpio_close(g_cfg.gpio.scl);
iot_gpio_close(g_cfg.gpio.sda);
return ERR_FAIL;
}
return ERR_OK;
}