移植正点原子CH395Q代码
网线连接到电脑上开启DHCP自动获取ip地址,一定要在电脑还是那个开启网络共享,
可看以下链接:原文链接:https://blog.csdn.net/Dontla/article/details/132422418
#include "spi.h" SPI_HandleTypeDef g_spi1_handler; /* SPI1句柄 */ /** * @brief SPI底层驱动,时钟使能,引脚配置 * @note 此函数会被HAL_SPI_Init()调用 * @param hspi:SPI句柄 * @retval 无 */ void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) { GPIO_InitTypeDef gpio_init_struct; if (hspi->Instance == SPI1_SPI) { SPI1_SCK_GPIO_CLK_ENABLE(); /* SPI1_SCK脚时钟使能 */ SPI1_MISO_GPIO_CLK_ENABLE(); /* SPI1_MISO脚时钟使能 */ SPI1_MOSI_GPIO_CLK_ENABLE(); /* SPI1_MOSI脚时钟使能 */ /* SCK引脚模式设置(复用输出) */ gpio_init_struct.Pin = SPI1_SCK_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_AF_PP; gpio_init_struct.Pull = GPIO_PULLUP; gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(SPI1_SCK_GPIO_PORT, &gpio_init_struct); /* MISO引脚模式设置(复用输出) */ gpio_init_struct.Pin = SPI1_MISO_GPIO_PIN; HAL_GPIO_Init(SPI1_MISO_GPIO_PORT, &gpio_init_struct); /* MOSI引脚模式设置(复用输出) */ gpio_init_struct.Pin = SPI1_MOSI_GPIO_PIN; HAL_GPIO_Init(SPI1_MOSI_GPIO_PORT, &gpio_init_struct); } } /** * @brief SPI初始化代码 * @note 主机模式,8位数据,禁止硬件片选 * @param 无 * @retval 无 */ void spi1_init(void) { SPI1_SPI_CLK_ENABLE(); /* SPI1时钟使能 */ g_spi1_handler.Instance = SPI1_SPI; /* SPI1 */ g_spi1_handler.Init.Mode = SPI_MODE_MASTER; /* 设置SPI工作模式,设置为主模式 */ g_spi1_handler.Init.Direction = SPI_DIRECTION_2LINES; /* 设置SPI单向或者双向的数据模式:SPI设置为双线模式 */ g_spi1_handler.Init.DataSize = SPI_DATASIZE_8BIT; /* 设置SPI的数据大小:SPI发送接收8位帧结构 */ g_spi1_handler.Init.CLKPolarity = SPI_POLARITY_HIGH; /* 串行同步时钟的空闲状态为高电平 */ g_spi1_handler.Init.CLKPhase = SPI_PHASE_2EDGE; /* 串行同步时钟的第二个跳变沿(上升或下降)数据被采样 */ g_spi1_handler.Init.NSS = SPI_NSS_SOFT; /* NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制 */ g_spi1_handler.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; /* 定义波特率预分频的值:波特率预分频值为256 */ g_spi1_handler.Init.FirstBit = SPI_FIRSTBIT_MSB; /* 指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始 */ g_spi1_handler.Init.TIMode = SPI_TIMODE_DISABLE; /* 关闭TI模式 */ g_spi1_handler.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; /* 关闭硬件CRC校验 */ g_spi1_handler.Init.CRCPolynomial = 7; /* CRC值计算的多项式 */ HAL_SPI_Init(&g_spi1_handler); /* 初始化 */ // spi1_set_speed(SPI_BAUDRATEPRESCALER_2); __HAL_SPI_ENABLE(&g_spi1_handler); /* 使能SPI2 */ spi1_read_write_byte(0Xff); /* 启动传输, 实际上就是产生8个时钟脉冲, 达到清空DR的作用, 非必需 */ } /** * @brief SPI1速度设置函数 * @note SPI2时钟选择来自APB1, 即PCLK1, 为36Mhz * SPI速度 = PCLK1 / 2^(speed + 1) * @param speed : SPI2时钟分频系数 取值为SPI_BAUDRATEPRESCALER_2~SPI_BAUDRATEPRESCALER_2 256 * @retval 无 */ void spi1_set_speed(uint8_t speed) { assert_param(IS_SPI_BAUDRATE_PRESCALER(speed)); /* 判断有效性 */ __HAL_SPI_DISABLE(&g_spi1_handler); /* 关闭SPI */ g_spi1_handler.Instance->CR1 &= 0XFFC7; /* 位3-5清零,用来设置波特率 */ g_spi1_handler.Instance->CR1 |= speed << 3; /* 设置SPI速度 */ __HAL_SPI_ENABLE(&g_spi1_handler); /* 使能SPI */ } /** * @brief SPI1读写一个字节数据 * @param txdata : 要发送的数据(1字节) * @retval 接收到的数据(1字节) */ uint8_t spi1_read_write_byte(uint8_t txdata) { uint8_t rxdata; HAL_SPI_TransmitReceive(&g_spi1_handler, &txdata, &rxdata, 1, 1000); return rxdata; /* 返回收到的数据 */ }
#include "ch395inc.h" #include "ch395cmd.h" #include "ch395.h" /** * @brief 复位ch395芯片 * @param 无 * @retval 无 */ void ch395_cmd_reset(void) { ch395_scs_low; ch395_write_cmd(CMD00_RESET_ALL); ch395_scs_hign; } /** * @brief 使ch395进入睡眠状态 * @param 无 * @retval 无 */ void ch395_cmd_sleep(void) { ch395_scs_low; ch395_write_cmd(CMD00_ENTER_SLEEP); ch395_scs_hign; } /** * @brief 获取芯片以及固件版本号,1字节,高四位表示芯片版本, * @param 无 * @retval 1字节芯片及固件版本号 */ uint8_t ch395_cmd_get_ver(void) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD01_GET_IC_VER); i = ch395_read_data(); ch395_scs_hign; return i; } /** * @brief 测试命令,用于测试硬件以及接口通讯, * @param 1字节测试数据 * @retval 硬件ok,返回 testdata按位取反 */ uint8_t ch395_cmd_check_exist(uint8_t testdata) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD11_CHECK_EXIST); ch395_write_data(testdata); i = ch395_read_data(); ch395_scs_hign; return i; } /** * @brief 设置phy,主要设置ch395 phy为100/10m 或者全双工半双工,ch395默为自动协商。 * @param 参考phy 命令参数/状态 * @retval 无 */ void ch395_cmd_set_phy(uint8_t phystat) {ch395_scs_low; ch395_write_cmd(CMD10_SET_PHY); ch395_write_data(phystat); ch395_scs_hign; } /** * @brief 获取phy的状态 * @param 无 * @retval 当前ch395phy状态,参考phy参数/状态定义 */ uint8_t ch395_cmd_get_phy_status(void) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD01_GET_PHY_STATUS); i = ch395_read_data(); ch395_scs_hign; return i; } /** * @brief 获取全局中断状态,收到此命令ch395自动取消中断,0x43及以下版本使用 * @param 无 * @retval 返回当前的全局中断状态 */ uint8_t ch395_cmd_get_glob_int_status(void) { uint8_t init_status; ch395_scs_low; ch395_write_cmd(CMD01_GET_GLOB_INT_STATUS); init_status = ch395_read_data(); ch395_scs_hign; return init_status; } /** * @brief 初始化ch395芯片 * @param 无 * @retval 返回执行结果 */ uint8_t ch395_cmd_init(void) { uint8_t i = 0; uint8_t s = 0; ch395_scs_low; ch395_write_cmd(CMD0W_INIT_CH395); ch395_scs_hign; while (1) { HAL_Delay(10); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出,本函数需要500MS以上执行完毕 */ } } return s; } /** * @brief 设置ch395串口波特率,仅在串口模式下有效 * @param baudrate 串口波特率 * @retval 无 */ void ch395_cmd_set_uart_baud_rate(uint32_t baudrate) { ch395_scs_low; ch395_write_cmd(CMD31_SET_BAUDRATE); ch395_write_data((uint8_t)baudrate); ch395_write_data((uint8_t)((uint16_t)baudrate >> 8)); ch395_write_data((uint8_t)(baudrate >> 16)); uint8_t i = ch395_read_data(); ch395_scs_hign; } /** * @brief 获取命令执行状态,某些命令需要等待命令执行结果 * @param 无 * @retval 返回上一条命令执行状态 */ uint8_t ch395_get_cmd_status(void) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD01_GET_CMD_STATUS); i = ch395_read_data(); ch395_scs_hign; return i; } /** * @brief 设置ch395的ip地址 * @param ipaddr 指ip地址 * @retval 无 */ void ch395_cmd_set_ipaddr(uint8_t *ipaddr) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD40_SET_IP_ADDR); for (i = 0; i < 4; i++) { ch395_write_data(*ipaddr++); } ch395_scs_hign; } /** * @brief 设置ch395的网关ip地址 * @param ipaddr 指向网关ip地址 * @retval 无 */ void ch395_cmd_set_gw_ipaddr(uint8_t *gwipaddr) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD40_SET_GWIP_ADDR); for (i = 0; i < 4; i++) { ch395_write_data(*gwipaddr++); } ch395_scs_hign; } /** * @brief 设置ch395的子网掩码,默认为255.255.255.0 * @param maskaddr 指子网掩码地址 * @retval 无 */ void ch395_cmd_set_maskaddr(uint8_t *maskaddr) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD40_SET_MASK_ADDR); for (i = 0; i < 4; i++) { ch395_write_data(*maskaddr++); } ch395_scs_hign; } /** * @brief 设置ch395的mac地址。 * @param mcaddr mac地址指针 * @retval 无 */ void ch395_cmd_set_macaddr(uint8_t *amcaddr) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD60_SET_MAC_ADDR); for (i = 0; i < 6; i++) { ch395_write_data(*amcaddr++); } ch395_scs_hign; HAL_Delay(100); } /** * @brief 获取ch395的mac地址。 * @param amcaddr mac地址指针 * @retval 无 */ void ch395_cmd_get_macaddr(uint8_t *amcaddr) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD06_GET_MAC_ADDR); for (i = 0; i < 6; i++) { *amcaddr++ = ch395_read_data(); } ch395_scs_hign; } /** * @brief 设置mac过滤。 * @param filtype 参考 mac过滤 * @param table0 hash0 * @param table1 hash1 * @retval 无 */ void ch395_cmd_set_macfilt(uint8_t filtype, uint32_t table0, uint32_t table1) {ch395_scs_low; ch395_write_cmd(CMD90_SET_MAC_FILT); ch395_write_data(filtype); ch395_write_data((uint8_t)table0); ch395_write_data((uint8_t)((uint16_t)table0 >> 8)); ch395_write_data((uint8_t)(table0 >> 16)); ch395_write_data((uint8_t)(table0 >> 24)); ch395_write_data((uint8_t)table1); ch395_write_data((uint8_t)((uint16_t)table1 >> 8)); ch395_write_data((uint8_t)(table1 >> 16)); ch395_write_data((uint8_t)(table1 >> 24)); ch395_scs_hign; } /** * @brief 获取不可达信息 (ip,port,protocol type) * @param list 保存获取到的不可达 @arg 第1个字节为不可达代码,请参考 不可达代码(ch395inc.h) @arg 第2个字节为ip包协议类型 @arg 第3-4字节为端口号 @arg 第4-8字节为ip地址 * @retval 无 */ void ch395_cmd_get_unreachippt(uint8_t *list) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD08_GET_UNREACH_IPPORT); for (i = 0; i < 8; i++) { *list++ = ch395_read_data(); } ch395_scs_hign; } /** * @brief 获取远端的ip和端口地址,一般在tcp server模式下使用 * @param sockindex socket索引 * @param list 保存ip和端口 * @retval 无 */ void ch395_cmd_get_remoteipp(uint8_t sockindex, uint8_t *list) { uint8_t i; ch395_scs_low; ch395_write_cmd(CMD06_GET_REMOT_IPP_SN); ch395_write_data(sockindex); for (i = 0; i < 6; i++) { *list++ = ch395_read_data(); } ch395_scs_hign; } /** * @brief 设置socket n的目的ip地址 * @param sockindex socket索引 * @param ipaddr 指向ip地址 * @retval 无 */ void ch395_set_socket_desip(uint8_t sockindex, uint8_t *ipaddr) {ch395_scs_low; ch395_write_cmd(CMD50_SET_IP_ADDR_SN); ch395_write_data(sockindex); ch395_write_data(*ipaddr++); ch395_write_data(*ipaddr++); ch395_write_data(*ipaddr++); ch395_write_data(*ipaddr++); ch395_scs_hign; } /** * @brief 设置socket 的协议类型 * @param sockindex socket索引,prottype 协议类型 * @param 请参考 socket协议类型定义(ch395inc.h) * @retval 无 */ void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype) {ch395_scs_low; ch395_write_cmd(CMD20_SET_PROTO_TYPE_SN); ch395_write_data(sockindex); ch395_write_data(prottype); ch395_scs_hign; } /** * @brief 设置socket n的协议类型 * @param sockindex socket索引 * @param desprot 2字节目的端口 * @retval 无 */ void ch395_set_socket_desport(uint8_t sockindex, uint16_t desprot) {ch395_scs_low; ch395_write_cmd(CMD30_SET_DES_PORT_SN); ch395_write_data(sockindex); ch395_write_data((uint8_t)desprot); ch395_write_data((uint8_t)(desprot >> 8)); ch395_scs_hign; } /** * @brief 设置socket n的协议类型 * @param sockindex socket索引 * @param desprot 2字节源端口 * @retval 无 */ void ch395_set_socket_sourport(uint8_t sockindex, uint16_t surprot) {ch395_scs_low; ch395_write_cmd(CMD30_SET_SOUR_PORT_SN); ch395_write_data(sockindex); ch395_write_data((uint8_t)surprot); ch395_write_data((uint8_t)(surprot >> 8)); ch395_scs_hign; } /** * @brief ip模式下,socket ip包协议字段 * @param sockindex socket索引 * @param prototype ipraw模式1字节协议字段 * @retval 无 */ void ch395_set_socket_ipraw_proto(uint8_t sockindex, uint8_t prototype) {ch395_scs_low; ch395_write_cmd(CMD20_SET_IPRAW_PRO_SN); ch395_write_data(sockindex); ch395_write_data(prototype); ch395_scs_hign; } /** * @brief 开启/关闭 ping * @param senable :0 / 1, 具体含义如下: * @arg 1: 开启ping * @arg 0: 关闭ping * @retval 无 */ void ch395_enable_ping(uint8_t enable) {ch395_scs_low; ch395_write_cmd(CMD01_PING_ENABLE); ch395_write_data(enable); ch395_scs_hign; } /** * @brief 向发送缓冲区写数据 * @param sockindex socket索引 * @param databuf 数据缓冲区 * @param len 长度 * @retval 无 */ void ch395_send_data(uint8_t sockindex, uint8_t *databuf, uint16_t len) { uint16_t i; ch395_scs_low; ch395_write_cmd(CMD30_WRITE_SEND_BUF_SN); ch395_write_data((uint8_t)sockindex); ch395_write_data((uint8_t)len); ch395_write_data((uint8_t)(len >> 8)); for (i = 0; i < len; i++) { ch395_write_data(*databuf++); } ch395_scs_hign; } /** * @brief 获取接收缓冲区长度 * @param sockindex socket索引 * @retval 返回接收缓冲区有效长度 */ uint16_t ch395_get_recv_length(uint8_t sockindex) { uint16_t i; ch395_scs_low; ch395_write_cmd(CMD12_GET_RECV_LEN_SN); ch395_write_data((uint8_t)sockindex); i = ch395_read_data(); i = (uint16_t)(ch395_read_data() << 8) + i; ch395_scs_hign; return i; } /** * @brief 清除接收缓冲区 * @param sockindex socket索引 * @retval 无 */ void ch395_clear_recv_buf(uint8_t sockindex) {ch395_scs_low; ch395_write_cmd(CMD10_CLEAR_RECV_BUF_SN); ch395_write_data((uint8_t)sockindex); ch395_scs_hign; } /** * @brief 读取接收缓冲区数据 * @param sockindex socket索引 * @param len 长度 * @param pbuf 缓冲区 * @retval 无 */ void ch395_get_recv_data(uint8_t sockindex, uint16_t len, uint8_t *pbuf) { uint16_t i; if (!len)return; ch395_scs_low; ch395_write_cmd(CMD30_READ_RECV_BUF_SN); ch395_write_data(sockindex); ch395_write_data((uint8_t)len); ch395_write_data((uint8_t)(len >> 8)); HAL_Delay(1); for (i = 0; i < len; i++) { *pbuf = ch395_read_data(); pbuf++; } ch395_scs_hign; } /** * @brief 设置重试次数 * @param count 重试值,最大为20次 * @retval 无 */ void ch395_cmd_set_retry_count(uint8_t count) {ch395_scs_low; ch395_write_cmd(CMD10_SET_RETRAN_COUNT); ch395_write_data(count); ch395_scs_hign; } /** * @brief 设置重试周期 * @param period 重试周期单位为毫秒,最大1000ms * @retval 无 */ void ch395_cmd_set_retry_period(uint16_t period) {ch395_scs_low; ch395_write_cmd(CMD10_SET_RETRAN_COUNT); ch395_write_data((uint8_t)period); ch395_write_data((uint8_t)(period >> 8)); ch395_scs_hign; } /** * @brief 获取socket * @param sockindex socket索引 * @retval socket n的状态信息,第1字节为socket 打开或者关闭,第2字节为tcp状态 */ void ch395_cmd_get_socket_status(uint8_t sockindex, uint8_t *status) {ch395_scs_low; ch395_write_cmd(CMD12_GET_SOCKET_STATUS_SN); ch395_write_data(sockindex); *status++ = ch395_read_data(); *status++ = ch395_read_data(); ch395_scs_hign; } /** * @brief 打开socket,此命令需要等待执行成功 * @param sockindex socket索引 * @retval 返回执行结果 */ uint8_t ch395_open_socket(uint8_t sockindex) {ch395_scs_low; uint8_t i = 0; uint8_t s = 0; ch395_write_cmd(CMD1W_OPEN_SOCKET_SN); ch395_write_data(sockindex); ch395_scs_hign; while (1) { HAL_Delay(5); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief 关闭socket, * @param sockindex socket索引 * @retval 返回执行结果 */ uint8_t ch395_close_socket(uint8_t sockindex) {ch395_scs_low; uint8_t i = 0; uint8_t s = 0; ch395_write_cmd(CMD1W_CLOSE_SOCKET_SN); ch395_write_data(sockindex); ch395_scs_hign; while (1) { HAL_Delay(5); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief tcp连接,仅在tcp模式下有效,此命令需要等待执行成功 * @param sockindex socket索引 * @retval 返回执行结果 */ uint8_t ch395_tcp_connect(uint8_t sockindex) {ch395_scs_low; uint8_t i = 0; uint8_t s = 0; ch395_write_cmd(CMD1W_TCP_CONNECT_SN); ch395_write_data(sockindex); ch395_scs_hign; while (1) { HAL_Delay(5); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief tcp监听,仅在tcp模式下有效,此命令需要等待执行成功 * @param sockindex socket索引 * @retval 返回执行结果 */ uint8_t ch395_tcp_listen(uint8_t sockindex) {ch395_scs_low; uint8_t i = 0; uint8_t s = 0; ch395_write_cmd(CMD1W_TCP_LISTEN_SN); ch395_write_data(sockindex); ch395_scs_hign; while (1) { HAL_Delay(5); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief tcp断开,仅在tcp模式下有效,此命令需要等待执行成功 * @param sockindex socket索引 * @retval 无 */ uint8_t ch395_tcp_disconnect(uint8_t sockindex) {ch395_scs_low; uint8_t i = 0; uint8_t s = 0; ch395_write_cmd(CMD1W_TCP_DISNCONNECT_SN); ch395_write_data(sockindex); ch395_scs_hign; while (1) { HAL_Delay(5); /* 延时查询,建议2MS以上 */ s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果CH395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief 获取socket n的中断状态 * @param sockindex socket索引 * @retval 中断状态 */ uint8_t ch395_get_socket_int(uint8_t sockindex) {ch395_scs_low; uint8_t intstatus; ch395_write_cmd(CMD11_GET_INT_STATUS_SN); ch395_write_data(sockindex); HAL_Delay(2); intstatus = ch395_read_data(); ch395_scs_hign; return intstatus; } /** * @brief 对多播地址进行crc运算,并取高6位。 * @param mac_addr mac地址 * @retval 返回crc32的高6位 */ uint8_t ch395_crcret_6bit(uint8_t *mac_addr) {ch395_scs_low; signed long perbyte; signed long perbit; const uint32_t poly = 0x04c11db7; uint32_t crc_value = 0xffffffff; uint8_t c; for ( perbyte = 0; perbyte < 6; perbyte ++ ) { c = *(mac_addr++); for ( perbit = 0; perbit < 8; perbit++ ) { crc_value = (crc_value << 1) ^ ((((crc_value >> 31)^c) & 0x01) ? poly : 0); c >>= 1; } } crc_value = crc_value >> 26; return ((uint8_t)crc_value); } /** * @brief 启动/停止dhcp * @param flag:0 / 1, 具体含义如下: * @arg 1:启动dhcp * @arg 0:停止dhcp * @retval 执行状态 */ uint8_t ch395_dhcp_enable(uint8_t flag) {ch395_scs_low; uint8_t i = 0; uint8_t s; ch395_write_cmd(CMD10_DHCP_ENABLE); ch395_write_data(flag); ch395_scs_hign; while (1) { HAL_Delay(20); s = ch395_get_cmd_status(); /* 不能过于频繁查询 */ if (s != CH395_ERR_BUSY) { break; /* 如果ch395芯片返回忙状态 */ } if (i++ > 200) { return CH395_ERR_UNKNOW; /* 超时退出 */ } } return s; } /** * @brief 获取dhcp状态 * @param 无 * @retval dhcp状态,0为成功,其他值表示错误 */ uint8_t ch395_get_dhcp_status(void) {ch395_scs_low; uint8_t status; ch395_write_cmd(CMD01_GET_DHCP_STATUS); status = ch395_read_data(); ch395_scs_hign; return status; } /** * @brief 获取ip,子网掩码和网关地址 * @param sockindex socket索引 * @retval 12个字节的ip,子网掩码和网关地址 */ void ch395_get_ipinf(uint8_t *addr) {ch395_scs_low; uint8_t i; ch395_write_cmd(CMD014_GET_IP_INF); for (i = 0; i < 20; i++) { *addr++ = ch395_read_data(); } ch395_scs_hign; } /** * @brief 写gpio寄存器 * @param regadd 寄存器地址 * @param regval 寄存器值 * @retval 无 */ void ch395_write_gpio_addr(uint8_t regadd, uint8_t regval) {ch395_scs_low; ch395_write_cmd(CMD20_WRITE_GPIO_REG); ch395_write_data(regadd); ch395_write_data(regval); } /** * @brief 读gpio寄存器 * @param regadd 寄存器地址 * @retval 寄存器的值 */ uint8_t ch395_read_gpio_addr(uint8_t regadd) {ch395_scs_low; uint8_t i; ch395_write_cmd(CMD10_READ_GPIO_REG); ch395_write_data(regadd); HAL_Delay(1); i = ch395_read_data(); return i; } /** * @brief 擦除eeprom * @param 无 * @retval 执行状态 */ uint8_t ch395_eeprom_erase(void) {ch395_scs_low; uint8_t i; ch395_write_cmd(CMD00_EEPROM_ERASE); while (1) { HAL_Delay(20); i = ch395_get_cmd_status(); if (i == CH395_ERR_BUSY) { continue; } break; } return i; } /** * @brief 写eeprom * @param eepaddr eeprom地址 * @param buf 缓冲区地址 * @param len 长度 * @retval 无 */ uint8_t ch395_eeprom_write(uint16_t eepaddr, uint8_t *buf, uint8_t len) {ch395_scs_low; uint8_t i; ch395_write_cmd(CMD30_EEPROM_WRITE); ch395_write_data((uint8_t)(eepaddr)); ch395_write_data((uint8_t)(eepaddr >> 8)); ch395_write_data(len); while (len--)ch395_write_data(*buf++); while (1) { HAL_Delay(20); i = ch395_get_cmd_status(); if (i == CH395_ERR_BUSY) { continue; } break; } return i; } /** * @brief 写eeprom * @param eepaddr eeprom地址 * @param buf 缓冲区地址 * @param len 长度 * @retval 无 */ void ch395_eeprom_read(uint16_t eepaddr, uint8_t *buf, uint8_t len) { ch395_write_cmd(CMD30_EEPROM_READ); ch395_write_data((uint8_t)(eepaddr)); ch395_write_data((uint8_t)(eepaddr >> 8)); ch395_write_data(len); HAL_Delay(1); while (len--) { *buf++ = ch395_read_data(); } } /** * @brief 设置tcp mss值 * @param tcpmss * @retval 无 */ void ch395_set_tcpmss(uint16_t tcpmss) { ch395_write_cmd(CMD20_SET_TCP_MSS); ch395_write_data((uint8_t)(tcpmss)); ch395_write_data((uint8_t)(tcpmss >> 8)); } /** * @brief 设置socket接收缓冲区 * @param sockindex socket索引,址,blknum * @param startblk 起始地 * @param 单位缓冲区个数 ,单位为512字节 * @retval 无 */ void ch395_set_socket_recv_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum) { ch395_write_cmd(CMD30_SET_RECV_BUF); ch395_write_data(sockindex); ch395_write_data(startblk); ch395_write_data(blknum); } /** * @brief 设置socket发送缓冲区 * @param sockindex socket索引 * @param startblk 起始地址 * @param blknum 单位缓冲区个数 * @retval 无 */ void ch395_set_socket_send_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum) { ch395_write_cmd(CMD30_SET_SEND_BUF); ch395_write_data(sockindex); ch395_write_data(startblk); ch395_write_data(blknum); } /** * @brief udp向指定的ip和端口发送数据 * @param buf : 发送数据缓冲区 * @param len : 发送数据长度 * @param ip : 目标ip * @param port : 目标端口 * @param sockeid : socket索引值 * @retval 无 */ void ch395_udp_send_data(uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint8_t sockindex) { ch395_set_socket_desip(sockindex, ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_desport(sockindex, port); ch395_send_data(sockindex, buf, len); } /** * @brief 设置ch395启动参数 * @param mdata 设置的参数 * @retval 无 */ void ch395_set_start_para(uint32_t mdata) { ch395_write_cmd(CMD40_SET_FUN_PARA); ch395_write_data((uint8_t)mdata); ch395_write_data((uint8_t)((uint16_t)mdata >> 8)); ch395_write_data((uint8_t)(mdata >> 16)); ch395_write_data((uint8_t)(mdata >> 24)); } /** * @brief 获取全局中断状态,收到此命令ch395自动取消中断,0x44及以上版本使用 * @param 无 * @retval 返回当前的全局中断状态 */ uint16_t ch395_cmd_get_glob_int_status_all(void) {ch395_scs_low; uint16_t init_status; ch395_write_cmd(CMD02_GET_GLOB_INT_STATUS_ALL); HAL_Delay(2); init_status = ch395_read_data(); init_status = (uint16_t)(ch395_read_data() << 8) + init_status; ch395_scs_hign; return init_status; } /** * @brief 设置keepalive功能 * @param sockindex socket号 * @param cmd 0:关闭 1:开启 * @retval 无 */ void ch395_set_keeplive(uint8_t sockindex, uint8_t cmd) { ch395_write_cmd(CMD20_SET_KEEP_LIVE_SN); ch395_write_data(sockindex); ch395_write_data(cmd); } /** * @brief 设置keepalive重试次数 * @param cnt 重试次数() * @retval 无 */ void ch395_keeplive_cnt(uint8_t cnt) { ch395_write_cmd(CMD10_SET_KEEP_LIVE_CNT); ch395_write_data(cnt); } /** * @brief 设置keeplive空闲 * @param idle 空闲时间(单位:ms) * @retval 无 */ void ch395_keeplive_idle(uint32_t idle) { ch395_write_cmd(CMD40_SET_KEEP_LIVE_IDLE); ch395_write_data((uint8_t)idle); ch395_write_data((uint8_t)((uint16_t)idle >> 8)); ch395_write_data((uint8_t)(idle >> 16)); ch395_write_data((uint8_t)(idle >> 24)); } /** * @brief 设置keeplive间隔时间 * @param intvl 间隔时间(单位:ms) * @retval 无 */ void ch395_keeplive_intvl(uint32_t intvl) { ch395_write_cmd(CMD40_SET_KEEP_LIVE_INTVL); ch395_write_data((uint8_t)intvl); ch395_write_data((uint8_t)((uint16_t)intvl >> 8)); ch395_write_data((uint8_t)(intvl >> 16)); ch395_write_data((uint8_t)(intvl >> 24)); } /** * @brief 设置ttl * @param ssockindex socket号 * @param ttlnum:ttl数 * @retval 无 */ void ch395_setttl_num(uint8_t sockindex, uint8_t ttlnum) { ch395_write_cmd(CMD20_SET_TTL); ch395_write_data(sockindex); ch395_write_data(ttlnum); }
#include "ch395.h" #include "spi2.h" struct ch395q_t g_ch395q_sta; /** * @brief ch395_gpio初始化 * @param 无 * @retval 无 */ void ch395_gpio_init( void ) { GPIO_InitTypeDef gpio_init_struct; CH395_SCS_GPIO_CLK_ENABLE(); /* 使能SCS时钟 */ CH395_INT_GPIO_CLK_ENABLE(); /* 使能INT时钟 */ CH395_RST_GPIO_CLK_ENABLE(); /* 使能RST时钟 */ /* SCS */ gpio_init_struct.Pin = CH395_SCS_GPIO_PIN; gpio_init_struct.Speed = GPIO_SPEED_FREQ_MEDIUM; gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 推拉输出 */ HAL_GPIO_Init( CH395_SCS_GPIO_PORT, &gpio_init_struct ); /* 初始化中断引脚 */ gpio_init_struct.Pin = CH395_INT_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */ HAL_GPIO_Init( CH395_INT_GPIO_PORT, &gpio_init_struct ); gpio_init_struct.Pin = CH395_RST_GPIO_PIN; gpio_init_struct.Mode = GPIO_MODE_OUTPUT_PP; /* 输出 */ gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH; /* 高速 */ gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */ HAL_GPIO_Init( CH395_RST_GPIO_PORT, &gpio_init_struct ); HAL_GPIO_WritePin(CH395_RST_GPIO_PORT, CH395_RST_GPIO_PIN, GPIO_PIN_SET); HAL_Delay(20); } /** * @brief 硬件SPI输出且输入8个位数据 * @param d:将要送入到ch395的数据 * @retval 无 */ uint8_t ch395_read_write_byte( uint8_t data ) { uint8_t rxdata; rxdata = spi1_read_write_byte(data); /* SPI写入一个CH395Q数据并返回一个数据 */ return rxdata; /* 返回收到的数据 */ } /** * @brief 向ch395写命令 * @param 将要写入ch395的命令码 * @retval 无 */ void ch395_write_cmd( uint8_t mcmd ) { ch395_scs_hign; /* 防止CS原来为低,先将CS置高 */ ch395_scs_low; /* 命令开始,CS拉低 */ ch395_read_write_byte(mcmd); /* SPI发送命令码 */ HAL_Delay(2); /* 必要延时,延时1.5uS确保读写周期不小于1.5uS */ } /** * @brief 向ch395写数据 * @param 将要写入ch395的数据 * @retval 无 */ void ch395_write_data( uint8_t mdata ) { ch395_read_write_byte(mdata); /* SPI发送数据 */ } /** * @brief 从ch395读数据 * @param 无 * @retval 返回读取的数据 */ uint8_t ch395_read_data( void ) { uint8_t i; i = ch395_read_write_byte(0xff); /* SPI读数据 */ return i; } /** * @brief ch395_keeplive_set 保活定时器参数设置 * @param 无 * @retval 无 */ void ch395_keeplive_set(void) { ch395_keeplive_cnt(DEF_KEEP_LIVE_CNT); ch395_keeplive_idle(DEF_KEEP_LIVE_IDLE); ch395_keeplive_intvl(DEF_KEEP_LIVE_PERIOD); } /** * @brief ch395 socket配置 * @param ch395_sokect:Socket配置信息 * @retval 无 */ uint8_t ch395q_socket_config(ch395_socket * ch395_sokect) { if (ch395_sokect == NULL) { return 0; } if (g_ch395q_sta.dhcp_status == DHCP_UP) /* DHCP获取成功状态 */ { ch395_sokect->net_info.ip[0] = g_ch395q_sta.ipinf_buf[0]; ch395_sokect->net_info.ip[1] = g_ch395q_sta.ipinf_buf[1]; ch395_sokect->net_info.ip[2] = g_ch395q_sta.ipinf_buf[2]; ch395_sokect->net_info.ip[3] = g_ch395q_sta.ipinf_buf[3]; ch395_sokect->net_info.gwip[0] = g_ch395q_sta.ipinf_buf[4]; ch395_sokect->net_info.gwip[1] = g_ch395q_sta.ipinf_buf[5]; ch395_sokect->net_info.gwip[2] = g_ch395q_sta.ipinf_buf[6]; ch395_sokect->net_info.gwip[3] = g_ch395q_sta.ipinf_buf[7]; ch395_sokect->net_info.mask[0] = g_ch395q_sta.ipinf_buf[8]; ch395_sokect->net_info.mask[1] = g_ch395q_sta.ipinf_buf[9]; ch395_sokect->net_info.mask[2] = g_ch395q_sta.ipinf_buf[10]; ch395_sokect->net_info.mask[3] = g_ch395q_sta.ipinf_buf[11]; ch395_sokect->net_info.dns1[0] = g_ch395q_sta.ipinf_buf[12]; ch395_sokect->net_info.dns1[1] = g_ch395q_sta.ipinf_buf[13]; ch395_sokect->net_info.dns1[2] = g_ch395q_sta.ipinf_buf[14]; ch395_sokect->net_info.dns1[3] = g_ch395q_sta.ipinf_buf[15]; ch395_sokect->net_info.dns2[0] = g_ch395q_sta.ipinf_buf[16]; ch395_sokect->net_info.dns2[1] = g_ch395q_sta.ipinf_buf[17]; ch395_sokect->net_info.dns2[2] = g_ch395q_sta.ipinf_buf[18]; ch395_sokect->net_info.dns2[3] = g_ch395q_sta.ipinf_buf[19]; } else /* DHCP获取失败状态,设置静态IP地址信息 */ { ch395_cmd_set_ipaddr(ch395_sokect->net_config.ipaddr); /* 设置CH395的IP地址 */ ch395_cmd_set_gw_ipaddr(ch395_sokect->net_config.gwipaddr); /* 设置网关地址 */ ch395_cmd_set_maskaddr(ch395_sokect->net_config.maskaddr); /* 设置子网掩码,默认为255.255.255.0*/ ch395_cmd_init(); HAL_Delay(10); } ch395_cmd_set_macaddr(ch395_sokect->net_config.macaddr); /* 设置MAC地址 */ memcpy(&g_ch395q_sta.socket[ch395_sokect->socket_index].config, ch395_sokect, sizeof(ch395_socket)); switch(ch395_sokect->proto) { case CH395Q_SOCKET_UDP: /* socket 为UDP模式 */ ch395_set_socket_desip(ch395_sokect->socket_index, ch395_sokect->des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(ch395_sokect->socket_index, PROTO_TYPE_UDP); /* 设置socket 0协议类型 */ ch395_set_socket_desport(ch395_sokect->socket_index, ch395_sokect->des_port); /* 设置socket 0目的端口 */ ch395_set_socket_sourport(ch395_sokect->socket_index, ch395_sokect->sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(ch395_sokect->socket_index)); /* 检查是否成功 */ break; case CH395Q_SOCKET_TCP_CLIENT: /* socket 为TCPClient模式 */ ch395_keeplive_set(); /* 保活设置 */ ch395_set_socket_desip(ch395_sokect->socket_index, ch395_sokect->des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(ch395_sokect->socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */ ch395_set_socket_desport(ch395_sokect->socket_index, ch395_sokect->des_port); /* 设置socket 0目的端口 */ ch395_set_socket_sourport(ch395_sokect->socket_index, ch395_sokect->sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(ch395_sokect->socket_index)); /* 检查sokect是否打开成功 */ g_ch395q_sta.ch395_error(ch395_tcp_connect(ch395_sokect->socket_index)); /* 检查tcp连接是否成功 */ break; case CH395Q_SOCKET_TCP_SERVER: /* socket 为TCPServer模式 */ ch395_set_socket_desip(ch395_sokect->socket_index, ch395_sokect->des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(ch395_sokect->socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */ ch395_set_socket_sourport(ch395_sokect->socket_index, ch395_sokect->sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(ch395_sokect->socket_index)); /* 检查sokect是否打开成功 */ g_ch395q_sta.ch395_error(ch395_tcp_listen(ch395_sokect->socket_index)); /* 监听tcp连接 */ break; case CH395Q_SOCKET_MAC_RAW: ch395_set_socket_prot_type(ch395_sokect->socket_index, PROTO_TYPE_MAC_RAW); /* 设置socket 0协议类型 */ g_ch395q_sta.ch395_error(ch395_open_socket(ch395_sokect->socket_index)); /* 检查sokect是否打开成功 */ break; } return 1; } /** * @brief 调试使用,显示错误代码,并停机 * @param ierror 检测命令 * @retval 无 */ void ch395_error(uint8_t ierror) { if (ierror == CMD_ERR_SUCCESS) { return; /* 操作成功 */ } printf("Error: %02X\r\n", (uint16_t)ierror); /* 显示错误 */ while ( 1 ) { HAL_Delay(200); HAL_Delay(200); } } /** * @brief CH395 PHY状态 * @param phy_status:PHY状态值 * @retval 无 */ void ch395_phy_status(uint8_t phy_status) { switch (phy_status) { case PHY_DISCONN: printf("PHY DISCONN\r\n"); break; case PHY_10M_FLL: printf("PHY 10M_FLL\r\n"); break; case PHY_10M_HALF: printf("PHY 10M_HALF\r\n"); break; case PHY_100M_FLL: printf("PHY 100M_FLL\r\n"); break; case PHY_100M_HALF: printf("PHY 100M_HALF\r\n"); break; default: printf("PHY AUTO\r\n"); break; } HAL_Delay(1000); } /** * @brief 设置socket接口的接收与发送缓冲区 * @param 无 * @retval 无 */ void ch395_socket_r_s_buf_modify(void) { ch395_set_socket_recv_buf(0,0,4); /* Socket 0 ,接收缓冲区4*512 = 2K,发送缓冲区2*512 = 1K*/ ch395_set_socket_send_buf(0,4,2); ch395_set_socket_recv_buf(1,6,4); /* Socket 1 */ ch395_set_socket_send_buf(1,10,2); ch395_set_socket_recv_buf(2,12,4); /* Socket 2 */ ch395_set_socket_send_buf(2,16,2); ch395_set_socket_recv_buf(3,18,4); /* Socket 3 */ ch395_set_socket_send_buf(3,22,2); ch395_set_socket_recv_buf(4,24,4); /* Socket 4 */ ch395_set_socket_send_buf(4,28,2); ch395_set_socket_recv_buf(5,30,4); /* Socket 5 */ ch395_set_socket_send_buf(5,34,2); ch395_set_socket_recv_buf(6,36,4); /* Socket 6 */ ch395_set_socket_send_buf(6,40,2); ch395_set_socket_recv_buf(7,42,4); /* Socket 7 */ ch395_set_socket_send_buf(7,46,2); } /** * @brief ch395_tcp初始化 * @param 无 * @retval 无 */ void ch395_hardware_init(void) { uint8_t i; ch395_gpio_init(); spi1_init(); g_ch395q_sta.ch395_error = ch395_error; g_ch395q_sta.ch395_phy_cb = ch395_phy_status; g_ch395q_sta.ch395_reconnection = ch395_reconnection; g_ch395q_sta.dhcp_status = DHCP_STA; i = ch395_cmd_check_exist(0x65); /* 测试命令,用于测试硬件以及接口通讯 */ HAL_Delay(5); if (i != 0x9a) { g_ch395q_sta.ch395_error(i); /* ch395q检测错误 */ } ch395_cmd_reset(); /* 对ch395q复位 */ HAL_Delay(100); /* 这里必须等待100以上延时 */ g_ch395q_sta.ch395_error(ch395_cmd_init()); /* 初始化ch395q命令 */ ch395_socket_r_s_buf_modify(); // ch395_set_tcpmss(536); // ch395_set_start_para(FUN_PARA_FLAG_TCP_SERVER | SOCK_CTRL_FLAG_SOCKET_CLOSE); do { g_ch395q_sta.phy_status = ch395_cmd_get_phy_status(); /* 获取PHY状态 */ g_ch395q_sta.ch395_phy_cb(g_ch395q_sta.phy_status); /* 判断双工和网速模式 */ } while(g_ch395q_sta.phy_status == PHY_DISCONN); g_ch395q_sta.version = ch395_cmd_get_ver(); /* 获取版本 */ printf("CH395VER : %2x\r\n", (uint16_t)g_ch395q_sta.version); i = ch395_dhcp_enable(1); /* 开启DHCP */ g_ch395q_sta.ch395_error(i); /* ch395q检测错误 */ HAL_Delay(1000); /* ch395q初始化延时 */ } /** * @brief CH395 socket 中断,在全局中断中被调用 * @param sockindex (0~7) * @retval 无 */ void ch395_socket_interrupt(uint8_t sockindex) { uint8_t sock_int_socket; uint16_t rx_len = 0; sock_int_socket = ch395_get_socket_int(sockindex); /* 获取socket 的中断状态 */ if (sock_int_socket & SINT_STAT_SENBUF_FREE) /* 发送缓冲区空闲,可以继续写入要发送的数据 */ { } if (sock_int_socket & SINT_STAT_SEND_OK) /* 发送完成中断 */ { } if (sock_int_socket & SINT_STAT_RECV) /* 接收中断 */ { g_ch395q_sta.socket[sockindex].config.recv.size = ch395_get_recv_length(sockindex); /* 获取当前缓冲区内数据长度 */ rx_len = g_ch395q_sta.socket[sockindex].config.recv.size; ch395_get_recv_data(sockindex, rx_len, g_ch395q_sta.socket[sockindex].config.recv.buf); /* 读取数据 */ g_ch395q_sta.socket[sockindex].config.recv.buf[rx_len] = '\0'; printf("%s", g_ch395q_sta.socket[sockindex].config.recv.buf); g_ch395q_sta.socket[sockindex].config.recv.recv_flag |= 0x04; } if (sock_int_socket & SINT_STAT_CONNECT) /* 连接中断,仅在TCP模式下有效 */ { if (g_ch395q_sta.socket[sockindex].config.proto == CH395Q_SOCKET_TCP_CLIENT) { ch395_set_keeplive(sockindex,1); /* 打开KEEPALIVE保活定时器 */ ch395_setttl_num(sockindex,60); /* 设置TTL */ } } if (sock_int_socket & SINT_STAT_DISCONNECT) /* 断开中断,仅在TCP模式下有效 */ { g_ch395q_sta.ch395_error(ch395_open_socket(g_ch395q_sta.socket[sockindex].config.socket_index)); switch(g_ch395q_sta.socket[sockindex].config.proto) { case CH395Q_SOCKET_TCP_CLIENT: g_ch395q_sta.ch395_error(ch395_tcp_connect(g_ch395q_sta.socket[sockindex].config.socket_index)); break; case CH395Q_SOCKET_TCP_SERVER: g_ch395q_sta.ch395_error(ch395_tcp_listen(g_ch395q_sta.socket[sockindex].config.socket_index)); break; default: break; } HAL_Delay(200); /* 延时200MS后再次重试,没有必要过于频繁连接 */ } if (sock_int_socket & SINT_STAT_TIM_OUT) /* 超时中断,仅在TCP模式下有效 */ { if (g_ch395q_sta.socket[sockindex].config.proto == CH395Q_SOCKET_TCP_CLIENT) { HAL_Delay(200); /* 延时200MS后再次重试,没有必要过于频繁连接 */ g_ch395q_sta.ch395_error(ch395_open_socket(g_ch395q_sta.socket[sockindex].config.socket_index)); g_ch395q_sta.ch395_error(ch395_tcp_connect(g_ch395q_sta.socket[sockindex].config.socket_index)); } } } /** * @brief CH395全局中断函数 * @param 无 * @retval 无 */ void ch395_interrupt_handler(void) { uint16_t init_status; uint8_t i; init_status = ch395_cmd_get_glob_int_status_all(); if (init_status & GINT_STAT_UNREACH) /* 不可达中断,读取不可达信息 */ { ch395_cmd_get_unreachippt(g_ch395q_sta.ipinf_buf); } if (init_status & GINT_STAT_IP_CONFLI) /* 产生IP冲突中断,建议重新修改CH395的 IP,并初始化CH395 */ { } if (init_status & GINT_STAT_PHY_CHANGE) /* 产生PHY改变中断 */ { g_ch395q_sta.phy_status = ch395_cmd_get_phy_status(); /* 获取PHY状态 */ } if (init_status & GINT_STAT_DHCP) /* 处理DHCP中断 */ { i = ch395_get_dhcp_status(); switch (i) { case DHCP_UP: ch395_get_ipinf(g_ch395q_sta.ipinf_buf); printf("IP:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[0], (uint16_t)g_ch395q_sta.ipinf_buf[1], (uint16_t)g_ch395q_sta.ipinf_buf[2], (uint16_t)g_ch395q_sta.ipinf_buf[3]); printf("GWIP:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[4], (uint16_t)g_ch395q_sta.ipinf_buf[5], (uint16_t)g_ch395q_sta.ipinf_buf[6], (uint16_t)g_ch395q_sta.ipinf_buf[7]); printf("Mask:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[8], (uint16_t)g_ch395q_sta.ipinf_buf[9], (uint16_t)g_ch395q_sta.ipinf_buf[10], (uint16_t)g_ch395q_sta.ipinf_buf[11]); printf("DNS1:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[12], (uint16_t)g_ch395q_sta.ipinf_buf[13], (uint16_t)g_ch395q_sta.ipinf_buf[14], (uint16_t)g_ch395q_sta.ipinf_buf[15]); printf("DNS2:%02d.%02d.%02d.%02d\r\n", (uint16_t)g_ch395q_sta.ipinf_buf[16], (uint16_t)g_ch395q_sta.ipinf_buf[17], (uint16_t)g_ch395q_sta.ipinf_buf[18], (uint16_t)g_ch395q_sta.ipinf_buf[19]); g_ch395q_sta.dhcp_status = DHCP_UP; break; default: g_ch395q_sta.dhcp_status = DHCP_DOWN; /* 设置默认IP地址信息 */ printf("静态IP信息.....................................\r\n"); break; } } if (init_status & GINT_STAT_SOCK0) { ch395_socket_interrupt(CH395Q_SOCKET_0); /* 处理socket 0中断 */ } if (init_status & GINT_STAT_SOCK1) { ch395_socket_interrupt(CH395Q_SOCKET_1); /* 处理socket 1中断 */ } if (init_status & GINT_STAT_SOCK2) { ch395_socket_interrupt(CH395Q_SOCKET_2); /* 处理socket 2中断 */ } if (init_status & GINT_STAT_SOCK3) { ch395_socket_interrupt(CH395Q_SOCKET_3); /* 处理socket 3中断 */ } if (init_status & GINT_STAT_SOCK4) { ch395_socket_interrupt(CH395Q_SOCKET_4); /* 处理socket 4中断 */ } if (init_status & GINT_STAT_SOCK5) { ch395_socket_interrupt(CH395Q_SOCKET_5); /* 处理socket 5中断 */ } if (init_status & GINT_STAT_SOCK6) { ch395_socket_interrupt(CH395Q_SOCKET_6); /* 处理socket 6中断 */ } if (init_status & GINT_STAT_SOCK7) { ch395_socket_interrupt(CH395Q_SOCKET_7); /* 处理socket 7中断 */ } } /** * @brief CH395全局管理函数 * @param 无 * @retval 无 */ void ch395q_handler(void) { if (ch395_int_pin_wire == 0) { ch395_interrupt_handler(); /* 中断处理函数 */ } g_ch395q_sta.ch395_reconnection(); /* 检测PHY状态,并重新连接 */ } /** * @brief 检测PHY状态,并重新连接 * @param 无 * @retval 无 */ void ch395_reconnection(void) { for (uint8_t socket_index = CH395Q_SOCKET_0 ; socket_index <= CH395Q_SOCKET_7 ; socket_index ++ ) { if (g_ch395q_sta.phy_status == PHY_DISCONN && (g_ch395q_sta.dhcp_status == DHCP_UP || g_ch395q_sta.dhcp_status == DHCP_DOWN || g_ch395q_sta.dhcp_status == DHCP_STA)) { if (g_ch395q_sta.socket[socket_index].config.socket_enable == CH395Q_ENABLE) { ch395_close_socket(g_ch395q_sta.socket[socket_index].config.socket_index); g_ch395q_sta.ch395_error(ch395_dhcp_enable(0)); /* ch395q检测错误 */ g_ch395q_sta.socket[socket_index].config.socket_enable = CH395Q_DISABLE; g_ch395q_sta.dhcp_status = DHCP_STA; } } else { if (g_ch395q_sta.phy_status != PHY_DISCONN && g_ch395q_sta.socket[socket_index].config.socket_enable == CH395Q_DISABLE) { if (g_ch395q_sta.dhcp_status == DHCP_STA) { ch395_cmd_reset(); /* 对ch395q复位 */ HAL_Delay(100); /* 这里必须等待100以上延时 */ ch395_cmd_init(); HAL_Delay(100); /* 这里必须等待100以上延时 */ ch395_socket_r_s_buf_modify(); // ch395_set_tcpmss(536); // ch395_set_start_para(FUN_PARA_FLAG_TCP_SERVER | SOCK_CTRL_FLAG_SOCKET_CLOSE); g_ch395q_sta.ch395_error(ch395_dhcp_enable(1)); /* 开启DHCP */ } do { if (ch395_int_pin_wire == 0) { ch395_interrupt_handler(); /* 中断处理函数 */ } } while (g_ch395q_sta.dhcp_status == DHCP_STA); /* 获取DHCP */ switch(g_ch395q_sta.socket[socket_index].config.proto) { case CH395Q_SOCKET_UDP: /* socket 为UDP模式 */ ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(socket_index, PROTO_TYPE_UDP); /* 设置socket 0协议类型 */ ch395_set_socket_desport(socket_index, g_ch395q_sta.socket[socket_index].config.des_port); /* 设置socket 0目的端口 */ ch395_set_socket_sourport(socket_index, g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查是否成功 */ break; case CH395Q_SOCKET_TCP_CLIENT: /* socket 为TCPClient模式 */ ch395_keeplive_set(); /* 保活设置 */ ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */ ch395_set_socket_desport(socket_index,g_ch395q_sta.socket[socket_index].config.des_port); /* 设置socket 0目的端口 */ ch395_set_socket_sourport(socket_index,g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */ g_ch395q_sta.ch395_error(ch395_tcp_connect(socket_index)); /* 检查tcp连接是否成功 */ break; case CH395Q_SOCKET_TCP_SERVER: /* socket 为TCPServer模式 */ ch395_set_socket_desip(socket_index, g_ch395q_sta.socket[socket_index].config.des_ip); /* 设置socket 0目标IP地址 */ ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP); /* 设置socket 0协议类型 */ ch395_set_socket_sourport(socket_index, g_ch395q_sta.socket[socket_index].config.sour_port); /* 设置socket 0源端口 */ g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */ g_ch395q_sta.ch395_error(ch395_tcp_listen(socket_index)); /* 监听tcp连接 */ break; case CH395Q_SOCKET_MAC_RAW: ch395_set_socket_prot_type(socket_index, PROTO_TYPE_MAC_RAW); /* 设置socket 0协议类型 */ g_ch395q_sta.ch395_error(ch395_open_socket(socket_index)); /* 检查sokect是否打开成功 */ break; default: ch395_set_socket_prot_type(socket_index, PROTO_TYPE_TCP); ch395_set_socket_sourport(socket_index, 8080); /* 设置socket 1~7源端口 */ break; } g_ch395q_sta.socket[socket_index].config.socket_enable = CH395Q_ENABLE; } } } }
#ifndef __CH395_H #define __CH395_H #include "ch395inc.h" #include "main.h" #include "ch395inc.h" #include "ch395cmd.h" #include "string.h" #include "stdio.h" /******************************************************************************************/ /* 引脚 定义 */ #define CH395_SCS_GPIO_PORT GPIOG #define CH395_SCS_GPIO_PIN GPIO_PIN_9 #define CH395_SCS_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOG_CLK_ENABLE(); }while(0) /* PG口时钟使能 */ #define CH395_INT_GPIO_PORT GPIOG #define CH395_INT_GPIO_PIN GPIO_PIN_6 #define CH395_INT_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOG_CLK_ENABLE(); }while(0) /* PG口时钟使能 */ #define CH395_RST_GPIO_PORT GPIOD #define CH395_RST_GPIO_PIN GPIO_PIN_7 #define CH395_RST_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0) /* PD口时钟使能 */ /******************************************************************************************/ #define ch395_scs_low HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_RESET) /* SPI片选引脚输出低电平 */ #define ch395_scs_hign HAL_GPIO_WritePin(GPIOG, GPIO_PIN_9, GPIO_PIN_SET) /* SPI片选引脚输出高电平 */ #define ch395_sdo_pin HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_6) /* 获取CH395的SPI数据输出引脚电平 */ #define ch395_int_pin_wire HAL_GPIO_ReadPin(GPIOG,GPIO_PIN_6) /* 假定CH395的INT#引脚,如果未连接那么也可以通过查询兼做中断输出的SDO引脚状态实现 */ typedef struct ch395q_socket_t { uint8_t socket_enable; /* Socket使能 */ uint8_t socket_index; /* Socket标号 */ uint8_t proto; /* Socket协议 */ uint8_t des_ip[4]; /* 目的IP地址 */ uint16_t des_port; /* 目的端口 */ uint16_t sour_port; /* 源端口 */ struct { uint8_t *buf; /* 缓冲空间 */ uint32_t size; /* 缓冲空间大小 */ } send; /* 发送缓冲 */ struct { uint8_t recv_flag; /* 接收数据标志位 */ uint8_t *buf; /* 缓冲空间 */ uint32_t size; /* 缓冲空间大小 */ } recv; /* 接收缓冲 */ struct { uint8_t ip[4]; /* IP地址 */ uint8_t gwip[4]; /* 网关IP地址 */ uint8_t mask[4]; /* 子网掩码 */ uint8_t dns1[4]; /* DNS服务器1地址 */ uint8_t dns2[4]; /* DNS服务器2地址 */ } net_info; /* 网络信息 */ struct { uint8_t ipaddr[4]; /* IP地址 32bit*/ uint8_t gwipaddr[4]; /* 网关地址 32bit*/ uint8_t maskaddr[4]; /* 子网掩码 32bit*/ uint8_t macaddr[6]; /* MAC地址 48bit*/ } net_config; /* 网络配置信息 */ } ch395_socket; /* DHCP状态 */ enum DHCP { DHCP_UP = 0, /* DHCP获取成功状态 */ DHCP_DOWN, /* DHCP获取失败状态 */ DHCP_STA, /* DHCP开启状态 */ }; struct ch395q_t { uint8_t version; /* 版本信息 */ uint8_t phy_status; /* PHY状态 */ uint8_t dhcp_status; /* DHCP状态 */ uint8_t ipinf_buf[20]; /* 获取IP信息 */ struct { ch395_socket config; /* 配置信息 */ } socket[8]; /* Socket状态 */ void (*ch395_error)(uint8_t i); /* ch395q错误检测函数 */ void (*ch395_phy_cb)(uint8_t phy_status); /* ch395q phy状态回调函数 */ void (*ch395_reconnection)(void); /* ch395q 重新连接函数 */ }; extern struct ch395q_t g_ch395q_sta; /* CH395Q模块Socket标号定义 */ #define CH395Q_SOCKET_0 0 /* Socket 0 */ #define CH395Q_SOCKET_1 1 /* Socket 1 */ #define CH395Q_SOCKET_2 2 /* Socket 2 */ #define CH395Q_SOCKET_3 3 /* Socket 3 */ #define CH395Q_SOCKET_4 4 /* Socket 4 */ #define CH395Q_SOCKET_5 5 /* Socket 5 */ #define CH395Q_SOCKET_6 6 /* Socket 6 */ #define CH395Q_SOCKET_7 7 /* Socket 7 */ /* 使能定义 */ #define CH395Q_DISABLE 1 /* 禁用 */ #define CH395Q_ENABLE 2 /* 使能 */ /* CH395Q模块Socket协议类型定义 */ #define CH395Q_SOCKET_UDP 0 /* UDP */ #define CH395Q_SOCKET_TCP_CLIENT 1 /* TCP客户端 */ #define CH395Q_SOCKET_TCP_SERVER 2 /* TCP服务器 */ #define CH395Q_SOCKET_MAC_RAW 3 /* MAC_RAW */ #define DEF_KEEP_LIVE_IDLE (15*1000) /* 空闲时间 */ #define DEF_KEEP_LIVE_PERIOD (15*1000) /* 间隔为15秒,发送一次KEEPLIVE数据包 */ #define DEF_KEEP_LIVE_CNT 200 uint8_t ch395_read_data(void ) ; void ch395_write_cmd( uint8_t mcmd ); void ch395_write_data( uint8_t mdata ); void ch395q_handler(void); void ch395_interrupt_handler(void); void ch395_hardware_init(void); uint8_t ch395q_socket_config(ch395_socket * ch395_sokect); void ch395_reconnection(void); #endif
#ifndef __CH395CMD_H__ #define __CH395CMD_H__ #include "ch395inc.h" #include "main.h" void ch395_cmd_reset(void); /* 复位 */ void ch395_cmd_sleep(void); /* 睡眠 */ uint8_t ch395_cmd_get_ver(void); /* 获取芯片及固件版本号 */ uint8_t ch395_cmd_check_exist(uint8_t testdata); /* 测试命令 */ void ch395_cmd_set_phy(uint8_t phystat); /* 设置phy状态 */ uint8_t ch395_cmd_get_phy_status(void); /* 获取phy状态 */ uint8_t ch395_cmd_get_glob_int_status(void); /* 获取ch395全局中断状态 */ uint8_t ch395_cmd_init(void); /* 初始化ch395 */ void ch395_cmd_set_uart_baud_rate(uint32_t baudrate); /* 设置波特率 */ uint8_t ch395_get_cmd_status(void); /* 获取命令执行状态 */ void ch395_cmd_set_ipaddr(uint8_t *ipaddr); /* 设置ch395的ip地址 */ void ch395_cmd_set_gw_ipaddr(uint8_t *gwipaddr); /* 设置ch395的网关ip地址 */ void ch395_cmd_set_maskaddr(uint8_t *maskaddr); /* 设置子网掩码 */ void ch395_cmd_set_macaddr(uint8_t *amcaddr); /* 设置ch395的mac地址 */ void ch395_cmd_get_macaddr(uint8_t *amcaddr); /* 获取mac地址 */ void ch395_cmd_set_macfilt(uint8_t filtype, uint32_t table0, uint32_t table1); /* 设置ch395的mac过滤 */ void ch395_cmd_get_unreachippt(uint8_t *list); /* 获取不可达地址以及端口 */ void ch395_cmd_get_remoteipp(uint8_t sockindex, uint8_t *list); /* 获取远端ip和端口,一般在tcp server下使用 */ void ch395_set_socket_desip(uint8_t sockindex, uint8_t *ipaddr); /* 设置scoket n的目的ip地址 */ void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype); /* 设置socket n的协议类型 */ void ch395_set_socket_desport(uint8_t sockindex, uint16_t desprot); /* 设置socket n的目的端口 */ void ch395_set_socket_sourport(uint8_t sockindex, uint16_t surprot); /* 设置socket n的源端口 */ void ch395_set_socket_ipraw_proto(uint8_t sockindex, uint8_t prototype); /* 在ipraw模式下,设置socket n的ip包协议字段 */ void ch395_set_recv_threslen(uint8_t sockindex, uint16_t len); /* 设置socket n的接收中断阀值 */ void ch395_send_data(uint8_t sockindex, uint8_t *databuf, uint16_t len); /* 向socket n的发送缓冲区写数据 */ uint16_t ch395_get_recv_length(uint8_t sockindex); /* 获取socket n的接收长度 */ void ch395_clear_recv_buf(uint8_t sockindex); /* 清除socket n的接收缓冲区 */ void ch395_get_recv_data(uint8_t sockindex, uint16_t len, uint8_t *pbuf); /* 获取接收数据 */ void ch395_cmd_set_retry_count(uint8_t count); /* 设置最大重试次数 */ void ch395_cmd_set_retry_period(uint16_t period); /* 设置最大重试周期 单位 毫秒 */ void ch395_cmd_get_socket_status(uint8_t sockindex, uint8_t *status) ; /* 获取socket n的状态 */ uint8_t ch395_open_socket(uint8_t sockindex); /* 打开socket n*/ uint8_t ch395_close_socket(uint8_t sockindex); /* 关闭socket n*/ uint8_t ch395_tcp_connect(uint8_t sockindex); /* tcp连接 */ uint8_t ch395_tcp_listen(uint8_t sockindex); /* tcp监听 */ uint8_t ch395_tcp_disconnect(uint8_t sockindex); /* tcp断开连接 */ uint8_t ch395_get_socket_int(uint8_t sockindex); /* 获取socket n的中断状态 */ uint8_t ch395_crcret_6bit(uint8_t *mac_addr); /* 多播地址crc32,用于hash过滤 function count = 36 */ void ch395_get_ipinf(uint8_t *addr); /* 获取ip,子网掩码和网关地址 */ uint8_t ch395_get_dhcp_status(void); /* 获取dhcp状态 */ uint8_t ch395_dhcp_enable(uint8_t flag); /* 启动/停止dhcp */ void ch395_write_gpio_addr(uint8_t regadd, uint8_t regval); /* 写gpio寄存器 */ uint8_t ch395_read_gpio_addr(uint8_t regadd); /* 读gpio寄存器 */ uint8_t ch395_eeprom_erase(void); /* 擦除eeprom */ uint8_t ch395_eeprom_write(uint16_t eepaddr, uint8_t *buf, uint8_t len); /* 写eeprom */ void ch395_eeprom_read(uint16_t eepaddr, uint8_t *buf, uint8_t len); /* 读eeprom */ void ch395_set_tcpmss(uint16_t tcpmss); /* 设置tcp mss值 */ void ch395_set_socket_recv_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum); /* 设置socket接收缓冲区 */ void ch395_set_socket_send_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum); /* 设置socket发送缓冲区 */ void ch395_udp_send_data(uint8_t *buf, uint32_t len, uint8_t *ip, uint16_t port, uint8_t sockindex); /* udp向指定的ip和端口发送数据 */ void ch395_set_start_para(uint32_t mdata); /* 设置ch395启动参数 */ uint16_t ch395_cmd_get_glob_int_status_all(void); /* 获取全局中断状态,收到此命令ch395自动取消中断,0x44及以上版本使用 */ void ch395_keeplive_idle(uint32_t idle); /* 设置keeplive空闲 */ void ch395_keeplive_intvl(uint32_t intvl); /* 设置keeplive间隔时间 */ void ch395_keeplive_cnt(uint8_t cnt); /* 设置keepalive重试次数 */ void ch395_set_keeplive(uint8_t sockindex, uint8_t cmd); /* 设置ttl */ void ch395_setttl_num(uint8_t sockindex, uint8_t ttlnum); /* 设置ttl */ #endif
#ifndef __CH395INC_H__ #define __CH395INC_H__ /* ********************************************************************************************************************* */ /* 常用类型和常量定义 */ #ifdef __cplusplus extern "C" { #endif #ifndef TRUE #define TRUE 1 #define FALSE 0 #endif #ifndef NULL #define NULL 0 #endif /* 命令代码: * 一个命令操作顺序包含: * 一个命令码(对于串口方式,命令码之前还需要两个同步码) * 若干个输入数据(可以是0个) * 若干个输出数据(可以是0个) * 命令码起名规则: CMDxy_NAME * 其中的x和y都是数字, x说明最少输入数据个数(字节数), y说明最少输出数据个数(字节数), y如果是W表示需要等待命令执行成功 * 有些命令能够实现0到多个字节的数据块读写, 数据块本身的字节数未包含在上述x或y之内 */ #define CMD01_GET_IC_VER 0x01 /* 获取芯片以及固件版本号 */ #define CMD31_SET_BAUDRATE 0x02 /* 串口方式: 设置串口通讯波特率(上电或者复位后的默认波特率为9600bps */ #define CMD00_ENTER_SLEEP 0x03 /* 进入睡眠状态 */ #define CMD00_RESET_ALL 0x05 /* 执行硬件复位 */ #define CMD11_CHECK_EXIST 0x06 /* 测试通讯接口以及工作状态 */ #define CMD02_GET_GLOB_INT_STATUS_ALL 0x19 /* 获取全局中断状态,V44版本以后的程序由于增加了socket数量需要用此命令获取全部的中断 */ #define CMD10_SET_PHY 0x20 /* 设置PHY,默认为Auto,自动协商 */ #define CMD60_SET_MAC_ADDR 0x21 /* 设置MAC地址 必须在CMD00H_INIT_CH395之前设置完毕 */ #define CMD40_SET_IP_ADDR 0x22 /* 设置IP地址 必须在CMD00H_INIT_CH395之前设置完毕 */ #define CMD40_SET_GWIP_ADDR 0x23 /* 设置网关IP地址 必须在CMD00H_INIT_CH395之前设置完毕 */ #define CMD40_SET_MASK_ADDR 0x24 /* 设置子网掩码, 必须在CMD00H_INIT_CH395之前设置完毕 */ #define CMD90_SET_MAC_FILT 0x25 /* 设置MAC过滤 可以进行广播,多播等过滤 */ #define CMD01_GET_PHY_STATUS 0x26 /* 获取PHY当前状态,如断开连接,10/100M FULL/HALF */ #define CMD0W_INIT_CH395 0x27 /* 初始化CH395 */ #define CMD08_GET_UNREACH_IPPORT 0x28 /* 获取不可达信息 */ #define CMD01_GET_GLOB_INT_STATUS 0x29 /* 获取全局中断状态,最大值为1S,不可以设置为0 */ #define CMD10_SET_RETRAN_COUNT 0x2A /* 重试次数,仅在TCP模式下有效 */ #define CMD20_SET_RETRAN_PERIOD 0x2B /* 重试周期,最大值为20,仅在TCP模式下有效,不可以设置为0 */ #define CMD01_GET_CMD_STATUS 0x2C /* 获取命令执行状态 */ #define CMD06_GET_REMOT_IPP_SN 0x2D /* 获取远端的端口以及IP地址,该命令在TCP服务器模式下使用 */ #define CMD10_CLEAR_RECV_BUF_SN 0x2E /* 清除接收缓冲区 */ #define CMD12_GET_SOCKET_STATUS_SN 0x2F /* 获取socket n状态 */ #define CMD11_GET_INT_STATUS_SN 0x30 /* 获取socket n的中断状态 */ #define CMD50_SET_IP_ADDR_SN 0x31 /* 设置socket n的目的IP地址 */ #define CMD30_SET_DES_PORT_SN 0x32 /* 设置socket n的目的端口 */ #define CMD30_SET_SOUR_PORT_SN 0x33 /* 设置socket n的源端口 */ #define CMD20_SET_PROTO_TYPE_SN 0x34 /* 设置socket n的协议类型 */ #define CMD1W_OPEN_SOCKET_SN 0x35 /* 打开socket n */ #define CMD1W_TCP_LISTEN_SN 0x36 /* socket n监听,收到此命令,socket n进入服务器模式,仅对TCP模式有效 */ #define CMD1W_TCP_CONNECT_SN 0x37 /* socket n连接,收到此命令,socket n进入客户端模式,仅对TCP模式有效 */ #define CMD1W_TCP_DISNCONNECT_SN 0x38 /* socket n断开连接,收到此命令,socket n断开已有连接,仅对TCP模式有效 */ #define CMD30_WRITE_SEND_BUF_SN 0x39 /* 向socket n缓冲区写入数据 */ #define CMD12_GET_RECV_LEN_SN 0x3B /* 获取socket n接收数据的长度 */ #define CMD30_READ_RECV_BUF_SN 0x3C /* 读取socket n接收缓冲区数据 */ #define CMD1W_CLOSE_SOCKET_SN 0x3D /* 关闭socket n */ #define CMD20_SET_IPRAW_PRO_SN 0x3E /* 在IP RAW下,设置socket n的IP包协议类型 */ #define CMD01_PING_ENABLE 0x3F /* 开启/关闭PING */ #define CMD06_GET_MAC_ADDR 0x40 /* 获取MAC地址 */ #define CMD10_DHCP_ENABLE 0x41 /* DHCP使能 */ #define CMD01_GET_DHCP_STATUS 0x42 /* 获取DHCP状态 */ #define CMD014_GET_IP_INF 0x43 /* IP,子网掩码,网关 */ #define CMD00_PPPOE_SET_USER_NAME 0x44 /* 设置PPPOE用户名 */ #define CMD00_PPPOE_SET_PASSWORD 0x45 /* 设置密码 */ #define CMD10_PPPOE_ENABLE 0x46 /* PPPOE使能 */ #define CMD01_GET_PPPOE_STATUS 0x47 /* 获取pppoe状态 */ #define CMD20_SET_TCP_MSS 0x50 /* 设置TCP MSS */ #define CMD20_SET_TTL 0x51 /* 设置TTL,TTL最大值为128 */ #define CMD30_SET_RECV_BUF 0x52 /* 设置SOCKET接收缓冲区 */ #define CMD30_SET_SEND_BUF 0x53 /* 设置SOCKET发送缓冲区 */ #define CMD10_SET_MAC_RECV_BUF 0x54 /* 设置MAC接收缓冲区 */ #define CMD40_SET_FUN_PARA 0x55 /* 设置功能参数 */ #define CMD40_SET_KEEP_LIVE_IDLE 0x56 /* 设置KEEPLIVE空闲 */ #define CMD40_SET_KEEP_LIVE_INTVL 0x57 /* 设置间隔时间 */ #define CMD10_SET_KEEP_LIVE_CNT 0x58 /* 重试次数 */ #define CMD20_SET_KEEP_LIVE_SN 0X59 /* 设置socket nkeeplive功能*/ #define CMD00_EEPROM_ERASE 0xE9 /* 擦除EEPROM*/ #define CMD30_EEPROM_WRITE 0xEA /* 写EEPROM */ #define CMD30_EEPROM_READ 0xEB /* 读EEPROM */ #define CMD10_READ_GPIO_REG 0xEC /* 读GPIO寄存器 */ #define CMD20_WRITE_GPIO_REG 0xED /* 写GPIO寄存器 */ /* 协议类型 */ #define PROTO_TYPE_IP_RAW 0 /* IP层原始数据 */ #define PROTO_TYPE_MAC_RAW 1 /* MAC层原始数据 */ #define PROTO_TYPE_UDP 2 /* UDP协议类型 */ #define PROTO_TYPE_TCP 3 /* TCP协议类型 */ /* PHY 命令参数/状态 */ #define PHY_DISCONN (1<<0) /* PHY断开 */ #define PHY_10M_FLL (1<<1) /* 10M全双工 */ #define PHY_10M_HALF (1<<2) /* 10M半双工 */ #define PHY_100M_FLL (1<<3) /* 100M全双工 */ #define PHY_100M_HALF (1<<4) /* 100M半双工 */ #define PHY_AUTO (1<<5) /* PHY自动模式,CMD10H_SET_PHY */ /* CH395 MAC过滤 */ #define MAC_FILT_RECV_BORADPKT (1<<0) /* 使能接收广播包 */ #define MAC_FILT_RECV_ALL (1<<1) /* 使能接收所有数据包 */ #define MAC_FILT_RECV_MULTIPKT (1<<2) /* 使能接收多播包 */ #define MAC_FILT_RECV_ENABLE (1<<3) /* 使能接收 */ #define MAC_FILT_SEND_ENABLE (1<<4) /* 使能发送 */ /* 中断状态 */ /* 以下为GLOB_INT会产生的状态 */ #define GINT_STAT_UNREACH (1<<0) /* 不可达中断 */ #define GINT_STAT_IP_CONFLI (1<<1) /* IP冲突 */ #define GINT_STAT_PHY_CHANGE (1<<2) /* PHY状态改变 */ #define GINT_STAT_DHCP (1<<3) /* PHY状态改变 */ #define GINT_STAT_SOCK0 (1<<4) /* socket0 产生中断 */ #define GINT_STAT_SOCK1 (1<<5) /* socket1 产生中断 */ #define GINT_STAT_SOCK2 (1<<6) /* socket2 产生中断 */ #define GINT_STAT_SOCK3 (1<<7) /* socket3 产生中断 */ #define GINT_STAT_SOCK4 (1<<8) /* scoket4 产生中断 */ #define GINT_STAT_SOCK5 (1<<9) /* scoket5 产生中断 */ #define GINT_STAT_SOCK6 (1<<10) /* scoket6 产生中断 */ #define GINT_STAT_SOCK7 (1<<11) /* scoket7 产生中断 */ /* 以下为Sn_INT会产生的状态 */ #define SINT_STAT_SENBUF_FREE (1<<0) /* 发送缓冲区空闲 */ #define SINT_STAT_SEND_OK (1<<1) /* 发送成功 */ #define SINT_STAT_RECV (1<<2) /* socket端口接收到数据或者接收缓冲区不为空 */ #define SINT_STAT_CONNECT (1<<3) /* 连接成功,TCP模式下产生此中断 */ #define SINT_STAT_DISCONNECT (1<<4) /* 连接断开,TCP模式下产生此中断 */ #define SINT_STAT_TIM_OUT (1<<6) /* ARP和TCP模式下会发生此中断 */ /* 获取命令状态 */ #define CMD_ERR_SUCCESS 0x00 /* 命令操作成功 */ #define CMD_RET_ABORT 0x5F /* 命令操作失败 */ #define CH395_ERR_BUSY 0x10 /* 忙状态,表示当前正在执行命令 */ #define CH395_ERR_MEM 0x11 /* 内存错误 */ #define CH395_ERR_BUF 0x12 /* 缓冲区错误 */ #define CH395_ERR_TIMEOUT 0x13 /* 超时 */ #define CH395_ERR_RTE 0x14 /* 路由错误*/ #define CH395_ERR_ABRT 0x15 /* 连接停止*/ #define CH395_ERR_RST 0x16 /* 连接复位 */ #define CH395_ERR_CLSD 0x17 /* 连接关闭/socket 在关闭状态 */ #define CH395_ERR_CONN 0x18 /* 无连接 */ #define CH395_ERR_VAL 0x19 /* 错误的值 */ #define CH395_ERR_ARG 0x1a /* 错误的参数 */ #define CH395_ERR_USE 0x1b /* 已经被使用 */ #define CH395_ERR_IF 0x1c /* MAC错误 */ #define CH395_ERR_ISCONN 0x1d /* 已连接 */ #define CH395_ERR_OPEN 0X20 /* 已经打开 */ #define CH395_ERR_UNKNOW 0xFA /* 未知错误 */ /* PPP状态 */ #define CH395_PPP_SUCCESS 0 /* 成功 */ #define CH395_PPPERR_PARM 1 /* 无效参数 */ #define CH395_PPPERR_OPEN 2 /* 无法打开PPP会话 */ #define CH395_PPPERR_DEVICE 3 /* 无效的PPP设备 */ #define CH395_PPPERR_ALLOC 4 /* 资源分配失败 */ #define CH395_PPPERR_USER 5 /* 用户中断 */ #define CH395_PPPERR_CONNECT 6 /* 连接断开 */ #define CH395_PPPERR_AUTHFAIL 7 /* 挑战鉴别失败 */ #define CH395_PPPERR_PROTOCOL 8 /* 握手协议失败 */ #define CH395_PPPERR_TIME_OUT 9 /* 超时失败 */ #define CH395_PPPERR_CLOSE 10 /* 关闭失败 */ /* 不可达代码 */ #define UNREACH_CODE_HOST 0 /* 主机不可达 */ #define UNREACH_CODE_NET 1 /* 网络不可达 */ #define UNREACH_CODE_PROTOCOL 2 /* 协议不可达 */ #define UNREACH_CODE_PROT 3 /* 端口不可达 */ /* 其他值请参考RFC792文档 */ /* 命令包头 */ #define SER_SYNC_CODE1 0x57 /* 串口命令同步码1 */ #define SER_SYNC_CODE2 0xAB /* 串口命令同步码2 */ /* TCP状态 */ #define TCP_CLOSED 0 #define TCP_LISTEN 1 #define TCP_SYN_SENT 2 #define TCP_SYN_RCVD 3 #define TCP_ESTABLISHED 4 #define TCP_FIN_WAIT_1 5 #define TCP_FIN_WAIT_2 6 #define TCP_CLOSE_WAIT 7 #define TCP_CLOSING 8 #define TCP_LAST_ACK 9 #define TCP_TIME_WAIT 10 /* GPIO寄存器地址 */ #define GPIO_DIR_REG 0x80 /* 寄存器方向寄存器,1:输出;0:输入 */ #define GPIO_IN_REG 0x81 /* GPIO输入寄存器 */ #define GPIO_OUT_REG 0x82 /* GPIO输出寄存器 */ #define GPIO_CLR_REG 0x83 /* GPIO输出清除: 0=keep, 1=clear */ #define GPIO_PU_REG 0x84 /* GPIO上拉使能寄存器 */ #define GPIO_PD_REG 0x85 /* GPIO下拉使能寄存器 */ /* 功能参数 */ #define FUN_PARA_FLAG_TCP_SERVER (1<<1) /* tcp server 多连接模式标志,0X44版本及以后支持 */ #define FUN_PARA_FLAG_LOW_PWR (1<<2) /* 低耗能模式 */ #define SOCK_CTRL_FLAG_SOCKET_CLOSE (1<<3) /* CH395不主动关闭Socket */ #define SOCK_DISABLE_SEND_OK_INT (1<<4) /* send ok中断控制位,为1表示关闭send ok中断 */ #ifdef __cplusplus } #endif #endif
浙公网安备 33010602011771号