赞
踩
高速USB转接芯片CH347是一款集成480Mbps高速USB接口、JTAG接口、SPI接口、I2C接口、异步UART串口、GPIO接口等多种硬件接口的转换芯片。
接口示意图:
CH347包括CH347T和CH347F两款型号,CH347T芯片使用I2C功能需要额外模式选择,芯片在复位时,会根据DTR1(CFG0)和RTS1(CFG1)引脚的电平状态配置其工作模式,各工作模式及功能说明如下:
工作模式 | 模式说明 | CFG0 | CFG1 |
Mode0 | 480Mbps高速USB转双UART(Baudrate最高9Mbps) | 1 | 1 |
Mode1 | 480Mbps高速USB转UART+SPI+I2C(厂商驱动模式) | 0 | 1 |
Mode2 | 480Mbps高速USB转UART+SPI+I2C(系统HID驱动模式) | 1 | 0 |
Mode3 | 480Mbps高速USB转UART+JTAG(厂商驱动模式) | 0 | 0 |
CH347可使用I2C的模式有两种,其区别在Mode1需要安装厂商驱动,Mode3可以使用系统内置HID驱动无需额外安装,只需在编程时调用CH347动态库进行软件编程即可,本博客使用Mode1来进行操作。
CH347F芯片不需要进行额外的模式选择,该型号默认支持所有接口功能。
从WCH官网下载CH347转SPI/I2C/JTAG/GPIO驱动:CH341PAR.EXE - 南京沁恒微电子股份有限公司
驱动下载后进行一次安装,后续即可实现系统“免驱”效果无需二次安装。未插入设备时安装会显示“驱动预安装成功”,此时驱动已经正常安装,硬件即插即用。
Windows驱动通过微软数字签名认证,支持32/64位 Windows 11/10/8.1/8/7/VISTA/XP/2000,SERVER 2019/2016/2012/2008/2003等系统,无需担心Windows不同系统兼容性问题。
官方同时提供驱动资源包CH341PAR.ZIP - 南京沁恒微电子股份有限公司,可将驱动安装文件打包至成熟产品一齐发布,且支持无界面安装操作,可通过软件编程调用命令行操作,只需执行“SETUP /S”命令即可静默驱动安装。
点击安装之后,等待弹出安装成功窗口后点击确定即可。
下载Linux驱动、应用库和软件包:CH341PAR_LINUX.ZIP - 南京沁恒微电子股份有限公司USB转JTAG/SPI/I2C/并口/GPIO等接口的Linux设备驱动程序,支持CH341的USB转SPI/I2C/EPP并口/MEM并口等,支持CH347的480Mbps高速USB转JTAG/SPI/I2C/GPIO等,支持32/64位操作系统。https://www.wch.cn/downloads/CH341PAR_LINUX_ZIP.html 按照压缩包内的说明资料使用驱动和其他资料。
1、执行 sudo make install 可自动编译与安装驱动;
2、插入USB设备可查看到生成前缀为ch34x_pis的设备节点。
本次操作CH347开发板板载EEPROM:24LC515H。
除此之外,CH347也可操作AT24xxx、M24xxx等等EEPROM
WCH提供了一套公用的库函数接口,即Windows&Linux平台接口函数名称与参数一致,其库函数接口特性如下:
操作SPI、I2C、GPIO等的接口在任何工作模式下都可使用同一API,在进行软件编写时,只需调用接口完成代码操作逻辑而不用关注当前硬件工作模式。提供插拔检测函数可动态监测设备插拔信息,更方便进行设备管理。
具体详细内容可参考官方开发手册:CH347EVT.ZIP - 南京沁恒微电子股份有限公司 【目录:CH347EVT\EVT\PUB\CH347应用开发手册.PDF】
- /***************插拔监测函数************/
- BOOL WINAPI CH347SetDeviceNotify( // 设定设备事件通知程序
- ULONG iIndex, // 指定设备序号,0对应第一个设备
- PCHAR iDeviceID, // 可选参数,指向字符串,指定被监控的设备的ID,字符串以\0终止
- mPCH347_NOTIFY_ROUTINE iNotifyRoutine ); // 指定设备事件回调程序,为NULL则取消事件通知,否则在检测到事件时调用该程序
- /********IIC接口函数通用于Mode1/2***********/
- // 设置串口流模式
- BOOL WINAPI CH347I2C_Set(ULONG iIndex, // 指定设备序号
- ULONG iMode ); // 指定模式,见下行
- // 位1-位0: I2C接口速度/SCL频率, 00=低速/20KHz,01=标准/100KHz(默认值),10=快速/400KHz,11=高速/750KHz
- // 其它保留,必须为0
-
- // 设置硬件异步延时,调用后很快返回,而在下一个流操作之前延时指定毫秒数
- BOOL WINAPI CH347I2C_SetDelaymS(ULONG iIndex, // 指定设备序号
- ULONG iDelay ) ; // 指定延时的毫秒数
-
- // 处理I2C数据流,2线接口,时钟线为SCL引脚,数据线为SDA引脚
- BOOL WINAPI CH347StreamI2C( ULONG iIndex, // 指定设备序号
- ULONG iWriteLength, // 准备写出的数据字节数
- PVOID iWriteBuffer, // 指向一个缓冲区,放置准备写出的数据,首字节通常是I2C设备地址及读写方向位
- ULONG iReadLength, // 准备读取的数据字节数
- PVOID oReadBuffer ); // 指向一个缓冲区,返回后是读入的数据
- #ifndef _CH341_DLL_H
- typedef enum _EEPROM_TYPE {// EEPROM型号
- ID_24C01,
- ID_24C02,
- ID_24C04,
- ID_24C08,
- ID_24C16,
- ID_24C32,
- ID_24C64,
- ID_24C128,
- ID_24C256,
- ID_24C512,
- ID_24C1024,
- ID_24C2048,
- ID_24C4096
- } EEPROM_TYPE;
- #endif
-
- // 从EEPROM中读取数据块,速度约56K字节
- BOOL WINAPI CH347ReadEEPROM(ULONG iIndex, // 指定设备序号
- EEPROM_TYPE iEepromID, // 指定EEPROM型号
- ULONG iAddr, // 指定数据单元的地址
- ULONG iLength, // 准备读取的数据字节数
- PUCHAR oBuffer ); // 指向一个缓冲区,返回后是读入的数据
- // 向EEPROM中写入数据块
- BOOL WINAPI CH347WriteEEPROM(ULONG iIndex, // 指定设备序号
- EEPROM_TYPE iEepromID, // 指定EEPROM型号
- ULONG iAddr, // 指定数据单元的地址
- ULONG iLength, // 准备写出的数据字节数
- PUCHAR iBuffer ); // 指向一个缓冲区,放置准备写出的数据
可参考官方开发资料:CH347EVT.ZIP - 南京沁恒微电子股份有限公司 【目录:CH347EVT\EVT\TOOLS\CH347Demo】
界面读写示例如下:
- /*
- * ch347 application demo
- *
- * Copyright (C) 2023 Nanjing Qinheng Microelectronics Co., Ltd.
- * Web: http://wch.cn
- * Author: WCH <tech@wch.cn>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Cross-compile with cross-gcc -I /path/to/cross-kernel/include
- *
- * V1.0 - initial version
- * V1.1 - add operation for HID mode
- * V1.2 - add serial port operation in HID and TTY mode
- * V1.3 - update with new library
- * V1.4 - add gpio interrupt funciton, update with new library,
- * - support more SPI and I2C stretching
- * - support I2C clock stretch
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include <stdint.h>
- #include <unistd.h>
- #include <sys/ioctl.h>
- #include <sys/types.h>
- #include <sys/time.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <time.h>
- #include <endian.h>
- #include <linux/hidraw.h>
-
- #include "ch347_lib.h"
-
- #define CMD_FLASH_SECTOR_ERASE 0x20
- #define CMD_FLASH_BYTE_PROG 0x02
- #define CMD_FLASH_READ 0x03
- #define CMD_FLASH_RDSR 0x05
- #define CMD_FLASH_WREN 0x06
- #define CMD_FLASH_JEDEC_ID 0x9F
-
- #define SPI_FLASH_PerWritePageSize 256
-
- typedef enum _CH347FUNCTYPE {
- FUNC_UART = 0,
- FUNC_SPI_I2C_GPIO,
- FUNC_JTAG_GPIO,
- FUNC_SPI_I2C_JTAG_GPIO,
- } CH347FUNCTYPE;
-
- struct ch34x {
- int fd;
- char version[100];
- CHIP_TYPE chiptype;
- uint32_t dev_id;
- CH347FUNCTYPE functype;
- };
-
- static struct ch34x ch347device;
-
- bool CH347_SPI_Init()
- {
- bool ret;
- mSpiCfgS SpiCfg = { 0 };
-
- /* set spi interface in [mode3] & [15MHz] & [MSB] & output [0xFF] by default */
- SpiCfg.iMode = 3;
- SpiCfg.iSpiSpeedHz = 30e6;
- SpiCfg.iByteOrder = 1;
- SpiCfg.iSpiOutDefaultData = 0xFF;
- SpiCfg.iChipSelect = 0x80;
-
- /* init spi interface */
- ret = CH347SPI_Init(ch347device.fd, &SpiCfg);
- if (!ret) {
- printf("Failed to init SPI interface.\n");
- return false;
- }
-
- return true;
- }
-
- bool CH347_I2C_Init()
- {
- bool ret;
- int iMode;
-
- /* set i2c interface in 750KHZ */
- iMode = 0x03;
-
- /* init i2c interface */
- ret = CH347I2C_Set(ch347device.fd, iMode);
- if (!ret) {
- printf("Failed to init I2C interface.\n");
- return false;
- }
-
- return true;
- }
-
- bool Flash_ID_Read()
- {
- int iChipSelect;
- int iLength;
- uint8_t ioBuffer[4] = { 0 };
- uint32_t Flash_ID;
-
- iChipSelect = 0x80;
- iLength = 4;
- ioBuffer[0] = CMD_FLASH_JEDEC_ID;
- memset(ioBuffer + 1, 0xFF, 3);
-
- if (CH347SPI_WriteRead(ch347device.fd, false, iChipSelect, iLength, ioBuffer) == false)
- return false;
- else {
- ioBuffer[0] = 0x00;
- memcpy(&Flash_ID, ioBuffer, 4);
- }
- Flash_ID = htole32(Flash_ID);
- printf("Read flash ID: 0x%x.\n", Flash_ID);
-
- if (Flash_ID == 0x000000 || Flash_ID == 0xffffff00) {
- printf("Read flash ID error.\n");
- return false;
- }
-
- return true;
- }
-
- unsigned int Flash_Block_Read(unsigned int address, uint8_t *pbuf, unsigned int len)
- {
- int iChipSelect;
- int iLength;
- int oLength;
- uint8_t ioBuffer[8192] = { 0 };
-
- iChipSelect = 0x80;
- iLength = 0x04;
- oLength = len;
- ioBuffer[0] = CMD_FLASH_READ;
- ioBuffer[1] = (uint8_t)(address >> 16);
- ioBuffer[2] = (uint8_t)(address >> 8);
- ioBuffer[3] = (uint8_t)(address);
-
- if (!CH347SPI_Read(ch347device.fd, false, iChipSelect, iLength, &oLength, ioBuffer)) {
- printf("Flash_Block_Read read %d bytes failed.\n", len);
- return 0;
- } else
- memcpy(pbuf, ioBuffer, oLength);
-
- return oLength;
- }
-
- bool Flash_Block_Read_Test()
- {
- double UseT;
- uint32_t DataLen, FlashAddr, i;
- uint8_t ioBuffer[8192] = { 0 };
- char FmtStr1[8 * 1024 * 3 + 16] = "";
-
- static struct timeval t1, t2;
- int delta_sec, delta_usec;
-
- FlashAddr = 0x00;
- DataLen = 0x500;
-
- gettimeofday(&t1, NULL);
- DataLen = Flash_Block_Read(FlashAddr, ioBuffer, DataLen);
- if (DataLen <= 0) {
- printf("\tFlash Read: Addr[0x%x] read %d bytes failed.\n", FlashAddr, DataLen);
- return false;
- }
- gettimeofday(&t2, NULL);
-
- delta_sec = t2.tv_sec - t1.tv_sec;
- delta_usec = t2.tv_usec - t1.tv_usec;
- UseT = (float)delta_sec + (float)delta_usec / 1000000;
-
- printf("\tFlash Read: Addr[0x%x] read %d bytes in %.3f seconds.\n", FlashAddr, DataLen, UseT);
- for (i = 0; i < DataLen; i++)
- sprintf(&FmtStr1[strlen(FmtStr1)], "%02x ", ioBuffer[i]);
- printf("\nRead: \n%s\n\n", FmtStr1);
-
- return true;
- }
-
- bool Flash_Write_Enable()
- {
- int iChipSelect;
- int iLength;
- uint8_t ioBuffer;
-
- iChipSelect = 0x80;
- iLength = 1;
- ioBuffer = CMD_FLASH_WREN;
-
- return CH347SPI_WriteRead(ch347device.fd, false, iChipSelect, iLength, &ioBuffer);
- }
-
- bool Flash_Wait()
- {
- int iChipSelect;
- int iLength;
- uint8_t ioBuffer[2];
- uint8_t status;
- int retry_times = 1000;
-
- iChipSelect = 0x80;
- iLength = 2;
-
- do {
- ioBuffer[0] = CMD_FLASH_RDSR;
- if (CH347SPI_WriteRead(ch347device.fd, false, iChipSelect, iLength, ioBuffer) == false)
- return false;
- status = ioBuffer[1];
- usleep(100);
- } while ((status & 0x01) && (retry_times--));
-
- if ((status & 0x01) == 0)
- return true;
- else
- return false;
- }
-
- bool Flash_Sector_Erase(uint32_t StartAddr)
- {
- int iChipSelect;
- int iLength;
- uint8_t ioBuffer[4];
-
- if (Flash_Write_Enable() == false)
- return false;
-
- iChipSelect = 0x80;
- iLength = 4;
- ioBuffer[0] = CMD_FLASH_SECTOR_ERASE;
- ioBuffer[1] = (uint8_t)(StartAddr >> 16 & 0xff);
- ioBuffer[2] = (uint8_t)(StartAddr >> 8 & 0xf0);
- ioBuffer[3] = 0x00;
-
- if (CH347SPI_WriteRead(ch347device.fd, false, iChipSelect, iLength, ioBuffer) == false)
- return false;
-
- if (Flash_Wait() == false)
- return false;
-
- return true;
- }
-
- bool W25X_Flash_Write_Page(uint8_t *pBuf, uint32_t address, uint32_t len)
- {
- int iChipSelect;
- int iLength;
- uint8_t ioBuffer[8192];
-
- if (!Flash_Write_Enable())
- return false;
-
- iChipSelect = 0x80;
- iLength = len + 4;
- ioBuffer[0] = CMD_FLASH_BYTE_PROG;
- ioBuffer[1] = (uint8_t)(address >> 16);
- ioBuffer[2] = (uint8_t)(address >> 8);
- ioBuffer[3] = (uint8_t)address;
- memcpy(&ioBuffer[4], pBuf, len);
-
- if (CH347SPI_Write(ch347device.fd, false, iChipSelect, iLength, SPI_FLASH_PerWritePageSize + 4, ioBuffer) ==
- false)
- return false;
-
- memset(ioBuffer, 0, sizeof(uint8_t) * len);
-
- if (!Flash_Wait())
- return false;
-
- return true;
- }
-
- bool Flash_Block_Write()
- {
- int ret;
- int i = 0;
- uint32_t DataLen, FlashAddr, BeginAddr, NumOfPage, NumOfSingle;
- uint8_t ioBuffer[0x500] = { 0 };
- uint8_t *pbuf = ioBuffer;
- double UseT;
-
- static struct timeval t1, t2;
- int delta_sec, delta_usec;
-
- /* write flash from addr 0 */
- FlashAddr = 0x00;
- BeginAddr = FlashAddr;
- DataLen = 0x500;
-
- for (i = 0; i < DataLen; i++)
- ioBuffer[i] = i;
-
- NumOfPage = DataLen / SPI_FLASH_PerWritePageSize;
- NumOfSingle = DataLen % SPI_FLASH_PerWritePageSize;
-
- /* caculate flash write time */
- gettimeofday(&t1, NULL);
- while (NumOfPage--) {
- ret = W25X_Flash_Write_Page(pbuf, FlashAddr, SPI_FLASH_PerWritePageSize);
- if (ret == false)
- goto exit;
- pbuf += SPI_FLASH_PerWritePageSize;
- FlashAddr += SPI_FLASH_PerWritePageSize;
- }
- if (NumOfSingle) {
- ret = W25X_Flash_Write_Page(pbuf, FlashAddr, NumOfSingle);
- if (ret == false)
- goto exit;
- }
- gettimeofday(&t2, NULL);
-
- delta_sec = t2.tv_sec - t1.tv_sec;
- delta_usec = t2.tv_usec - t1.tv_usec;
- UseT = ((float)delta_sec + (float)delta_usec / 1000000);
-
- printf("\tFlash Write: Addr[0x%x] write %d bytes in %.3f seconds.\n", BeginAddr, DataLen, UseT / 1000);
-
- return true;
-
- exit:
- printf("\tFlash Write: Addr [0x%x] write %d bytes failed.\n", BeginAddr, DataLen);
- return false;
- }
-
- bool EEPROM_Read()
- {
- bool ret = false;
- EEPROM_TYPE eeprom;
- int iAddr;
- int iLength;
- int i;
- uint8_t oBuffer[256] = { 0 };
-
- eeprom = ID_24C02;
- iAddr = 0;
- iLength = 256;
-
- ret = CH347ReadEEPROM(ch347device.fd, eeprom, 0, iLength, oBuffer);
- if (ret == false)
- goto exit;
-
- printf("\nRead EEPROM data:\n");
- for (i = 0; i < iLength; i++) {
- printf("%02x ", oBuffer[i]);
- if (((i + 1) % 10) == 0)
- putchar(10);
- }
- putchar(10);
-
- exit:
- return ret;
- }
-
- bool EEPROM_Write()
- {
- bool ret = false;
- EEPROM_TYPE eeprom;
- int iAddr;
- int iLength;
- int i;
- uint8_t iBuffer[256] = { 0 };
-
- eeprom = ID_24C02;
- iAddr = 0;
- iLength = 256;
- for (i = 0; i < 256; i++)
- iBuffer[i] = i;
-
- printf("\nWrite EEPROM data:\n");
- ret = CH347WriteEEPROM(ch347device.fd, eeprom, iAddr, iLength, iBuffer);
- if (ret == false)
- goto exit;
-
- for (i = 0; i < iLength; i++) {
- printf("%02x ", iBuffer[i]);
- if (((i + 1) % 10) == 0)
- putchar(10);
- }
- putchar(10);
-
- exit:
- return ret;
- }
-
- void ch34x_demo_flash_operate()
- {
- bool ret = false;
-
- ret = CH347_SPI_Init();
- if (ret == false) {
- printf("Failed to init CH347 SPI interface.\n");
- return;
- }
- printf("CH347 SPI interface init succeed.\n");
-
- /* read flash ID */
- ret = Flash_ID_Read();
- if (!ret) {
- printf("Failed to read flash ID.\n");
- return;
- }
-
- /* read flash block data */
- ret = Flash_Block_Read_Test();
- if (!ret) {
- printf("Failed to read flash.\n");
- return;
- }
-
- /* erase flash sector data */
- ret = Flash_Sector_Erase(0x00);
- if (!ret) {
- printf("Failed to erase flash.\n");
- return;
- }
- printf("Erase one sector from Addr[0x%x] of flash succeed.\n", 0x00);
-
- /* write flash block data */
- ret = Flash_Block_Write();
- if (!ret) {
- printf("Failed to write flash.\n");
- return;
- }
-
- /* read flash block data */
- ret = Flash_Block_Read_Test();
- if (!ret) {
- printf("Failed to read flash.\n");
- return;
- }
- }
-
- void ch34x_demo_eeprom_operate()
- {
- bool ret = false;
-
- ret = CH347_I2C_Init();
- if (!ret) {
- printf("Failed to init CH347 I2C.\n");
- return;
- }
- printf("CH347 I2C interface init succeed.\n");
-
- ret = EEPROM_Read();
- if (!ret) {
- printf("Failed to read eeprom.\n");
- return;
- }
-
- ret = EEPROM_Write();
- if (!ret) {
- printf("Failed to write eeprom.\n");
- return;
- }
-
- ret = EEPROM_Read();
- if (!ret) {
- printf("Failed to read eeprom.\n");
- return;
- }
- }
-
- void ch34x_demo_jtag_operate()
- {
- int i;
- int oReadLength;
- uint8_t retue[32] = { 0 };
- uint8_t IDCODE[4096] = { 0 };
-
- oReadLength = 32;
- /* init jtag tck clock */
- CH347Jtag_INIT(ch347device.fd, 4);
- /* reset target jtag device */
- CH347Jtag_SwitchTapState(ch347device.fd, 0);
- /* SHIFT-DR Read the Target IDCODE */
- CH347Jtag_ByteReadDR(ch347device.fd, &oReadLength, &retue);
-
- printf("Target IDCODE: \n");
- for (i = 0; i < 4; i++) {
- printf("0x%2x", retue[3 - i]);
- }
- puts("");
-
- return;
- }
-
- bool CH347_SPI_Slave_Init()
- {
- bool ret;
- mSpiCfgS SpiCfg = { 0 };
-
- /* set spi interface in spi slave mode, [mode3] & [MSB] & output [0xFF] by default */
- SpiCfg.iByteOrder = 1;
- SpiCfg.iSpiOutDefaultData = 0xFF;
- SpiCfg.iMode = 0x83;
-
- /* init spi interface */
- ret = CH347SPI_Init(ch347device.fd, &SpiCfg);
- if (!ret) {
- printf("Failed to init SPI interface.\n");
- return false;
- } else {
- printf("SPI init slave ok.\n");
- }
-
- return true;
- }
-
- void ch34x_demo_spi_slave_operate(bool enable)
- {
- bool ret = false;
- uint8_t oBuffer[SPI_SLAVE_MAX_LENGTH];
- uint32_t oLength;
- int i;
-
- if (enable) {
- ret = CH347_SPI_Slave_Init();
- if (ret == false) {
- printf("Failed to init CH347 SPI interface.\n");
- return;
- }
- printf("CH347 SPI interface init succeed.\n");
- ret = CH347SPI_Slave_Control(ch347device.fd, true);
- if (!ret)
- return;
- printf("Begin read data in slave mode.\n");
- while (1) {
- ret = CH347SPI_Slave_QweryData(ch347device.fd, &oLength);
- if (!ret) {
- printf("CH347SPI_Slave_QweryData failed.\n");
- goto exit;
- }
- if (oLength == 0) {
- usleep(10 * 1000);
- continue;
- }
- ret = CH347SPI_Slave_ReadData(ch347device.fd, oBuffer, &oLength);
- if (!ret) {
- printf("CH347SPI_Slave_ReadData failed.\n");
- goto exit;
- }
- printf("\nRead Slave data, len: %d, contents:\n", oLength);
- for (i = 0; i < oLength; i++) {
- printf("%02x ", oBuffer[i]);
- if (((i + 1) % 20) == 0)
- putchar(20);
- }
- putchar(20);
- }
- } else
- ret = CH347SPI_Slave_Control(ch347device.fd, false);
-
- return;
-
- exit:
- CH347SPI_Slave_Control(ch347device.fd, false);
- }
-
- static void ch34x_demo_gpio_input_operate()
- {
- bool ret;
- int i, j;
- int gpiocount = 8;
- uint8_t iDir = 0xff;
- uint8_t iData = 0x00;
-
- ret = CH347GPIO_Get(ch347device.fd, &iDir, &iData);
- if (ret == false) {
- printf("CH347GPIO_Set error.\n");
- return;
- }
-
- printf("\n********** GPIO Input Start **********\n\n");
- for (i = 0; i < gpiocount; i++) {
- if ((iData & (1 << i)))
- printf("H");
- else
- printf("L");
- }
- printf("\n");
- printf("\n********** GPIO Input End **********\n\n");
- }
-
- static void ch34x_demo_gpio_output_operate()
- {
- bool ret;
- int i, j;
- int gpiocount = 8;
- uint8_t iEnable = 0xff;
- uint8_t iSetDirOut = 0xff;
- uint8_t iSetDataOut = 0x00;
-
- /* analog leds here */
- CH347GPIO_Set(ch347device.fd, iEnable, iSetDirOut, iSetDataOut);
-
- printf("\n********** GPIO Output Start **********\n");
- for (i = 0; i < gpiocount; i++) {
- iSetDataOut = 1 << i;
- ret = CH347GPIO_Set(ch347device.fd, iEnable, iSetDirOut, iSetDataOut);
- if (ret == false) {
- printf("CH347GPIO_Set error.\n");
- return;
- }
- printf("\n");
- for (j = 0; j < gpiocount; j++) {
- if (j == i)
- printf("H");
- else
- printf("L");
- }
- printf("\n");
- usleep(200 * 1000);
- }
- iSetDataOut = 0x00;
- CH347GPIO_Set(ch347device.fd, iEnable, iSetDirOut, iSetDataOut);
- printf("\n********** GPIO Output End **********\n\n");
- }
-
- static void ch34x_demo_isr_handler(int signo)
- {
- static int int_times = 0;
-
- printf("ch34x interrupt times: %d\n", int_times++);
- }
-
- static void ch34x_demo_irq_operate(bool enable)
- {
- bool ret;
- int gpioindex = 6;
-
- ret = CH347GPIO_IRQ_Set(ch347device.fd, gpioindex, enable, IRQ_TYPE_EDGE_BOTH, ch34x_demo_isr_handler);
- if (!ret) {
- printf("Failed to set CH347 irq function.");
- return;
- }
- }
-
- void ch34x_demo_uart_operate()
- {
- bool ret = false;
- uint8_t iBuffer[256];
- uint8_t oBuffer[256];
- uint32_t ioLength;
- int i;
-
- ioLength = 256;
- for (i = 0; i < 256; i++)
- iBuffer[i] = i;
-
- ret = CH347Uart_Init(ch347device.fd, 115200, 3, 0, 0, 1);
- if (!ret) {
- printf("Failed to init CH347 UART interface.\n");
- return;
- }
- printf("CH347 UART interface init succeed.\n");
-
- ret = CH347Uart_Write(ch347device.fd, iBuffer, &ioLength);
- if (ret == false) {
- printf("CH347Uart_Write failed.\n");
- return;
- }
- printf("Uart wrote %d bytes already.\n", ioLength);
-
- ret = CH347Uart_Read(ch347device.fd, oBuffer, &ioLength);
- if (ret == false) {
- printf("CH347Uart_Read failed.\n");
- return;
- }
-
- printf("\nRead Uart data:\n");
- for (i = 0; i < ioLength; i++) {
- printf("%02x ", oBuffer[i]);
- if (((i + 1) % 10) == 0)
- putchar(10);
- }
- putchar(10);
- }
-
- bool Show_DevMsg(char *pathname)
- {
- unsigned char buf[256];
- int ret;
- int i;
- struct hidraw_devinfo info;
- uint16_t vendor, product;
- CHIP_TYPE chiptype;
-
- if (strstr(pathname, "tty")) {
- printf("Device operating has function [UART].\n");
- ch347device.functype = FUNC_UART;
- } else if (strstr(pathname, "hidraw")) {
- /* Get Raw Name */
- ret = ioctl(ch347device.fd, HIDIOCGRAWNAME(256), buf);
- if (ret < 0) {
- perror("HIDIOCGRAWNAME");
- goto exit;
- } else
- printf("Raw Name: %s\n", buf);
-
- /* Get Raw Info */
- ret = ioctl(ch347device.fd, HIDIOCGRAWINFO, &info);
- if (ret < 0) {
- perror("HIDIOCGRAWINFO");
- goto exit;
- } else {
- printf("Raw Info:\n");
- printf("\tvendor: 0x%04hx\n", info.vendor);
- printf("\tproduct: 0x%04hx\n", info.product);
- }
-
- if (info.vendor == 0x1a86) {
- if (info.product == 0x55dc)
- ch347device.chiptype = CHIP_CH347T;
- else if (info.product == 0x55e5)
- ch347device.chiptype = CHIP_CH347F;
- else {
- printf("Current HID device PID is not CH347.\n");
- return -1;
- }
- } else {
- printf("Current HID device VID is not CH347.\n");
- return -1;
- }
-
- /* Get Physical Location */
- ret = ioctl(ch347device.fd, HIDIOCGRAWPHYS(256), buf);
- if (ret < 0) {
- perror("HIDIOCGRAWPHYS");
- goto exit;
- } else
- printf("Raw Phys: %s\n", buf);
-
- if (ch347device.chiptype == CHIP_CH347T) {
- if (strstr(buf, "input0")) {
- ch347device.functype = FUNC_UART;
- printf("Device operating has function [UART].\n");
- } else {
- ch347device.functype = FUNC_SPI_I2C_GPIO;
- printf("Device operating has function [SPI+I2C+GPIO].\n");
- }
- } else {
- if (strstr(buf, "input0")) {
- ch347device.functype = FUNC_UART;
- printf("Device operating has function [UART].\n");
- } else if (strstr(buf, "input2")) {
- ch347device.functype = FUNC_UART;
- printf("Device operating has function [UART].\n");
- } else {
- ch347device.functype = FUNC_SPI_I2C_GPIO;
- printf("Device operating has function [SPI+I2C+JTAG+GPIO].\n");
- }
- }
- } else if (strstr(pathname, "ch34x_pis")) {
- /* Get Driver Version */
- ret = CH34x_GetDriverVersion(ch347device.fd, ch347device.version);
- if (ret == false) {
- printf("CH34x_GetDriverVersion error.\n");
- goto exit;
- }
- printf("Driver version: %s\n", ch347device.version);
-
- /* Get Chip Type */
- ret = CH34x_GetChipType(ch347device.fd, &ch347device.chiptype);
- if (ret == false) {
- printf("CH34x_GetChipType error.\n");
- goto exit;
- }
- if (ch347device.chiptype == CHIP_CH341) {
- printf("Current chip operating is CH341, please use ch341_demo.\n");
- goto exit;
- }
-
- /* Get Device ID */
- ret = CH34X_GetDeviceID(ch347device.fd, &ch347device.dev_id);
- if (ret == false) {
- printf("CH34X_GetDeviceID error.\n");
- goto exit;
- }
- vendor = ch347device.dev_id;
- product = ch347device.dev_id >> 16;
- printf("Vendor ID: 0x%4x, Product ID: 0x%4x\n", vendor, product);
- if (product == 0x55db) {
- ch347device.functype = FUNC_SPI_I2C_GPIO;
- printf("Device operating has function [SPI+I2C+GPIO].\n");
- } else if (product == 0x55dd) {
- ch347device.functype = FUNC_JTAG_GPIO;
- printf("Device operating has function [JTAG+GPIO].\n");
- } else if (product == 0x55de) {
- ch347device.functype = FUNC_SPI_I2C_JTAG_GPIO;
- printf("Device operating has function [SPI+I2C+JTAG+GPIO].\n");
- }
- }
- return true;
-
- exit:
- return false;
- }
-
- int main(int argc, char *argv[])
- {
- bool ret;
- char choice, ch;
-
- if (argc != 2) {
- printf("Usage: sudo %s [device]\n", argv[0]);
- return -1;
- }
-
- /* open device */
- ch347device.fd = CH347OpenDevice(argv[1]);
- if (ch347device.fd < 0) {
- printf("CH347OpenDevice false.\n");
- return -1;
- }
- printf("Open device %s succeed, fd: %d\n", argv[1], ch347device.fd);
-
- ret = Show_DevMsg(argv[1]);
- if (ret == false)
- return -1;
- sleep(1);
-
- if (strstr(argv[1], "ch34x_pis")) {
- ret = CH34xSetTimeout(ch347device.fd, 2000, 2000);
- if (ret == false) {
- printf("CH34xSetTimeout false.\n");
- return -1;
- }
- }
-
- switch (ch347device.functype) {
- case FUNC_UART:
- while (1) {
- printf("\npress u to operate uart, q to quit.\n");
- scanf("%c", &choice);
- while ((ch = getchar()) != EOF && ch != '\n')
- ;
- if (choice == 'q')
- break;
- switch (choice) {
- case 'u':
- ch34x_demo_uart_operate();
- break;
- default:
- break;
- }
- }
- break;
- case FUNC_SPI_I2C_GPIO:
- case FUNC_SPI_I2C_JTAG_GPIO:
- while (1) {
- printf("\npress f to operate spi flash, e to operate eeprom,\n"
- "a to get gpio status, g to gpio output test, j to operate jtag interface,\n"
- "s to enable spi slave mode, o to disable spi slave mode,\n"
- "i to enable interrupt, d to disable interrupt, q to quit.\n");
-
- scanf("%c", &choice);
- while ((ch = getchar()) != EOF && ch != '\n')
- ;
- if (choice == 'q')
- break;
-
- switch (choice) {
- case 'f':
- printf("FLASH Test begin.\n");
- ch34x_demo_flash_operate();
- break;
- case 'e':
- printf("EEPROM Test begin.\n");
- ch34x_demo_eeprom_operate();
- break;
- case 'a':
- printf("GPIO Input Test Begin.\n");
- ch34x_demo_gpio_input_operate();
- break;
- case 'g':
- printf("GPIO Output Test Begin.\n");
- ch34x_demo_gpio_output_operate();
- break;
- case 'i':
- printf("IRQ Test Begin.");
- ch34x_demo_irq_operate(true);
- break;
- case 'd':
- printf("IRQ Test Over.\n");
- ch34x_demo_irq_operate(false);
- break;
- case 'j':
- if (ch347device.functype == FUNC_SPI_I2C_JTAG_GPIO) {
- printf("JTAG Test begin.\n");
- ch34x_demo_jtag_operate();
- } else {
- printf("Chip is not CH347F.\n");
- }
- break;
- case 's':
- if (ch347device.chiptype == CHIP_CH347F) {
- printf("SPI Slave Test Begin.\n");
- ch34x_demo_spi_slave_operate(true);
- } else {
- printf("Chip is not CH347F.\n");
- }
- break;
- case 'o':
- if (ch347device.chiptype == CHIP_CH347F) {
- printf("SPI Slave Test Over.\n");
- ch34x_demo_spi_slave_operate(false);
- } else {
- printf("Chip is not CH347F.\n");
- }
- break;
- default:
- printf("Bad choice, please input again.\n");
- break;
- }
- }
- break;
- case FUNC_JTAG_GPIO:
- while (1) {
- printf("\npress j to operate jtag interface, a to get gpio status,\n"
- "g to gpio output test q to quit.\n");
-
- scanf("%c", &choice);
- while ((ch = getchar()) != EOF && ch != '\n')
- ;
- if (choice == 'q')
- break;
-
- switch (choice) {
- case 'j':
- printf("JTAG Test begin.\n");
- ch34x_demo_jtag_operate();
- break;
- case 'a':
- printf("GPIO Input Test Begin.\n");
- ch34x_demo_gpio_input_operate();
- break;
- case 'g':
- printf("GPIO Test begin.\n");
- ch34x_demo_gpio_output_operate();
- default:
- printf("Bad choice, please input again.\n");
- break;
- }
- }
- break;
- default:
- break;
- }
-
- /* close the device */
- if (CH347CloseDevice(ch347device.fd)) {
- printf("Close device succeed.\n");
- }
-
- return 0;
- }
执行截图:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。