CH579-USB Device & Host

USB Device

  1 /********************************** (C) COPYRIGHT *******************************
  2 * File Name          : Main.c
  3 * Author             : WCH
  4 * Version            : V1.0
  5 * Date               : 2018/12/15
  6 * Description        : 自定义USB设备(CH372设备),提供8个非0通道(上传+下传),实现数据先下传,然后数据内容取反上传
  7 *******************************************************************************/
  8 
  9 #include "CH57x_common.h"
 10 
 11 #define DevEP0SIZE    0x40
 12 // 设备描述符
 13 const UINT8  MyDevDescr[] = { 
 14 0x12, 0x01, 0x10, 0x01,0xFF, 0x80, 0x55, DevEP0SIZE,                             
 15 0x48, 0x43, 0x37, 0x55,                      // 厂商ID和产品ID
 16 0x00, 0x01, 0x01, 0x02, 0x00, 0x01,
 17 };
 18 // 配置描述符
 19 const UINT8  MyCfgDescr[] = { 
 20 0x09, 0x02, 0x4A, 0x00, 0x01, 0x01, 0x00, 0x80, 0x32,
 21 0x09, 0x04, 0x00, 0x00, 0x08, 0xFF, 0x80, 0x55, 0x00,
 22 0x07, 0x05, 0x84, 0x02, 0x40, 0x00, 0x00,
 23 0x07, 0x05, 0x04, 0x02, 0x40, 0x00, 0x00,
 24 0x07, 0x05, 0x83, 0x02, 0x40, 0x00, 0x00,
 25 0x07, 0x05, 0x03, 0x02, 0x40, 0x00, 0x00,
 26 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00,
 27 0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
 28 0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
 29 0x07, 0x05, 0x01, 0x02, 0x40, 0x00, 0x00,
 30 };
 31 // 语言描述符
 32 const UINT8  MyLangDescr[] = { 0x04, 0x03, 0x09, 0x04 };
 33 // 厂家信息
 34 const UINT8  MyManuInfo[] = { 0x0E, 0x03, 'w', 0, 'c', 0, 'h', 0, '.', 0, 'c', 0, 'n', 0 };
 35 // 产品信息
 36 const UINT8  MyProdInfo[] = { 0x0C, 0x03, 'C', 0, 'H', 0, '5', 0, '7', 0, 'x', 0 };
 37 
 38 /**********************************************************/
 39 UINT8   DevConfig;
 40 UINT8   SetupReqCode;
 41 UINT16  SetupReqLen;
 42 const UINT8 *pDescr;
 43 
 44 /******** 用户自定义分配端点RAM ****************************************/
 45 __align(4) UINT8 EP0_Databuf[64+64+64];    //ep0(64)+ep4_out(64)+ep4_in(64)
 46 __align(4) UINT8 EP1_Databuf[64+64];    //ep1_out(64)+ep1_in(64)
 47 __align(4) UINT8 EP2_Databuf[64+64];    //ep2_out(64)+ep2_in(64)
 48 __align(4) UINT8 EP3_Databuf[64+64];    //ep3_out(64)+ep3_in(64)
 49 
 50 
 51 void USB_DevTransProcess( void )
 52 {
 53     UINT8  len, chtype;
 54     UINT8  intflag, errflag = 0;
 55     
 56     intflag = R8_USB_INT_FG;
 57     if( intflag & RB_UIF_TRANSFER )
 58     {
 59         switch ( R8_USB_INT_ST & ( MASK_UIS_TOKEN | MASK_UIS_ENDP ) ) //分析操作令牌和端点号
 60         {
 61             case UIS_TOKEN_SETUP:
 62                 R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_NAK;
 63                 len = R8_USB_RX_LEN;
 64                 if ( len == sizeof( USB_SETUP_REQ ) ) 
 65                 {
 66                     SetupReqLen = pSetupReqPak->wLength;
 67                     SetupReqCode = pSetupReqPak->bRequest;
 68                     chtype = pSetupReqPak->bRequestType;
 69                     
 70                     len = 0;
 71                     errflag = 0;
 72                     if ( ( pSetupReqPak->bRequestType & USB_REQ_TYP_MASK ) != USB_REQ_TYP_STANDARD )   
 73                     {
 74                         errflag = 0xFF;                /* 非标准请求 */
 75                     }
 76                     else    /* 标准请求 */
 77                     {
 78                         switch( SetupReqCode )  
 79                         {
 80                             case USB_GET_DESCRIPTOR:
 81                             {                            
 82                                 switch( ((pSetupReqPak->wValue)>>8) )
 83                                 {    
 84                                     case USB_DESCR_TYP_DEVICE:
 85                                         pDescr = MyDevDescr;
 86                                         len = MyDevDescr[0];
 87                                         break;
 88                                     
 89                                     case USB_DESCR_TYP_CONFIG:
 90                                         pDescr = MyCfgDescr;
 91                                         len = MyCfgDescr[2];
 92                                         break;
 93                                     
 94                                     case USB_DESCR_TYP_STRING:
 95                                         switch( (pSetupReqPak->wValue)&0xff )
 96                                         {
 97                                             case 1:
 98                                                 pDescr = MyManuInfo;
 99                                                 len = MyManuInfo[0];
100                                                 break;
101                                             case 2:
102                                                 pDescr = MyProdInfo;
103                                                 len = MyProdInfo[0];
104                                                 break;
105                                             case 0:
106                                                 pDescr = MyLangDescr;
107                                                 len = MyLangDescr[0];
108                                                 break;
109                                             default:
110                                                 errflag = 0xFF; // 不支持的字符串描述符
111                                                 break;
112                                         }
113                                         break;
114                                     
115                                     default :
116                                         errflag = 0xff;
117                                         break;
118                                 }
119                                 if( SetupReqLen>len )    SetupReqLen = len;        //实际需上传总长度
120                                 len = (SetupReqLen >= DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;  
121                                 memcpy( pEP0_DataBuf, pDescr, len );   
122                                 pDescr += len;
123                             }
124                                 break;
125                             
126                             case USB_SET_ADDRESS:
127                                 SetupReqLen = (pSetupReqPak->wValue)&0xff;
128                                 break;
129                             
130                             case USB_GET_CONFIGURATION:
131                                 pEP0_DataBuf[0] = DevConfig;
132                                 if ( SetupReqLen > 1 )        SetupReqLen = 1;
133                                 break;
134                             
135                             case USB_SET_CONFIGURATION:
136                                 DevConfig = (pSetupReqPak->wValue)&0xff;
137                                 break;
138                             
139                             case USB_CLEAR_FEATURE:
140                                 if ( ( pSetupReqPak->bRequestType & USB_REQ_RECIP_MASK ) == USB_REQ_RECIP_ENDP ) //端点
141                                 {
142                                     switch( (pSetupReqPak->wIndex)&0xff )
143                                     {
144                                     case 0x82:
145                                         R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK;
146                                         break;
147                                     case 0x02:
148                                         R8_UEP2_CTRL = (R8_UEP2_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK;
149                                         break;
150                                     case 0x81:
151                                         R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_T_TOG|MASK_UEP_T_RES )) | UEP_T_RES_NAK;
152                                         break;
153                                     case 0x01:
154                                         R8_UEP1_CTRL = (R8_UEP1_CTRL & ~( RB_UEP_R_TOG|MASK_UEP_R_RES )) | UEP_R_RES_ACK;
155                                         break;
156                                     default:
157                                         errflag = 0xFF;    // 不支持的端点
158                                         break;
159                                     }
160                                 }
161                                 else    errflag = 0xFF;    
162                                 break;
163                             
164                             case USB_GET_INTERFACE:
165                                 pEP0_DataBuf[0] = 0x00;
166                                  if ( SetupReqLen > 1 )        SetupReqLen = 1;
167                                 break;
168                             
169                             case USB_GET_STATUS:
170                                 pEP0_DataBuf[0] = 0x00;
171                                 pEP0_DataBuf[1] = 0x00;
172                                 if ( SetupReqLen > 2 )        SetupReqLen = 2;
173                                 break;
174                             
175                             default:
176                                 errflag = 0xff;
177                                 break;
178                         }
179                     }
180                 }
181                 else    errflag = 0xff;
182                 
183                 if( errflag == 0xff)        // 错误或不支持
184                 {
185 //                    SetupReqCode = 0xFF;
186                     R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_STALL | UEP_T_RES_STALL; //STALL
187                 }
188                 else
189                 {
190                     if( chtype & 0x80 )        // 上传
191                     {
192                         len = (SetupReqLen>DevEP0SIZE) ? DevEP0SIZE : SetupReqLen;
193                         SetupReqLen -= len;
194                     }
195                     else    len = 0;        // 下传    
196                     
197                     R8_UEP0_T_LEN = len; 
198                     R8_UEP0_CTRL = RB_UEP_R_TOG | RB_UEP_T_TOG | UEP_R_RES_ACK | UEP_T_RES_ACK; //默认数据包是DATA1
199                 }                
200                 break;
201             
202             case UIS_TOKEN_IN:
203                 switch( SetupReqCode )
204                 {
205                 case USB_GET_DESCRIPTOR:
206                     len = SetupReqLen >= DevEP0SIZE ? DevEP0SIZE : SetupReqLen;//本次传输长度
207                     memcpy( pEP0_DataBuf, pDescr, len ); /* 加载上传数据 */
208                     SetupReqLen -= len;
209                     pDescr += len;
210                     R8_UEP0_T_LEN = len;
211                     R8_UEP0_CTRL ^= RB_UEP_T_TOG; // 翻转
212                     break;
213                 case USB_SET_ADDRESS:
214                     R8_USB_DEV_AD = (R8_USB_DEV_AD&RB_UDA_GP_BIT) | SetupReqLen;
215                     R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
216                     break;
217                 default:
218                     R8_UEP0_T_LEN = 0;    // 状态阶段完成中断或者是强制上传0长度数据包结束控制传输
219                     R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
220                     break;
221                 }                
222                 break;
223             
224             case UIS_TOKEN_OUT:
225                 len = R8_USB_RX_LEN;
226                 break;
227             
228             case UIS_TOKEN_OUT | 1:
229                 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 
230                 {                       // 不同步的数据包将丢弃
231                     len = R8_USB_RX_LEN;
232                     DevEP1_OUT_Deal( len );
233                 }
234                 break;
235             
236             case UIS_TOKEN_IN | 1:
237                 R8_UEP1_CTRL = (R8_UEP1_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
238                 break;
239             
240             case UIS_TOKEN_OUT | 2:
241                 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 
242                 {                       // 不同步的数据包将丢弃
243                     len = R8_USB_RX_LEN;
244                     DevEP2_OUT_Deal( len );
245                 }
246                 break;
247             
248             case UIS_TOKEN_IN | 2:
249                 R8_UEP2_CTRL = (R8_UEP2_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
250                 break;
251             
252             case UIS_TOKEN_OUT | 3:
253                 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 
254                 {                       // 不同步的数据包将丢弃
255                     len = R8_USB_RX_LEN;
256                     DevEP3_OUT_Deal( len );
257                 }
258                 break;
259             
260             case UIS_TOKEN_IN | 3:
261                 R8_UEP3_CTRL = (R8_UEP3_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
262                 break;
263             
264             case UIS_TOKEN_OUT | 4:
265                 if ( R8_USB_INT_ST & RB_UIS_TOG_OK ) 
266                 {   
267                     R8_UEP4_CTRL ^= RB_UEP_R_TOG;
268                     len = R8_USB_RX_LEN;
269                     DevEP4_OUT_Deal( len );
270                 }
271                 break;
272             
273             case UIS_TOKEN_IN | 4:
274                 R8_UEP4_CTRL ^=  RB_UEP_T_TOG;
275                 R8_UEP4_CTRL = (R8_UEP4_CTRL & ~MASK_UEP_T_RES) | UEP_T_RES_NAK;
276                 break;
277             
278             default :
279                 break;
280         }
281         R8_USB_INT_FG = RB_UIF_TRANSFER;
282     }
283     else if( intflag & RB_UIF_BUS_RST )
284     {
285         R8_USB_DEV_AD = 0;
286         R8_UEP0_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK;
287         R8_UEP1_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
288         R8_UEP2_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
289         R8_UEP3_CTRL = UEP_R_RES_ACK | UEP_T_RES_NAK | RB_UEP_AUTO_TOG;
290         R8_USB_INT_FG |= RB_UIF_BUS_RST;
291     }
292     else if( intflag & RB_UIF_SUSPEND )
293     {
294         if ( R8_USB_MIS_ST & RB_UMS_SUSPEND ) {;}    // 挂起
295         else        {;}                                // 唤醒
296         R8_USB_INT_FG = RB_UIF_SUSPEND;
297     }
298     else
299     {
300         R8_USB_INT_FG = intflag;
301     }
302 }
303 
304 
305 
306 void DebugInit(void)        
307 {
308     GPIOA_SetBits(GPIO_Pin_9);
309     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
310     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
311     UART1_DefInit();
312 }
313 
314 int main()
315 {
316     SetSysClock( CLK_SOURCE_HSE_32MHz );
317     PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL );    //打开PLL
318     DelayMs(5);
319     
320     DebugInit();
321     printf("start\n");
322 
323     pEP0_RAM_Addr = EP0_Databuf;
324     pEP1_RAM_Addr = EP1_Databuf;
325     pEP2_RAM_Addr = EP2_Databuf;
326     pEP3_RAM_Addr = EP3_Databuf;
327     USB_DeviceInit();
328     NVIC_EnableIRQ( USB_IRQn );
329     
330     while(1);
331 }
332 
333 void DevEP1_OUT_Deal( UINT8 l )
334 { /* 用户可自定义 */
335     UINT8 i;
336     
337     for(i=0; i<l; i++)
338     {
339         pEP1_IN_DataBuf[i] = ~pEP1_OUT_DataBuf[i];
340     }
341     DevEP1_IN_Deal( l );
342 }
343 
344 void DevEP2_OUT_Deal( UINT8 l )
345 { /* 用户可自定义 */
346     UINT8 i;
347     
348     for(i=0; i<l; i++)
349     {
350         pEP2_IN_DataBuf[i] = ~pEP2_OUT_DataBuf[i];
351     }
352     DevEP2_IN_Deal( l );
353 }
354 
355 void DevEP3_OUT_Deal( UINT8 l )
356 { /* 用户可自定义 */
357     UINT8 i;
358     
359     for(i=0; i<l; i++)
360     {
361         pEP3_IN_DataBuf[i] = ~pEP3_OUT_DataBuf[i];
362     }
363     DevEP3_IN_Deal( l );
364 }
365 
366 void DevEP4_OUT_Deal( UINT8 l )
367 { /* 用户可自定义 */
368     UINT8 i;
369     
370     for(i=0; i<l; i++)
371     {
372         pEP4_IN_DataBuf[i] = ~pEP4_OUT_DataBuf[i];
373     }
374     DevEP4_IN_Deal( l );
375 }
376 
377 void USB_IRQHandler (void)/*USB中断服务程序,使用寄存器组1 */
378 {
379     USB_DevTransProcess();
380 }

U_DISK_EXAM1

  1 /********************************** (C) COPYRIGHT *******************************
  2 * File Name          : EXAM1.C
  3 * Author             : WCH
  4 * Version            : V1.0
  5 * Date               : 2018/08/15
  6 * Description        :
  7  C语言的U盘文件字节读写示例程序,文件指针偏移,修改文件属性,删除文件等操作
  8  支持: FAT12/FAT16/FAT32
  9  注意包含 CH579UFI.LIB/USBHOST.C/DEBUG.C
 10 *******************************************************************************/
 11 
 12 /** 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭定义 #define    FOR_ROOT_UDISK_ONLY  */
 13 /** 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 #define DISK_BASE_BUF_LEN        512          */
 14 
 15 #include "CH57x_common.h"
 16 #include "CH579UFI.H"
 17 
 18 __align(4) UINT8  RxBuffer[ MAX_PACKET_SIZE ];  // IN, must even address
 19 __align(4) UINT8  TxBuffer[ MAX_PACKET_SIZE ];  // OUT, must even address
 20 
 21 UINT8  buf[100];  //长度可以根据应用自己指定
 22 
 23 
 24 /* 检查操作状态,如果错误则显示错误代码并停机 */
 25 void mStopIfError( UINT8 iError )
 26 {
 27     if ( iError == ERR_SUCCESS )
 28     {
 29         return;    /* 操作成功 */
 30     }
 31     printf( "Error: %02X\n", (UINT16)iError );  /* 显示错误 */
 32     /* 遇到错误后,应该分析错误码以及CH554DiskStatus状态,例如调用CH579DiskReady查询当前U盘是否连接,如果U盘已断开那么就重新等待U盘插上再操作,
 33        建议出错后的处理步骤:
 34        1、调用一次CH579DiskReady,成功则继续操作,例如Open,Read/Write等
 35        2、如果CH579DiskReady不成功,那么强行将从头开始操作(等待U盘连接,CH554DiskReady等) */
 36     while ( 1 )
 37     {  }
 38 }
 39 
 40 int main( )
 41 {
 42     UINT8   s, c, i;
 43 //    UINT16  TotalCount;
 44     
 45     SetSysClock( CLK_SOURCE_HSE_32MHz );
 46     PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL );        // 打开PLL
 47     DelayMs(5);
 48     
 49     GPIOA_SetBits(GPIO_Pin_9);
 50     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
 51     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
 52     UART1_DefInit();
 53     PRINT( "Start @ChipID=%02X %s \n", R8_CHIP_ID, __TIME__);
 54 
 55     pHOST_RX_RAM_Addr = RxBuffer;
 56     pHOST_TX_RAM_Addr = TxBuffer;
 57     USB_HostInit();    
 58     CH579LibInit( ); //初始化U盘程序库以支持U盘文件
 59     
 60     FoundNewDev = 0;
 61     while ( 1 )
 62     {
 63         s = ERR_SUCCESS;
 64         if ( R8_USB_INT_FG & RB_UIF_DETECT )   // 如果有USB主机检测中断则处理
 65         {
 66             R8_USB_INT_FG = RB_UIF_DETECT ;   // 清连接中断标志
 67             s = AnalyzeRootHub( );            // 分析ROOT-HUB状态
 68             if ( s == ERR_USB_CONNECT )         FoundNewDev = 1;
 69         }
 70         
 71         if ( FoundNewDev || s == ERR_USB_CONNECT ) // 有新的USB设备插入
 72         {
 73             FoundNewDev = 0;
 74             mDelaymS( 200 );  // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
 75             s = InitRootDevice();  // 初始化USB设备
 76             if ( s == ERR_SUCCESS )
 77             {
 78                 // U盘操作流程:USB总线复位、U盘连接、获取设备描述符和设置USB地址、可选的获取配置描述符,之后到达此处,由CH579子程序库继续完成后续工作
 79                 CH579DiskStatus = DISK_USB_ADDR;
 80                 for ( i = 0; i != 10; i ++ )
 81                 {
 82                     printf( "Wait DiskReady\n" );
 83                     s = CH579DiskReady( );  //等待U盘准备好
 84                     if ( s == ERR_SUCCESS )
 85                     {
 86                         break;
 87                     }
 88                     else
 89                     {
 90                         printf("%02x\n",(UINT16)s);
 91                     }
 92                     mDelaymS( 50 );
 93                 }
 94                 
 95                 if ( CH579DiskStatus >= DISK_MOUNTED )
 96                 {                    
 97 //                  /* 读文件 */
 98 //                  strcpy( mCmdParam.Open.mPathName, "/C51/CH579HFT.C" ); //设置将要操作的文件路径和文件名/C51/CH579HFT.C
 99 //                  s = CH579FileOpen( );                                //打开文件
100 //                  if ( s == ERR_MISS_DIR || s == ERR_MISS_FILE ) {     //没有找到文件
101 //                      printf( "没有找到文件\n" );
102 //                  }
103 //                  else
104 //                  {                                        //找到文件或者出错
105 //                      TotalCount = 100;  //设置准备读取总长度100字节
106 //                      printf( "读出的前%d个字符是:\n",TotalCount );
107 //                      while ( TotalCount ) {             //如果文件比较大,一次读不完,可以再调用CH579ByteRead继续读取,文件指针自动向后移动
108 //                           if ( TotalCount > (MAX_PATH_LEN-1) ) c = MAX_PATH_LEN-1;//剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.Other.mBuffer )
109 //                           else c = TotalCount;//最后剩余的字节数 
110 //                           mCmdParam.ByteRead.mByteCount = c; //请求读出几十字节数据 
111 //                           mCmdParam.ByteRead.mByteBuffer= &buf[0];
112 //                           s = CH579ByteRead( ); //以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 
113 //                           TotalCount -= mCmdParam.ByteRead.mByteCount; //计数,减去当前实际已经读出的字符数 
114 //                           for ( i=0; i!=mCmdParam.ByteRead.mByteCount; i++ ) printf( "%C", mCmdParam.ByteRead.mByteBuffer[i] );//显示读出的字符 
115 //                           if ( mCmdParam.ByteRead.mByteCount < c ) { //实际读出的字符数少于要求读出的字符数,说明已经到文件的结尾 
116 //                                printf( "\n" );
117 //                                printf( "文件已经结束\n" );
118 //                                break;
119 //                           }
120 //                      }
121 //                      printf( "Close\n" );
122 //                      i = CH579FileClose( );   // 关闭文件 
123 //                      mStopIfError( i );
124 //                  }
125 //                  /*如果希望从指定位置开始读写,可以移动文件指针 */
126 //                  mCmdParam.ByteLocate.mByteOffset = 608;  //跳过文件的前608个字节开始读写
127 //                  CH579ByteLocate( );
128 //                  mCmdParam.ByteRead.mByteCount = 5;  //读取5个字节
129 //                  mCmdParam.ByteRead.mByteBuffer= &buf[0];
130 //                  CH579ByteRead( );   //直接读取文件的第608个字节到612个字节数据,前608个字节被跳过
131 //                  //如果希望将新数据添加到原文件的尾部,可以移动文件指针
132 //                  CH579FileOpen( );
133 //                  mCmdParam.ByteLocate.mByteOffset = 0xffffffff;  //移到文件的尾部
134 //                  CH579ByteLocate( );
135 //                  mCmdParam.ByteWrite.mByteCount = 13;  //写入13个字节的数据
136 //                  CH579ByteWrite( );   //在原文件的后面添加数据,新加的13个字节接着原文件的尾部放置
137 //                  mCmdParam.ByteWrite.mByteCount = 2;  //写入2个字节的数据
138 //                  CH579ByteWrite( );   //继续在原文件的后面添加数据
139 //                  mCmdParam.ByteWrite.mByteCount = 0;  //写入0个字节的数据,实际上该操作用于通知程序库更新文件长度
140 //                  CH579ByteWrite( );   //写入0字节的数据,用于自动更新文件的长度,所以文件长度增加15,如果不这样做,那么执行CH554FileClose时也会自动更新文件长度
141                     //创建文件演示
142                     printf( "Create\n" );
143                     strcpy( (PCHAR)mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); // 新文件名,在根目录下,中文文件名 
144                     s = CH579FileCreate( ); //新建文件并打开,如果文件已经存在则先删除后再新建 
145                     mStopIfError( s );
146                     printf( "ByteWrite\n" );
147                     //实际应该判断写数据长度和定义缓冲区长度是否相符,如果大于缓冲区长度则需要多次写入
148                     i = sprintf( (PCHAR)buf,"Note: \xd\xa这个程序是以字节为单位进行U盘文件读写,579简单演示功能。\xd\xa"); //演示 
149                     for(c=0; c<10; c++)
150                     {
151                         mCmdParam.ByteWrite.mByteCount = i;  //指定本次写入的字节数 
152                         mCmdParam.ByteWrite.mByteBuffer = buf; //指向缓冲区 
153                         s = CH579ByteWrite( );    //以字节为单位向文件写入数据 
154                         mStopIfError( s );
155                         printf("成功写入 %02X次\n",(UINT16)c);
156                     }
157                     //演示修改文件属性
158 //                  printf( "Modify\n" );
159 //                  mCmdParam.Modify.mFileAttr = 0xff;   //输入参数: 新的文件属性,为0FFH则不修改
160 //                  mCmdParam.Modify.mFileTime = 0xffff;   //输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间
161 //                  mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2015, 5, 18 );  //输入参数: 新的文件日期: 2015.05.18
162 //                  mCmdParam.Modify.mFileSize = 0xffffffff;  // 输入参数: 新的文件长度,以字节为单位写文件应该由程序库关闭文件时自动更新长度,所以此处不修改
163 //                  i = CH579FileModify( );   //修改当前文件的信息,修改日期
164 //                  mStopIfError( i );
165                     printf( "Close\n" );
166                     mCmdParam.Close.mUpdateLen = 1; //自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 
167                     i = CH579FileClose( );
168                     mStopIfError( i );
169                     
170 //                  strcpy( (PCHAR)mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); //新文件名,在根目录下,中文文件名 
171 //                  s = CH579FileOpen( );  // 新建文件并打开,如果文件已经存在则先删除后再新建 
172 //                  mStopIfError( s );
173                    
174                     
175 //                  /* 删除某文件 */
176 //                  printf( "Erase\n" );
177 //                  strcpy( mCmdParam.Create.mPathName, "/OLD" );  //将被删除的文件名,在根目录下
178 //                  i = CH579FileErase( );  //删除文件并关闭
179 //                  if ( i != ERR_SUCCESS ) printf( "Error: %02X\n", (UINT16)i ); //显示错误
180                 }
181             }
182         }
183         mDelaymS( 100 );  // 模拟单片机做其它事
184         SetUsbSpeed( 1 );  // 默认为全速
185     }
186 }
USB dev in
Reset host port
GetDevDescr: x12 x01 x00 x02 x00 x00 x00 x40 x08 x19 x26 x02 x11 x01 x00 x00 x00 x01 
GetCfgDescr: x09 x02 x20 x00 x01 x01 x00 x80 x32 x09 x04 x00 x00 x02 x08 x06 x50 x00 x07 x05 x01 x02 x40 x00 x00 x07 x05 x81 x02 x40 x00 x00 
Wait DiskReady
Create
ByteWrite
成功写入 00次
成功写入 01次
成功写入 02次
成功写入 03次
成功写入 04次
成功写入 05次
成功写入 06次
成功写入 07次
成功写入 08次
成功写入 09次
Close
USB dev out

U_DISK_EXAM11

  1 /********************************** (C) COPYRIGHT *******************************
  2 * File Name          : EXAM11.C
  3 * Author             : WCH
  4 * Version            : V1.0
  5 * Date               : 2018/08/15
  6 * Description        : CH579 C语言的U盘目录文件枚举程序
  7  支持: FAT12/FAT16/FAT32
  8  注意包含 CH579UFI.LIB/USBHOST.C/DEBUG.C
  9 *******************************************************************************/
 10 
 11 /** 不使用U盘文件系统库或者U盘挂载USBhub下面,需要关闭定义 #define    FOR_ROOT_UDISK_ONLY  */
 12 /** 使用U盘文件系统库,需要开启下面定义, 不使用请关闭 #define DISK_BASE_BUF_LEN        512          */
 13 
 14 
 15 #include "CH57x_common.h"
 16 #include "CH579UFI.H"
 17 
 18 __align(4) UINT8  RxBuffer[ MAX_PACKET_SIZE ];  // IN, must even address
 19 __align(4) UINT8  TxBuffer[ MAX_PACKET_SIZE ];  // OUT, must even address
 20 
 21 
 22 /* 检查操作状态,如果错误则显示错误代码并停机 */
 23 void    mStopIfError( UINT8 iError )
 24 {
 25     if ( iError == ERR_SUCCESS )
 26     {
 27         return;    /* 操作成功 */
 28     }
 29     printf( "Error: %02X\n", (UINT16)iError );  /* 显示错误 */
 30     /* 遇到错误后,应该分析错误码以及CH579DiskStatus状态,例如调用CH579DiskReady查询当前U盘是否连接,如果U盘已断开那么就重新等待U盘插上再操作,
 31        建议出错后的处理步骤:
 32        1、调用一次CH579DiskReady,成功则继续操作,例如Open,Read/Write等
 33        2、如果CH579DiskReady不成功,那么强行将从头开始操作(等待U盘连接,CH579DiskReady等) */
 34     while ( 1 )
 35     {   }
 36 }
 37 
 38 
 39 int main( )
 40 {
 41    UINT8   s, i;
 42    PUINT8  pCodeStr;
 43    UINT16  j;
 44 
 45    SetSysClock( CLK_SOURCE_HSE_32MHz );
 46    PWR_UnitModCfg( ENABLE, UNIT_SYS_PLL );    //打开PLL
 47    DelayMs(5);
 48     
 49     GPIOA_SetBits(GPIO_Pin_9);
 50     GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
 51     GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
 52     UART1_DefInit();
 53     PRINT( "Start @ChipID=%02X %s \n", R8_CHIP_ID, __TIME__);
 54 
 55   pHOST_RX_RAM_Addr = RxBuffer;
 56   pHOST_TX_RAM_Addr = TxBuffer;
 57     USB_HostInit();    
 58     CH579LibInit( ); //初始化U盘程序库以支持U盘文件
 59 
 60     
 61     FoundNewDev = 0;
 62     printf( "Wait Device In\n" );
 63     while ( 1 )
 64     {
 65         s = ERR_SUCCESS;
 66         if ( R8_USB_INT_FG & RB_UIF_DETECT )   // 如果有USB主机检测中断则处理
 67         {
 68             R8_USB_INT_FG = RB_UIF_DETECT ;  // 清连接中断标志
 69             s = AnalyzeRootHub( );    // 分析ROOT-HUB状态
 70             if ( s == ERR_USB_CONNECT )         FoundNewDev = 1;
 71         }
 72         
 73         if ( FoundNewDev || s == ERR_USB_CONNECT )
 74         {
 75             // 有新的USB设备插入
 76             FoundNewDev = 0;
 77             mDelaymS( 200 ); // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
 78             s = InitRootDevice( ); // 初始化USB设备
 79             if ( s == ERR_SUCCESS )
 80             {
 81                 printf( "Start UDISK_demo @CH579UFI library\n" );
 82                 // U盘操作流程:USB总线复位、U盘连接、获取设备描述符和设置USB地址、可选的获取配置描述符,之后到达此处,由CH579子程序库继续完成后续工作
 83                 CH579DiskStatus = DISK_USB_ADDR;
 84                 for ( i = 0; i != 10; i ++ )
 85                 {
 86                     printf( "Wait DiskReady\n" );
 87                     s = CH579DiskReady( );
 88                     if ( s == ERR_SUCCESS )
 89                     {
 90                         break;
 91                     }
 92                     mDelaymS( 50 );
 93                 }
 94                 if ( CH579DiskStatus >= DISK_MOUNTED )   //U盘准备好
 95                 {                    
 96                     /* 读文件 */
 97                     printf( "Open\n" );
 98                     strcpy( (PCHAR)mCmdParam.Open.mPathName, "/C51/CH579HFT.C" ); //设置要操作的文件名和路径
 99                     s = CH579FileOpen( );   //打开文件
100                     if ( s == ERR_MISS_DIR )
101                     {
102                         printf("不存在该文件夹则列出根目录所有文件\n");
103                         pCodeStr = (PUINT8)"/*";
104                     }
105                     else
106                     {
107                         pCodeStr = (PUINT8)"/C51/*";    //列出\C51子目录下的的文件
108                     }
109                     
110                     printf( "List file %s\n", pCodeStr );
111                     for ( j = 0; j < 10000; j ++ ) //限定10000个文件,实际上没有限制
112                     {
113                         strcpy( (PCHAR)mCmdParam.Open.mPathName, (PCCHAR)pCodeStr );//搜索文件名,*为通配符,适用于所有文件或者子目录
114                         i = strlen( (PCHAR)mCmdParam.Open.mPathName );
115                         mCmdParam.Open.mPathName[ i ] = 0xFF; //根据字符串长度将结束符替换为搜索的序号,从0到254,如果是0xFF即255则说明搜索序号在CH579vFileSize变量中
116                         CH579vFileSize = j; //指定搜索/枚举的序号
117                         i = CH579FileOpen( ); //打开文件,如果文件名中含有通配符*,则为搜索文件而不打开
118                         /* CH579FileEnum 与 CH579FileOpen 的唯一区别是当后者返回ERR_FOUND_NAME时那么对应于前者返回ERR_SUCCESS */
119                         if ( i == ERR_MISS_FILE )
120                         {
121                             break;    //再也搜索不到匹配的文件,已经没有匹配的文件名
122                         }
123                         if ( i == ERR_FOUND_NAME ) //搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中
124                         {
125                             printf( "  match file %04d#: %s\n", (unsigned int)j, mCmdParam.Open.mPathName ); //显示序号和搜索到的匹配文件名或者子目录名 
126                             continue;   //继续搜索下一个匹配的文件名,下次搜索时序号会加1 
127                         }
128                         else  //出错
129                         {
130                             mStopIfError( i );
131                             break;
132                         }
133                     }
134                     i = CH579FileClose( ); //关闭文件
135                     printf( "U盘演示完成\n" );                     
136                 }
137                 else
138                 {
139                     printf( "U盘没有准备好 ERR =%02X\n", (UINT16)s );
140                 }
141             }
142             else
143             {
144                 printf("初始化U盘失败,请拔下U盘重试\n");
145             }
146         }
147         mDelaymS( 100 );  // 模拟单片机做其它事
148         SetUsbSpeed( 1 );  // 默认为全速
149     }
150 }
Start @ChipID=79 14:22:47 
Wait Device In
USB dev in
Reset host port
GetDevDescr: x12 x01 x00 x02 x00 x00 x00 x40 x08 x19 x26 x02 x11 x01 x00 x00 x00 x01 
GetCfgDescr: x09 x02 x20 x00 x01 x01 x00 x80 x32 x09 x04 x00 x00 x02 x08 x06 x50 x00 x07 x05 x01 x02 x40 x00 x00 x07 x05 x81 x02 x40 x00 x00 
Start UDISK_demo @CH579UFI library
Wait DiskReady
Open
不存在该文件夹则列出根目录所有文件
List file /*
  match file 0000#: /SYSTEM~1
  match file 0001#: /ANTUTU~1.APK
  match file 0002#: /LOST.DIR
  match file 0003#: /ANDROID
  match file 0004#: /NEWFILE.TXT
U盘演示完成

猜你喜欢

转载自www.cnblogs.com/kingboy100/p/12419724.html