/**
* @file ch423s.h
* @brief
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
*
* @copyright Copyright (c) 2025 by OLE, All Rights Reserved.
*
* @par 修改日志:
*
* | Date | Version | Author | Description
* |
|---|
| 20251224 | 2.0 | test | 内容
* |
*/
#ifdef IO_CHIP_CH423S
#include
#include
#include
#include
#include
#include "head.h"
/* 设置系统参数命令 */
#define CH423_SYS_CMD 0x48 // 设置系统参数命令,默认方式
#define BIT_SLEEP 0x30 // 低功耗睡眠控制 0正常工作 1睡眠模式
#define BIT_INTENS 0x20 // 动态显示驱动亮度控制
#define BIT_OD_OE 0x10 // 输出引脚 OC15~OC0 开漏输出使能 0推挽输出低电平和高电平 1开漏输出低电平和不输出
#define BIT_X_INT 0x08 // 使能输入电平变化中断 0禁止输入电平变化中断 为1并且DEC_H为0允许从OC15引脚输出电平变化中断
#define BIT_DEC_H 0x04 // 控制开漏输出引脚高8位的片选译码 0通用输出 1分时显示扫描计数器译码后
#define BIT_DEC_L 0x02 // 控制开漏输出引脚低8位的片选译码 0通用输出 1分时显示扫描计数器译码后
#define BIT_IO_OE 0x01 // 控制双向输入输出引脚的三态输出 0禁止输出 1允许输出
/* 设置低8位开漏输出命令 */
#define CH423_OC_L_CMD 0x44 // 设置低8位开漏输出命令,默认方式
#define BIT_OC0_L_DAT 0x01 // OC0为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC1_L_DAT 0x02 // OC1为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC2_L_DAT 0x04 // OC2为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC3_L_DAT 0x08 // OC3为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC4_L_DAT 0x10 // OC4为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC5_L_DAT 0x20 // OC5为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC6_L_DAT 0x40 // OC6为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC7_L_DAT 0x80 // OC7为0则使引脚输出低电平,为1则引脚不输出
/* 设置高8位开漏输出命令 */
#define CH423_OC_H_CMD 0x46 // 设置低8位开漏输出命令,默认方式
#define BIT_OC8_L_DAT 0x01 // OC8为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC9_L_DAT 0x02 // OC9为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC10_L_DAT 0x04 // OC10为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC11_L_DAT 0x08 // OC11为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC12_L_DAT 0x10 // OC12为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC13_L_DAT 0x20 // OC13为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC14_L_DAT 0x40 // OC14为0则使引脚输出低电平,为1则引脚不输出
#define BIT_OC15_L_DAT 0x80 // OC15为0则使引脚输出低电平,为1则引脚不输出
/* 设置双向输入输出命令 */
#define CH423_SET_IO_CMD 0x60 // 设置双向输入输出命令,默认方式
#define BIT_IO0_DAT 0x01 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO0为0输出低电平,为1输出高电平
#define BIT_IO1_DAT 0x02 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO1为0输出低电平,为1输出高电平
#define BIT_IO2_DAT 0x04 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO2为0输出低电平,为1输出高电平
#define BIT_IO3_DAT 0x08 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO3为0输出低电平,为1输出高电平
#define BIT_IO4_DAT 0x10 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO4为0输出低电平,为1输出高电平
#define BIT_IO5_DAT 0x20 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO5为0输出低电平,为1输出高电平
#define BIT_IO6_DAT 0x40 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO6为0输出低电平,为1输出高电平
#define BIT_IO7_DAT 0x80 // 写入双向输入输出引脚的输出寄存器,当IO_OE=1,IO7为0输出低电平,为1输出高电平
struct t_dev_cfg
{
uint8_t uc_port;
uint8_t uc_pin;
};
struct t_dev_cfg t_ch423_gpio[] =
{
{CH423_OC_L_CMD, 0},
{CH423_OC_L_CMD, 1},
{CH423_OC_L_CMD, 2},
{CH423_OC_L_CMD, 3},
{CH423_OC_L_CMD, 4},
{CH423_OC_L_CMD, 5},
{CH423_OC_L_CMD, 6},
{CH423_OC_L_CMD, 7},
{CH423_OC_H_CMD, 8},
{CH423_OC_H_CMD, 9},
{CH423_OC_H_CMD, 10},
{CH423_OC_H_CMD, 11},
{CH423_OC_H_CMD, 12},
{CH423_OC_H_CMD, 13},
{CH423_OC_H_CMD, 14},
{CH423_OC_H_CMD, 15},
{CH423_SET_IO_CMD, 16},
{CH423_SET_IO_CMD, 17},
{CH423_SET_IO_CMD, 18},
{CH423_SET_IO_CMD, 19},
{CH423_SET_IO_CMD, 20},
{CH423_SET_IO_CMD, 21},
{CH423_SET_IO_CMD, 22},
{CH423_SET_IO_CMD, 23},
};
#define I2C_DEV "/dev/i2c-5"
static int sl_ch423s_fd = -1, sl_ch423s_init = -1;
static uint32_t sul_io_status = 0;
static unsigned long mtll_updata_ch423s_timer = 0;
/**
* @brief
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @param[in/out] {uint8_t} _uc_cmd 命令
* @param[in/out] {uint8_t} _uc_state 状态
* @return * int
* @retval none
*
* @warning none
* @note none
*/
static int ch423_write_data(uint8_t _uc_cmd, uint8_t _uc_state)
{
uint8_t uca_data[2] = {0};
uca_data[0] = _uc_cmd;
uca_data[1] = _uc_state;
if (write(sl_ch423s_fd, &uca_data[0], 2) != 2)
{
dp_err_n_c_rt("Failed to send init command: %s", strerror(errno));
return -1;
}
return 0;
}
/**
* @brief
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @param[in/out] {uint8_t} _uc_idx
* @param[in/out] {uint8_t} _uc_state
* @return * void
* @retval none
*
* @warning none
* @note none
*/
static void ch423s_updata_port_status(uint8_t _uc_idx, uint8_t _uc_state)
{
/* 清除原始状态 */
if ((sul_io_status >> _uc_idx) & 0x01)
{
sul_io_status ^= (1 << _uc_idx);
}
/* 重新设置 */
sul_io_status |= _uc_state ? (0 << _uc_idx) : (1 << _uc_idx);
}
/**
* @brief 定时更新gpio状态
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @return * int
* @retval none
*
* @warning none
* @note none
*/
int ch423sio_updata_status_ontime(void)
{
uint8_t uca_state[3] = {0};
int l_ret = 0;
if (bsp_ustimer_get_duration(mtll_updata_ch423s_timer) < (USTIMER_MS * 50) || sl_ch423s_fd < 0)
{
return -1;
}
mtll_updata_ch423s_timer = bsp_ustimer_get_origin();
uca_state[0] = (uint8_t)(sul_io_status & 0xff);
(0 = ch423_write_data(CH423_OC_L_CMD, uca_state[0])) ? l_ret : l_ret--;
uca_state[1] = (uint8_t)((sul_io_status >> 8) & 0xff);
(0 = ch423_write_data(CH423_OC_H_CMD, uca_state[1])) ? l_ret : l_ret--;
uca_state[2] = (uint8_t)((sul_io_status >> 16) & 0xff);
(0 = ch423_write_data(CH423_SET_IO_CMD, uca_state[2])) ? l_ret : l_ret--;
return l_ret;
}
/**
* @brief 设置io状态
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @param[in/out] {uint8_t} _uc_idx 下标
* @param[in/out] {uint8_t} _uc_state 电平状态
* @return * int
* @retval none
*
* @warning none
* @note none
*/
int ch423sio_set_io(uint8_t _uc_idx, uint8_t _uc_state)
{
uint8_t uc_num = sizeof(t_ch423_gpio) / sizeof(struct t_dev_cfg);
if (_uc_idx >= uc_num || sl_ch423s_init < 0 || _uc_state > 1)
{
return -1;
}
switch (t_ch423_gpio[_uc_idx].uc_port)
{
case CH423_OC_L_CMD:
ch423s_updata_port_status(t_ch423_gpio[_uc_idx].uc_pin, _uc_state);
break;
case CH423_OC_H_CMD:
ch423s_updata_port_status(t_ch423_gpio[_uc_idx].uc_pin, _uc_state);
break;
case CH423_SET_IO_CMD:
ch423s_updata_port_status(t_ch423_gpio[_uc_idx].uc_pin, _uc_state);
break;
default:
return -2;
break;
}
return 0;
}
/**
* @brief 初始化设备
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @return * int
* @retval none
*
* @warning none
* @note none
*/
int ch423sio_init_dev(void)
{
// 打开I2C设备
sl_ch423s_fd = open(I2C_DEV, O_RDWR);
if (sl_ch423s_fd < 0)
{
dp_err_n_c_rt("Failed to open I2C device %s: %s", I2C_DEV, strerror(errno));
return -1;
}
ch423_write_data(CH423_SYS_CMD, BIT_IO_OE); /* 将IO7~IO0设置为输出 其它参数使用默认值 */
ch423_write_data(CH423_OC_L_CMD, 0xff);
ch423_write_data(CH423_OC_H_CMD, 0xff);
ch423_write_data(CH423_SET_IO_CMD, 0xff);
sl_ch423s_init = 0;
return 0;
}
/**
* @brief 关闭句柄
* @author lch (lch_work@foxmail.com)
* @version 1.0
* @date 20251224
* @return * int
* @retval none
*
* @warning none
* @note none
*/
int ch423sio_exit_dev(void)
{
if (sl_ch423s_fd >= 0)
{
close(sl_ch423s_fd);
sl_ch423s_fd = -1;
}
return 0;
}
#endif /* TMP_CHIP_AHT20 */