很多MCU可能沒有以太網MAC,但是又有聯網需求,此時一款MAC+PHY集一體的芯片就是剛需;類似的FPGA平臺要集成MAC的IP既占用空間又需要額外IP成本,MAC+PHY芯片也特別適用于FPGA平臺,省得再自己去折騰MAC。
剛好看到了沁恒的CH390系列MAC+PHY芯片,完美的解決了上述需求。CH390系列具備封裝小、集成度高外圍BOM簡單、開發簡單等優點,確實是一款小而美,解決剛需的芯片。我們本文就來分享下該款芯片。
CH390是沁恒一款自帶10/100M以太網介質傳輸層(MAC)和物理層收發器(PHY)的工業級以太網控制器芯片,支持10BASE-T的CAT3、4、5和100BASE-TX的CAT5、6連接,支持Auto-MDIX,低功耗設計,符合IEEE 802.3u規范。CH390內置16K字節SRAM,支持并行接口和SPI串行接口,用于兼容各種MCU、MPU、DSP,FPGA等控制器。
CH390的系統框圖如下, 集PHY+MAC于一體。

CH390系列具備以下特點,下面紅色部分是個人覺得比較獨特的。
1)集以太網介質傳輸層(MAC)和物理層(PHY)一體。常規MCU+CH390也可以方便地實現以太網連接。
2)不同型號分別支持SPI、8位并口、16位并口, 適合MCU和FPGA等主控使用。

CH390L支持8位并行接口和16位并行接口,CH390F支持8位并行接口,CH390H和CH390D支持SPI串行接口。CH390F/H具有獨立的I/O電源引腳VDDIO,支持1.2V~3.3V接口電壓。
3)每個芯片內置唯一的以太網MAC地址,無需另外購買或分配,無需外部EEPROM。
4)集成基于DSP算法實現的低功耗10/100M收發器Transceiver。
5)支持Auto-MDIX交換TX/RX,自動識別正負信號線。
6)支持10BASE-T和100BASE-TX及自動協商。
7)支持UTP CAT5、CAT6雙絞線,支持120米傳輸距離。
8)支持用于遠程喚醒的樣本幀、鏈路狀態變化和魔法包事件。
9)支持IEEE 802.3x的流量控制。
10)支持IPv4 TCP/UDP和IPv6 TCP/UDP校驗和的生成和檢查。
這個特性非常有用,可以降低主控運行協議棧時的校驗計算時間,極大地提高效率。我們之前有測試過協議棧跑起來很大一部分主控的消耗就是計算校驗和。
11)內置50Ω阻抗匹配電阻,內置晶體振蕩器所需電容,外圍電路精簡。這降低了BOM成本,價格敏感產品選型時這就是很大的優勢。
12)支持可選的外部EEPROM配置芯片。
13)支持QFN20(CH390D)/QFN28(CH390F)/QFN32X5(CH390H)/LQFP48(CH390L),QFN20封裝尺寸才3x3mm, 特別適合空間受限應用場景。
市面上也能搜到其他廠家的類似的芯片比如DAVICOM的DM9000和DM9051,和CH390的對應如下。

CH390H引腳兼容DM9051,CH390L引腳兼容DM9000。可以看到CH390的特點、優點還是很明顯的,CH390有更寬的VIO電壓域、更低的運行功耗,更小的封裝尺寸,更高的集成度(BOM要求簡單成本低),并提供MAC地址。
官網提供了相關的資料,可從如下地址下載:
資源包:包括CH390評估板說明,原理圖及參考例程等內容。
https://www.wch.cn/downloads/CH390EVT_ZIP.html數據手冊:
https://www.wch.cn/downloads/CH390DS1_PDF.html 評估板實物圖如下,我手里的是CH390D,就以該評估板配合自己的主控開發板來進行相關功能的測試。

原理圖如下:
可以看到外圍器件超級簡單,CH390D外圍只需要5個電容加一個25MHz晶體,降低了BOM成本,同時PCB布局布線也很簡單,占用空間也小。
網絡變壓器這邊只需要兩個電阻和兩個電容。


這里使用STM32F103ZET6的開發板測試,使用Demo:EVT\EXAM\NET_MAC\NET_MAC.uvprojx。
我這里用的是MDKV5.43 默認ARMCC編譯器版本是版本6,需要配置為對應版本。


切換到編譯器版本6,編譯會提示
../SRC/CMSIS\core_cm3.h(1204): error: unknown type name 'inline'等錯誤
需要更新CMSIS, 更新core_cm3.h為
https://github.com/ARM-software/CMSIS_6/blob/main/CMSIS/Core/Include/core_cm3.h添加以下文件
https://github.com/ARM-software/CMSIS_6/blob/main/CMSIS/Core/Include/cmsis_version.hhttps://github.com/ARM-software/CMSIS_6/blob/main/CMSIS/Core/Include/cmsis_compiler.hhttps://github.com/ARM-software/CMSIS_6/blob/main/CMSIS/Core/Include/cmsis_armclang.hhttps://github.com/ARM-software/CMSIS_6/blob/main/CMSIS/Core/Include/m-profile/cmsis_armclang_m.h
還提示 NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;錯誤則
IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;改為
IPR[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;CH390.h中選擇接口模式
我這里使用SPI,如果支持并口可配置對應的接口,
// #define CH390_INTERFACE_8_BIT // CH390L/CH390F 8-bit mode// #define CH390_INTERFACE_16_BIT // CH390L 16-bit mode
如果并口支持FSMC還可以使用FSMC,可以極大提高效率。
對應使用的引腳如下
默認調試串口為USART1 PA9/PA10
接線如下

運行后打印如下,打印狀態以及收到的數據包,說明收發正常。

使用STM32F103的SPI1,時鐘來源于APB2(72MHz)。
CH390_Interface.c中配置分頻
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;STM32F103最大可配置為
main.c中ch390_int_handler下注釋掉打印
//print_packet(receive_buff, length);main.c中可以修改一次發送大小
main函數中連續發送
/*** @brief Main program* @param None* @retval None*/int main(void){//Delay_Init();SysTick_Config(SystemCoreClock/1000);NVIC_EnableIRQ(SysTick_IRQn);USART_Printf_Init(115200);ch390_gpio_init();ch390_spi_init();ch390_hardware_reset();// Don't read/write CH390 registers within 10ms after power onDelay_Ms(10);ch390_default_config();ch390_print_info();init_packet_data();while (1){if (ch390_get_int_pin()){ch390_int_handler();}if (phy_linked){ch390_send_packet(packet_data, TEST_DATA_LEN);}}}
以上簡單測試一下。CH390使用SPI時最大支持72M時鐘, 網上看到用CH390單發速度有68.6Mbps,可能的優化方向是,提高SPI時鐘頻率到最大72MHz,優化SPI發送接口比如使用DMA等。 也可以使用8/16位并口的型號,使用fsmc提高效率。
使用Demo:EVT\EXAM\WakeOnLan\WakeOnLan.uvprojx
關鍵代碼如下
配置GPIO引腳輸入中斷,這里用PA8,中斷可喚醒MCU:
ch390_interrupt_init(); 配置CH390喚醒幀過濾器:
sample_frame_filter_config();// Enable magic packet and sample packet wake up
配置幀喚醒事件
ch390_wakeup_config(WCR_MAGICEN | WCR_SAMPLEEN); 每收到5包,配置CH390進入等待喚醒狀態,MCU進入WFI狀態,如果喚醒則產生WOL中斷,觸發MCU喚醒繼續執行。
// Sleep every 5 packets receivedif(receive_count >= 5){receive_count = 0;ch390_wake_notify();printf("Sleep\r\n");__WFI();printf("Wake on LAN!\r\n");}
運行打印如下

使用Demo:EVT\EXAM\LwIP_Example\LwIP_Example.uvprojx
Cc.h中
typedef unsigned long u32_t;typedef signed long s32_t;
改為
typedef unsigned int u32_t;typedef signed int s32_t;
開發板IP配置 IP4_ADDR(&ipaddr, 192, 168, 1, 120);
所以電腦配置為同網段 192, 168, 1, 119
main.c中可以配置是否使能DHCP,這里不使能
main.c中測試udp收發
udpecho_init();//tcp_client_init();//tcp_server_init();
本地端口是2300,遠程端口是1000
void udpecho_init(void){udp_echo_pcb = udp_new();udp_bind(udp_echo_pcb, IP_ADDR_ANY, 2300);udp_connect(udp_echo_pcb, IP_ADDR_ANY, 1000);udp_recv(udp_echo_pcb, udpecho_recv, NULL);}
上位機中使用網絡調試助手收發測試,開發板收到數據原樣返回,測試功能正常。

//udpecho_init();//tcp_client_init();tcp_server_init();
開發板收到數據原樣返回, 使用上位機調試助手,測試收發如下,功能測試正常。

//udpecho_init();tcp_client_init();//tcp_server_init();
如下函數中修改服務端地址和端口
void tcp_client_init(void){extern struct netif ch390_netif;ip4_addr_t server_ip;uint16_t server_port = 2200;IP4_ADDR(&server_ip, 192, 168, 1, 119);tcp_client_pcb = tcp_new();if (tcp_client_pcb == NULL){printf("tcp_new error\n");return;}tcp_bind(tcp_client_pcb, IP_ANY_TYPE, 0);tcp_err(tcp_client_pcb, tcp_client_error);tcp_connect(tcp_client_pcb, (const ip_addr_t *)&server_ip,server_port, tcp_client_connected);}
開發板收到數據原樣返回, 使用上位機調試助手,測試收發如下,功能測試正常。

從上可以看出CH390集成MAC+PHY,適用于無MAC的MCU和FPGA等主控快速實現以太網連接。CH390有較寬的VIO電壓域、較低的功耗、小的封裝尺寸、高的集成度(BOM要求簡單成本低)、提供MAC地址等明顯的優點,是相應需求時非常不錯的選擇。有了該芯片,媽媽再也不用擔心我無MAC的MCU和無MAC IP的FPGA聯網了。
官方提供了STM32F103的例程, 可以直接基于此實現以太網RAW、UDP、TCP數據收發的應用,其他平臺移植也很簡單,只需要實現簡單的接口替換即可。