阅读:2299回复:12
高分 求三星FLASH读写方面的有关资料
希望大家能够支持.
[编辑 - 6/1/04 by lixiaojun_001] |
|
|
沙发#
发布于:2004-05-31 13:44
乱世当用重典,求资料我用重金.
|
|
|
板凳#
发布于:2004-05-31 15:05
我刚开始写的时候就是看nand flash 的spec。
不过偶的代码不敢给,套用一句话:“那么多bug,能见人吗?” :) 不过记得好像这里以前有人发过 |
|
|
地板#
发布于:2004-06-14 16:04
各位大侠大都搞过U盘的开发,想来对FLASH的读写,有一定的心得。
为什么不能够给新手以指点,使其不在走弯路,恳请各位给于帮忙,不盛感激。 |
|
|
地下室#
发布于:2004-06-14 17:58
俺给你一个汇编的程序,其中有你要的代码,CYPRESS的U盘用的
;///////////////////////////////////////////////////////////////////////// ; Supports Bulk ONLY Transport ; Supports UFI Commands ; Simon: Jul/10/2000 Initial Create to Support CF/SSFDC ; Simon: Sep/11/2000 Support two Icons in WinME and Win2K ; Simon: Oct/20/2000 Support multi-devices for combo (ver. 0.61) ; Simon: Nov/02/2000 Support Suspend mode ; Simon: Nov/20/2000 Support Write Protect for Mac ; Apr/11/2000 Fix Microdrive on Mac; Release firmware into VC ; Simon: Aug/15/2001 Add support for TD: Used GPIO18 as the Write Protect ; fix 128MB SM bug in the Build_Table ; Add work arround Bug fix for TI-HUB (Primax) ; Michael: Mar/01/2002 Fix write protect, eject issues for NAND flash ; Michael: Apr/19/2002 Clean-up NAND Flash code for production release ; Michael: May/21/2002 Implemented boot loader for compliance to USBCV ; Michael: Jun/11/2002 Added LOW_POWER flag ;///////////////////////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////////////////////// ; Compiler flags: ; NOECC -- Disables ECC algorithms for throughput boost ; DEVELOPMENT -- Allows multiple devices to be plugged into a host by ; changing last digit of serial number; FOR DEVELOPMENT ONLY ; LOW_POWER -- Use this switch if the device's suspend current is less ; than 500uA ; HD_ICON -- Makes device non-removable: must be partitioned before ; format allowed; Eject option disappears from "My Computer" ; in Windows; Changes device's icon in Win98/Me. ; USE_SLOW -- Setup wait states for slower SRAM memory ; USE_12 -- Setup processor for 12MHz crystal ;///////////////////////////////////////////////////////////////////////// .xlist include nandflsh.inc .list cDevSel equ 0xe0 ;********************************************************************** ; Software Init: Default Setting to Rec command From Host ; Using Scan for Enhancement code ;********************************************************************** dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw 0xc006 ;mov [0xc006],0 setup processor at 48MHz #ifdef USE_12 dw 0x40 ;setup for 12MHz oscillator #else dw 0 ;setup for 48MHz oscillator #endif dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw 0xc03a #ifdef USE_SLOW dw 0x00b ;ext=16-bit,0-wait|rom=16,bit-0wait|ram=8-bit,3-wait #else dw 0x009 ;ext=16-bit,0-wait|rom=16,bit-0wait|ram=8-bit,1-wait #endif dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw (83*2) dw std_class dw 0xc3b6 ;enhancement signature dw 6 ;length of stuff db 0 ;COPY opcode dw (91*2) ;string descriptor loc dw conf_desc dw string_desc dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw (USB_DELTA_CONFIG_INT*2) dw New_Delta dw 0xc3b6 ;enhancement signature dw ((IRAM0_E-IRAM0_S)+2) ;length of IRAM0 db 0 ;memory copy dw IRAM0 reloc IRAM0 IRAM0_S: ;********************************************************************** ; Arm Setup for Endpoint1/Endpoint ;********************************************************************** ArmSetup: mov [r10],64 ArmSetup0: mov [pkg_cnt],(cMAXSIZE/128) int ARM_INT ret ;********************************************************************** ; Initialize and arm endpoint 1 to send USB Status packets ;********************************************************************** _InitEP1: mov [USB_EP1_ADDR],SCMD ;setup to send command mov [USB_EP1_CNT],0xd ;Command Block size ArmEP1: mov [LastAddr1],[USB_EP1_ADDR] mov [LastCnt1],[USB_EP1_CNT] mov [USB_EP1_CNTRL],cDMA1ENA ret ;********************************************************************** ; Require r9=pointer to 32-bit length ;********************************************************************** dUpdate64: mov r0,cBUFFSIZE ;input expected len, return r0=remainder mov r9,_xLenLSB dChkSize: sub [r9++],r0 ;sub low word subb [r9],0 ;dec the high word rnc xor [r9],[r9] ;MSB = 0 subi r9,2 add r0,[r9] ;return r0 = remainder xor [r9],[r9] ;LSB = 0 ret ;********************************************************************** ; UpdateBuff: Updates dual USB buffer (512 bytes * 2) and wraps if at end ;********************************************************************** UpdateBuff: mov r10,nBuff ;Update USB Buffer DATA ptr mov r7,[r10] ;return current ptr in r8 add [r10],r0 ;next block, r0=512 ChkWrap: cmp [r10],(DATA0+cMAXSIZE) rl mov [r10],DATA0 ;check buffer wrap arround ret pkg_cnt: dw 0 page_cnt: dw 0 IRAM0_E: err<z (IRAM0Size-(IRAM0_E-IRAM0_S)) ; check if go over limited range dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw USB_RESET_VEC dw USB_reset dw 0xc3b6 ;enhancement signature dw ((IRAM1_E-IRAM1_S)+2) ;length of stuff db 0 ;memory copy dw IRAM1 reloc IRAM1 IRAM1_S: std_class: mov [(90*2)],dev_desc ; new device descriptor #ifdef DEVELOPMENT cmp [sse1],0x30 ; check sse1 for '0' (0x30) jne @f mov r0,[USB_ADDR_REG] ; load the word with USB address and r0,0x7 ; pull off the USB address add [sse1],r0 ; digit is ASCII '0'- add r0 @@: #endif jmpl USB_Stand ;********************************************************************** ; new_71: Replace ISR for interrupt 71 ;********************************************************************** new_71: addi r15,2 ;adjust the stack int 70 int 71 ;incase main execute return IRAM1_E: err<z (IRAM1Size-(IRAM1_E-IRAM1_S)) ; check if go over limited range dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw USB_EP1_VEC ;mov [USB_EP1_VEC],endp_1_int dw endp_1_int dw 0xc3b6 ;enhancement signature dw ((IRAM2_E-IRAM2_S)+2) ;length of stuff db 0 ;memory copy dw IRAM2 reloc IRAM2 IRAM2_S: _gIdeState: dw 0 ;********************************************************************** ; RegSetup: Sets up registers to default states ;********************************************************************** RegSetup: mov rCNTRL,gHighOut ; 0xc024 mov rCMD,_gCmd ; Read/Write Command mov rSTATE,_gIdeState ; Setup register 12 ret ;********************************************************************** ; Endpoint 1 ISR: Send Command Status/Data to host ; use registers: r14-r12, r10, r7: should not use in other subroutines ; Host Read from Peripheral ;********************************************************************** endp_1_int: push [flags] int SAVE_REGS ;save all registers to stack test [_gIdeState],eSndData ;send data jz SetDefault ;no set Default Buffer ep1_data: mov r10,USB_EP1_ADDR ep_common: call dUpdate64 ;xLen -= 64 and r0,r0 jnz @f mov [_gIdeState],eSndStatus jmp exit_isr @@: mov [r10+2],r0 ;update xfer length on USB_EPx_CNT call ChkWrap ;check buffer wrap arround dec [pkg_cnt] ;kick off Read/Write in the MainTask jz exit_isr int ARM_INT exit_isr: int REST_REGS ;restore all registers pop_exit: pop [flags] sti ret IRAM2_E: err<z (IRAM2Size-(IRAM2_E-IRAM2_S)) ; check if go over limited range dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw USB_EP2_VEC ;mov [USB_EP2_VEC],endp_2_int dw endp_2_int dw 0xc3b6 ;enhancement signature dw ((IRAM3_E-IRAM3_S)+2) ;length of IRAM3 db 0 ;memory copy dw IRAM3 reloc IRAM3 IRAM3_S: ;////////////////////////////////////////////////////////////////////// ;// Code required for device startup ;////////////////////////////////////////////////////////////////////// New_Delta: call USB_DELTA_SUB ;it will be called in USB_reset ;********************************************************************** ; Call this when This delta config is setup to avoid BIOS reset the endpoint ;********************************************************************** HwInit: mov [0xc03e],2 ;Debug mode disable (reduces power) mov [0xc00e],0x21 ;enable only USB must removed UART int mov [0x2d2],MainTask ;Use UART_TASK for main program or [gHighOut],cOutData ;setup default output control signals or [gHighEn],cCtrlEna ;Setup Control signals mov [_gCmd],0 ;04/04/2000 add for MAC support mov [(87*2)],Class_Int ;Class Int sub mov [TIMER0_VEC],Timer_0_int ; *** Begin WP_status init here *** mov r0,[gHighIn] ;Store power-on status of WP and r0,cGPIO18 ;mask the bit mov [WP_flag],r0 ;move it to status variable ; *** End WP_status init here *** test [startup],1 jz SwInit ret startup: dw 1 MainTask: test [startup],1 ;Check startup jz MainTask2 ;Jump to MainTask2 if startup completed mov r1,xIRAM4 ;Load IRAM4 from location on EEPROM mov r11,IRAM3_E ;Place IRAM4 at IRAM3_E mov r9,IRAM4Size ;Copy IRAM4Size bytes @@: xor r0,r0 int 65 ;Use INT 65 to read the EEPROM mov b[r11++],r0 dec r9 jnz @b mov [startup],0 ;Clear startup for next time jmp SwInit ;********************************************************************** ; Timer_0_int ISR: Handles LED, USB Suspend functions ;********************************************************************** Timer_0_int: push [flags] add [uTimer],0xffff ; 64ms timer0 test [_gIdeState],7 ; check for idle time jnz @f or [gHighOut],cCS0 ; turn LED off only not BUSY @@: inc [0x272] ; hardcode sof_tic cmp [0x272],4 jne @f and [gHighEn],!(cCF_Pins|cPWC) ;remove CF power push [0xc00e] ; push Interrupt Enable mov [0xc00e],0 ; disable all hardware interrupts mov [0xc00a],0x26 ; suspend chip pop [0xc00e] ; restore or [gHighEn],(cCF_Pins|cPWC) ;apply power @@: jmp pop_exit ;********************************************************************** ; USB_reset ISR: Bug fix for MAC OS reset timing ;********************************************************************** USB_reset: mov [0xc080],0 mov [0xc080],1 jmpl USB_RESET_SUB ; jmp to BIOS USB_reset ;********************************************************************** ; Class_Int ISR: Handles USB Class interrupt ;********************************************************************** Class_Int: cmp b[r8+bRequestP],254 je SendLUN int USB_FINISH_INT ; Finish the interrupt ret SendLUN: xor [r8],[r8] ; Only SSFDC support mov r7, 1 jmp SEND_DATA_SUB ;////////////////////////////////////////////////////////////////////// ;// Descriptors and data required for startup ;////////////////////////////////////////////////////////////////////// conf_desc: db 9 ;len of config db 2 ;type of config dw (end_all-conf_desc) db 1 ;one interface db 1 ;config #1 db 0 ;index of string describing config db 0xc0 ;bus + self power #ifdef LOW_POWER db 50 ;100mA #else db 51 ;102mA #endif interface_desc: db 9 db 4 db 0 ;base # db 0 ;alt db 2 ;# endpoints db 0x08 ;0xff=vendor, 0=Composite 8=(Mass Storage) db 0x05 ;subclass for SFF8070i compliant devices db 0x50 ;bulk only class, interface proto (vendor) db 0 ;index of string describing interface ep2: db 7 ;len db 5 ;type (endpoint) db 0x02 ;Host Write db 2 dw cBUFFSIZE ;64 db 0 ;interval ep1: db 7 ;len db 5 ;type (endpoint) db 0x81 ;Host Read db 2 ;bulk mode dw cBUFFSIZE ;64 db 0 ;interval end_all: string_desc: db STR0_LEN db 3 dw 0x409 ;english language id STR0_LEN equ ($-string_desc) str0: db STR1_LEN db 3 str2: dw 'CYPRESS FLASH DISK ' ;Leave 24 characters for Mfg. Utility STR1_LEN equ ($-str0) str1: db STR2_LEN db 3 dw 'FEDCBA987654321' ;Serial number for Mfg. Utility sse1: dw '0' ;Last digit of ser # changed by DEVELOPMENT flag STR2_LEN equ ($-str1) dev_desc: db 0x12 ;length db 1 ;desc type dw 0x0110 ;USB spec 1.1 db 0x00 ;device class db 0 ;device subclass db 0 ;should be 0x8 db 8 ;max packet size for endpoint 0 dw 0x04B4 ;VID dw 0x4616 ;PID dw 0x0082 ;device release number db 1 ;index of manufacture string db 1 ;index of product string db 2 ;index of serial number string (Unix need GUID) db 1 ;number of configurations WP_flag: dw 0x0004 ; Assume that WP is off at startup IRAM3_E: err<z (IRAM3Size-(IRAM3_E-IRAM3_S)) ; check if go over limited range dw 0xc3b6 ;enhancement signature dw 4 ;length of stuff db 0 ;COPY opcode dw (2*71) dw new_71 dw 0xc3b6 dw 2 db 4 dw HwInit reloc_off IRAM4Size equ (IRAM4_E-IRAM4_S) xIRAM4: reloc IRAM3_E IRAM4_S: SwInit: call _InitEP1 mov [_gIdeState],eRecCommand ;default set to receive the command mov [USB_EP2_ADDR],SCMD ;setup to receive command mov [USB_EP2_CNT],31 ;Command Block size ArmEP2: mov [LastAddr2],[USB_EP2_ADDR] mov [LastCnt2],[USB_EP2_CNT] mov [USB_EP2_CNTRL],cDMA2ENA ret ;********************************************************************** ; Endpoint 2 ISR (Rec Command) ; Host Write to Peripheral ;********************************************************************** endp_2_int: push [flags] int SAVE_REGS ;save all registers to stack mov [USB_EP1_CNTRL],cDMA1DIS ;disable EP1 to prevent host read???? call RegSetup mov r10,USB_EP2_ADDR test [rSTATE],eRecData ;check data phase transfer jnz ep_common mov r9,(SCMD+2) cmp [r9],cCookie ;check if it is a command block jne SetDefault ;setup to get command again mov [r9++],0x5342 addi r9,4 ;skip dCBWTag mov r7,[r9++] ;r7= Length LSB mov [_xLenLSB],r7 ;copy working length mov [_xLenMSB],[r9++] ;[r8] = Length MSB and [r9],0x180 xor [r9],0x80 ;change direction mov b[rCMD],[r9] xor [r9++],[r9] ;Set Return status = 0, r9=pointer to length and CDB mov [r10],DATA0 mov [nBuff],[r10++] ;setup DATA pointer call SS_ChkOpCode ;SSFDC ChkOpcode: need to reserved r7, r10 @@: or r7,[_xLenMSB] ;check data jnz DoDATA SetDefault: call SwInit ;reset to default ep2_exit: jmp exit_isr DoDATA: call dUpdate64 and b[rCMD],b[rCMD] ;test r4,0x80 check direction jnz DoWrite DoRead: mov [(ARM_INT*2)],ArmEP1 mov r10,USB_EP1_ADDR mov [r10++],DATA0 mov [r10],r0 addi [rSTATE],eSndData ;send data to host call Xfer512 call ArmSetup0 call Xfer512 jmp ep2_exit DoWrite: mov [(ARM_INT*2)],ArmEP2 addi [rSTATE],eRecData ;wait for USB send 64 data from host call ArmSetup jmp ep2_exit ;********************************************************************** ; MainTask for NAND Flash ;********************************************************************** MainTask2: mov [(90*2)],0xf756 ;restore dev_desc call RegSetup ChkDATA: test [rSTATE],eSndStatus ;check if need to send STATUS pharse jz @f ssfd_chk: test [bStatus],0x100 ;check if all transfer then set done jz DoXfer sw_init: jmp SwInit @@: cmp [pkg_cnt],0 ;Buffer not ready rnz test [rSTATE],(eSndData|eRecData) rz mov r10,USB_EP1_CNT test [rSTATE],eSndData jnz @f mov r10,USB_EP2_CNT ;Concurrent Kick off SIE DMA @@: call ArmSetup Xfer512: test [bStatus],0x100 ;xfer done rnz DoXfer: mov r0,512 mov r9,LenLSB ;update Host Xfer Length on the SCMD call dChkSize ;r0==0 means no more data to transfer call UpdateBuff add [_gLBA_L],1 ;inc sector cnt addc b[_gLBA_H],0 and b[rCMD],b[rCMD] ;check Read/Write jz chk_ecc set_ecc: ;WRITE TO FLASH mov r8,r7 #ifndef NOECC call _set_ecc ;Compute ECC #endif call _sSetAdd0 mov r8,r7 call _Write512 ;Write DATA call _Write16 ;Write redundant DATA call sWritePage ;Enable the Write Command add [_gSectorPN_L],1 ;Updated PN Sector addc b[_gSectorPN_H],0 dec [_gBLK] jnz @f call SS_FinalStatus test [_gLBA_L],b[_gPageMask] ; check if need to do Tail Copy jz DoErase ;every done just erase and return call DoTailCopy ;copy tail data then erase jmp DoErase @@: test [_gLBA_L],b[_gPageMask] rnz call DoErase ;erase previous block jmp _SetupWrite DoErase: mov r0,[_gSrcBlkPN] ;if erase block is valid cmp r0,[_gDstBlkPN] rz mov r8,[_gEraseBlk] ;Set block status erased or [r8],0xf000 ;BLOCK is Free now call _Blk2Pages ;get PN address call _sWaitBusy jmp sEraseBlock ;Erase this Block chk_ecc: ;READ from FLASH call _sWaitBusy ;wait for busy mov r8,r7 call _Read512 ;read DATA call _Read16 ;read Redundant data mov r8,r7 #ifndef NOECC call _chk_ecc #endif dec [_gBLK] jz SS_FinalStatus mov r3,b[_gPageMask] ;check if need to Remap and r3,[_gLBA_L] ;get Page Offset rnz jmp _SetupRead ;SetupRead (r3=offset) ;********************************************************************** ; Read commands ;********************************************************************** ;********************************************************************** ; DATA TABLE ;********************************************************************** ; initial permutation IP IP_Table: DB 58,50,42,34,26,18,10,2 DB 60,52,44,36,28,20,12,4 DB 62,54,46,38,30,22,14,6 DB 64,56,48,40,32,24,16,8 DB 57,49,41,33,25,17, 9,1 DB 59,51,43,35,27,19,11,3 DB 61,53,45,37,29,21,13,5 DB 63,55,47,39,31,23,15,7 ; final permutation IP^-1 IPR_Table: DB 40, 8, 48, 16, 56, 24, 64, 32 DB 39, 7, 47, 15, 55, 23, 63, 31 DB 38, 6, 46, 14, 54, 22, 62, 30 DB 37, 5, 45, 13, 53, 21, 61, 29 DB 36, 4, 44, 12, 52, 20, 60, 28 DB 35, 3, 43, 11, 51, 19, 59, 27 DB 34, 2, 42, 10, 50, 18, 58, 26 DB 33, 1, 41, 9, 49, 17, 57, 25 ; expansion operation matrix E_Table: DB 32, 1, 2, 3, 4, 5, 4, 5 DB 6, 7, 8, 9, 8, 9, 10, 11 DB 12, 13, 12, 13, 14, 15, 16, 17 DB 16, 17, 18, 19, 20, 21, 20, 21 DB 22, 23, 24, 25, 24, 25, 26, 27 DB 28, 29, 28, 29, 30, 31, 32, 1 ; 32-bit permutation function P used on the output of the S-boxes P_Table: DB 16, 7, 20, 21, 29, 12, 28, 17 DB 1, 15, 23, 26, 5, 18, 31, 10 DB 2, 8, 24, 14, 32, 27, 3, 9 DB 19, 13, 30, 6, 22, 11, 4, 25 ; permuted choice table (key) PC1_Table: DB 57, 49, 41, 33, 25, 17, 9, 1 DB 58, 50, 42, 34, 26, 18, 10, 2 DB 59, 51, 43, 35, 27, 19, 11, 3 DB 60, 52, 44, 36, 63, 55, 47, 39 DB 31, 23, 15, 7, 62, 54, 46, 38 DB 30, 22, 14, 6, 61, 53, 45, 37 DB 29, 21, 13, 5, 28, 20, 12, 4 ; permuted choice key (table) PC2_Table: DB 14, 17, 11, 24, 1, 5, 3, 28 DB 15, 6, 21, 10, 23, 19, 12, 4 DB 26, 8, 16, 7, 27, 20, 13, 2 DB 41, 52, 31, 37, 47, 55, 30, 40 DB 51, 45, 33, 48, 44, 49, 39, 56 DB 34, 53, 46, 42, 50, 36, 29, 32 ; number left rotations of pc1 LOOP_Table: DB 1, 1, 2, 2, 2, 2, 2, 2 DB 1, 2, 2, 2, 2, 2, 2, 1 ; The (in)famous S-boxes ;const static char S_Box[8][4][16] = { S_Box1: DB 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7 DB 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8 DB 4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0 DB 15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13 S_Box2: DB 5, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10 DB 3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5 DB 0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15 DB 13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9 S_Box3: DB 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8 DB 13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1 DB 13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7 DB 1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12 S_Box4: DB 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15 DB 13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9 DB 10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4 DB 3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14 S_Box5: DB 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9 DB 14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6 DB 4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14 DB 11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3 S_Box6: DB 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11 DB 10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8 DB 9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6 DB 4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13 S_Box7: DB 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1 DB 13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6 DB 1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2 DB 6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12 S_Box8: DB 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7 DB 1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2 DB 7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8 DB 2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11 ; static bool SubKey[16][48];// 16Ȧ×ÓÃÜÔ¿ ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** DESR_EC: push r8 push r7 push r0 mov [SZ_Li],SZ_M mov [SZ_Ri],(SZ_M+32) mov r0,64 mov r7,SZ_M call ByteToBit mov r7,SZ_M mov r9,IP_Table mov r0,64 call Transform mov r0,16 @@: push r0 mov r8,SZ_Tmp mov r7,SZ_Ri mov r0,32 call memcpy mov r8,SZ_Ri mov r7,SubKey pop r0 add r7,r0 push r0 call F_func mov r8,SZ_Ri mov r7,SZ_Li mov r0,32 call Xor mov r8,SZ_Li mov r7,SZ_Tmp mov r0,32 call memcpy pop r0 dec r0 jnz @b jmp DESR_END ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** DESR_EC: push r8 push r7 push r0 mov [SZ_Li],SZ_M mov [SZ_Ri],(SZ_M+32) mov r0,64 mov r7,SZ_M call ByteToBit mov r7,SZ_M mov r9,IP_Table mov r0,64 call Transform mov r0,16 @@: push r0 mov r8,SZ_Tmp mov r7,SZ_Li mov r0,32 call memcpy mov r8,SZ_Li mov r7,SubKey pop r0 add r7,r0 push r0 call F_func mov r8,SZ_Li mov r7,SZ_Ri mov r0,32 call Xor mov r8,SZ_Ri mov r7,SZ_Tmp mov r0,32 call memcpy pop r0 dec r0 jnz @b DESR_END: mov r8,SZ_M mov r7,SZ_N mov r9,IRP_Table mov r0,64 call Transform pop r8 push r8 mov r7,SZ_M mov r0,64 call Bit2Byte pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** Des_SetKey: ; static bool K[64], *KL = &K[0], *KR = &K[28]; mov [SZ_KL],SZ_K mov r0,SZ_K add r0,28 mov [SZ_KR],r0 mov r7,r8 push r8 mov r8,SZ_K mov r0,64 call ByteToBit mov r8,SZ_K mov r7,SZ_K mov r9,PC1_Table mov r0,56 call Transform mov r0,16 @@: push r0 mov r8,SZ_KL mov r7,28 mov r9,LOOP_Table pop r0 push r0 add r9,r0 call RotateL mov r8,SZ_KR mov r7,28 mov r9,LOOP_Table pop r0 push r0 add r9,r0 CALL RotateL mov r8,SubKey pop r0 push r0 add r8,r0 mov r7,SZ_K mov r9,PC2_Table mov r0,48 call Transform pop r0 dec r0 jnz @b pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** F_func: push r8 mov r7,r8 mov r8,SZ_MR mov r9,E_Table mov r0,48 call Transform mov r8,SZ_MR mov r7,SZ_Ki mov r0,48 call Xor pop r8 push r8 mov r7,SZ_MR call S_func pop r8 push r8 mov r7,r8 mov r9,P_Table mov r0,32 call Transform pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** S_func: push r8 push r7 mov r0,8 mov [SZ_S_BOX],S_Box1 @@ push r0 pop r9 push r9 add r9,5 pop r7 push r7 rr r7 add r9,r7 pop r0 push r0 add r0,4 mov r0,[r0] pop r7 push r7 inc r7 mov r7,[r7] rr r7 rr r7 rr r7 add r0,r7 pop r7 push r7 add r7,2 mov r7,[r7] rr r7 rr r7 add r0,r7 pop r7 push r7 add r7,3 mov r7,[r7] rr r7 add r0,[r7] pop r8 push r8 add [SZ_S_BOX],64 add [SZ_S_BOX],r9 add [SZ_S_BOX],r0 mov r7,[SZ_S_BOX] mov r0,4 call ByteToBit pop r0 dec r0 jnz @b pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** Transform: push r8 push r7 push r9 @@: push r0 add r9,r0 mov r7,[r9] pop r0 pop r9 push r9 push r0 add r9,r7 mov r7,[r9] mov r9,SZ_Tmp pop r0 push r0 add r9,r0 mov [r9],[r7] pop r0 dec r0 jnz @b pop r9 pop r7 pop r8 push r8 push r7 push r9 pop r0 push r0 call memcpy pop r9 pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** Xor: push r8 push r7 @@: push r0 pop r0 pop r7 pop r8 push r8 push r7 push r0 add r8,r0 add r7,r0 xor [r8],[r7] pop r0 dec r0 jnz @b pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** RotateL: push r8 push r7 push r0 mov r8,SZ_Tmp pop r0 push r0 pop r8 push r8 mov r7,r8 call memcpy pop r0 pop r8 push r8 push r0 mov r7,r8 add r7,r0 call memcpy pop r0 pop r7 push r7 push r0 mov r8,r7 add r8,r0 call memcpy pop r0 pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** ByteToBit: push r8 push r7 mov r9,1 @@: push r0 pop r7 add r7,r0 test r0,r9 jz BTB01 pop r8 push r8 add r8,r9 mov [r8],1 rl [r8] rl r9 jmp BTB02 BTB01: pop r8 push r8 add r8,r9 rl r9 mov [r8],0 rl [r8] BTB02: pop r0 dec r0 jnz @b pop r7 pop r8 ret ;********************************************************************** ; R8:input R7:output R0:cnt R9 ;********************************************************************** ByteToBit: push r8 push r7 mov r9,1 @@: push r0 pop r7 add r7,r0 test r0,r9 jz BTB01 pop r8 push r8 add r8,r9 rl r9 or [r8],1 jmp BTB02 BTB01: pop r8 push r8 add r8,r9 rl r9 mov [r8],0 BTB02: pop r0 dec r0 jnz @b pop r7 pop r8 ret ;********************************************************************** ; Read commands ;********************************************************************** _Read16: mov r0, 16 _Read: mov r8,_gRedunt jmp RdCommon _Read512: mov r0, 512 ; Read 512 bytes RdCommon: mov r11, gLowIn ; Set the R11 ptr to Data IN mov r2, cDATA_H mov r1, cDATA_RD @@: mov [rCNTRL], r1 ; Assert Read mov b[r8++], [r11] ; Read Data mov [rCNTRL], r2 ; De-assert Read mov [rCNTRL], r1 ; Assert Read mov b[r8++], [r11] ; Read Data mov [rCNTRL], r2 ; De-assert Read mov [rCNTRL], r1 ; Assert Read mov b[r8++], [r11] ; Read Data mov [rCNTRL], r2 ; De-assert Read mov [rCNTRL], r1 ; Assert Read mov b[r8++], [r11] ; Read Data mov [rCNTRL], r2 ; De-assert Read subi r0, 4 ; Decrement the counter jnz @b ; Loop back ret ;********************************************************************** ; Write commands ;********************************************************************** _Write16: mov r0,16 _Write: mov r8,_gRedunt jmp WrCommon _Write512: mov r0, 512 ; Write 512 bytes _WriteData: mov [gLowEn],0xff ; set Output mode WrCommon: mov r11, gLowOut ; Set the R11 ptr to Data OUT mov r2, cDATA_H mov r1, cDATA_WR @@: mov [r11], b[r8++] ; Write Data mov [rCNTRL], r1 ; Assert Write mov [rCNTRL], r2 ; De-assert Write mov [r11], b[r8++] ; Write Data mov [rCNTRL], r1 ; Assert Write mov [rCNTRL], r2 ; De-assert Write mov [r11], b[r8++] ; Write Data mov [rCNTRL], r1 ; Assert Write mov [rCNTRL], r2 ; De-assert Write mov [r11], b[r8++] ; Write Data mov [rCNTRL], r1 ; Assert Write mov [rCNTRL], r2 ; De-assert Write subi r0, 4 ; Decrement the counter jnz @b ; Loop back ret ;********************************************************************** ; SS_ChkOpcode: Decodes and responds to MSC requests ; r9 pointer to length, CDB, r7=length ;********************************************************************** SS_ChkOpCode: inc r9 ;skip length mov r0,b[r9] ;r0=CDB[0] and r0,r0 ;check TUR jz SS_TUR call Save_LBA ;sets r8 to point at DATA0 cmp r0,s_READ ;special handling for READ/WRITE je SS_Read mov r1,s_WRITE cmp r0,r1 je SS_Write cmp r0,0x2e ;write and verify je SS_Write mov r9,LenLSB ;Clear LenLSB, LenMSB and Data @@: xor [r9++],[r9] ;clear buffer dec r1 jnz @b inc b[(bStatus+1)] ;set done flag cmp r0,s_INQUIRY je SS_Inquiry cmp r0,s_FORMAT je SS_Format cmp r0,s_READ_FORMAT_CAPACITY je SS_Read_Format_Capacity cmp r0,s_READ_CAPACITY je SS_Read_Capacity cmp r0,s_START_STOP je SS_StartStop cmp r0,s_MODE_SENSE je SS_Mode_Sense cmp r0,s_REQUEST_SENSE je SS_Request_Sense cmp r0,s_VERIFY ;return Status Success for now rle ;********************************************************************** ; SS_Err: Completes failed commands ;********************************************************************** SS_Err: addi [bStatus],1 ret ;********************************************************************** ; SS_StartStop: Responds to request to eject media ;********************************************************************** SS_StartStop: test b[(_gLBA_L+1)],6 rz or [rCMD],(cEject0|cMedia0) ; set EJECT media ret ;********************************************************************** ; SS_Mode_Sense: Returns status of WP bit ;********************************************************************** SS_Mode_Sense: mov b[r8++],0x00 ; DATA[0] mov b[r8++],0x06 ; DATA[1] length = 6, in v.77 was incorrectly length = 8 mov b[r8++],0x00 ; DATA[2] test [gHighIn],cGPIO18 ; WP=0 rnz mov b[r8],0x80 ; set write protect bit in DATA[3] ret ;********************************************************************** ; SS_Request_Sense: Returns error codes of previous command. ; Scans for: ; 1. Eject ; 2. Media Change (triggered on write protect change) ;********************************************************************** SS_Request_Sense: mov [r8++],0x70 ; Error Code = 0x70h mov b[(DATA0+7)],0x06 ; Additional Sense Length = 0x06h test [rCMD],cEject0 ; Flag set until device unplug jz @f mov [r8],0x02 ; Return sense key ILLEGAL REQUEST mov [(DATA0+12)],0x3A ; Return ASC & ASCQ MEDIA REMOVAL PREVENTED ret @@: test [rCMD],cMedia0 ; Check for media change or eject jz @f mov [r8],0x06 ; Return sense key UNIT ATTENTION mov [(DATA0+12)],0x28 ; Return ASC NOT READY TO READY TRANSISTION - MEDIA CHANGED and [rCMD],!cMedia0 ; Clear cMedia0 status flag ret @@: ret ; No more known errors detected, add additional errors here if needed read_capacity_hdr: test [rCMD],(cEject0|cRemoved0) ;SSFDC detect insert jnz SS_FinalStatus and [rCNTRL],!(cPWC|cWP|cCLE|cALE|cCS0) or [gHighEn],cPWC ; insert power call Delay call SM_Reset call sReadID ; read ID and get Capacity push r5 ; save actual blk count call _Build_Table ; uses r8 pop r0 ; restore in r0 for sector count call _BlkShft ; computed total sectors size ret ;********************************************************************** ; SS_Read_Format_Capacity: RETURNS THE TOTAL NUMBER OF BLOCKS ;********************************************************************** SS_Read_Format_Capacity: call read_capacity_hdr mov r2,r1 shr r2,8 mov r8,DATA0 ; put r8 back at DATA[0] mov b[r8++],0 mov b[r8++],0 mov b[r8++],0 mov b[r8++],8 mov b[r8++],r2 ; BYTE3 mov b[r8++],r1 ; BYTE2 mov r2,r0 shr r2,8 mov b[r8++],r2 ; BYTE1 mov b[r8],r0 ; BYTE0 addi b[(DATA0+10)],2 ; BYTE10 for 512 bytes per page jmp SS_FinalStatus ;********************************************************************** ; SS_Read_Capacity: Returns the last LBA address (NUM BLOCKS - 1) ;********************************************************************** SS_Read_Capacity: call read_capacity_hdr subi r0,1 ; subtract one subb r1,0 ; subtract w/ carry bit mov r2,r1 shr r2,8 mov r8,DATA0 mov b[r8++],r2 ; BYTE3 mov b[r8++],r1 ; BYTE2 mov r2,r0 shr r2,8 mov b[r8++],r2 ; BYTE1 mov b[r8],r0 ; BYTE0 addi b[(DATA0+6)],2 ; BYTE6 for 512 bytes per page jmp SS_FinalStatus ;********************************************************************** ; SS_TUR (TEST_UNIT_READY) checks for the following error(s): ; 1. WP switch change ; If an error is detected then jump to SS_Err. ; If no errors are present then jump to SS_FinalStatus. ;********************************************************************** SS_TUR: mov r0,[gHighIn] ; Test WP and r0,cGPIO18 cmp r0,[WP_flag] ; Compare to last known state je SS_FinalStatus ; If no change in WP then finish command mov [WP_flag],r0 ; Update WP status or [rCMD],cMedia0 ; Set flag so media change error reported before write protect error jmp SS_Err ;********************************************************************** ; SS_FinalStatus: Completes successful commands ;********************************************************************** SS_FinalStatus: mov [bStatus],0x100 mov r0,[rCMD] and [rCMD],!cRemoved0 ; clear error test r0,(cRemoved0|cEject0) ; cMedia0| ? jnz SS_Err ret ;********************************************************************** ; This will be used in Head/Tail Copy data ; r3,r4 = Source Sector ; r5,r6 = Dest Sector ; gLen = Sector Count ;********************************************************************** DoTailCopy: mov r5,[_gSectorPN_L] ; save current Dest sector mov r6,b[_gSectorPN_H] mov r0,[_gSrcBlkPN] ; read Source Data call _Blk2Pages ; Blk to Sector mov r3,r0 mov r4,r1 mov r0,[_gLBA_L], and r0,b[_gPageMask] add r3,r0 mov [_gLen],b[_gPageSize] sub [_gLen],r0 ; Tail Len to be copied jmp CopyData ;********************************************************************** ; SS_Read: Sets up read from NAND Flash ;********************************************************************** SS_Read: test [rCMD],(cEject0|cRemoved0) ;SSFDC detect insert jnz SS_FinalStatus mov r3,b[_gPageMask] and r3,[_gLBA_L] _SetupRead: call Sector2PN ;new page map call _Blk2Pages ;Sector LN to Sector PN or [_gSectorPN_L],r3 ;add offset jmp _sSetAdd0 ;setup address ;********************************************************************** ; SS_Write: Sets up write from NAND Flash ;********************************************************************** SS_Write: test [rCMD],(cEject0|cRemoved0) ;SSFDC detect insert jnz SS_FinalStatus call _SetupWrite ; Remap and get new PN block mov [_gLen],[_gLBA] and [_gLen],b[_gPageMask] ; check for HEAD copy DATA rz mov r5,r0 ; need to copy Head mov r6,r1 mov r0,[_gSrcBlkPN] ; read Source Data call _Blk2Pages ; Blk to Sector mov r3,r0 mov r4,r1 ;********************************************************************** ; This will be used in Head/Tail Copy data ; r3,r4 = Source Sector ; r5,r6 = Dest Sector ; gLen = Sector Count ;********************************************************************** CopyData: push [_gLBA_L] cp_lp: mov [_gSectorPN_L],r3 mov b[_gSectorPN_H],r4 xor r0,r0 call _sSetAddr ; read source data call _sWaitBusy mov r8,[nBuff] ; user buffer DATA0 call _Read512 ; read DATA call _Read16 ; read Redundant data call _SetBlkAddr ; update Redundant area mov [_gSectorPN_L],r5 mov b[_gSectorPN_H],r6 call _sSetAdd0 ; Set Address for Writing mov r8,[nBuff] ; user buffer DATA0 call _Write512 call _Write16 call sWritePage inc r3 inc r5 mov [_gSectorPN_L],r5 ; updated it dec [_gLen] jnz cp_lp pop [_gLBA_L] ret ;********************************************************************** ; Write: ; Copy Head if lba not align ; len = lba & 0xf; ; When finish writing all the data: ; Copy Tail when (lba + blk) is not aligned, then erase ;********************************************************************** _SetupWrite: test [gHighIn],cGPIO18 ; WP=0 jnz @f or [rCMD],cMedia0 ; Set media changed error on WP change call SS_FinalStatus jmp SS_Err @@: call Sector2PN ; LBA -> PN mov r1,r0 mov r9,r8 ; save current gLog2Phys[zone][gBlockLN] mov [_gSrcBlkPN],r1 ; Head Src Blk mov r6,b[_gZones] test r1,cUSED_MASK ; check if block is used jnz @f call _SetBlkUsed ; if used, need to erase mov [_gEraseBlk],r8 ; save erase address @@: call _GetFreeBlk ; get dest free block mov [_gDstBlkPN],r0 and [r9],0xf000 or [r9],r0 ; gLog2Phys[zone][gBlockLN] = r0 mov r1,r0 call _SetBlkUsed ; set this block is used call _SetBlkAddr ; update Redundant area test [_gSrcBlkPN],cUSED_MASK ; set src=dest if addr is invalided jz @f mov [_gSrcBlkPN],[_gDstBlkPN] ; make sure to have valid SRC BLK @@: mov r0,[_gDstBlkPN] ; fall though to Blk2Page ;********************************************************************** ; _Blk2Pages: Block Address to 512 sector page ; Blk2Pages(Blkaddr) ;********************************************************************** _Blk2Pages: mov r1,b[_gZones] ror r1,6 ; r1 * Zone or r0,r1 _BlkShft: xor r1,r1 ; 32-bit shift add r0,r0 addc r1,r1 add r0,r0 addc r1,r1 add r0,r0 addc r1,r1 add r0,r0 addc r1,r1 test b[_gPageMask],0x10 jz b2p_ret add r0,r0 addc r1,r1 b2p_ret: mov [_gSectorPN_L],r0 ; save in SectorPN mov b[_gSectorPN_H],r1 ret ;********************************************************************** ; Write command to FLASH ;********************************************************************** sCmdWrite: mov [rCNTRL],cCMD_H mov [gLowEn],0xff sWRITE: mov [gLowOut],r0 and [rCNTRL],!cWR ; Assert cWR or [rCNTRL],cWR ; Negate cWR ret ;********************************************************************** ; Read data from FLASH interface ;********************************************************************** sREAD: and [rCNTRL], !cRD ; Assert READ mov r0, b[gLowIn] ; Read data or [rCNTRL], cRD ; Negate READ ret ; Exit ;********************************************************************** ; r0 = 0x80 = Address Write, r0 = 0x00 = Address Read ; sSetAdd0() ; sSetAddr(short cmd) ; Address setting for FLASH ;********************************************************************** _sSetAdd0: mov r0,b[rCMD] _sSetAddr: call _sWaitBusy ; need this for page read/write call sCmdWrite ; set CLE high xor r0,r0 mov [rCNTRL],cALE_H ; set ALE high call sWRITE sCommon: mov r0,[_gSectorPN_L] ; 24-bit address call sWRITE ; ALE is high shr r0,8 call sWRITE mov r0,[_gSectorPN_H] test r0,cThirdAddr ; check if 64MB+ jz sDATA0 sWRITE0: call sWRITE ; ALE is high jmp sDATA0 ; ALE low (DATA mode) ;********************************************************************** ; Erase Block: [_gSectorPN_H] [_gSectorPN_L] ;********************************************************************** sWritePage: mov r0,0x10 ; Write Page jmp sCmdWrite0 sEraseBlock: mov r0,0x60 ; Start Erase Command call sCmdWrite mov [rCNTRL],cALE_H mov r0,[_gSectorPN_L] ; 24-bit address call sWRITE ; ALE is high shr r0,8 call sWRITE mov r0,[_gSectorPN_H] test r0,cThirdAddr ; check if 64MB+ jz sSetEndCmd call sWRITE ; ALE is high sSetEndCmd: mov r0,0xd0 ; end erase command sCmdWrite0: call sCmdWrite sDATA0: mov [rCNTRL],cDATA_H mov [gLowEn],0 ; set INPUT mode ret ;********************************************************************** ; _sWaitBusy: Waits for BUSY pin on NAND Flash to go high ;********************************************************************** _sWaitBusy: test [gLowIn],cRB ; Check BUSY jz _sWaitBusy ; Wait while BUSY is LO ret ;********************************************************************** ; void SetBlkAddr(addr) ; redundant: 0xffff, 0xffff, 0xffff, wAddr1, bECC2[3], wAddr2, bECC1[3] ;********************************************************************** _SetBlkAddr: mov r0,[_gBlockLN] mov r8,_gRedunt mov [r8],-1 ; set 0xffff, 0xffff, 0xffff mov [r8],[r8++] mov [r8++],[r8++] ; set Status shl r0,0x1 or r0,0x1000 BitCnt: xor r2,r2 ; r2 = 0 mov r1,1 bitloop: test r0,r1 ; count the number of bits in word jz @f inc r2 ; r2++ @@: shl r1,1 jnz bitloop test r2,0x1 ; check if odd/even parity bit jz @f inc r0 @@: mov r1,r0 shr r0,8 mov b[r8++],r0 ; MSB of Addr1 mov b[r8],r1 ; LSB of Addr1 addi r8,4 mov b[r8++],r0 ; MSB of Addr2 mov b[r8],r1 ; LSB of Addr2 ret ;********************************************************************** ; _MapLog2Phys: Converts logical block to physical block ; short MapLog2Phys() ;********************************************************************** _MapLog2Phys: mov r0,[_gLBA_L] mov r1,[_gLBA_H] shr r0,4 ; 16 pages shl r1,8 and r0,0x0fff test [_gPageMask],0x10 ; page=32 jz @f shr r0,1 shl r1,3 ; shift left 11 jmp p2b_exit @@: shl r1,4 ; shift left 12 p2b_exit: or r1,r0 ; gBlockLN xor r0,r0 ; zone=0 mov r2,[_gLogBlocks] ; return remainder in r1 map_lp: cmp r1,r2 jc @f sub r1,r2 inc r0 ; inc zone jmp map_lp @@: mov [_gBlockLN],r1 mov b[_gZones],r0 ;********************************************************************** ; short GetLog2Phys(short zone, short addr) ;********************************************************************** _SetLog2Phys: _GetLog2Phys: mov r8,r1 shl r8,0x1 ; r8 = remainder ror r0,0x5 ; r0 * 32 add r8,r0 add r8,_gLog2Phys ret ;********************************************************************** ; need r1=blk addr ;********************************************************************** _SetBlkUsed: mov r0,r6 call _SetLog2Phys ; BLK USE = 0x0xxx and [r8],0xfff ret ;********************************************************************** ; short GetFreeBlk() ;********************************************************************** _GetFreeBlk: mov r1,[_gSrcBlkPN] mov r3,[_gMaxBlocks] ; for (i=addr; i<gMaxBlocks; i++) mov r2,b[_gZones] ; setup constant for zone ror r2,5 call sGetFree rz xor r1,r1 mov r3,[_gSrcBlkPN] ; for (i=0; i<addr; i++) sGetFree: cmp r1,r3 ; return if r1>r3 rg @@: mov r8,r1 shl r8,1 ; word add r8,r2 ; add zone mov r0,[r8+_gLog2Phys] and r0,cBLK_FREE ; mark of cmp r0,cBLK_FREE ; return zero flag je sFreeExit inc r1 cmp r1,r3 jb @b or r0,r8 ; return non zero flag sFreeExit: mov r0,r1 ret ;********************************************************************** ; return r0 -> PN Block Address ; gBlockLN -> contains logical block address ; return r8 -> pointer to address of gLog2Phys[zone][gBlockLN] ;********************************************************************** Sector2PN: call _MapLog2Phys ; LN block to PN block mov r0,[r8] and r0,0x0fff ; get PN block address ret ;********************************************************************** ; ECC code include ;********************************************************************** .xlist include secc.asm .list _gLogBlocks: dw 1000 ;************************************************************************ SS_Inquiry: ; set byte0 = DIRECT_ACCESS_DEVICE = 0 Do_Inquiry: mov r8,DATA0 #ifdef HD_ICON xor [r8++],[r8] #else mov [r8++],0x8000 ; set Removable Media bit #endif xor [r8++],[r8] xor [r8++],[r8] xor [r8++],[r8] ; point to o_VendorID at offset 8 mov r9,str2 mov r1,((STR1_LEN-2)/2) @@: mov b[r8++],[r9++] ; copy Mfg and Prod String dec r1 jnz @b mov r1,40 @@: mov b[r8++],0x20 dec r1 jnz @b ret ;********************************************************************** ; The time of delay generated by this function varies on clock frequency ; This code should not be directly ported to other platforms ;********************************************************************** Delay: mov r0,-1 ;delay here @@: dec r0 jnz @b ret ;********************************************************************** ; Common code for both CF/SSFDC ;********************************************************************** Save_LBA: addi r9,2 mov b[(_gLBA_H+1)],b[r9++] ;byte3 mov b[(_gLBA_H+0)],b[r9++] ;byte2 mov b[(_gLBA_L+1)],b[r9++] ;byte1 mov b[(_gLBA_L+0)],b[r9++] ;byte0 inc r9 ;CDB[7] mov b[(_gBLK+1)],b[r9++] ;MSB mov b[(_gBLK+0)],b[r9] ;LSB number of sector mov r8,DATA0 ret ;********************************************************************** ; _Build_Table: Build the Logical to Physical remap table ;********************************************************************** _Build_Table: mov r8,_gLog2Phys mov r0,(cMaxBlocks*4) mov r4,0xffff @@: mov [r8++],r4 ; mask all blocks erased mov [r8++],r4 ; mask all blocks erased dec r0 jnz @b xor r6,r6 ; initialize all remap table mov [_gSectorPN_L],r6 mov b[_gSectorPN_H],r6 zone_lp: xor r5,r5 blk_lp: mov r0,0x50 ; read redundant area call _sSetAddr mov r9,4 ; try 4 pages getlp: call _sWaitBusy call _Read16 mov r8,(_gRedunt+6) mov r3,b[r8++] ; addr1-MSB shl r3,8 or r3,b[r8] ; addr1-LSB addi r8,4 mov r2,b[r8++] ; addr2-MSB shl r2,8 or r2,b[r8] ; addr2-LSB cmp r3,r2 ; if (addr1 = addr2) jnz next_page cmp r3,r4 ; check blank jz ChkBlank and r2,0xf000 ; r2 & 0xF000 cmp r2,0x1000 ; if (r2 = 0x1000) jnz next_page mov r1,r3 and r1,0x0fff ; return valid address shr r1,1 mov r0,r6 call _SetLog2Phys ; gLog2Phys[r0][r1]=r5 and [r8],0xf000 ; update Blk Address or [r8],r5 xor r2,r2 ; set Blk Used jmp SetBlkUsed next_page: and r6,r6 ; other zone is OK jnz @f cmp r5,2 ; only 1-time for block0-1 jb ChkBlank @@: dec r9 ; retry 4 times jnz getlp ChkBlank: mov r8,_gRedunt mov r0,4 chkloop: cmp [r8++],r4 ; check for blank data = 0xffff jnz SetBlkBad dec r0 jnz chkloop jmp SetInc ; skip set the bad block SetBlkBad: mov r2,cBLK_BAD SetBlkUsed: mov r1,r5 call _SetBlkUsed ; gLog2Phys[r0][r5]=r2 or [r8],r2 SetInc: add [_gSectorPN_L],b[_gPageSize] addc b[_gSectorPN_H],0 inc r5 cmp r5,[_gMaxBlocks] jb blk_lp inc r6 cmp r6,b[_gMaxZones] jb zone_lp SM_Reset: mov r0,0xff call sCmdWrite0 jmp _sWaitBusy ; exit ;********************************************************************** ; sReadID: Reads ID and determines capacity ; r8 = buffer ;********************************************************************** sReadID: call _sWaitBusy mov r0,0x90 ; ReadID command call sCmdWrite mov [rCNTRL],cALE_H ; set ALE high xor r0,r0 call sWRITE0 call sREAD ; maker code call sREAD ; SSFD card ID mov r1, 32 ; Assume 32 Pages mov r2, 8 ; 8 zones mov r3, 1024 ; Assume 1024 Log blocks/Zone mov r4, 1000 mov r5, 8000 mov [_gSectorPN_H],cThirdAddr cmp r0, 0x79 ; 8192B/32P = 128MB je sID_Exit cmp r0, 0xDA ; 8192B/32P je sID_Exit shr r2,1 ; 4 zones shr r5,1 cmp r0, 0x76 ; 4096B/32P = 64MB je sID_Exit cmp r0, 0xD9 ; 4096B/32P je sID_Exit mov [_gSectorPN_H],r2 ; clear cThirdAddr and 2MB device shr r2,1 ; Assume 2 Zones shr r5,1 cmp r0, 0x75 ; 2048B/32P = 32MB je sID_Exit ; Yep cmp r0, 0x58 ; 2048B/32P je sID_Exit ; Yep shr r2, 1 ; Assume 1 Zones shr r5, 1 cmp r0, 0x73 ; 1024B/32P = 16MB je sID_Exit ; Yep cmp r0, 0x57 ; 1024B/32P je sID_Exit ; Yep shr r1, 1 cmp r0, 0xE6 ; 1024B/16P = 8MB je sID_Exit ; Yep cmp r0, 0xD6 ; 1024B/16P je sID_Exit ; Yep shr r3,1 ; check 4MB shr r4,1 shr r5,1 sID_Exit: mov b[_gPageSize],r1 ; page size dec r1 mov b[_gPageMask],r1 ; mask mov b[_gMaxZones],r2 ; max zone mov [_gMaxBlocks],r3 mov [_gLogBlocks],r4 ; max log block mov r0, 0x70 ; Send the command call sCmdWrite0 call sREAD test r0,0x80 ; check Write Protect bit rnz or [_gSectorPN_H],cWP_Status ret _gMaxZones: db 0 _gZones: db 0 _gPageSize db 0 _gPageMask: db 0 _gMaxBlocks: dw 0 ;********************************************************************** ; SS_Format: Erases entire FLASH and prepares for use ;********************************************************************** SS_Format: call sReadID xor r0,r0 mov [_gSectorPN_L],r0 ;starting block 0 mov b[_gSectorPN_H],r0 mov r6,b[_gMaxZones] ror r6,6 ;get the number of zone fm_lp: call sEraseBlock ;erase current block call _sWaitBusy add [_gSectorPN_L],b[_gPageSize] addc b[_gSectorPN_H],0 dec r6 ;whole flash device jnz fm_lp mov r5,56 mov r8,DATA0 mov r9,CIS mov r11,(DATA0+0x100) @@: mov [r8++],[r9] mov [r11++],[r9++] dec r5 jnz @b mov r5,72 @@: xor [r8++],[r8] xor [r11++],[r11] dec r5 jnz @b mov r8,_gRedunt mov r9,CIS_r addi r5,8 @@: mov [r8++],[r9++] dec r5 jnz @b mov [_gSectorPN_L],r5 mov b[_gSectorPN_H],r5 mov b[rCMD],0x80 ;Set Address for Writing call _sSetAdd0 mov r8,DATA0 call _Write512 ;Write DATA call _Write16 ;Write redundant DATA call sWritePage ;Enable the Write Command xor r7,r7 jmp _sWaitBusy CIS: dw 0x0301 dw 0x01d9 dw 0x18ff dw 0xdf02 dw 0x2001 dw 0x0004 dw 0x0000 dw 0x2100 dw 0x0402 dw 0x2201 dw 0x0102 dw 0x2201 dw 0x0203 dw 0x0704 dw 0x051a dw 0x0301 dw 0x0200 dw 0x1b0f dw 0xc008 dw 0xa1c0 dw 0x5501 dw 0x0008 dw 0x1b20 dw 0xc10a dw 0x9941 dw 0x5501 dw 0xf064 dw 0xffff dw 0x1b20 dw 0x820c dw 0x1841 dw 0x61ea dw 0x01f0 dw 0xf607 dw 0x0103 dw 0x1bee dw 0x830c dw 0x1841 dw 0x61ea dw 0x0170 dw 0x7607 dw 0x0103 dw 0x15ee dw 0x0514 dw 0x2000 dw 0x2020 dw 0x2020 dw 0x2020 dw 0x2000 dw 0x2020 dw 0x0020 dw 0x2e30 dw 0x0030 dw 0x14ff dw 0xff00 dw 0x0000 CIS_r: dw 0xffff dw 0xffff dw 0xffff dw 0x0000 dw 0xcc0c dw 0x00c3 dw 0x0c00 dw 0xc3cc code_end: IRAM4_E: err<z (IRAM3Size - (IRAM3_E-IRAM3_S)-(IRAM4_E-IRAM4_S)-(cMAXSIZE+cVars_Used)) ; check if go over limited reloc_off err<z (I2CSize - $) |
|
|
5楼#
发布于:2004-06-15 08:49
给你一段东芝flash的读写代码吧!没有什么难的!!
void Read_Flash_16(LBA lba) { char idata temp; int xdata i; // //printf("\nInter the flash read program"); i=0; LED=0; //SEND THE COMMAND 00 TO THE FLASH CE=0; CLE=1; XBYTE[FLASH]=0X50; CLE=0; //SEND ADDRESS TO THE FLASH ALE=1; XBYTE[FLASH]=(unsigned char)lba.A1; XBYTE[FLASH]=(unsigned char)lba.A2;//low XBYTE[FLASH]=(unsigned char)lba.A3;//high ALE=0; while(RY!=READY); //READ DATA FROM THE FLASH TO THE DATABUF for(i=0;i<=15;i++) { temp=XBYTE[FLASH]; buffer_16=temp; } CE=1; LED=1; set_flash_point(); } |
|
6楼#
发布于:2004-06-15 21:15
在本站的源代码下摘区有个DSP做的U盘+MP3的固件,里面肯定有FLASH读写的源代码,你用MP3关键字搜
|
|
7楼#
发布于:2004-06-16 21:01
对各位无私的大无畏的精神,表示崇高的敬意。并保证想你们学习。
谢谢。非常感谢。 |
|
|
8楼#
发布于:2004-06-18 13:28
各位兄弟姐妹 帮帮忙吧 !
能否贴个三星的存储器的程序来瞧瞧。 就差一步了。 |
|
|
9楼#
发布于:2004-06-18 15:03
我给你个
呵呵 不过没写的很全 只有单字节写的 你自己慢慢的玩ba 兄弟 TC58v32 K9F3208 呵呵 兼容的 |
|
|
10楼#
发布于:2004-06-21 19:52
资源越多 就越好啊
对大家都有利 同意的就发贴吧 让这个帖子成为精华 还需要各位的鼎立支持啊 |
|
|
11楼#
发布于:2004-06-21 21:40
我师兄上学期将三星的kf2808的程序调通,16MB的!其实,程序很简单的,你看一下芯片的技术文档就行了,里面的编程流程都有!但是不同的单片机作控制,程序就不一样,这主要是时序的问题,不过这很费时的。有一点,很关键,就是单片机和flash芯片之间的驱动要配合好,这是最关键的!只要将这一点把握好,什么问题都迎刃而解。还有,别人给你的程序,要是单片机不一样,程序给你也没有用。自己下一点工夫吧!!!
|
|
12楼#
发布于:2004-08-23 11:01
进行写操作时,先发送写命令,然后是地址,在是数据,最后发确认命令,这里的数据,我应该送多少个呢?如果是A区,需要送256个,我送两百个,结果会怎么样呢?能出现什么问题。
|
|
|