网络通,测试flash
This commit is contained in:
918
Src/ch395f.c
918
Src/ch395f.c
@@ -1,918 +0,0 @@
|
||||
/*
|
||||
* 模块名称: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 <string.h>
|
||||
|
||||
/*
|
||||
* 私有宏定义区
|
||||
*/
|
||||
#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();
|
||||
}
|
||||
|
||||
/*
|
||||
* 函数功能:启用/禁用 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;
|
||||
}
|
||||
20
Src/gpio.c
20
Src/gpio.c
@@ -50,16 +50,20 @@ void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, LED1_Pin|LED2_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, LED3_Pin|LED4_Pin|CH395_SCS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, LED3_Pin|LED4_Pin|CH395_SCS_Pin|GD_WP_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOF, LED5_Pin|LED6_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, GD_CS_Pin|GD_HOLD_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pins : LED1_Pin LED2_Pin */
|
||||
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
@@ -88,6 +92,20 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(CH395_SCS_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : GD_WP_Pin */
|
||||
GPIO_InitStruct.Pin = GD_WP_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GD_WP_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : GD_CS_Pin GD_HOLD_Pin */
|
||||
GPIO_InitStruct.Pin = GD_CS_Pin|GD_HOLD_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
95
Src/main.c
95
Src/main.c
@@ -27,6 +27,8 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "ch395f.h"
|
||||
#include "gd5f2gq5ue.h"
|
||||
#include "flashdb.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -92,10 +94,93 @@ int main(void)
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_SPI2_Init();
|
||||
MX_SPI1_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
/* CH395F 初始化 */
|
||||
ch395f_reset();
|
||||
ch395f_init();
|
||||
char dbg[64];
|
||||
uint8_t mac[6];
|
||||
|
||||
ch395f_reset();
|
||||
|
||||
/* [1/5] SPI 通信检测 */
|
||||
sprintf(dbg, "[1/5] CH395F %s\r\n",
|
||||
(ch395f_check_exist() == CH395F_STATUS_OK) ? "detected" : "ERROR: not detected");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [2/5] 芯片版本 */
|
||||
sprintf(dbg, "[2/5] CH395F version: 0x%02X\r\n", ch395f_get_version());
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* 配置 IP/网关/掩码 */
|
||||
{
|
||||
uint8_t ip[4] = {192, 168, 1, 100};
|
||||
uint8_t gw[4] = {192, 168, 1, 1};
|
||||
uint8_t mask[4] = {255, 255, 255, 0};
|
||||
ch395f_set_ip_addr(ip);
|
||||
ch395f_set_gwip_addr(gw);
|
||||
ch395f_set_mask_addr(mask);
|
||||
}
|
||||
|
||||
/* [3/5] 协议栈初始化 */
|
||||
sprintf(dbg, "[3/5] Protocol stack init %s\r\n",
|
||||
(ch395f_init() == CH395F_STATUS_OK) ? "OK" : "ERROR");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [4/5] MAC 地址 */
|
||||
ch395f_get_mac_addr(mac);
|
||||
sprintf(dbg, "[4/5] MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [5/5] 强制 100M 全双工后检测 PHY */
|
||||
ch395f_set_phy(CH395F_PHY_100M_FULL);
|
||||
HAL_Delay(3000);
|
||||
{
|
||||
uint8_t s = ch395f_get_phy_status();
|
||||
const char *desc = (s == CH395F_PHY_DISCONN) ? "DISCONNECTED" :
|
||||
(s == CH395F_PHY_100M_FULL) ? "100M FULL" :
|
||||
(s == CH395F_PHY_100M_HALF) ? "100M HALF" :
|
||||
(s == CH395F_PHY_10M_FULL) ? "10M FULL" :
|
||||
(s == CH395F_PHY_10M_HALF) ? "10M HALF" : "RESERVED";
|
||||
sprintf(dbg, "[5/5] PHY: 0x%02X (%s)\r\n", s, desc);
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
}
|
||||
|
||||
/* ===================== FlashDB KVDB 测试 ===================== */
|
||||
{
|
||||
uint8_t gd_mid, gd_did;
|
||||
int ret;
|
||||
|
||||
/* 检测 GD5F2GQ5UE */
|
||||
ret = gd5f2gq5ue_read_id(&gd_mid, &gd_did);
|
||||
sprintf(dbg, "[GD5F] ID: MID=0x%02X DID=0x%02X %s\r\n",
|
||||
gd_mid, gd_did,
|
||||
(ret == GD5F_OK && gd_mid == 0xC8 && gd_did == 0x52) ? "OK" : "FAIL");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* 初始化 FlashDB KVDB */
|
||||
{
|
||||
static struct fdb_kvdb kvdb;
|
||||
ret = fdb_kvdb_init(&kvdb, "db", "fdb_kvdb1", NULL, NULL);
|
||||
sprintf(dbg, "[FlashDB] KVDB init: %s\r\n",
|
||||
(ret == FDB_NO_ERR) ? "OK" : "FAIL");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
if (ret == FDB_NO_ERR) {
|
||||
/* 写入测试 KV */
|
||||
fdb_kv_set(&kvdb, "test_key", "hello_flashdb");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)"[FlashDB] KV set OK\r\n", 21, 1000);
|
||||
|
||||
/* 读取测试 KV */
|
||||
char *val = fdb_kv_get(&kvdb, "test_key");
|
||||
if (val) {
|
||||
sprintf(dbg, "[FlashDB] KV get: %s\r\n", val);
|
||||
} else {
|
||||
sprintf(dbg, "[FlashDB] KV get: NULL\r\n");
|
||||
}
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
@@ -111,7 +196,7 @@ int main(void)
|
||||
HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin);
|
||||
HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);
|
||||
HAL_GPIO_TogglePin(LED6_GPIO_Port, LED6_Pin);
|
||||
HAL_UART_Transmit(&huart1, str, strlen((char*)str), 1000);
|
||||
//HAL_UART_Transmit(&huart1, str, strlen((char*)str), 1000);
|
||||
HAL_Delay(500);
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
@@ -195,4 +280,4 @@ void assert_failed(uint8_t *file, uint32_t line)
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
87
Src/spi.c
87
Src/spi.c
@@ -24,8 +24,41 @@
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
SPI_HandleTypeDef hspi2;
|
||||
|
||||
/* SPI1 init function */
|
||||
void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 10;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
/* SPI2 init function */
|
||||
void MX_SPI2_Init(void)
|
||||
{
|
||||
@@ -41,10 +74,10 @@ void MX_SPI2_Init(void)
|
||||
hspi2.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi2.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
@@ -63,7 +96,32 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(spiHandle->Instance==SPI2)
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* SPI1 clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PB3 ------> SPI1_SCK
|
||||
PB4 ------> SPI1_MISO
|
||||
PB5 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GD_SCLK_Pin|GD_SO_Pin|GD_SI_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
else if(spiHandle->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspInit 0 */
|
||||
|
||||
@@ -100,7 +158,26 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
if(spiHandle->Instance==SPI2)
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PB3 ------> SPI1_SCK
|
||||
PB4 ------> SPI1_MISO
|
||||
PB5 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GD_SCLK_Pin|GD_SO_Pin|GD_SI_Pin);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
else if(spiHandle->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspDeInit 0 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user