📄 usb.lst
字号:
333 };
334 //SCSI-Mode_Sense命令的返回数据
335 code unsigned char B_Mode_Sense_TPP[] = {0xf0, 0x00, //Mode Data Length
336 05, 00, 00, 00, 00, 0x0b, 00, 00, 00, 00, 0x24, 00, 00, 00, 00, 00
337 };
338 //SCSI-Mode_Sense命令的返回数据
339 code unsigned char B_Mode_Sense_ZERO[] = {0x00, 0x06, //Mode Data Length
340 0x00, //Medium Type Code
341 0, //write enabled
342 0, 0, 0, 0 //reserved
343 };
344
345
346 void SCSI_Mode_Sense()
347 {
348 if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_TPP) //Page Code=Timer and Potect Page
349 {WriteEpBulk(1, sizeof(B_Mode_Sense_TPP), B_Mode_Sense_TPP);}
350 else if(bulk_CBW.CBWCB[2] == SCSI_MSPGCD_RETALL) //Page Code=All
351 {WriteEpBulk(1, sizeof(B_Mode_Sense_ALL), B_Mode_Sense_ALL);}
352 else {WriteEpBulk(1, sizeof(B_Mode_Sense_ZERO), B_Mode_Sense_ZERO);}
353 }
354
355 void SCSI_Read_Format_Capacities()
356 {
357 if(bulk_CBW.CBWCB[7]==0 && bulk_CBW.CBWCB[8]==0)return;
358 WriteEpBulk(1, sizeof(B_Read_Format_capacities), B_Read_Format_capacities);
359 }
360
361 extern void ReadFlash();
362 extern void WriteFlash();
363
364 void SCSI_Read10()
C51 COMPILER V7.50 USB 03/07/2005 09:36:38 PAGE 7
365 {
366 unsigned char data i;
367 union
368 {
369 unsigned long Block;
370 unsigned char Addr[4];
371 }data BLK;
372 unsigned char length; //传输的簇数
373 //将起始地址变换为K9F5608适合的模式;
374 // BLK.Addr[0] = bulk_CBW.CBWCB[2];
375 // BLK.Addr[1] = bulk_CBW.CBWCB[3];
376 BLK.Addr[2] = bulk_CBW.CBWCB[4];
377 BLK.Addr[3] = bulk_CBW.CBWCB[5];
378
379 //将扇区数填入计数变量每循环一次读出一扇区的值;
380 // PG.Addr[0] = bulk_CBW.CBWCB[7];
381 // PG.Addr[1] = bulk_CBW.CBWCB[8];
382 length = bulk_CBW.CBWCB[8];
383 while(length>0)
384 {
385
386 K9F_FUN = COMMAND; //读出一个page
387 *((unsigned char xdata *)K9F5608) = 0x00;
388 K9F_FUN = ADDRESS;
389 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
390 *((unsigned char xdata *)K9F5608) = BLK.Addr[3]; //A9-A16
391 *((unsigned char xdata *)K9F5608) = BLK.Addr[2]; //A17-A24
392
393 K9F_FUN = D_DATA;
394 UEPNUM=0x01; //指向端点
395 UEPSTAX|=DIR; //传输方向
396 while(!(K9F_FUN & RB));
397
398 for(i=0;i<8;i++) //读出512个字节的数据发送到usb
399 {
400 ReadFlash();
401 UEPSTAX|=TXRDY;
402 while(!(UEPSTAX&TXCMP)); //等待发送完成
403 UEPSTAX&=(~(TXCMP)); //清中断标志clear TXCMP
404 UEPINT=0;
405 }
406 *((unsigned char xdata *)K9F5608) = INACTIVE;
407
408 length--; //传输的簇数减1
409 BLK.Block ++; //flash的页地址加1
410 }
411 TransmitCSW(); //返回CSW
412 }
413
414 void delay() //延时20us
415 {
416 unsigned char data i=20;
417 while(i-->0);
418 }
419
420 #define BuffBlock (0xc0) //缓冲区为从偶数块开始的连续两个Block 这里定为2046和2047两个Block
421 //BuffBlock只代表块号的低字节
422 void SCSI_Write10() //之所以选用两个Block作为缓冲区,与Flash的Copy - Back功能的特性相关,
423 { //清仔细阅读Flash 的datasheet
424 union
425 {
426 unsigned long page;
C51 COMPILER V7.50 USB 03/07/2005 09:36:38 PAGE 8
427 unsigned char addr[4];
428 }data PG;
429
430 unsigned char data i=0,length=0,nBeginPage=0;
431
432 //所有写入都要缓冲,所以先清除缓冲区
433 K9F_FUN = COMMAND;
434 *((unsigned char xdata *)K9F5608) = 0x60; //擦除第2046个Block作为缓冲区
435 K9F_FUN = ADDRESS;
436 *((unsigned char xdata *)K9F5608) = BuffBlock; //A9-A16
437 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
438 K9F_FUN = COMMAND;
439 *((unsigned char xdata *)K9F5608) = 0xd0;
440 K9F_FUN = D_DATA;
441 delay();
442 // printuf(" %x",PG.addr[0]);printuf(" %x",PG.addr[1]);printuf(" %x",PG.addr[2]);printuf(" %x",PG.addr[
-3]);
443 // printuf(" %x",length); printuf(" %x",nBeginPage);
444 while(!(K9F_FUN & RB)); //等待擦除操作的完成
445
446 K9F_FUN = COMMAND;
447 *((unsigned char xdata *)K9F5608) = 0x60; //擦除第2047个Block作为缓冲区
448 K9F_FUN = ADDRESS;
449 *((unsigned char xdata *)K9F5608) = BuffBlock|0x20; //A9-A16
450 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
451 K9F_FUN = COMMAND;
452 *((unsigned char xdata *)K9F5608) = 0xd0;
453 K9F_FUN = D_DATA;
454 //从SCSI命令中分离出逻辑地址
455 // PG.addr[0] = bulk_CBW.CBWCB[2];
456 // PG.addr[1] = bulk_CBW.CBWCB[3];
457 PG.addr[2] = bulk_CBW.CBWCB[4];
458 PG.addr[3] = bulk_CBW.CBWCB[5];
459
460 length = bulk_CBW.CBWCB[8]; //windows 系统每次写入的最大长度为0x80个扇区取一字节已够用
461 nBeginPage = PG.addr[3]&0x1f; //计算出要写入块内的要写入的起始扇区号
462 UEPNUM = 0x02; //指向Bulk端点2
463 delay();
464 while(!(K9F_FUN & RB)); //等待擦除操作的完成
465
466 if(nBeginPage>0) //如果起始写入page与flash的Block未对齐,则将当前Block中的前nBeginPage页
467 { //拷贝到缓冲区的相同位置
468 for(i=0;i<nBeginPage;i++)
469 {
470 K9F_FUN = COMMAND;
471 *((unsigned char xdata *)K9F5608) = 0x00; //命令的第一个字节
472 K9F_FUN = ADDRESS;
473 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
474 *((unsigned char xdata *)K9F5608) = (PG.addr[3]&0xe0)|i; //A9-A16
475 *((unsigned char xdata *)K9F5608) = PG.addr[2]; //A17-A24
476 K9F_FUN = D_DATA;
477 delay();
478 while(!(K9F_FUN & RB)); //等待操作的完成
479
480 K9F_FUN = COMMAND;
481 *((unsigned char xdata *)K9F5608) = 0x8a; //命令的第二个字节
482 K9F_FUN = ADDRESS;
483 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
484 *((unsigned char xdata *)K9F5608) = BuffBlock|(PG.addr[3]&0x20)|i; //A9-A16
485 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
486 K9F_FUN = D_DATA;
487 delay();
C51 COMPILER V7.50 USB 03/07/2005 09:36:38 PAGE 9
488 while(!(K9F_FUN & RB)); //等待操作的完成
489 }
490 nBeginPage=0; //起始扇区值赋为0
491 }
492
493 while(length>0) //传输的扇区数大于0
494 {
495 K9F_FUN = COMMAND; //数据写入到缓冲区的对应位置
496 *((unsigned char xdata *)K9F5608) = 0x80;
497 K9F_FUN = ADDRESS;
498 *((unsigned char xdata *)K9F5608) = 0; //A0-A7
499 *((unsigned char xdata *)K9F5608) = (PG.addr[3]&0x3f)|BuffBlock; //A9-A16
500 *((unsigned char xdata *)K9F5608) = 0xff; //A17-A24
501 K9F_FUN = D_DATA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -