Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ch395): Add support for CH395Q(UART and SPI dual stack). (IDFGH-12408) #25

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

SergeyKharenko
Copy link
Contributor

@SergeyKharenko SergeyKharenko commented Mar 17, 2024

Brief Introduction

CH395 is the first domestic Ethernet controller that supports 10M/100M and has a built-in TCP/IP protocol stack. It was designed by NanjingQinhengMicroelectronics CO LTD (abbreviated as WCH) and officially launched on March 1, 2013. In terms of functionality, ch395 is comparable to Wiznet W5500. In addition, this chip can also use UART to communicate, which has fewer lines than SPI.

However, WCH only provides sample code on 80C51. What's worse, sample code is more focus on hardware TCP/IP stack of the chip. Introductions about MAC Raw mode are pretty brief. This seriously hinders its compatibility with the lwip.

My work is to explore the functionality of the chip in MAC RAW mode and port it into the esp-eth-drivers. As far as I know, no one has ever done that.

High Lights

  1. SPI and UART dual stack support
  2. UART automatic baudrate configuration(refer to README in detail)
  3. Static cache to store fragmented data generated during transmission and reception
  4. Optimization of frequently used function
  5. Passed 5 hours iperf stability test with no error

Issue & Solution

  1. Cannot send pack less than 60 bytes in MAC RAW mode. Just padding 0 to these packs before transferring to CH395
  2. Cannot accept continuous R/W in SPI Mode. R/W one byte per transaction.
  3. Send CMD01_GET_CMD_STATUS before the CH395 init, the status is keeping CH395_ERR_BUSY. Leave enough waiting time for some operations that require query to avoid queries.
  4. Fail to init CH395 after sending CMD40_SET_FUN_PARA to disable SEND_OK interrupt. Add additional delay(20 ms)
  5. After sending CMD10_SET_PHY to setup mode of PHY, within a short period of time, user would get unknow status of PHY(using CMD01_GET_PHY_STATUS). Add additional delay(350 ms)

Performance Report

UART Mode

Baudrate(bps) TCP Receive(Mbps) UDP Send(Mbps)
3000000 1.8 1.94
1500000 0.92 0.99
921600 0.54 0.61
460800 0.28 0.30
250000 0.15 0.16

Both transmit and receive increase LINEARLY as the baudrate increases. That fully demonstrates that the system bottleneck is not in the driver layer, but in baudrate instead.

SPI Mode

Frequency(MHz) TCP Receive(Mbps) UDP Send(Mbps)
40(OC) 0.54 0.58
30 0.53 0.57
20 0.53 0.57
16 0.50 0.53
10 0.51 0.55
4 0.46 0.49
1 0.30 0.32

The sending and receiving speed gradually becomes saturated after the SPI frequency is higher than 10MHz. This is mainly because the chip cannot support SPI continuous reading and writing, and a certain delay must be added between bytes, which makes DMA useless. I have already sent my questions to WCH engineers and hope to get a reply soon. On the other hand, someone could provide me with some valuable advice on SPI transmission if possible?

After Optimization

Frequency(MHz) TCP Receive(Mbps) UDP Send(Mbps)
20 1.63 13.58
16 1.55 11.47
10 0.95 7.82

Optimization is based on the following "features":

  1. At frequency below 20MHz, 4 bytes of continuous reading of SRAM is correct. Thus, in ch395_rx_buffer, packet reads are performed in 4-byte increments to improve efficiency. I guess this may be due to the SRAM's synchronization mechanism.
  2. Continuous writing of SRAM has no issue. Thus, in ch395_tx_buffer, packet writings are performed in one transmission. That's why TX Performance has been greatly improved.
  3. However, register reading cannot be continuous. I tried frequency below 10MHz to read MAC addresses continuously. Only the first byte is correct. Therefore, ch395_spi_io operations are as legacy.

PS:
Here is the introduction to this ethernet controller in detail:
CH395 is an Ethernet protocol stack management IC which provides Ethernet communication ability for MCU system. CH395 has built-in 10 / 100M Ethernet MAC and PHY and fully compatible with IEEE 802.3 protocol, it also has built-in protocol stack firmware such as PPPOE, IP, DHCP, ARP, ICMP, IGMP, UDP, TCP and etc. A MCU system can easily connect to Ethernet through CH395. CH395 supports 3 types of communication interfaces: 8-bit parallel port, SPI or USART. A MCU/DSP/MPU can use any of the above communication interfaces to operate CH395 for Ethernet communication.
image

@kostaond kostaond self-assigned this Mar 21, 2024
@github-actions github-actions bot changed the title feat(ch395): Add support for CH395Q(UART and SPI dual stack). feat(ch395): Add support for CH395Q(UART and SPI dual stack). (IDFGH-12408) Mar 21, 2024
@espressif-bot espressif-bot assigned kostaond and unassigned kostaond Mar 22, 2024
@kostaond
Copy link
Collaborator

kostaond commented Nov 8, 2024

@SergeyKharenko could you please consider distributing this driver also over your private repository on Component Registry? Unfortunately, we don't have resources to take it under our maintenance but it would be pity to be driver not published.

@SergeyKharenko
Copy link
Contributor Author

SergeyKharenko commented Nov 8, 2024

@kostaond Thanks for your attention! It is okay to close this PR as I have mentioned #37.

Although this driver initially make CH395 works on esp32, it is actually the same as W5500, the driver forces the chips working in MACRAW mode, which does not fully take advantage of these hardwired-stack chips(HWSC). So I have moved my work to hwss and I am glad to share it with you. This project aims to:

  1. Provide an abstract layer of all the HWSCs(W5500, W5100S, W6100, W5300, CH395, CH394, et.al)
  2. Bypass the lwip to maximize the performance, but share definitions of basic params(for example ip address)
  3. Make it possible to be compatible with the environment where lwip coexists, which is a huge problem when porting original drivers from manufactures of HWSCs to esp-idf, for example ioLibrary_Driver from Wiznet
  4. Refer to the Design Philosophy of esp-idf framework
  5. Minimize the cost when users migrating the example code from none HWSCs

This framework has been initially established, protocols above L3 have not been implemented and I haven't had time to write the document yet~ A small demo is implemented in main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants