多的不说,直接上代码,干就完了!!!!
CH395Q.c
#include "ch395q.h"
#include "delay.h"
#include <string.h>
#include "usart.h"
uint8_t tcp_connect = 0;
uint8_t status[2];
uint8_t socket_buff[8][1024]; /* 数据缓冲区 */
/********************************** (C) COPYRIGHT *******************************
* File Name : CH395_interface_operation.c
* Author : WCH
* Version : V1.0.0
* Date : 2020/10/12
* Description : CH395各接口实现函数
*******************************************************************************/
uint8_t ITDATA[2];
/*******************************************************************************
* Function Name : ch395_cmd_reset
* Description : 软复位
* Input : None
* Return : None
*******************************************************************************/
void ch395_cmd_reset(void)
{
ch395_write_cmd(CMD00_RESET_ALL);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_hard_reset
* Description : 软复位
* Input : None
* Return : None
*******************************************************************************/
void ch395_cmd_hard_reset(void)
{
GPIO_ResetBits(GPIOA,GPIO_Pin_1);
delay_ms(100);
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
/*******************************************************************************
* Function Name : ch395_cmd_sleep
* Description : 进入睡眠模式
* Input : None
* Return : None
*******************************************************************************/
void ch395_cmd_sleep(void)
{
ch395_write_cmd(CMD00_ENTER_SLEEP);
ch395_scs_hign;
}
uint8_t ch395_cmd_get_ver(void)
{
uint8_t i;
ch395_write_cmd(CMD01_GET_IC_VER);
i = ch395_read_data();
ch395_scs_hign;
return i;
}
uint8_t ch395_cmd_check_exist(uint8_t testdata)
{
uint8_t i;
ch395_write_cmd(CMD11_CHECK_EXIST);
ch395_write_data(testdata);
delay_us(10);
i = ch395_read_data();
// printf("ch395_cmd_check_exist=%02x\r\n",i);
delay_us(1);
ch395_scs_hign;
return i;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_phy
* Description : 设置phy,主要设置CH395 phy为100/10m 或者全双工半双工,CH395默为自动协商。
* Input : None
* Return : None
*******************************************************************************/
void ch395_cmd_set_phy(uint8_t phystat)
{
ch395_write_cmd(CMD10_SET_PHY);
ch395_write_data(phystat);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_get_phy_status
* Description : 获取phy的状态
* Input : None
* Return : 当前ch395phy状态,参考phy参数/状态定义
*******************************************************************************/
uint8_t ch395_cmd_get_phy_status(void)
{
uint8_t i;
ch395_write_cmd(CMD01_GET_PHY_STATUS);
i = ch395_read_data();
ch395_scs_hign;
// printf("phy_status:%04x\n",i);
return i;
}
/*******************************************************************************
* Function Name : ch395_cmd_get_glob_int_status
* Description : 获取全局中断状态,收到此命令CH395自动取消中断,0x43及以下版本使用
* Input : None
* Return : 返回当前的全局中断状态
*******************************************************************************/
uint8_t ch395_cmd_get_glob_int_status(void)
{
uint8_t init_status;
ch395_write_cmd(CMD01_GET_GLOB_INT_STATUS);
init_status = ch395_read_data();
ch395_scs_hign;
return init_status;
}
/*******************************************************************************
* Function Name : ch395_cmd_init
* Description : 初始化CH395芯片
* Input : None
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_cmd_init(void)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD0W_INIT_CH395);
ch395_scs_hign;
while (1)
{
delay_ms(10); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出,本函数需要500MS以上执行完毕 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_uart_baud_rate
* Description : 设置CH395串口波特率,仅在串口模式下有效
* Input : baudrate
* Return : None
*******************************************************************************/
#ifdef USE_USART2_CTRL_CH395
void ch395_cmd_set_uart_baud_rate(uint32_t baudrate)
{
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));
delay_ms(1);
set_usart2_bandrate(UART_WORK_BAUDRATE);
uint8_t i = ch395_read_data();
printf("baudrate_i:%02x\n",i);
ch395_scs_hign;
}
#endif
/*******************************************************************************
* Function Name : ch395_get_cmd_status
* Description : 获取命令执行状态,某些命令需要等待命令执行结果
* Input : None
* Return : 返回上一条命令执行状态
*******************************************************************************/
uint8_t ch395_get_cmd_status(void)
{
uint8_t i;
ch395_write_cmd(CMD01_GET_CMD_STATUS);
i = ch395_read_data();
// printf("ch395_get_cmd_status:%06x\n",i);
ch395_scs_hign;
return i;
}
/*******************************************************************************
* Function Name : ch395_get_cmd_status
* Description : 设置CH395的ip地址
* Input : ipaddr:ip地址
* Return : None
*******************************************************************************/
void ch395_cmd_set_ipaddr(uint8_t *ipaddr)
{
uint8_t i;
ch395_write_cmd(CMD40_SET_IP_ADDR);
for (i = 0; i < 4; i++)
{
ch395_write_data(*ipaddr++);
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_gw_ipaddr
* Description : 设置CH395的网关ip地址
* Input : gwipaddr
* Return : None
*******************************************************************************/
void ch395_cmd_set_gw_ipaddr(uint8_t *gwipaddr)
{
uint8_t i;
ch395_write_cmd(CMD40_SET_GWIP_ADDR);
for (i = 0; i < 4; i++)
{
ch395_write_data(*gwipaddr++);
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_maskaddr
* Description : 设置CH395的子网掩码,默认为255.255.255.0
* Input : maskaddr 指子网掩码地址
* Return : None
*******************************************************************************/
void ch395_cmd_set_maskaddr(uint8_t *maskaddr)
{
uint8_t i;
ch395_write_cmd(CMD40_SET_MASK_ADDR);
for (i = 0; i < 4; i++)
{
ch395_write_data(*maskaddr++);
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_macaddr
* Description : 设置CH395的mac地址。
* Input : mcaddr mac地址指针
* Return : None
*******************************************************************************/
void ch395_cmd_set_macaddr(uint8_t *amcaddr)
{
uint8_t i;
ch395_write_cmd(CMD60_SET_MAC_ADDR);
for (i = 0; i < 6; i++)
{
ch395_write_data(*amcaddr++);
}
ch395_scs_hign;
delay_ms(100);
}
/*******************************************************************************
* Function Name : ch395_cmd_get_macaddr
* Description : 获取CH395的mac地址。
* Input : amcaddr mac地址指针
* Return : None
*******************************************************************************/
void ch395_cmd_get_macaddr(uint8_t *amcaddr)
{
uint8_t i;
ch395_write_cmd(CMD06_GET_MAC_ADDR);
for (i = 0; i < 6; i++)
{
*amcaddr++ = ch395_read_data();
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_macfilt
* Description : 设置mac过滤。
* Input : filtype
table0 hash0
table1 hash1
* Return : None
*******************************************************************************/
void ch395_cmd_set_macfilt(uint8_t filtype, uint32_t table0, uint32_t table1)
{
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;
}
/*******************************************************************************
* Function Name : ch395_cmd_get_unreachippt
* Description : 保存获取到的不可达
* Input : list
* arg : 第1个字节为不可达代码,请参考 不可达代码(ch395inc.h)
第2个字节为ip包协议类型
第3-4字节为端口号
第4-8字节为ip地址
* Return : None
*******************************************************************************/
void ch395_cmd_get_unreachippt(uint8_t *list)
{
uint8_t i;
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 无
*/
/*******************************************************************************
* Function Name : ch395_cmd_get_remoteipp
* Description : 获取远端的ip和端口地址,一般在tcp server模式下使用
* Input : sockindex socket索引
list 保存ip和端口
* Return : None
*******************************************************************************/
void ch395_cmd_get_remoteipp(uint8_t sockindex, uint8_t *list)
{
uint8_t i;
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;
}
/*******************************************************************************
* Function Name : ch395_set_socket_desip
* Description : 设置socket n的目的ip地址
* Input : sockindex socket索引
ipaddr 指向ip地址
* Return : None
*******************************************************************************/
void ch395_set_socket_desip(uint8_t sockindex, uint8_t *ipaddr)
{
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;
}
/*******************************************************************************
* Function Name : ch395_set_socket_prot_type
* Description : 设置socket 的协议类型
* Input : sockindex socket索引
prottype
请参考 socket协议类型定义(ch395inc.h)
* Return : None
*******************************************************************************/
void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype)
{
ch395_write_cmd(CMD20_SET_PROTO_TYPE_SN);
ch395_write_data(sockindex);
ch395_write_data(prottype);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_set_socket_desport
* Description : 设置socket n的协议类型
* Input : sockindex socket索引
desprot 2字节目的端口
* Return : None
*******************************************************************************/
void ch395_set_socket_desport(uint8_t sockindex, uint16_t desprot)
{
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;
}
/*******************************************************************************
* Function Name : ch395_set_socket_sourport
* Description : 设置socket n的协议类型
* Input : sockindex socket索引
desprot 2字节源端口
* Return : None
*******************************************************************************/
void ch395_set_socket_sourport(uint8_t sockindex, uint16_t surprot)
{
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;
}
/*******************************************************************************
* Function Name : ch395_set_socket_ipraw_proto
* Description : ip模式下,socket ip包协议字段
* Input : sockindex socket索引
prototype ipraw模式1字节协议字段
* Return : None
*******************************************************************************/
void ch395_set_socket_ipraw_proto(uint8_t sockindex, uint8_t prototype)
{
ch395_write_cmd(CMD20_SET_IPRAW_PRO_SN);
ch395_write_data(sockindex);
ch395_write_data(prototype);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_enable_ping
* Description : 开启/关闭 ping
* Input : senable :0 / 1
1: 开启ping
0: 关闭ping
* Return : None
*******************************************************************************/
void ch395_enable_ping(uint8_t enable)
{
ch395_write_cmd(CMD01_PING_ENABLE);
ch395_write_data(enable);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_send_data
* Description : 向发送缓冲区写数据
* Input : sockindex socket索引
databuf 数据缓冲区
len 长度
* Return : None
*******************************************************************************/
void ch395_send_data(uint8_t sockindex, uint8_t *databuf, uint16_t len)
{
uint16_t i;
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++)
{
#ifdef USE_SPI1_CTRL_CH395
spi_data_write(*databuf++);
#else
ch395_write_data(*databuf++);
#endif
}
delay_us(5);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_get_recv_length
* Description : 获取接收缓冲区长度
* Input : sockindex socket索引
* Return : 返回接收缓冲区有效长度
*******************************************************************************/
uint16_t ch395_get_recv_length(uint8_t sockindex)
{
uint16_t i;
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;
}
/*******************************************************************************
* Function Name : ch395_clear_recv_buf
* Description : 清除接收缓冲区
* Input : sockindex socket索引
* Return : 无
*******************************************************************************/
void ch395_clear_recv_buf(uint8_t sockindex)
{
ch395_write_cmd(CMD10_CLEAR_RECV_BUF_SN);
ch395_write_data((uint8_t)sockindex);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_get_recv_data
* Description : 读取接收缓冲区数据
* Input : sockindex socket索引
len 长度
pbuf 缓冲区
* Return : 无
*******************************************************************************/
void ch395_get_recv_data(uint8_t sockindex, uint16_t len, uint8_t *pbuf)
{
uint16_t i;
if (!len)return;
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));
for (i = 0; i < len; i++)
{
*pbuf = ch395_read_data();
pbuf++;
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_retry_count
* Description : 设置重试次数
* Input : count 重试值,最大为20次
* Return : 无
*******************************************************************************/
void ch395_cmd_set_retry_count(uint8_t count)
{
ch395_write_cmd(CMD10_SET_RETRAN_COUNT);
ch395_write_data(count);
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_set_retry_period
* Description : 设置重试周期
* Input : period 重试周期单位为毫秒,最大1000ms
* Return : 无
*******************************************************************************/
void ch395_cmd_set_retry_period(uint16_t period)
{
ch395_write_cmd(CMD10_SET_RETRAN_COUNT);
ch395_write_data((uint8_t)period);
ch395_write_data((uint8_t)(period >> 8));
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_get_socket_status
* Description : 获取socket
* Input : sockindex socket索引
* Return : socket n的状态信息,第1字节为socket 打开或者关闭,第2字节为tcp状态
*******************************************************************************/
void ch395_cmd_get_socket_status(uint8_t sockindex, uint8_t *status)
{
ch395_write_cmd(CMD12_GET_SOCKET_STATUS_SN);
ch395_write_data(sockindex);
*status++ = ch395_read_data();
*status++ = ch395_read_data();
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_open_socket
* Description : 打开socket,此命令需要等待执行成功
* Input : sockindex socket索引
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_open_socket(uint8_t sockindex)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD1W_OPEN_SOCKET_SN);
ch395_write_data(sockindex);
ch395_scs_hign;
while (1)
{
delay_ms(5); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_close_socket
* Description : 关闭socket,
* Input : sockindex socket索引
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_close_socket(uint8_t sockindex)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD1W_CLOSE_SOCKET_SN);
ch395_write_data(sockindex);
ch395_scs_hign;
while (1)
{
delay_ms(5); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_tcp_connect
* Description : tcp连接,仅在tcp模式下有效,此命令需要等待执行成功
* Input : sockindex socket索引
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_tcp_connect(uint8_t sockindex)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD1W_TCP_CONNECT_SN);
ch395_write_data(sockindex);
ch395_scs_hign;
while (1)
{
delay_ms(5); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_tcp_listen
* Description : tcp监听,仅在tcp模式下有效,此命令需要等待执行成功
* Input : sockindex socket索引
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_tcp_listen(uint8_t sockindex)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD1W_TCP_LISTEN_SN);
ch395_write_data(sockindex);
ch395_scs_hign;
while (1)
{
delay_ms(5); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_tcp_disconnect
* Description : tcp断开,仅在tcp模式下有效,此命令需要等待执行成功
* Input : sockindex socket索引
* Return : 返回执行结果
*******************************************************************************/
uint8_t ch395_tcp_disconnect(uint8_t sockindex)
{
uint8_t i = 0;
uint8_t s = 0;
ch395_write_cmd(CMD1W_TCP_DISNCONNECT_SN);
ch395_write_data(sockindex);
ch395_scs_hign;
while (1)
{
delay_ms(5); /* 延时查询,建议2MS以上 */
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_get_socket_int
* Description : 获取socket n的中断状态
* Input : sockindex socket索引
* Return : 中断状态
*******************************************************************************/
uint8_t ch395_get_socket_int(uint8_t sockindex)
{
uint8_t intstatus;
ch395_write_cmd(CMD11_GET_INT_STATUS_SN);
ch395_write_data(sockindex);
// delay_us(2);
intstatus = ch395_read_data();
ch395_scs_hign;
return intstatus;
}
/*******************************************************************************
* Function Name : ch395_crcret_6bit
* Description : 对多播地址进行crc运算,并取高6位。
* Input : mac_addr mac地址
* Return : 返回crc32的高6位
*******************************************************************************/
uint8_t ch395_crcret_6bit(uint8_t *mac_addr)
{
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);
}
/*******************************************************************************
* Function Name : ch395_dhcp_enable
* Description : 启动/停止dhcp
* Input : flag:0 / 1, 具体含义如下:
* @arg 1: 启动dhcp
* @arg 0:停止dhcp
* Return : 返回crc32的高6位
*******************************************************************************/
uint8_t ch395_dhcp_enable(uint8_t flag)
{
uint8_t i = 0;
uint8_t s;
ch395_write_cmd(CMD10_DHCP_ENABLE);
ch395_write_data(flag);
ch395_scs_hign;
while (1)
{
delay_ms(20);
s = ch395_get_cmd_status(); /* 不能过于频繁查询 */
if (s != CH395_ERR_BUSY)
{
break; /* 如果CH395芯片返回忙状态 */
}
if (i++ > 200)
{
return CH395_ERR_UNKNOW; /* 超时退出 */
}
}
return s;
}
/*******************************************************************************
* Function Name : ch395_get_dhcp_status
* Description : 获取dhcp状态
* Input : None
* Return : dhcp状态,0为成功,其他值表示错误
*******************************************************************************/
uint8_t ch395_get_dhcp_status(void)
{
uint8_t status;
ch395_write_cmd(CMD01_GET_DHCP_STATUS);
status = ch395_read_data();
ch395_scs_hign;
return status;
}
/*******************************************************************************
* Function Name : ch395_get_ipinf
* Description : 获取ip,子网掩码和网关地址
* Input : sockindex socket索引
* Return : 12个字节的ip,子网掩码和网关地址
*******************************************************************************/
void ch395_get_ipinf(uint8_t *addr)
{
uint8_t i;
ch395_write_cmd(CMD014_GET_IP_INF);
for (i = 0; i < 20; i++)
{
*addr++ = ch395_read_data();
}
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_write_gpio_addr
* Description : 写gpio寄存器
* Input : regadd 寄存器地址
regval 寄存器值
* Return : None
*******************************************************************************/
void ch395_write_gpio_addr(uint8_t regadd, uint8_t regval)
{
ch395_write_cmd(CMD20_WRITE_GPIO_REG);
ch395_write_data(regadd);
ch395_write_data(regval);
}
/*******************************************************************************
* Function Name : ch395_read_gpio_addr
* Description : 读gpio寄存器
* Input : regadd 寄存器地址
* Return : 寄存器的值
*******************************************************************************/
uint8_t ch395_read_gpio_addr(uint8_t regadd)
{
uint8_t i;
ch395_write_cmd(CMD10_READ_GPIO_REG);
ch395_write_data(regadd);
delay_ms(1);
i = ch395_read_data();
return i;
}
/*******************************************************************************
* Function Name : ch395_eeprom_erase
* Description : 擦除eeprom
* Input : None
* Return : 执行状态
*******************************************************************************/
uint8_t ch395_eeprom_erase(void)
{
uint8_t i;
ch395_write_cmd(CMD00_EEPROM_ERASE);
while (1)
{
delay_ms(20);
i = ch395_get_cmd_status();
if (i == CH395_ERR_BUSY)
{
continue;
}
break;
}
return i;
}
/*******************************************************************************
* Function Name : ch395_eeprom_write
* Description : 写eeprom
* Input : eepaddr eeprom地址
buf 缓冲区地址
len 长度
* Return : 执行状态
*******************************************************************************/
uint8_t ch395_eeprom_write(uint16_t eepaddr, uint8_t *buf, uint8_t len)
{
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)
{
delay_ms(20);
i = ch395_get_cmd_status();
if (i == CH395_ERR_BUSY)
{
continue;
}
break;
}
return i;
}
/*******************************************************************************
* Function Name : ch395_eeprom_write
* Description : 读eeprom
* Input : eepaddr eeprom地址
buf 缓冲区地址
len 长度
* Return : None
*******************************************************************************/
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);
delay_ms(1);
while (len--)
{
*buf++ = ch395_read_data();
}
}
/*******************************************************************************
* Function Name : ch395_set_tcpmss
* Description : 设置tcp mss值
* Input : tcpmss
* Return : None
*******************************************************************************/
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));
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_set_socket_recv_buf
* Description : 设置socket接收缓冲区
* Input : sockindex socket索引,址,blknum
startblk 起始地址
单位缓冲区个数 ,单位为512字节
* Return : None
*******************************************************************************/
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);
ch395_scs_hign;
// delay_us(2);
}
/*******************************************************************************
* Function Name : ch395_set_socket_send_buf
* Description : 设置socket发送缓冲区
* Input : sockindex socket索引,址,blknum
startblk 起始地址
单位缓冲区个数 ,单位为512字节
* Return : None
*******************************************************************************/
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);
ch395_scs_hign;
// delay_us(2);
}
/*******************************************************************************
* Function Name : ch395_udp_send_data
* Description : udp向指定的ip和端口发送数据
* Input : buf : 发送数据缓冲区
len : 发送数据长度
ip : 目标ip
port : 目标端口
sockeid : socket索引值
* Return : None
*******************************************************************************/
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);
}
/*******************************************************************************
* Function Name : ch395_set_start_para
* Description : 设置CH395启动参数
* Input : madata
* Return : None
*******************************************************************************/
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));
ch395_scs_hign;
}
/*******************************************************************************
* Function Name : ch395_cmd_get_glob_int_status_all
* Description : 获取全局中断状态,收到此命令CH395自动取消中断,0x44及以上版本使用
* Input : None
* Return : 返回当前的全局中断状态
*******************************************************************************/
uint16_t ch395_cmd_get_glob_int_status_all(void)
{
uint16_t init_status;
uint8_t i,init[2];
// #ifdef USE_USART2_CTRL_CH395
// if(UART_WORK_BAUDRATE==9600)
// {
// ch395_write_cmd(CMD02_GET_GLOB_INT_STATUS_ALL);
// delay_ms(25);
// for (i = 0; i < 2; i++)
// {
// init[i] = ch395_read_data();
// }
// init_status = (uint16_t)(init[1] << 8) + init[0];
// }
// else
// {
// USART_DMA_Config();
// delay_ms(10);
// ch395_write_cmd(CMD02_GET_GLOB_INT_STATUS_ALL);
// delay_ms(2);
// for (i = 0; i < 2; i++)
// {
// init[i] = ITDATA[i];
// }
// init_status = (uint16_t)(init[1] << 8) + init[0];
//
// DMA_Cmd(DMA1_Channel6, DISABLE);
// USART_DMACmd(USART2,USART_DMAReq_Rx,DISABLE);
// }
// #else
ch395_write_cmd(CMD02_GET_GLOB_INT_STATUS_ALL); /* 获取全局中断状态,V44版本以后的程序由于增加了socket数量需要用此命令获取全部的中断 */
delay_us(2);
for (i = 0; i < 2; i++)
{
init[i] = ch395_read_data();
}
init_status = (uint16_t)(init[1] << 8) + init[0];
// #endif
ch395_scs_hign;
return init_status;
}
/*******************************************************************************
* Function Name : ch395_set_keeplive
* Description : 设置keepalive功能
* Input : sockindex Socket号
cmd 0:关闭 1:开启
* Return : None
*******************************************************************************/
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);
}
/*******************************************************************************
* Function Name : ch395_keeplive_cnt
* Description : 设置keepalive重试次数
* Input : cnt 重试次数
* Return : None
*******************************************************************************/
void ch395_keeplive_cnt(uint8_t cnt)
{
ch395_write_cmd(CMD10_SET_KEEP_LIVE_CNT);
ch395_write_data(cnt);
}
/*******************************************************************************
* Function Name : ch395_keeplive_idle
* Description : 设置KEEPLIVE空闲
* Input : idle 空闲时间(单位:ms)
* Return : None
*******************************************************************************/
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));
}
/*******************************************************************************
* Function Name : ch395_keeplive_intvl
* Description : 设置KeepLive间隔时间
* Input : intvl 间隔时间(单位:ms)
* Return : None
*******************************************************************************/
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));
}
/*******************************************************************************
* Function Name : ch395_setttl_num
* Description : 设置TTL
* Input : sockindex Socket号
TTLnum:TTL数
* Return : None
*******************************************************************************/
void ch395_setttl_num(uint8_t sockindex, uint8_t ttlnum)
{
ch395_write_cmd(CMD20_SET_TTL);
ch395_write_data(sockindex);
ch395_write_data(ttlnum);
}
/*******************************************************************************
* Function Name : USART_DMA_Config
* Description : USART2DMA接收中断信息数据
* Input : None
* Return : None
*******************************************************************************/
//void USART_DMA_Config(void)
//{
// DMA_InitTypeDef DMA_InitStructure;
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
//
// DMA_DeInit(DMA1_Channel6);
// DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&USART2->DATAR);
// DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ITDATA;
// DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
// DMA_InitStructure.DMA_BufferSize = 2;
// DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
// DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
// DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
// DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
// DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// DMA_Init(DMA1_Channel6, &DMA_InitStructure);
// DMA_Cmd(DMA1_Channel6, ENABLE);
// USART_DMACmd(USART2,USART_DMAReq_Rx,ENABLE);
//}
/******************************************************************************
Description : CH395基本操作步骤
*******************************************************************************/
/* CH395本地配置 */
struct _CH395_SYS ch395inf; /* 保存CH395信息 */
extern uint8_t local_ip[]; /* CH395IP地址 */
extern uint8_t gateway_ip[] ; /* CH395网关 */
extern uint8_t mask_ip[]; /* CH395子网掩码 */
/* CH395socket配置 */
extern uint16_t source_port[8];
extern uint16_t destination_port[8];
extern uint8_t socket_desip0[4];
extern uint8_t socket_desip1[4];
extern uint8_t socket_desip2[4];
extern uint8_t socket_desip3[4];
extern uint8_t socket_desip4[4];
extern uint8_t socket_desip5[4];
extern uint8_t socket_desip6[4];
extern uint8_t socket_desip7[4];
extern struct _SOCK_INF sockinf[8];
/*******************************************************************************
* Function Name : CH395_if_init
* Description : CH32的硬件接口初始化
* Input : None
* Return : None
*******************************************************************************/
void CH395_if_init(void)
{
//#ifdef USE_USART2_CTRL_CH395
// USART2_init();
// control_UART_Init(); /* io口相关的初始化 */
//#else
SPI_FullDuplex_Init();/* SPI初始化和SPI相关的GPIO口初始化 */
control_SPI_Init(); /* io口相关的初始化 */
//#endif
}
/*******************************************************************************
* Function Name : CH395_init
* Description : CH395初始化
* Input : None
* Return : 初始化状态
*******************************************************************************/
uint8_t CH395_init(void)
{
uint8_t i;
i=ch395_cmd_check_exist(0x65);
if(i != 0x9a)return CH395_ERR_UNKNOW;
delay_ms(10);
i = ch395_cmd_get_ver();
printf("版本号CH395VER : %2x\r\n",i);
ch395_cmd_reset(); /* 软复位命令 */
delay_ms(50); /* 软复位之后起码延时50毫秒 */
ch395_cmd_set_ipaddr(ch395inf.IPAddr); /* 设置CH395的IP地址 */
ch395_cmd_set_gw_ipaddr(ch395inf.GWIPAddr); /* 设置网关地址 */
ch395_cmd_set_maskaddr(ch395inf.MASKAddr); /* 设置子网掩码,默认为255.255.255.0*/
delay_ms(300);
i = ch395_cmd_init(); /* 初始化CH395芯片 */
return i;
}
/*******************************************************************************
* Function Name : ch395_inf_init
* Description : CH395本地信息初始化
* Input : None
* Return : 初始化状态
*******************************************************************************/
void ch395_inf_init(void)
{
memset(&ch395inf, 0, sizeof(ch395inf)); /* 将CH395Inf全部清零 */
memcpy(ch395inf.IPAddr, local_ip, 4); /* 将IP地址写入CH395Inf中 */
memcpy(ch395inf.GWIPAddr, gateway_ip, 4); /* 将网关IP地址写入CH395Inf中 */
memcpy(ch395inf.MASKAddr, mask_ip, 4); /* 将子网掩码写入CH395Inf中 */
}
/*******************************************************************************
* Function Name : ch395_socket_init
* Description : CH395socke信息初始化
* Input : None
* Return : None
*******************************************************************************/
void ch395_socket_init(void)
{
memset(&sockinf[0],0,sizeof(sockinf[0])); /* 将SockInf[0]全部清零*/
memcpy(&sockinf[0].IPAddr, &socket_desip0, 4); /* 将目标IP写入结构体 */
memcpy(&sockinf[0].SourPort, &source_port[0], 2); /* 将本地端口写入 */
memcpy(&sockinf[0].DesPort, &destination_port[0], 2); /* 将目的端口写入 */
sockinf[0].ProtoType = PROTO_TYPE_TCP; /* TCP模式 */
sockinf[0].TcpMode = TCP_CLIENT_MODE; /* TCP客户端模式 */
}
/*******************************************************************************
* Function Name : socket_open
* Description : CH395socke开启
* Input : None
* Return : None
*******************************************************************************/
void socket_open(void)
{
uint8_t rc;
ch395_set_socket_desip(0,sockinf[0].IPAddr);
ch395_set_socket_prot_type(0,sockinf[0].ProtoType);
ch395_set_socket_desport(0,sockinf[0].DesPort);
ch395_set_socket_sourport(0,sockinf[0].SourPort);
rc=ch395_open_socket(0);
stop_if_error(rc);
rc=ch395_tcp_connect(0);
stop_if_error(rc);
delay_ms(500);
}
/*********************************************************************************
* Function Name : Socket_R_S_Buf_Modify
* Description : Socket收发缓冲区定义
* Input : None
* Output : None
* Return : None
**********************************************************************************/
void 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);
}
/**********************************************************************************
* Function Name : KeepLive_Set
* Description : 保活定时器参数设置
* Input : None
* Output : None
* Return : None
**********************************************************************************/
void KeepLive_Set(void)
{
ch395_keeplive_cnt(DEF_KEEP_LIVE_CNT);
ch395_keeplive_idle(DEF_KEEP_LIVE_IDLE);
ch395_keeplive_intvl(DEF_KEEP_LIVE_PERIOD);
}
#define SPI1_SR *(uint32_t*)(0x40013008)
#define SPI1_DR *(uint32_t*)(0x4001300C)
DMA_InitTypeDef DMA_InitStructure;
SPI_InitTypeDef SPI_InitStructure;
void control_SPI_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* CH395中断输入脚 PA0*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* CH395中断配置:单片机引脚设为上拉输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* */
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* 控制CH395硬件复位脚 PA1*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; /* 硬件复位输出配置为开漏输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* */
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_SetBits(GPIOA,GPIO_Pin_1);
}
void control_UART_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* CH395中断输入脚 PA0*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; /* CH395中断配置:单片机引脚设为上拉输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* */
GPIO_Init( GPIOA, &GPIO_InitStructure );
/* 控制CH395硬件复位脚 PA1*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; /* 硬件复位输出配置为开漏输出 */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /* */
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_SetBits(GPIOA,GPIO_Pin_1);
/* PA0设为下降沿中断 */
GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
EXTI_InitStructure.EXTI_Line=EXTI_Line0;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*
------------------------------------SPI接口相关---------------------------------
*/
/*******************************************************************************
* Function Name : SPI_FullDuplex_Init
* Description : Configuring the SPI for full-duplex communication.
* Input : None
* Return : None
*******************************************************************************/
#ifdef USE_SPI1_CTRL_CH395
void SPI_FullDuplex_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1, ENABLE );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure );
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOA, &GPIO_InitStructure );
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;
SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
SPI_InitStructure.SPI_CRCPolynomial = 7;
SPI_Init( SPI1, &SPI_InitStructure );
SPI_Cmd( SPI1, ENABLE );
}
#else
void USART2_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
/* USART2 TX-->A.2 RX-->A.3 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void set_usart2_bandrate(uint32_t bandrate)
{
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = bandrate;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
#endif
/**
*描述:语句基本构成:写命令
*/
void ch395_write_cmd( uint8_t mCmd )
{
ch395_scs_hign; /* 防止CS原来为低,先将CS置高 */
ch395_scs_low; /* 命令开始,CS拉低 */
#ifdef USE_USART2_CTRL_CH395
ch395_write_data(0x57);
ch395_write_data(0xab);
#endif
ch395_write_data(mCmd); /* SPI发送命令码 */
delay_us(2); /* 必要延时,延时1.5uS确保读写周期不小于1.5uS */
}
#if 1
uint8_t SPI1_ReadWriteByte(uint8_t Tx_Data)
{
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET) ;
SPI_I2S_SendData(SPI1, Tx_Data);
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
return SPI_I2S_ReceiveData(SPI1);
}
#endif
uint8_t SPI1_ReadByte(uint8_t Tx_Data)
{
u8 i=0;
while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET)
{
i++;
if(i>200)return 0;
}
return SPI_I2S_ReceiveData(SPI1);
}
#if SPI1_DMA_EN
void SPI_DMA_Read(u16 length)
{
u16 i=0;
DMA_InitStructure.DMA_BufferSize=length;
DMA_Init( DMA1_Channel2, &DMA_InitStructure );
DMA_Cmd( DMA1_Channel2, ENABLE );
SPI_I2S_DMACmd( SPI1, SPI_I2S_DMAReq_Rx, ENABLE );
for(i=0;i<length;i++)
{
SPI_I2S_SendData(SPI1,0xff);
}
Delay_Us(1);
while( (DMA_GetFlagStatus(DMA1_FLAG_TC2)) == RESET)
{
// DMA_ClearFlag(DMA1_FLAG_TC2);//清除通道2传输完成标志
}
DMA_ClearFlag(DMA1_FLAG_TC2);//清除通道2传输完成标志
SPI_I2S_DMACmd( SPI1, SPI_I2S_DMAReq_Rx, DISABLE );
DMA_Cmd( DMA1_Channel2, DISABLE );
for( i=0; i<length; i++ )
{
TxData[i]=RxData[i];
}
DMA_DeInit(DMA1_Channel2);
SPI1_DMA_Rx_Init( DMA1_Channel2, (uint32_t)&SPI1->DATAR, (uint32_t)RxData, 20 );
}
#endif
/**
---------------------------------------- CH395硬件写取函数 -----------------------------------------
--------------------------------------- 移植更换API入口位置 -----------------------------------------
*/
void ch395_write_data( uint8_t mData )
{
#ifdef USE_SPI1_CTRL_CH395
SPI1_ReadWriteByte(mData);
#else
USART_SendData(USART2, mData);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
#endif
}
void spi_data_write(uint8_t mData)
{
while ((SPI1_SR & SPI_I2S_FLAG_TXE) == RESET) ;
SPI1_DR=mData;
}
/**
----------------------------------------- CH395硬件读取函数 -----------------------------------------
---------------------------------------- 移植更换API入口位置 -----------------------------------------
*/
uint8_t ch395_read_data( void )
{
#ifdef USE_SPI1_CTRL_CH395
while((SPI1_SR & SPI_I2S_FLAG_TXE)==RESET);
SPI1_DR=0xff;
while((SPI1_SR & SPI_I2S_FLAG_RXNE)==RESET);
// return (uint8_t)SPI1->DATAR;//沁恒单片机
return (uint8_t)SPI1->DR;
#else
uint32_t x;
for(x=0;x<500000;x++)
{
if(USART_GetFlagStatus(USART2,USART_IT_RXNE) == SET)
{
return (uint8_t)USART_ReceiveData(USART2);
}
}
return (0);
#endif
}
/*
-------------------------------------------------------------------------------------------------------
USART接口相关
-------------------------------------------------------------------------------------------------------
*/
/**********************************************************************************
* Function Name : CH395SocketInterrupt
* Description : CH395 socket 中断,在全局中断中被调用
* Input : sockindex:socket索引号
* Output : None
* Return : None
**********************************************************************************/
void CH395SocketInterrupt(uint8_t sockindex)
{
uint8_t sock_int_socket,i;
uint16_t len;
uint16_t tmp;
sock_int_socket = ch395_get_socket_int(sockindex); /* 获取socket 的中断状态 获取不同的中断状态 处理不同的中断状态 */
if(sock_int_socket & SINT_STAT_SENBUF_FREE) /* 发送缓冲区空闲,可以继续写入要发送的数据 */
{
delay_us(300);
}
if(sock_int_socket & SINT_STAT_SEND_OK) /* 发送完成中断 */
{
// printf("send ok!\n");
}
if(sock_int_socket & SINT_STAT_RECV) /* 接收中断 */
{
len = ch395_get_recv_length(sockindex); /* 获取当前缓冲区内数据长度 */
printf("接收到的字节数长度 = %d\r\n",len);
#ifdef USE_SPI1_CTRL_CH395
delay_us(200);
#endif
if(len == 0)return;
if(len > default_tcp_mss)len = default_tcp_mss; /* MyBuffer缓冲区长度为512*/
ch395_get_recv_data(sockindex,len,socket_buff[sockindex]); /* 读取数据 */
// delay_us(100);
// ch395_send_data(sockindex,socket_buff[sockindex],len); /* 发送数据 */
}
if(sock_int_socket & SINT_STAT_CONNECT) /* 连接中断,仅在TCP模式下有效*/
{
uint8_t target_inf[6];
printf("*");
tcp_connect = 1;
if(sockinf[sockindex].TcpMode == TCP_SERVER_MODE) /* 如果socket 为服务器模式,用户可以获取远端的IP和端口*/
{
ch395_cmd_get_remoteipp(sockindex,target_inf);
tmp = (uint16_t)(target_inf[5]<<8) + target_inf[4];
printf("IP address = %d.%d.%d.%d\n",(uint16_t)target_inf[0],(uint16_t)target_inf[1],(uint16_t)target_inf[2],(uint16_t)target_inf[3]);
printf("Port = %d\n",tmp);
}
}
/*
**产生断开连接中断和超时中断时,CH395默认配置是内部主动关闭,用户不需要自己关闭该Socket,如果想配置成不主动关闭Socket需要配置
**SOCK_CTRL_FLAG_SOCKET_CLOSE标志位(默认为0),如果该标志为1,CH395内部不对Socket进行关闭处理,用户在连接中断和超时中断时调用
**CH395CloseSocket函数对Socket进行关闭,如果不关闭则该Socket一直为连接的状态(事实上已经断开),就不能再去连接了。
*/
/*SOCK_CTRL_FLAG_SOCKET_CLOSE被置位后,下面的中断需要关闭Socket,再进行其他操作。不置位则不需要CH395CloseSocket,CH395内部已经关闭。*/
if(sock_int_socket & SINT_STAT_DISCONNECT) /* 断开中断,仅在TCP模式下有效 */
{
i = ch395_close_socket(sockindex); //关闭socket
stop_if_error(i);//打印出被关闭的Socket
delay_ms(2);
i = ch395_open_socket(sockindex);
stop_if_error(i);
}
if(sock_int_socket & SINT_STAT_TIM_OUT) /* 超时中断,仅在TCP模式下有效 */
{
printf("SINT_STAT_TIM_OUT超时");
i = ch395_close_socket(sockindex);
stop_if_error(i);
delay_ms(2);
i = ch395_open_socket(sockindex);
stop_if_error(i);
}
}
/**********************************************************************************
* Function Name : CH395GlobalInterrupt
* Description : CH395全局中断函数
* Input : None
* Output : None
* Return : None
**********************************************************************************/
void CH395GlobalInterrupt(void)
{
uint16_t init_status,tem_flag;
uint8_t i,buf[10];
init_status = ch395_cmd_get_glob_int_status_all();
printf("init_status = %x\r\n",init_status);
if(init_status & GINT_STAT_UNREACH) /* 不可达中断,读取不可达信息 */
{
ch395_cmd_get_unreachippt(buf);
}
if(init_status & GINT_STAT_IP_CONFLI) /* 产生IP冲突中断,建议重新修改CH395的 IP,并初始化CH395*/
{
}
if(init_status & GINT_STAT_PHY_CHANGE) /* 产生PHY改变中断*/
{
printf("Init status : GINT_STAT_PHY_CHANGE\r\n");
}
tem_flag=GINT_STAT_SOCK0;
for(i=0;i<8;i++)
{
if(init_status & tem_flag)
{
CH395SocketInterrupt(i);
}
tem_flag=(1<<(4+1+i));
}
}
CH395Q.h
#ifndef __CH395Q_H
#define __CH395Q_H
#include "sys.h"
#define default_tcp_mss 4096 /* 默认的MSS大小设置 */
#define DEF_KEEP_LIVE_IDLE (20*1000) /* 空闲时间 */
#define DEF_KEEP_LIVE_PERIOD (15*1000) /* 间隔15s,发送一次KEPPLIVE数据包 */
#define DEF_KEEP_LIVE_CNT 200 /* 重试次数 */
/* CH32操作CH395的硬件接口选择 */
//#if 0
#define USE_SPI1_CTRL_CH395 1 /* 使用SPI口作为默认的控制H395的接口 */
//#else
//#define USE_USART2_CTRL_CH395 /* 使用USART2口作为默认的控制CH395的接口 */
//#endif
#define UART_WORK_BAUDRATE 921600
#define stop_if_error(x)\
if(x!=0){printf("Error: %02x,@ line %d of \"%s\".\r\n", (uint16_t)x,__LINE__,__FILE__);while(1);}
#define server_port source_port[0] /* 服务器端口 */
#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
#define TCP_CLIENT_MODE 0
#define TCP_SERVER_MODE 1
struct _CH395_SYS
{
uint8_t IPAddr[4]; /* CH395IP地址 32bit*/
uint8_t GWIPAddr[4]; /* CH395网关地址 32bit*/
uint8_t MASKAddr[4]; /* CH395子网掩码 32bit*/
uint8_t MacAddr[6]; /* CH395MAC地址 48bit*/
uint8_t PHYStat; /* CH395 PHY状态码 8bit*/
uint8_t MackFilt; /* CH395 MAC过滤,默认为接收广播,接收本机MAC 8bit*/
uint32_t RetranCount; /* 重试次数 默认为10次*/
uint32_t RetranPeriod; /* 重试周期,单位MS,默认200MS */
uint8_t IntfMode; /* 接口模式 */
uint8_t UnreachIPAddr[4]; /* 不可到达IP */
uint16_t UnreachPort; /* 不可到达端口 */
};
struct _SOCK_INF
{
uint8_t IPAddr[4]; /* socket目标IP地址 32bit*/
uint8_t MacAddr[6]; /* socket目标地址 48bit*/
uint8_t ProtoType; /* 协议类型 */
uint8_t ScokStatus; /* socket状态,参考scoket状态定义 */
uint8_t TcpMode; /* TCP模式 */
uint32_t IPRAWProtoType; /* 协议类型 */
uint16_t DesPort; /* 目的端口 */
uint16_t SourPort; /* 目的端口 */
uint16_t SendLen; /* 发送数据长度 */
uint16_t RemLen; /* 剩余长度 */
uint8_t *pSend; /* 发送指针 */
};
//
#ifndef uint8_t
typedef unsigned char uint8_t;
#endif
#ifndef uint16_t
typedef unsigned short uint16_t;
#endif
#ifndef uint32_t
typedef unsigned int uint32_t;
#endif
void ch395_cmd_reset(void);
void ch395_cmd_hard_reset(void);
uint8_t ch395_cmd_get_ver(void);
void ch395_write_cmd( uint8_t mCmd );
uint8_t ch395_cmd_check_exist(uint8_t testdata);
void ch395_cmd_set_ipaddr(uint8_t *ipaddr);
void ch395_cmd_set_gw_ipaddr(uint8_t *gwipaddr);
void ch395_cmd_set_maskaddr(uint8_t *maskaddr);
uint8_t ch395_get_cmd_status(void);
uint8_t ch395_cmd_init(void);
void ch395_set_socket_sourport(uint8_t sockindex, uint16_t surprot);
uint8_t ch395_open_socket(uint8_t sockindex);
uint8_t ch395_close_socket(uint8_t sockindex);
uint8_t ch395_tcp_listen(uint8_t sockindex);
uint8_t ch395_get_socket_int(uint8_t sockindex);
uint16_t ch395_get_recv_length(uint8_t sockindex);
void ch395_get_recv_data(uint8_t sockindex, uint16_t len, uint8_t *pbuf);
uint16_t ch395_cmd_get_glob_int_status_all(void);
void ch395_cmd_get_unreachippt(uint8_t *list);
void ch395_cmd_get_remoteipp(uint8_t sockindex, uint8_t *list);
void ch395_set_start_para(uint32_t mdata);
void ch395_set_tcpmss(uint16_t tcpmss);
void ch395_send_data(uint8_t sockindex, uint8_t *databuf, uint16_t len);
void ch395_cmd_set_uart_baud_rate(uint32_t baudrate);
void ch395_keeplive_cnt(uint8_t cnt);
void ch395_set_keeplive(uint8_t sockindex, uint8_t cmd);
void ch395_keeplive_idle(uint32_t idle);
void ch395_keeplive_intvl(uint32_t intvl);
void ch395_set_socket_desip(uint8_t sockindex, uint8_t *ipaddr);
void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype);
void ch395_set_socket_desport(uint8_t sockindex, uint16_t desprot);
void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype);
uint8_t ch395_tcp_connect(uint8_t sockindex);
//void USART_DMA_Config(void);
void ch395_cmd_get_socket_status(uint8_t sockindex, uint8_t *status);
void CH395_if_init(void);
uint8_t CH395_init(void);
void ch395_inf_init(void);
uint8_t ch395_cmd_get_phy_status(void);
void ch395_set_socket_recv_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum);
void ch395_set_socket_send_buf(uint8_t sockindex, uint8_t startblk, uint8_t blknum);
void ch395_set_socket_prot_type(uint8_t sockindex, uint8_t prottype);
void socket_open(void);
void ch395_socket_init(void);
void Socket_R_S_Buf_Modify(void );
void KeepLive_Set(void);
void CH395GlobalInterrupt(void);
/* Global Variable */
void CH395GlobalInterrupt(void);
void CH395SocketInterrupt(uint8_t sockindex);
//#define ch395_scs_hign
//#define ch395_scs_low
#ifdef USE_SPI1_CTRL_CH395
#define ch395_scs_hign (*(uint32_t*)(GPIOA_BASE+0x10))|=(1<<4)
#define ch395_scs_low (*(uint32_t*)(GPIOA_BASE+0x14))|=(1<<4)
#else
#define ch395_scs_hign
#define ch395_scs_low
#endif
#define ch32_gpio_in_a (*(uint32_t*)(GPIOA_BASE+0x08))
#define ch395_exti_stat (ch32_gpio_in_a&0x0001)
void SPI_FullDuplex_Init(void);
void control_SPI_Init(void);
void ch395_write_cmd( uint8_t mCmd );
void ch395_write_data( uint8_t mData );
uint8_t ch395_read_data( void );
void USART2_init(void);
void set_usart2_bandrate(uint32_t bandrate);
void SPI1_DMA_Tx_Init(DMA_Channel_TypeDef* DMA_CHx,uint32_t cpar,uint32_t cmar,u16 bufsize);
void SPI1_DMA_Rx_Init( DMA_Channel_TypeDef* DMA_CHx, uint32_t ppadr, uint32_t memadr, u16 bufsize );
void SPI_DMA_Read(u16 length);
uint8_t SPI1_ReadByte(uint8_t TxData);
void spi_data_write(uint8_t mData);
void control_UART_Init(void);
#endif