OSDN Git Service

V309 Modified APPEND" in the long run, clusters can become non-contiguous
[fast-forth/master.git] / forthMSP430FR_SD_INIT.asm
index 7444ba7..04c1a17 100644 (file)
@@ -30,7 +30,7 @@
 ; First sector of physical drive (sector 0) content :
 ; ---------------------------------------------------
 ; dec@| HEX@
-; 446 |0x1BE    : partition table first record  ==> logical drive 0       
+; 446 |0x1BE    : partition table first record  ==> logical drive 0
 ; 462 |0x1CE    : partition table 2th record    ==> logical drive 1
 ; 478 |0x1DE    : partition table 3th record    ==> logical drive 2
 ; 494 |0x1EE    : partition table 4th record    ==> logical drive 3
@@ -81,7 +81,7 @@
 ; First sector of physical drive (sector 0) content :
 ; ---------------------------------------------------
 ; dec@| HEX@
-; 446 |0x1BE    : partition table first record  ==> logical drive 0       
+; 446 |0x1BE    : partition table first record  ==> logical drive 0
 ; 462 |0x1CE    : partition table 2th record    ==> logical drive 1
 ; 478 |0x1DE    : partition table 3th record    ==> logical drive 2
 ; 494 |0x1EE    : partition table 4th record    ==> logical drive 3
@@ -91,7 +91,7 @@
 ; 450 |0x1C2 = 0x0C         : type FAT32 using LBA addressing
 ; 454 |0x1C6 = 00 20 00 00  : FirstSector (of logical drive 0) = BS_FirstSector = 8192
 
-; 
+;
 ; FirstSector of logical block (sector 0) content :
 ; -------------------------------------------------
 ; dec@| HEX@ =  HEX                                                       decimal
 
 ; 32  | 0x20 = 00 C0 EC 00  : BPB_TotSec32              BPB_TotSec32    = 15515648
 ; 36  | 0x24 = 30 3B 00 00  : BPB_FATSz32               BPB_FATSz32     = 15152
-; 40  | 0x28 = 00 00        : BPB_ExtFlags              BPB_ExtFlags 
+; 40  | 0x28 = 00 00        : BPB_ExtFlags              BPB_ExtFlags
 ; 44  | 0x2C = 02 00 00 00  : BPB_RootClus              BPB_RootClus    = 2
 ; 48  | 0x30 = 01 00        : BPB_FSInfo                BPB_FSInfo      = 1
 ; 50  | 0x33 = 06 00        : BPB_BkBootSec             BPB_BkBootSec   = 6
 ; 82  | 0x52 = "FAT32"      : BS_FilSysType             BS_FilSysType   (not used)
 
-; 
+;
 ; all values below are evaluated in logical sectors
 ; FAT1           = BPB_RsvdSecCnt = 32
 ; FAT2           = BPB_RsvdSecCnt + BPB_FATSz32 = 32 + 15152 = 15184
     .restore
 
 ; ===========================================================
-; Init hardware SD_Card, called by WARM
+; WARNING! SD_INIT DRAW BIG CURRENT; IF THE SUPPLY IS TOO WEAK
+; THE SD_CARD LOW VOLTAGE THRESHOLD MAY BE REACHED ==> SD_ERROR 4FF !
 ; ===========================================================
+
+; ===========================================================
+; Init SD_Card software, called by INIT_FORTH(INIT_SOFT_APP)
+; ===========================================================
+;-----------------------------------;
+INIT_SOFT_SD                        ; called by INI_FORTH common part of ?ABORT|RST
+;-----------------------------------;
+;            CMP #0,TOS              ; USERSYS = 0 ?
+;            JZ INIT_HSD_END         ; no hardware init if USERSYS = 0 SYS
+;            MOV #HandlesLen,X       ; clear all handles
+;ClearHandle SUB #2,X                ; 1
+;            MOV #0,FirstHandle(X)   ; 3
+;            JNZ ClearHandle         ; 2
+            MOV #0,&CurrentHdl      ;
+            MOV #INIT_SOFT_TERM,PC  ; link to previous INI_SOFT_APP then RET
 ;-----------------------------------;
-INIT_SD     CALL @PC+               ; link to previous INI_APP
-INIT_SD_PFA .word INIT_TERM         ; which activates all previous I/O settings and set TOS = RSTIV_MEM.
+
+; ===========================================================
+; Init hardware SD_Card, called by WARM(INIT_HARD_APP)
+; ===========================================================
+
+; web search: "SDA simplified specifications"
+
 ;-----------------------------------;
-            CMP #0,TOS              ; RSTIV_MEM = WARM ?
-            JZ INI_SD_END           ; no init if RSTIV_MEM = WARM
+INIT_HARD_SD CALL @PC+              ; link to previous INI_HARD_APP
+            .word INIT_TERM         ; which activates all previous I/O settings and set TOS = RSTIV_MEM.
 ;-----------------------------------;
             BIT.B #CD_SD,&SD_CDIN   ; SD_memory in SD_Card module ?
-            JNZ INI_SD_END          ; no
+            JNZ INIT_HSD_END        ; no
 ;-----------------------------------;
             MOV #0A981h,&SD_CTLW0   ; UCxxCTL1  = CKPH, MSB, MST, SPI_3, SMCLK  + UCSWRST
-            MOV #FREQUENCY*3,&SD_BRW; UCxxBRW init SPI CLK = 333 kHz ( < 400 kHz) for SD_Card initialisation
+            MOV #FREQUENCY*3,&SD_BRW; UCxxBRW init SPI CLK = 333 kHz ( <= 400 kHz) for SD_Card initialisation
             BIS.B #CS_SD,&SD_CSDIR  ; SD Chip Select as output high
             BIS #BUS_SD,&SD_SEL     ; Configure pins as SIMO, SOMI & SCK (PxDIR.y are controlled by eUSCI module)
             BIC #1,&SD_CTLW0        ; release eUSCI from reset
 ;-----------------------------------;
-        .IF RAM_LEN < 2048          ; case of MSP430FR57xx : SD datas are in FRAM not initialized by RESET.
-            MOV #SD_LEN,X           ; clear all SD datas                      
+            MOV #SD_LEN,X           ; clear all SD datas
 ClearSDdata SUB #2,X                ; 1
-            MOV #0,SD_ORG(X)        ; 3 
+            MOV #0,SD_ORG(X)        ; 3
             JNZ ClearSDdata         ; 2
-        .ENDIF                      ;
 ;-----------------------------------;
 SD_POWER_ON
 ; ----------------------------------;
-    MOV     #8,X                    ; send 64 clk on SD_clk
+    MOV     #8,X                    ; send 8*8 = 64 clk on SPI
     CALL    #SPI_X_GET              ;
     BIC.B   #CS_SD,&SD_CSOUT        ; preset Chip Select output low to switch in SPI mode
 ; ----------------------------------;
-INIT_CMD0                           ; all SD area is 0 filled
+INIT_CMD0                           ; SD_CMD_FRM+2 is already cleared...
 ; ----------------------------------;
     MOV     #4,S                    ; preset error 4R1 for CMD0
-    MOV     #95h,&SD_CMD_FRM        ; $(95 00 00 00 00 00)
-    MOV     #4000h,&SD_CMD_FRM+4    ; $(95 00 00 00 00 40); send CMD0 
+    MOV     #0095h,&SD_CMD_FRM      ; $(95 00 00 00 00 00)
+    MOV     #4000h,&SD_CMD_FRM+4    ; $(95 00 00 00 00 40) = CMD0
 ; ----------------------------------;
-SEND_CMD0                           ; CMD0 : GO_IDLE_STATE expected SPI_R1 response = 1 = idle state
+SEND_CMD0                           ; GO_IDLE_STATE, expected SPI_R1 response = 1 = idle state
 ; ----------------------------------;
-    CALL    #sendCommandIdleRet     ;X
+    CALL    #sendCommandIdleRet     ;X send command (does little to big endian conversion), see forthMSP430FR_SD_lowLvl.asm
     JZ      INIT_CMD8               ; if idle state
 SD_INIT_ERROR                       ;
     MOV     #SD_CARD_ERROR,PC       ; ReturnError = $04R1, case of defectuous card (or insufficient SD_POWER_ON clk)
@@ -175,9 +194,9 @@ INIT_CMD8                           ; mandatory if SD_Card >= V2.x     [11:8]sup
     MOV     #1,&SD_CMD_FRM+2        ; $(87 AA 01 00 ...)  (CRC:CHECK PATTERN:VHS set as 2.7to3.6V:0)
     MOV     #4800h,&SD_CMD_FRM+4    ; $(87 AA 01 00 00 48)
 ; ----------------------------------;
-SEND_CMD8                           ; CMD8 = SEND_IF_COND; expected R1 response (first byte of SPI R7) = 01h : idle state
+SEND_CMD8                           ; SEND_IF_COND; expected R1 response (first byte of SPI R7) = 01h : idle state
 ; ----------------------------------;
-    CALL    #sendCommandIdleRet     ;X time out occurs with SD_Card V1.x (and all MMC_card) 
+    CALL    #sendCommandIdleRet     ;X time out occurs with SD_Card V1.x (and all MMC_card)
 ; ----------------------------------;
     MOV     #4,X                    ; skip end of SD_Card V2.x type R7 response (4 bytes), because useless
     CALL    #SPI_X_GET              ;WX
@@ -186,7 +205,7 @@ INIT_ACMD41                         ; no more CRC needed from here
 ; ----------------------------------;
     MOV     #1,&SD_CMD_FRM          ; $(01 00 ...   set stop bit
     MOV     #0,&SD_CMD_FRM+2        ; $(01 00 00 00 ...
-;    MOV.B   #16,Y                   ; init 16 * ACMD41 repeats (power on fails with SanDisk ultra 8GB "HC I" and Transcend 2GB)
+;    MOV.B   #16,Y                   ; init 16 * ACMD41 repeats (fails with SanDisk ultra 8GB "HC I" and Transcend 2GB)
 ;    MOV.B   #32,Y                   ; init 32 * ACMD41 repeats ==> ~400ms time out
     MOV.B   #-1,Y                   ; init 255 * ACMD41 repeats ==> ~3 s time out
     MOV     #8,S                    ; preset error 8R1 for ACMD41
@@ -210,94 +229,64 @@ setBLockLength                      ; set block = 512 bytes (buffer size), usefu
     ADD     S,S                     ; preset error $10 for CMD16
 SEND_CMD16                          ; CMD16 = SET_BLOCKLEN
     MOV     #02h,&SD_CMD_FRM+2      ; $(01 00 02 00 ...)
-    MOV     #5000h,&SD_CMD_FRM+4    ; $(01 00 02 00 00 50) 
+    MOV     #5000h,&SD_CMD_FRM+4    ; $(01 00 02 00 00 50)
     CALL    #WaitIdleBeforeSendCMD  ; wait until idle then send CMD16
     JNZ     SD_INIT_ERROR           ; if W = R1 <> 0, ReturnError = $20R1 ; send command ko
 ; ----------------------------------; W = R1 = 0
 SwitchSPIhighSpeed                  ; end of SD init ==> SD_CLK = SMCLK
 ; ----------------------------------;
-    BIS     #1,&SD_CTLW0            ; Software reset
+    BIS     #1,&SD_CTLW0            ; UC Software reset
     MOV     #0,&SD_BRW              ; UCxxBRW = 0 ==> SPI_CLK = MCLK
     BIC     #1,&SD_CTLW0            ; release from reset
 ; ----------------------------------;
-Read_EBP_FirstSector                ; W=0, BS_FirstSectorHL=0
+Read_EBP_FirstSector                ; BS_FirstSectorHL=0
 ; ----------------------------------;
+    MOV     #0,W                    ;
     MOV     #0,X                    ;
-    CALL    #readSectorWX           ; read physical first sector
+    CALL    #readSectorWX           ; read physical first sector, W=0
     MOV     #SD_BUF,Y               ;
-    MOV     454(Y),&BS_FirstSectorL ; so, sectors become logical
-    MOV     456(Y),&BS_FirstSectorH ; 
-    MOV.B   450(Y),W                ; W = partition ID 
+    MOV     454(Y),&BS_FirstSectorL ; so, from here, sectors become logical
+    MOV     456(Y),&BS_FirstSectorH ;
+    MOV.B   450(Y),S                ; S = partition ID
 ; ----------------------------------;
 TestPartitionID                     ;
 ; ----------------------------------;
-    MOV     #1,&FATtype             ; preset FAT16
-FAT16_CHS_LBA_Test                  ;
-    SUB.B   #6,W                    ; ID=06h Partition FAT16 > 32MB using CHS & LBA ?
-    JZ      Read_MBR_FirstSector    ; W = 0
-FAT16_LBA_Test                      ;
-    SUB.B   #8,W                    ; ID=0Eh Partition FAT16 using LBA ?
-    JZ      Read_MBR_FirstSector    ; W = 0
+    SUB.B   #0Ch,S                  ; ID=0Ch Partition FAT32 using LBA ?
+    JZ      Read_MBR_FirstSector    ;
+    ADD.B   #1,S                    ; ID=0Bh Partition FAT32 using CHS & LBA ?
+    JZ      Read_MBR_FirstSector    ;
+    ADD.B   #4,S                    ; ID=07h assigned to FAT 32 by MiniTools Partition Wizard....
+    JZ      Read_MBR_FirstSector    ;
+    ADD     #02007h,S               ; set ReturnError = $20 & restore ID value
+    MOV     #SD_CARD_ID_ERROR,PC    ; see: https://en.wikipedia.org/wiki/Partition_type
 ; ----------------------------------;
-    MOV     #2,&FATtype             ; set FAT32
-FAT32_LBA_Test                      ;
-    ADD.B   #2,W                    ; ID=0Ch Partition FAT32 using LBA ?
-    JZ      Read_MBR_FirstSector    ; W = 0
-FAT32_CHS_LBA_Test                  ;
-    ADD.B   #1,W                    ; ID=0Bh Partition FAT32 using CHS & LBA ?
-    JZ      Read_MBR_FirstSector    ; W = 0
-    ADD.B   #4,W                    ; ID=07h assigned to FAT 32 by MiniTools Partition Wizard....
-    JZ      Read_MBR_FirstSector    ; W = 0
-    ADD     #0200Bh,W               ;
-    MOV     W,S                     ;
-    MOV     #SD_CARD_ID_ERROR,PC    ; S = ReturnError = $20xx with xx = partition ID 
-; ----------------------------------; see: https://en.wikipedia.org/wiki/Partition_type
 Read_MBR_FirstSector                ; read first logical sector
-; ----------------------------------; W = 0
-    MOV     #0,X                    ;
+; ----------------------------------;
+    MOV     #0,X                    ; W = 0
     CALL    #readSectorWX           ; ...with the good CMD17 bytes/sectors frame ! (good switch FAT16/FAT32)
 ; ----------------------------------;
 FATxx_SetFileSystem                 ;
 ; ----------------------------------;
-    MOV.B   13(Y),&SecPerClus       ;
-    MOV     14(Y),X                 ;3 X = BPB_RsvdSecCnt
+;    MOV     44(Y),&DIRClusterL      ; init DIRcluster as FAT32 RootDIR
+    MOV     #2,&DIRClusterL         ; init DIRcluster as FAT32 RootDIR
+; ----------------------------------;
+    MOV     14(Y),X                 ;3 X = BPB_RsvdSecCnt (05FEh=1534)
     MOV     X,&OrgFAT1              ;3 set OrgFAT1
-    MOV     22(Y),W                 ; W = BPB_FATsize
-    CMP     #0,W                    ; BPB_FATsize <> 0 ?
-    JNZ     Set_FATsize             ; yes
-    MOV     36(Y),W                 ; W = BPB_FATSz32
-Set_FATsize                         ;
-    MOV     W,&FATSize              ; limited to 16384 sectors....
+; ----------------------------------;
+    MOV     36(Y),W                 ; no set W = BPB_FATSz32 (1D01h=7425)
+    MOV     W,&FATSize              ; limited to 32767 sectors....
+; ----------------------------------;
     ADD     W,X                     ;
-    MOV     X,&OrgFAT2              ; X = OrgFAT1 + FATsize = OrgFAT2
-    ADD     W,X                     ; X = OrgFAT2 + FATsize = FAT16 OrgRootDir | FAT32 OrgDatas
-    CMP     #2,&FATtype             ; FAT32?
-    JZ      FATxx_SetFileSystemNext ; yes
-FAT16_SetRootCluster                ;
-    MOV     X,&OrgRootDIR           ; only FAT16 use, is a sector used by ComputeClusFrstSect
-    ADD     #32,X                   ; OrgRootDir + RootDirSize = OrgDatas
+    MOV     X,&OrgFAT2              ; X = OrgFAT1 + FATsize = OrgFAT2 (8959)
+; ----------------------------------;
+    ADD     W,X                     ; X = OrgFAT2 + FATsize = FAT32 OrgDatas (16384)
 FATxx_SetFileSystemNext             ;
-    SUB     &SecPerClus,X           ; OrgDatas - SecPerClus*2 = OrgClusters
-    SUB     &SecPerClus,X           ; no borrow expected
+    MOV.B   13(Y),Y                 ; Logical sectors per cluster (8)
+    MOV     Y,&SecPerClus           ;
+    SUB     Y,X                     ; OrgDatas - SecPerClus*2 = OrgClusters
+    SUB     Y,X                     ; no borrow expected
     MOV     X,&OrgClusters          ; X = virtual cluster 0 address (clusters 0 and 1 don't exist)
-    MOV     &FATtype,&DIRClusterL   ; init DIRcluster as RootDIR
-INI_SD_END                          ;
-    MOV @RSP+,PC                    ; RET
+INIT_HSD_END                        ;
+    MOV     @RSP+,PC                ; RET
 ;-----------------------------------;
 
-; ===========================================================
-; Init FORTH SD_Card, called by ?ABORT|RST
-; ===========================================================
-;-----------------------------------; 
-INI_FORTH_SD                        ; common part of ?ABORT|RST
-;-----------------------------------;
-            CALL @PC+               ; link to previous INI_FORTH_APP
-RSAB_SD_PFA .word RET_ADR           ; which does nothing
-;-----------------------------------;
-            MOV #HandlesLen,X       ; clear all handles                      
-ClearHandle SUB #2,X                ; 1
-            MOV #0,FirstHandle(X)   ; 3 
-            JNZ ClearHandle         ; 2
-            MOV #0,&CurrentHdl      ;
-            MOV @RSP+,PC            ; RET
-;-----------------------------------;