关于CH390使用注意事项

CH390替换DM90xx硬件注意事项

1、CH390L替换DM9000

  • AVDD33的对地电容建议1uF贴近芯片放置,42脚为主电源AVDD33需10uF并联0.1uF。各AVDD33需分别接电容,供电电压都为3.3V;
  • AVDDK和DVDDK需要分别外接电容并贴近芯片放置。两个AVDDK引脚建议任选一个外接1uF,另一个外接0.1uF。DVDDK外接0.1uF对地电容,DM9000 1脚接外置电阻的位置应改成0.1uF电容;
  • VDDIO为CH390L的I/O电源,VDDIO支持3.3V或者2.5V,外接0.1uF对地电容;
  • 43脚和44脚XI、XO不要接电阻,由于芯片内置12pf负载电容,因此如果晶振的负载电容是12pf则不需要再接负载电容,如果晶体负载电容为20pF时建议贴15pF的负载电容;晶振必须是25MHz优选贴片晶振;如果是外部时钟输入,需要从43脚XI输入;
  • 芯片已内置终端电阻,因此不要接49.9欧或50欧等任何电阻;
  • 网络变压器的中心抽头分别通过0.1uF~1uF电容接地,不要接任何电源;

2、CH390H替换DM9051

  • AVDD33的对地电容建议1uF贴近芯片放置,42脚为主电源AVDD33需10uF并联0.1uF。各AVDD33需分别接电容,供电电压都为3.3V;
  • AVDDK和DVDDK需要分别外接电容并贴近芯片放置。两个AVDDK引脚建议任选一个外接1uF,另一个外接0.1uF。DVDDK外接0.1uF对地电容,DM9051 1脚接外置电阻的位置应改成0.1uF电容;
  • VDDIO为CH390H的I/O电源,VDDIO支持3.3V或者2.5V,外接0.1uF对地电容;
  • 30脚和31脚XI、XO不要接电阻,由于芯片内置12pf负载电容,因此如果晶振的负载电容是12pf则不需要再接负载电容,如果晶体负载电容为20pF时建议贴15pF的负载电容;晶振必须是25MHz优选贴片晶振;如果是外部时钟输入,那么从30脚XI输入;
  • 芯片已内置终端电阻,因此不要接49.9欧或50欧等任何电阻;
  • 网络变压器的中心抽头分别通过0.1uF~1uF电容接地,不要接任何电源;

PS:如果采用杜邦线或飞线连接评估板调试,因CH390支持最高50M的SPICLK为防止串扰需要注意MCU与CH390之间可靠接地其他联络线尽量短且可靠连接,若出现SPI读写多数据或少数据的情况可以考虑在MCU与CH390的CS与CLK两端分别接10到20pF电容到地。

CH390DS1手册注意事项

CH390DS1手册中寄存器描述(H)对应CH390H,(L)对应CH390L;未标明(H)或(L)则适用于CH390H与CH390L。

引脚:I=输入;O=输出;I/O=输入/输出;P=电源;PD=内置下拉电阻;PU=内置上拉电阻。

寄存器描述中,默认形式如下:

复位值:

1位设置为逻辑1;

0位设置为逻辑0;

X没有默认值;

P=上电复位默认值;

H=硬件复位默认值;

S=软件复位默认值;

E=来自EEPROM的默认值;

T=配置引脚的默认值;

h=十六进制。

访问类型:

RO=只读;

WO=只写;

RW=读/写;

R/C=读和清除。

RW/C1=读写、通过写1清除;

保留位在读写访问时未定义

以中断屏蔽寄存器(IMR)为例,如果用的是CH390H需要访问的地址是7Fh,如果是CH390L则需要访问FFh,该寄存器的上电复位与软件复位默认值是00h,除第6位保留位为只读外其他位可读可写。

附CH390DS1手册:https://www.wch.cn/downloads/CH390DS1_PDF.html

手册描述的漏电流为浮空引脚的漏电流。

软件注意事项

可以先尝试读CH390的VID/PID验证SPI或并口通信是否正常,如果读VID/PID异常需确认接口通信是否满足CH390的时序要求。

1、CH390H支持从模式SPI模式0与SPI模式3。

SPI模式0

SPI模式3

需要注意的是一次SPI操作于SCS下降沿启动,于SCS上升沿停止,因此每次读写寄存器都需要拉低SCS直到读写完毕。

2、CH390L支持16位或者8位的被动并行总线接口

通过片选CS来选择访问CH390L。CS引脚默认为低电平有效,可以通过EEPROM配置重新定义。通过主机接口可以访问两个端口,一个是INDEX地址索引端口,另一个是DATA数据端口。引脚CMD=0时,选择INDEX端口,CMD=1时,选择DATA端口。INDEX端口的内容是DATA端口的寄存器地址。在访问任何寄存器之前,该寄存器的地址必须保存在INDEX端口中。

CH390数据包收发

  1.数据包发送

首先通过写指令寄存器MWCMD将数据写入发送缓冲区,然后将字节数写入TXPLL和TXPLH寄存器,最后将TCR寄存器位0置1开启数据包发送。上电默认从索引A开始发送数据,在数据包A发送结束之前,可以将下一个(索引B)数据包的数据写入发送缓冲区。在数据包A的传输完成后,将数据包B的长度写入TXPLL和TXPLH寄存器,并置位TCR寄存器即可发送数据包B。后续数据包以A,B,A,B…交替的顺序以同样的方式发送。

 1 /**
2 * @name ch390_write_mem
3 * @brief Write data to TX SRAM
4 * @param data - Data buffer
5 * @param length - Length to write
6 */
7 void ch390_write_mem(uint8_t *data, int length)
8 {
9 int i;
10 ch390_if.scs(0);
11 ch390_if.spi_exc_data(OPC_MEM_WRITE);
12 for(i = 0; i < length; i++) {
13 ch390_if.spi_exc_data(data[i]);
14 }
15 ch390_if.scs(1);
16 }
1 /**
2 * @name ch390_send_request
3 * @brief Issue transmit request
4 */
5 void ch390_send_request()
6 {
7 uint8_t tcr = ch390_read_reg(CH390_TCR);
8 ch390_write_reg(CH390_TCR, tcr | TCR_TXREQ);
9 }
 1 /**
2 * @name ch390_send_packet
3 * @brief Send packet
4 * @param buff - Data to be sent
5 * @param length - Less than 3k bytes.
6 */
7 void ch390_send_packet(uint8_t *buff, uint16_t length)
8 {
9 // Write data to SRAM
10 ch390_write_mem(buff, length);
11 // Wait until last transmit complete
12 while(ch390_read_reg(CH390_TCR) & TCR_TXREQ);
13 // Set current packet length
14 ch390_write_reg(CH390_TXPLL, length & 0xff);
15 ch390_write_reg(CH390_TXPLH, (length >> 8) & 0xff);
16 // Issue transmit request
17 ch390_send_request();
18 }

  2.数据包接受

接收缓冲区是一个环形缓冲区。系统复位后,接收缓冲区的起始地址为0C00h。每个数据包包含4字节的帧头,数据域,以及CRC。4字节帧头的格式为:01h,状态,数据长度低字节,数据长度高字节。

接收数据时需要先读两次无地址递增内存数据预取读命令寄存器(MRCMDX),第一次读为执行预取命令,第二次读才是取该寄存器里的实际值。通过该值判断接收到的是否为有效数据,如果为有效数据则需要通过地址递增的内存数据读命令寄存器(MRCMD)取数据即可。

 1 /**
2 * @name ch390_receive_packet
3 * @brief Receive packet
4 * @param buff - Size equal to CH390_PKT_MAX
5 * @param rx_status - Output abnormal status while receiving packet.
6 * It has the same meaning as RSR(06h).
7 * @return Packet length
8 */
9 uint32_t ch390_receive_packet(uint8_t *buff, uint8_t *rx_status)
10 {
11 uint8_t rx_ready;
12 uint16_t rx_len = 0;
13 uint8_t ReceiveData[4];
14
15 // Check packet ready or not
16 ch390_read_reg(CH390_MRCMDX);
17 rx_ready = ch390_read_reg(CH390_MRCMDX);
18
19 // if rxbyte != 1 or 0 reset device
20 if (rx_ready & CH390_PKT_ERR)
21 {
22 // Reset RX FIFO pointer
23 ch390_write_reg(CH390_RCR, 0); //RX disable
24 ch390_write_reg(CH390_MPTRCR, 0x01); //Reset RX FIFO pointer
25 ch390_write_reg(CH390_MRRH, 0x0c);
26 ch390_if.delay_us(1000);
27 ch390_write_reg(CH390_RCR, RCR_RXEN); //RX Enable
28 return 0;
29 }
30 if (!(rx_ready & CH390_PKT_RDY))
31 {
32 return 0;
33 }
34
35 ch390_read_mem(ReceiveData, 4);
36
37 *rx_status = ReceiveData[1];              //对应RSR寄存器
38 rx_len = ReceiveData[2] | (ReceiveData[3] << 8);  //接收数据长度
39
40 if(rx_len <= CH390_PKT_MAX)
41 {
42 ch390_read_mem(buff, rx_len);
43 }
44
45 if ((*rx_status & 0x3f) || (rx_len > CH390_PKT_MAX))
46 {
47 return 0;
48 }
49 return rx_len;
50 }
 1 /**
2 * @name ch390_read_mem
3 * @brief Read data from RX SRAM
4 * @param data - Data buffer
5 * @param length - Length to read
6 */
7 void ch390_read_mem(uint8_t *data, int length)
8 {
9 int i;
10 ch390_if.scs(0);
11 ch390_if.spi_exc_data(OPC_MEM_READ);
12
13 for(i = 0; i < length; i++) {
14 data[i] = ch390_spi_dummy_read();
15 }
16 ch390_if.scs(1);
17 }

CH390中断说明

中断状态寄存器(ISR)写1清零,其中第五位LINKCHG位比较特殊需要如下处理否则可能会出现不报中断状态的情况。

 1 /**
2 * @name ch390_int_handler
3 * @brief Handle CH390 interrupt events, include packet receive
4 */
5 void ch390_int_handler()
6 {
7 uint8_t int_status = ch390_get_int_status();
8 // Link status changed
9 if(int_status & ISR_LNKCHG)
10 {
11 Delay_Ms(100);
12 ch390_write_phy(0x1f, 0);
13 while(ch390_read_phy(0x1e));
14 phy_linked = ch390_get_link_status();
15 printf("Link status: %d\r\n", phy_linked);
16 ch390_write_reg(CH390_ISR, ISR_LNKCHG);
17 }
18 // Receive overflow
19 if(int_status & ISR_ROS) printf("Receive overflow\r\n");
20 // Receive overflow counter overflow
21 if(int_status & ISR_ROO) printf("Overflow counter overflow\r\n");
22 // Packet transmitted
23 if(int_status & ISR_PT) printf("Packet sent\r\n");
24 // Packet received
25 if(int_status & ISR_PR)
26 {
27 /* Multiple packets may be received in a single packet receive
28 * event. So "ch390_receive_packet" should be called until the
29 * return value is 0. Otherwise data will accumulate in RX SRAM
30 * and cause overflow. */
31 uint8_t rx_status = 0;
32 while(rx_fifo.write_p->valid == 0)
33 {
34 rx_fifo.write_p->length = ch390_receive_packet(
35 rx_fifo.write_p->data,
36 &rx_status);
37 if(rx_fifo.write_p->length != 0)
38 {
39 rx_fifo.write_p->valid = 1;
40 rx_fifo.write_p = rx_fifo.write_p->next;
41 }
42 else break;
43 }
44 }
45 }

附CH390EVT例程:https://www.wch.cn/downloads/CH390EVT_ZIP.html

CH390使用注意事项的更多相关文章

  1. jQuery UI resizable使用注意事项、实时等比例拉伸及你不知道的技巧

    这篇文章总结的是我在使用resizable插件的过程中,遇到的问题及变通应用的奇思妙想. 一.resizable使用注意事项 以下是我在jsfiddle上写的测试demo:http://jsfiddl ...

  2. Windows Server 2012 NIC Teaming介绍及注意事项

    Windows Server 2012 NIC Teaming介绍及注意事项 转载自:http://www.it165.net/os/html/201303/4799.html Windows Ser ...

  3. TODO:Golang指针使用注意事项

    TODO:Golang指针使用注意事项 先来看简单的例子1: 输出: 1 1 例子2: 输出: 1 3 例子1是使用值传递,Add方法不会做任何改变:例子2是使用指针传递,会改变地址,从而改变地址. ...

  4. app开发外包注意事项,2017最新资讯

    我们见过很多创业者,栽在这app外包上.很多创业者对于app外包这件事情不是特别重视,以为将事情交给app外包公司就完事了,实际上不是的.无论是从选择app外包公司还是签订合同.售后维护等各方面都有许 ...

  5. favicon.ioc使用以及注意事项

    1.效果 2.使用引入方法 2.1 注意事项:(把图标命名为favicon.ico,并且放在根目录下,同时使用Link标签,多重保险) 浏览器默认使用根目录下的favicon.ico 图标(如果你并没 ...

  6. ORACLE分区表梳理系列(二)- 分区表日常维护及注意事项(红字需要留意)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  7. 【原】Masonry+UIScrollView的使用注意事项

    [原]Masonry+UIScrollView的使用注意事项 本文转载请注明出处 —— polobymulberry-博客园 1.问题描述 我想实现的使用在一个UIScrollView依次添加三个UI ...

  8. 《连载 | 物联网框架ServerSuperIO教程》- 5.轮询通讯模式开发及注意事项。附:网友制作的类库说明(CHM)

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  9. 《连载 | 物联网框架ServerSuperIO教程》- 6.并发通讯模式开发及注意事项

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

  10. 《连载 | 物联网框架ServerSuperIO教程》- 7.自控通讯模式开发及注意事项

    1.C#跨平台物联网通讯框架ServerSuperIO(SSIO)介绍 <连载 | 物联网框架ServerSuperIO教程>1.4种通讯模式机制. <连载 | 物联网框架Serve ...

随机推荐

  1. C语言中的窗口滑动技术

    学习文章:C语言中的窗口滑动技术 滑动窗口法 C语言中的窗口滑动技术 循环几乎是每个复杂问题的一部分.太多的循环/嵌套循环会增加所需的时间,从而增加程序的时间复杂性.窗口滑动技术是一种计算技术,用于减 ...

  2. JVM:java虚拟机栈

  3. Fail pg walkthrough Intermediate

    nmap ┌──(root㉿kali)-[/home/ftpuserr] └─# nmap -p- -A 192.168.159.126 Starting Nmap 7.94SVN ( https:/ ...

  4. atomikos实现分布式事务

    date: 2022-04-25 categories: [java, 编程] tags: [分布式事务] 概述 多数据源单服务写入, 分布式事务实现 使用随机数控制产生异常 注: 网上很多都是只有多 ...

  5. 天翼云CDR基本概念

    本文分享自天翼云开发者社区<天翼云CDR基本概念>,作者:f****n 产品定义 云容灾CT-CDR(Cloud Disaster Recovery)为云主机提供跨可用区的容灾保护能力,R ...

  6. spark-sql查询Iceberg时处理流程

    1.查询表结构 show create table data_lake_ods.test CREATE TABLE spark_catalog.data_lake_ods.test ( `user_n ...

  7. 五分钟搞定!Linux平台上用Ansible自动化部署SQL Server AlwaysOn集群

    五分钟搞定!Linux平台上用Ansible自动化部署SQL Server AlwaysOn集群 前言 以下内容是由红帽官方博客整理而成,使用Ansible在Linux平台上自动化部署SQL Serv ...

  8. keycloak~关于社区认证的总结

    keycloak关于社区认证它有统一的设计,社区认证包括了github,microsoft,wechat,qq,dingtalk等等,当然你还可以扩展很多实现了oauth2协议的第三方社区,将它们对接 ...

  9. Vue 页面批量导入其他组件

    <template> <div> <template v-for="(item) in names"> <component :is=&q ...

  10. C++最基本调用动态链接库dll方法的小结

    针对当时初学动态链接.静态链接,有些文档整理一下发出来算是给自己和读者一个小结. 首先创建DLL 编辑头文件 dllmain.h 头文件: #pragma once #if defined(_DLL_ ...