/* * 模块名称:CH395F SPI Ethernet Protocol Stack Driver * 模块功能:CH395F 以太网协议栈芯片 SPI 驱动实现,提供芯片检测、初始化、 * 网络参数配置、PHY 管理、DHCP、Socket 管理及数据收发功能 * 适用平台:STM32F4 系列(SPI2 接口) * 作者:王建锋 * 创建日期:2026-03-14 * 修改记录: * 2026-03-14 王建锋 创建初始版本,按代码规范重构 */ /* 头文件包含区 - 先包含本模块头文件,再包含依赖头文件 */ #include "ch395f.h" #include "spi.h" #include /* * 私有宏定义区 */ #define CH395F_CHECK_EXIST_TEST_DATA 0x57U /* 芯片检测测试字节 */ #define CH395F_RESET_DELAY_MS 20U /* 复位后等待延时(ms) */ #define CH395F_INIT_TIMEOUT_MS 500U /* 初始化超时时间(ms) */ #define CH395F_SPI_BEGIN_DELAY_MS 1U /* SPI 事务开始延时(ms) */ /* * 私有函数声明区 */ static void ch395f_spi_begin(void); static void ch395f_spi_end(void); /* * 私有函数实现区 */ /* * 函数功能:开始 SPI 事务(CS 拉高 -> 拉低) * 函数说明:手册要求 SPI 模式下字节间无需间隔 */ static void ch395f_spi_begin(void) { /* CS 先拉高,确保空闲状态 */ HAL_GPIO_WritePin(CH395_SCS_GPIO_Port, CH395_SCS_Pin, GPIO_PIN_SET); HAL_Delay(CH395F_SPI_BEGIN_DELAY_MS); /* CS 拉低,启动事务 */ HAL_GPIO_WritePin(CH395_SCS_GPIO_Port, CH395_SCS_Pin, GPIO_PIN_RESET); } /* * 函数功能:结束 SPI 事务(CS 拉高) */ static void ch395f_spi_end(void) { /* CS 拉高,结束事务 */ HAL_GPIO_WritePin(CH395_SCS_GPIO_Port, CH395_SCS_Pin, GPIO_PIN_SET); } /* * 公共函数实现区 */ /* * 函数功能:向 CH395 写入命令字节 * 入口参数:cmd - 命令码 uint8_t 0x00 - 0xFF * 返回值:命令码回显值 uint8_t * 限定条件:需在 ch395f_spi_begin() 和 ch395f_spi_end() 之间调用 * 函数说明:SPI 模式下命令与数据之间无需间隔 */ uint8_t ch395f_write_cmd(uint8_t cmd) { uint8_t rx_data; /* 通过 SPI 发送命令并接收回显 */ HAL_SPI_TransmitReceive(&hspi2, &cmd, &rx_data, 1, HAL_MAX_DELAY); return rx_data; } /* * 函数功能:向 CH395 写入数据字节 * 入口参数:data - 数据字节 uint8_t 0x00 - 0xFF * 返回值:数据回显值 uint8_t * 限定条件:需在 ch395f_spi_begin() 和 ch395f_spi_end() 之间调用 */ uint8_t ch395f_write_data(uint8_t data) { uint8_t rx_data; /* 通过 SPI 发送数据并接收回显 */ HAL_SPI_TransmitReceive(&hspi2, &data, &rx_data, 1, HAL_MAX_DELAY); return rx_data; } /* * 函数功能:从 CH395 读取数据字节 * 返回值:接收到的数据字节 uint8_t * 限定条件:需在 ch395f_spi_begin() 和 ch395f_spi_end() 之间调用 */ uint8_t ch395f_read_data(void) { uint8_t tx_dummy = 0xFFU; uint8_t rx_data; /* 发送 0xFF 作为时钟源,读取芯片返回的数据 */ HAL_SPI_TransmitReceive(&hspi2, &tx_dummy, &rx_data, 1, HAL_MAX_DELAY); return rx_data; } /* * 函数功能:检测 CH395 芯片是否存在且通信正常 * 返回值:CH395F_STATUS_OK - 检测到芯片,CH395F_STATUS_NOT_DETECTED - 未检测到 * 限定条件:SPI2 已正确初始化 * 函数说明:发送 CMD_CHECK_EXIST (0x06) 及测试字节 0x57, * 芯片应返回按位取反值 0xA8 */ ch395f_status_t ch395f_check_exist(void) { uint8_t test_data = CH395F_CHECK_EXIST_TEST_DATA; uint8_t reply_data; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送检测命令 */ ch395f_write_cmd(CH395F_CMD_CHECK_EXIST); /* 发送测试数据 */ ch395f_write_data(test_data); /* 读取芯片回复 */ reply_data = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); /* 验证回复是否为测试数据的按位取反 */ if (reply_data == (uint8_t)(~test_data)) { return CH395F_STATUS_OK; } return CH395F_STATUS_NOT_DETECTED; } /* * 函数功能:读取 CH395 芯片版本号 * 返回值:版本字节(bit5:0 为版本号)uint8_t * 限定条件:芯片已通过 ch395f_check_exist() 检测 */ uint8_t ch395f_get_version(void) { uint8_t version; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送版本读取命令 */ ch395f_write_cmd(CH395F_CMD_GET_IC_VER); /* 读取版本号 */ version = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return version; } /* * 函数功能:软件复位 CH395 * 返回值:CH395F_STATUS_OK * 限定条件:SPI2 已正确初始化 * 函数说明:复位耗时约 15ms(TE0),函数内部已包含延时 */ ch395f_status_t ch395f_reset(void) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送复位命令 */ ch395f_write_cmd(CH395F_CMD_RESET_ALL); /* 结束 SPI 事务 */ ch395f_spi_end(); /* 等待复位完成(TE0 = 15ms 典型值,等待 20ms) */ HAL_Delay(CH395F_RESET_DELAY_MS); return CH395F_STATUS_OK; } /* * 函数功能:查询命令执行状态 * 返回值:状态字节(CH395F_ERR_SUCCESS / CH395F_ERR_BUSY / ...)uint8_t * 限定条件:仅在长执行命令(如初始化)后调用 */ uint8_t ch395f_get_cmd_status(void) { uint8_t status; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送状态查询命令 */ ch395f_write_cmd(CH395F_CMD_GET_CMD_STATUS); /* 读取状态字节 */ status = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return status; } /* * 函数功能:初始化 CH395(包含 MAC、PHY、TCP/IP 协议栈) * 返回值:CH395F_STATUS_OK - 成功,CH395F_STATUS_TIMEOUT - 超时失败 * 限定条件:芯片已通过 ch395f_reset() 复位 * 函数说明:阻塞等待初始化完成或超时(典型 5ms,TE1) */ ch395f_status_t ch395f_init(void) { uint8_t status; uint32_t retry_count = 0U; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送初始化命令 */ ch395f_write_cmd(CH395F_CMD_INIT_CH395); /* 结束 SPI 事务 */ ch395f_spi_end(); /* 轮询等待初始化完成 */ while (1) { /* 每次轮询延时 1ms */ HAL_Delay(1U); /* 查询命令执行状态 */ status = ch395f_get_cmd_status(); /* 状态非 BUSY 表示执行完毕 */ if (status != CH395F_ERR_BUSY) { break; } /* 超时判断 */ if (++retry_count > CH395F_INIT_TIMEOUT_MS) { return CH395F_STATUS_TIMEOUT; } } /* 返回最终执行结果 */ if (status == CH395F_ERR_SUCCESS) { return CH395F_STATUS_OK; } return CH395F_STATUS_ERROR; } /* * 函数功能:设置 CH395 IP 地址(低字节在前) * 入口参数:p_ip - 4 字节 IP 地址指针 uint8_t* * 限定条件:指针非空,芯片已初始化 */ void ch395f_set_ip_addr(uint8_t *p_ip) { uint8_t i; /* 检查输入参数合法性 */ if (p_ip == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置 IP 命令 */ ch395f_write_cmd(CH395F_CMD_SET_IP_ADDR); /* 逐字节发送 IP 地址 */ for (i = 0; i < 4; i++) { ch395f_write_data(p_ip[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置网关 IP 地址(低字节在前) * 入口参数:p_gwip - 4 字节网关 IP 指针 uint8_t* * 限定条件:指针非空,芯片已初始化 */ void ch395f_set_gwip_addr(uint8_t *p_gwip) { uint8_t i; /* 检查输入参数合法性 */ if (p_gwip == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置网关命令 */ ch395f_write_cmd(CH395F_CMD_SET_GWIP_ADDR); /* 逐字节发送网关 IP */ for (i = 0; i < 4; i++) { ch395f_write_data(p_gwip[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置子网掩码(低字节在前) * 入口参数:p_mask - 4 字节子网掩码指针 uint8_t* * 限定条件:指针非空,芯片已初始化 */ void ch395f_set_mask_addr(uint8_t *p_mask) { uint8_t i; /* 检查输入参数合法性 */ if (p_mask == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置掩码命令 */ ch395f_write_cmd(CH395F_CMD_SET_MASK_ADDR); /* 逐字节发送子网掩码 */ for (i = 0; i < 4; i++) { ch395f_write_data(p_mask[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置 MAC 地址(低字节在前,存储于 EEPROM) * 入口参数:p_mac - 6 字节 MAC 地址指针 uint8_t* * 限定条件:指针非空,芯片已初始化 * 函数说明:执行耗时约 30us(TE5) */ void ch395f_set_mac_addr(uint8_t *p_mac) { uint8_t i; /* 检查输入参数合法性 */ if (p_mac == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置 MAC 命令 */ ch395f_write_cmd(CH395F_CMD_SET_MAC_ADDR); /* 逐字节发送 MAC 地址 */ for (i = 0; i < 6; i++) { ch395f_write_data(p_mac[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:从 CH395 读取 MAC 地址 * 出口参数:p_mac - 6 字节 MAC 地址缓冲区指针 uint8_t* * 限定条件:指针非空 */ void ch395f_get_mac_addr(uint8_t *p_mac) { uint8_t i; /* 检查输入参数合法性 */ if (p_mac == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取 MAC 命令 */ ch395f_write_cmd(CH395F_CMD_GET_MAC_ADDR); /* 逐字节读取 MAC 地址 */ for (i = 0; i < 6; i++) { p_mac[i] = ch395f_read_data(); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:读取 IP 信息(IP + 掩码 + DNS,共 20 字节) * 出口参数:p_buf - 20 字节缓冲区指针 uint8_t* * 限定条件:指针非空 */ void ch395f_get_ip_inf(uint8_t *p_buf) { uint8_t i; /* 检查输入参数合法性 */ if (p_buf == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取 IP 信息命令 */ ch395f_write_cmd(CH395F_CMD_GET_IP_INF); /* 逐字节读取 IP 信息(共 20 字节) */ for (i = 0; i < 20; i++) { p_buf[i] = ch395f_read_data(); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:获取 PHY 连接状态 * 返回值:PHY 状态码(CH395F_PHY_DISCONN、CH395F_PHY_10M_FULL 等)uint8_t * 限定条件:芯片已初始化 */ uint8_t ch395f_get_phy_status(void) { uint8_t status; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取 PHY 状态命令 */ ch395f_write_cmd(CH395F_CMD_GET_PHY_STATUS); /* 读取 PHY 状态 */ status = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return status; } /* * 函数功能:设置 PHY 连接模式 * 入口参数:phystat - 连接模式码 uint8_t 0x20 = 自动协商 * 限定条件:芯片已初始化 */ void ch395f_set_phy(uint8_t phystat) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置 PHY 命令 */ ch395f_write_cmd(CH395F_CMD_SET_PHY); /* 发送连接模式参数 */ ch395f_write_data(phystat); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:使能/关闭 CH395 响应 PING * 入口参数:enable - 1 使能 PING 响应,0 关闭 * 限定条件:芯片已初始化 * 函数说明:手册 5.37 CMD_PING_ENABLE,默认关闭 */ void ch395f_ping_enable(uint8_t enable) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送 PING 使能命令 */ ch395f_write_cmd(CH395F_CMD_PING_ENABLE); /* 发送使能标志 */ ch395f_write_data(enable); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:启用/禁用 DHCP * 入口参数:enable - 1 启用,0 禁用 uint8_t * 限定条件:芯片已初始化 */ void ch395f_set_dhcp(uint8_t enable) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送 DHCP 使能命令 */ ch395f_write_cmd(CH395F_CMD_DHCP_ENABLE); /* 发送启用/禁用参数 */ ch395f_write_data(enable); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:获取 DHCP 状态 * 返回值:0 = 成功,非零 = 错误/超时 uint8_t * 限定条件:芯片已初始化且 DHCP 已启用 */ uint8_t ch395f_get_dhcp_status(void) { uint8_t status; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取 DHCP 状态命令 */ ch395f_write_cmd(CH395F_CMD_GET_DHCP_STATUS); /* 读取 DHCP 状态 */ status = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return status; } /* * 函数功能:设置 Socket 协议类型 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * proto - 协议类型 uint8_t CH395F_PROTO_TYPE_xxx * 限定条件:Socket 未打开 */ void ch395f_set_proto_type(uint8_t sock, uint8_t proto) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置协议类型命令 */ ch395f_write_cmd(CH395F_CMD_SET_PROTO_TYPE_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 发送协议类型 */ ch395f_write_data(proto); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置 Socket 目标 IP 地址 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * p_ip - 4 字节目标 IP 指针 uint8_t* * 限定条件:指针非空 */ void ch395f_set_des_ip(uint8_t sock, uint8_t *p_ip) { uint8_t i; /* 检查输入参数合法性 */ if (p_ip == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置目标 IP 命令 */ ch395f_write_cmd(CH395F_CMD_SET_IP_ADDR_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 逐字节发送目标 IP */ for (i = 0; i < 4; i++) { ch395f_write_data(p_ip[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置 Socket 目标端口(小端序) * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * port - 目标端口 uint16_t * 限定条件:无 */ void ch395f_set_des_port(uint8_t sock, uint16_t port) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置目标端口命令 */ ch395f_write_cmd(CH395F_CMD_SET_DES_PORT_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 发送端口低字节 */ ch395f_write_data(port & 0xFFU); /* 发送端口高字节 */ ch395f_write_data((port >> 8) & 0xFFU); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:设置 Socket 源端口(小端序) * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * port - 源端口 uint16_t * 限定条件:无 */ void ch395f_set_sour_port(uint8_t sock, uint16_t port) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送设置源端口命令 */ ch395f_write_cmd(CH395F_CMD_SET_SOUR_PORT_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 发送端口低字节 */ ch395f_write_data(port & 0xFFU); /* 发送端口高字节 */ ch395f_write_data((port >> 8) & 0xFFU); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:打开 Socket * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 限定条件:协议类型、目标 IP、端口已设置 */ void ch395f_open_socket(uint8_t sock) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送打开 Socket 命令 */ ch395f_write_cmd(CH395F_CMD_OPEN_SOCKET_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:关闭 Socket * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 限定条件:Socket 已打开 */ void ch395f_close_socket(uint8_t sock) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送关闭 Socket 命令 */ ch395f_write_cmd(CH395F_CMD_CLOSE_SOCKET_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:启动 TCP 监听模式 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 限定条件:Socket 已打开且协议类型为 TCP */ void ch395f_tcp_listen(uint8_t sock) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送 TCP 监听命令 */ ch395f_write_cmd(CH395F_CMD_TCP_LISTEN_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:启动 TCP 连接 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 限定条件:Socket 已打开且协议类型为 TCP */ void ch395f_tcp_connect(uint8_t sock) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送 TCP 连接命令 */ ch395f_write_cmd(CH395F_CMD_TCP_CONNECT_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:断开 TCP 连接 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 限定条件:TCP 已建立连接 */ void ch395f_tcp_disconnect(uint8_t sock) { /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送 TCP 断开命令 */ ch395f_write_cmd(CH395F_CMD_TCP_DISCONNECT_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:向 Socket 发送缓冲区写入数据 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * p_data - 数据指针 uint8_t* * len - 数据长度 uint16_t * 限定条件:指针非空,长度大于 0,TCP 已连接或 UDP 已打开 */ void ch395f_write_send_buf(uint8_t sock, uint8_t *p_data, uint16_t len) { uint16_t i; /* 检查输入参数合法性 */ if (p_data == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送写入发送缓冲区命令 */ ch395f_write_cmd(CH395F_CMD_WRITE_SEND_BUF_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 发送数据长度低字节 */ ch395f_write_data(len & 0xFFU); /* 发送数据长度高字节 */ ch395f_write_data((len >> 8) & 0xFFU); /* 逐字节发送数据 */ for (i = 0; i < len; i++) { ch395f_write_data(p_data[i]); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:从 Socket 接收缓冲区读取数据 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * p_data - 输出缓冲区指针 uint8_t* * len - 待读取数据长度 uint16_t * 限定条件:指针非空,长度大于 0,接收缓冲区有数据 */ void ch395f_read_recv_buf(uint8_t sock, uint8_t *p_data, uint16_t len) { uint16_t i; /* 检查输入参数合法性 */ if (p_data == NULL) { return; } /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取接收缓冲区命令 */ ch395f_write_cmd(CH395F_CMD_READ_RECV_BUF_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 发送读取长度低字节 */ ch395f_write_data(len & 0xFFU); /* 发送读取长度高字节 */ ch395f_write_data((len >> 8) & 0xFFU); /* 逐字节读取数据 */ for (i = 0; i < len; i++) { p_data[i] = ch395f_read_data(); } /* 结束 SPI 事务 */ ch395f_spi_end(); } /* * 函数功能:获取 Socket 接收缓冲区数据长度 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 返回值:接收数据长度 uint16_t * 限定条件:Socket 已打开 */ uint16_t ch395f_get_recv_len(uint8_t sock) { uint16_t recv_len; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送获取接收长度命令 */ ch395f_write_cmd(CH395F_CMD_GET_RECV_LEN_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 读取长度低字节 */ recv_len = ch395f_read_data(); /* 读取长度高字节并组合 */ recv_len |= (uint16_t)ch395f_read_data() << 8; /* 结束 SPI 事务 */ ch395f_spi_end(); return recv_len; } /* * 函数功能:获取全局中断状态 * 返回值:中断状态字节 uint8_t * 限定条件:芯片已初始化 */ uint8_t ch395f_get_glob_int_status(void) { uint8_t status; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取全局中断状态命令 */ ch395f_write_cmd(CH395F_CMD_GET_GLOB_INT_STATUS); /* 读取中断状态 */ status = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return status; } /* * 函数功能:获取 Socket 中断状态 * 入口参数:sock - Socket 索引 uint8_t 0 - 3 * 返回值:Socket 中断状态字节 uint8_t * 限定条件:芯片已初始化 */ uint8_t ch395f_get_sock_int_status(uint8_t sock) { uint8_t status; /* 开始 SPI 事务 */ ch395f_spi_begin(); /* 发送读取 Socket 中断状态命令 */ ch395f_write_cmd(CH395F_CMD_GET_INT_STATUS_SN); /* 发送 Socket 索引 */ ch395f_write_data(sock); /* 读取中断状态 */ status = ch395f_read_data(); /* 结束 SPI 事务 */ ch395f_spi_end(); return status; }