51單片機和CH376,讀寫U盤兼容性不好,測試結(jié)果如下:
1. 金士頓2G或4G U盤、MORNSUN 2G U盤 讀寫正常 2. 大于8G的U盤: 識別U盤、創(chuàng)建文件、寫文件成功,但是生成的文件在PC機上打開是空的,大小只有1字節(jié) 3. 某個疑似金士頓品牌的2G U盤: 識別U盤成功,創(chuàng)建目錄和文件失敗
請問可能是什么原因?是CH376芯片的問題嗎?
CH376芯片驅(qū)動的源代碼如下:
/******************************************************************************************************** * CONSTANTS ********************************************************************************************************/
#define CH376_DATA_PORT 0 #define CH376_CMD_PORT 1
/******************************************************************************************************** * FUNCTION PROTOTYPES ********************************************************************************************************/
static unsigned char read_data_block(void *data); static unsigned char write_data_block(const void *data); static void write_buffer(const void *data,unsigned char offset,unsigned char len);
static unsigned char read_var_u8(unsigned char addr); static void write_var_u8(unsigned char addr,unsigned char val); static unsigned long read_var_u32(unsigned char addr); static void write_var_u32(unsigned char addr,unsigned long val);
static void write_port(unsigned char port,unsigned char val); static unsigned char read_port(unsigned char port); static unsigned char wait_interrupt(void);
/******************************************************************************************************** * GLOBAL VARIABLES ********************************************************************************************************/
/******************************************************************************************************** * LOCAL VARIABLES ********************************************************************************************************/
/******************************************************************************************************** * OPERATIONS ********************************************************************************************************/
/* low-level */ #define write_command(c) write_port(CH376_CMD_PORT,c) #define read_status() read_port(CH376_CMD_PORT) #define write_data(v) write_port(CH376_DATA_PORT,v) #define read_data() read_port(CH376_DATA_PORT)
/******************************************************************************************************** * GLOBAL FUNCTIONS ********************************************************************************************************/
/******************************************************************************************************** * ch376_init * * Description : This function initialize CH376 * Arguements : None * * Returns : 0 --- success others --- failed * * Notes : USB Host mode ********************************************************************************************************/ int ch376_init(void) { unsigned char ret; /* power-up delay */ delay_ms(CH376_PWR_DLY); /* pin initialize */ ch376_pin_init(); ch376_high_cs(); ch376_high_rd(); ch376_high_wr(); /* test chip */ write_command(CMD11_CHECK_EXIST); write_data(CH376_TEST_PATTERN); ret = read_data() + CH376_TEST_PATTERN; if (ret != 0x0ff) return -1; /* set mode : USB Host */ write_command(CMD11_SET_USB_MODE); write_data(CH376_MODE_HOST_SOF); /* USB Host mode */ delay_ms(1); ret = read_data(); if (ret != CMD_RET_SUCCESS) return -1; return 0; } /*******************************************************************************************************/
/******************************************************************************************************** * ch376_check_disk * * Description : This function check and initialize U-disk * * Arguements : None * * Returns : 0 --- success others --- failed * * Notes : ********************************************************************************************************/ int ch376_check_disk(void) { unsigned char ret; /* check connection */ write_command(CMD0H_DISK_CONNECT); ret = wait_interrupt(); if (ret != USB_INT_SUCCESS) return -1; /* no U-disk connected */ delay_ms(CH376_STABLE_DLY); /* wait until stable */ /* mount U-disk */ write_command(CMD0H_DISK_MOUNT); ret = wait_interrupt(); if (ret != USB_INT_SUCCESS) return -1; /* mount U-disk failed */ if (read_var_u8(VAR_DISK_STATUS) < DEF_DISK_MOUNTED) return -1; /* U-disk not ready */ return 0; } /*******************************************************************************************************/
/******************************************************************************************************** * ch376_query_disk * * Description : This function query U-disk * * Arguements : None * * Returns : 0 --- success others --- failed * * Notes : ********************************************************************************************************/ int ch376_query_disk(struct disk_info_t *disk) { unsigned char ret; /* disk inquery */ write_command(CMD0H_DISK_INQUIRY); ret = wait_interrupt(); if (ret != USB_INT_SUCCESS) return -1; /* error */ read_data_block(&(disk->device_type)); /* disk capacity */ write_command(CMD0H_DISK_CAPACITY); ret = wait_interrupt(); if (ret != USB_INT_SUCCESS) return -1; /* error */ read_data_block(&disk->phy_sect); /* disk query */ write_command(CMD0H_DISK_QUERY); ret = wait_interrupt(); if (ret != USB_INT_SUCCESS) return -1; /* error */ read_data_block(&(disk->total_sect)); return 0; } /*******************************************************************************************************/
/******************************************************************************************************** * ch376_open_file * * Description : This function open a file or directory in current directory * * Arguements : name --- file or directory name * * Returns : 0 --- success others --- failed * * Notes : file name terminated with '\0', directory name terminated with separator character ********************************************************************************************************/ int ch376_open_file(const char *name) { unsigned char ret; /* set file name */ write_command(CMD10_SET_FILE_NAME); write_data(*name++); /* the first character */ while ((*name != 0) && (*name != DEF_SEPAR_CHAR1) && (*name != DEF_SEPAR_CHAR2)) { write_data(*name); name++; } write_data(0); /* terminator */ /* open */ write_command(CMD0H_FILE_OPEN); ret = wait_interrupt(); if (*name != 0) /* directory */ { if (ret != ERR_OPEN_DIR) return -1; } else /* file */ { if (ret != USB_INT_SUCCESS) return -1; } return 0; } /*******************************************************************************************************/
/******************************************************************************************************** * ch376_open_path * * Description : This function open a file by its full path name * * Arguements : path --- full path name of file * * Returns : 0 --- success o