OSDN Git Service

encore un lot de bogues... corrigées
[fast-forth/master.git] / forthMSP430FR_SD_INIT.asm
1 ; -*- coding: utf-8 -*-
2 ; forthMSP430FR_SD_INIT.asm
3
4 ; http://patorjk.com/software/taag/#p=display&f=Banner&t=Fast Forth
5
6 ; Fast Forth For Texas Instrument MSP430FRxxxx FRAM devices
7 ; Copyright (C) <2017>  <J.M. THOORENS>
8 ;
9 ; This program is free software: you can redistribute it and/or modify
10 ; it under the terms of the GNU General Public License as published by
11 ; the Free Software Foundation, either version 3 of the License, or
12 ; (at your option) any later version.
13 ;
14 ; This program is distributed in the hope that it will be useful,
15 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ; GNU General Public License for more details.
18 ;
19 ; You should have received a copy of the GNU General Public License
20 ; along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22 ; ===========================================================
23 ; ABOUT INIT SD_CARD AND HOW TO SELECT FAT16/FAT32 FORMAT
24 ; ===========================================================
25 ; FAT16/FAT32 selection is made via the ID of partition in EBP
26 ; because SD must be always FAT16 and SDHC must be always FAT32
27 ; this is automatically done when we format the SD_Card !
28
29
30 ; =====================================================================
31 ; goal : accept 64 MB up to 64 GB SD_CARD
32 ; =====================================================================
33 ; thus FAT and RootClus logical sectors are word addressable.
34
35 ; FAT is a little endian structure.
36 ; CMD frame is sent as big endian.
37
38 ; we assume that SDSC Card (up to 2GB) is FAT16 with a byte addressing
39 ; and that SDHC Card (4GB up to 64GB) is FAT32 with a sector addressing (sector = 512 bytes)
40 ; for SDHC Card = 64 GB, cluster = 64 sectors ==> max clusters = 20 0000h ==> FAT size = 16384 sectors
41 ; ==> FAT1 and FAT2 can be addressed with a single word.
42
43 ; ref. https://en.wikipedia.org/wiki/Extended_boot_record
44 ; ref. https://en.wikipedia.org/wiki/Partition_type
45
46 ; Formatage FA16 d'une SDSC Card 2GB
47 ; First sector of physical drive (sector 0) content :
48 ; ---------------------------------------------------
49 ; dec@| HEX@
50 ; 446 |0x1BE    : partition table first record  ==> logical drive 0       
51 ; 462 |0x1CE    : partition table 2th record    ==> logical drive 1
52 ; 478 |0x1DE    : partition table 3th record    ==> logical drive 2
53 ; 494 |0x1EE    : partition table 4th record    ==> logical drive 3
54
55 ; partition of first record content :
56 ; ---------------------------------------------------
57 ; 450 |0x1C2 = 0x0E         : type FAT16 using LBA addressing
58 ; 454 |0x1C6 = 89 00 00 00  : FirstSector (of logical drive 0) BS_FirstSector  = 137
59
60
61 ; Partition type Description
62 ; 0         empty / unused
63 ; 1         FAT12
64 ; 4         FAT16 for partitions <= 32 MiB
65 ; 5         extended partition
66 ; 6         FAT16 for partitions > 32 MiB
67 ; 11    FAT32 for partitions <= 2 GiB
68 ; 12    Same as type 11 (FAT32), but using LBA addressing, which removes size constraints
69 ; 14    Same as type 6 (FAT16), but using LBA addressing
70 ; 15    Same as type 5, but using LBA addressing
71 ; ref. https://www.compuphase.com/mbr_fat.htm#BOOTSECTOR
72
73 ; FirstSector of logical drive (sector 0) content :
74 ; -------------------------------------------------
75 ; dec@| HEX@ =  HEX                                                       decimal
76 ; 11  | 0x0B = 00 02        : 512 bytes/sector          BPB_BytsPerSec  = 512
77 ; 13  | 0x0D = 40           : 64 sectors/cluster        BPB_SecPerClus  = 64
78 ; 14  | 0x0E = 01 00        : 2 reserved sectors        BPB_RsvdSecCnt  = 1
79 ; 16  | 0x10 = 02           : 2 FATs                    BPB_NumFATs     = 2 (always 2)
80 ; 17  | 0x11 = 00 02        : 512 entries/directory     BPB_RootEntCnt  = 512
81 ; 19  | 0x13 = 00 00        : BPB_TotSec16 (if < 65535) BPB_TotSec16    = 0
82 ; 22  | 0x16 = EB 00        : 235 sectors/FAT (FAT16)   BPB_FATSize     = 235
83 ; 32  | 0x20 = 77 9F 3A 00  : ‭3841911‬ total sectors     BPB_TotSec32    = ‭3841911‬
84 ; 54  | 0x36 = "FAT16"                                  BS_FilSysType   (not used)
85
86 ; all values below are evaluated in logical sectors
87 ; FAT1           = BPB_RsvdSecCnt = 1
88 ; FAT2           = BPB_RsvdSecCnt + BPB_FATSz32 = 1 + 235 = 236
89 ; OrgRootDirL    = BPB_RsvdSecCnt + (BPB_FATSize * BPB_NumFATs) = 471
90 ; RootDirSize    = BPB_RootEntCnt * 32 / BPB_BytsPerSec         = 32 sectors
91 ; OrgDatas       = OrgRootDir + RootDirSize                     = 503
92 ; OrgCluster     = OrgRootDir - 2*BPB_SecPerClus                = 375 (virtual value)
93 ; FirstSectorOfCluster(n) = OrgCluster + n*BPB_SecPerClus       ==> cluster(3) = 705
94
95 ; ====================================================================================
96
97 ; Formatage FA32 d'une SDSC Card 8GB
98 ; First sector of physical drive (sector 0) content :
99 ; ---------------------------------------------------
100 ; dec@| HEX@
101 ; 446 |0x1BE    : partition table first record  ==> logical drive 0       
102 ; 462 |0x1CE    : partition table 2th record    ==> logical drive 1
103 ; 478 |0x1DE    : partition table 3th record    ==> logical drive 2
104 ; 494 |0x1EE    : partition table 4th record    ==> logical drive 3
105
106 ; partition record content :
107 ; ---------------------------------------------------
108 ; 450 |0x1C2 = 0x0C         : type FAT32 using LBA addressing
109 ; 454 |0x1C6 = 00 20 00 00  : FirstSector (of logical drive 0) = BS_FirstSector = 8192
110
111
112 ; FirstSector of logical block (sector 0) content :
113 ; -------------------------------------------------
114 ; dec@| HEX@ =  HEX                                                       decimal
115 ; 11  | 0x0B = 00 02        : 512 bytes/sector          BPB_BytsPerSec  = 512
116 ; 13  | 0x0D = 08           : 8 sectors/cluster         BPB_SecPerClus  = 8
117 ; 14  | 0x0E = 20 00        : 32 reserved sectors       BPB_RsvdSecCnt  = 32
118 ; 16  | 0x10 = 02           : 2 FATs                    BPB_NumFATs     = 2 (always 2)
119 ; 17  | 0x11 = 00 00        : 0                         BPB_RootEntCnt  = 0 (always 0 for FAT32)
120
121 ; 32  | 0x20 = 00 C0 EC 00  : BPB_TotSec32              BPB_TotSec32    = 15515648
122 ; 36  | 0x24 = 30 3B 00 00  : BPB_FATSz32               BPB_FATSz32     = 15152
123 ; 40  | 0x28 = 00 00        : BPB_ExtFlags              BPB_ExtFlags 
124 ; 44  | 0x2C = 02 00 00 00  : BPB_RootClus              BPB_RootClus    = 2
125 ; 48  | 0x30 = 01 00        : BPB_FSInfo                BPB_FSInfo      = 1
126 ; 50  | 0x33 = 06 00        : BPB_BkBootSec             BPB_BkBootSec   = 6
127 ; 82  | 0x52 = "FAT32"      : BS_FilSysType             BS_FilSysType   (not used)
128
129
130 ; all values below are evaluated in logical sectors
131 ; FAT1           = BPB_RsvdSecCnt = 32
132 ; FAT2           = BPB_RsvdSecCnt + BPB_FATSz32 = 32 + 15152 = 15184
133 ; OrgRootDirL    = BPB_RsvdSecCnt + BPB_FATSz32 * BPB_NumFATs = 32 + 15152*2 = 30336
134 ; OrgCluster     = OrgRootDir - 2*BPB_SecPerClus = 30320
135 ; RootDirSize    = BPB_RootEntCnt * 32 / BPB_BytsPerSec         = 0
136 ; OrgDatas       = OrgRootDir + RootDirSize                     = 30336
137 ; FirstSectorOfCluster(n) = OrgCluster + n*BPB_SecPerClus       ==> cluster(6) = 30368
138
139 ; ===========================================================
140 ; 0- Init FRAM SD datas, case of MSP430FR57xx
141 ; ===========================================================
142
143     .IFDEF RAM_1K               ; case of MSP430FR57xx : SD datas are in FRAM
144         MOV #SD_LEN_DATA,X      ; so are not initialised by COLD/RESET
145 InitSDdata                      ;
146         SUB #2,X
147         MOV #0,SD_ORG_DATA(X)   ;
148         JNZ InitSDdata          ;
149     .ENDIF
150
151 ; ===========================================================
152 ; 1- Init eUSCI dedicated to SD_Card SPI driver
153 ; ===========================================================
154
155     MOV #0A981h,&SD_CTLW0           ; UCxxCTL1  = CKPH, MSB, MST, SPI_3, SMCLK  + UCSWRST
156     MOV #FREQUENCY*3,&SD_BRW        ; UCxxBRW init SPI CLK = 333 kHz ( < 400 kHz) for SD_Card init
157     BIS.B #SD_CS,&SD_CSDIR          ; SD_CS as output high
158     BIS #SD_BUS,&SD_SEL             ; Configure pins as SIMO, SOMI & SCK (PxDIR.y are controlled by eUSCI module)
159 ;    BIC #SD_BUS,&SD_REN             ; disable pullup resistors for SIMO/SOMI/SCK pins
160     BIC #1,&SD_CTLW0                ; release eUSCI from reset
161
162 ; ===========================================================
163 ; 2- Init SD_Card
164 ; ===========================================================
165
166 SD_POWER_ON
167     MOV     #8,X                    ; send 64 clk on SD_clk
168     CALL    #SPI_X_GET              ;
169     BIC.B   #SD_CS,&SD_CSOUT        ; preset SD_CS output low to switch in SPI mode
170     MOV     #4,S                    ; preset error 4R1
171 ; ----------------------------------;
172 INIT_CMD0                           ; all SD area is 0 filled
173 ; ----------------------------------;
174     MOV     #95h,&SD_CMD_FRM        ; $(95 00 00 00 00 00)
175     MOV     #4000h,&SD_CMD_FRM+4    ; $(95 00 00 00 00 40); send CMD0 
176 ; ----------------------------------;
177 SEND_CMD0                           ; CMD0 : GO_IDLE_STATE expected SPI_R1 response = 1 = idle state
178 ; ----------------------------------;
179     CALL    #sendCommandIdleRet     ;X
180     JZ      INIT_CMD8               ; if idle state
181 SD_INIT_ERROR                       ;
182     MOV     #SD_CARD_ERROR,PC       ; ReturnError = $04R1, case of defectuous card (or insufficient SD_POWER_ON clk)
183 ; ----------------------------------;
184 INIT_CMD8                           ; mandatory if SD_Card >= V2.x     [11:8]supply voltage(VHS)
185 ; ----------------------------------;
186     CALL    #SPI_GET                ; (needed to pass SanDisk ultra 8GB "HC I")
187     CMP.B   #-1,W                   ; FFh expected value <==> MISO = high level
188     JNE     INIT_CMD8               ; loop back while yet busy
189     MOV     #0AA87h,&SD_CMD_FRM     ; $(87 AA ...)  (CRC:CHECK PATTERN)
190     MOV     #1,&SD_CMD_FRM+2        ; $(87 AA 01 00 ...)  (CRC:CHECK PATTERN:VHS set as 2.7to3.6V:0)
191     MOV     #4800h,&SD_CMD_FRM+4    ; $(87 AA 01 00 00 48)
192 ; ----------------------------------;
193 SEND_CMD8                           ; CMD8 = SEND_IF_COND; expected R1 response (first byte of SPI R7) = 01h : idle state
194 ; ----------------------------------;
195     CALL    #sendCommandIdleRet     ;X time out occurs with SD_Card V1.x (and all MMC_card) 
196 ; ----------------------------------;
197     MOV     #4,X                    ; skip end of SD_Card V2.x type R7 response (4 bytes), because useless
198     CALL    #SPI_X_GET              ;WX
199 ; ----------------------------------;
200 INIT_ACMD41                         ; no more CRC needed from here
201 ; ----------------------------------;
202     MOV     #1,&SD_CMD_FRM          ; $(01 00 ...   set stop bit
203     MOV     #0,&SD_CMD_FRM+2        ; $(01 00 00 00 ...
204 ;    MOV.B   #16,Y                   ; init 16 * ACMD41 repeats (power on fails with SanDisk ultra 8GB "HC I" and Transcend 2GB)
205 ;    MOV.B   #32,Y                   ; init 32 * ACMD41 repeats ==> ~400ms time out
206     MOV.B   #-1,Y                   ; init 255 * ACMD41 repeats ==> ~3 s time out
207 ; ----------------------------------;
208 SEND_ACMD41                         ; send CMD55+CMD41
209 ; ----------------------------------;
210     MOV     #8,S                    ; preset error 8R1 for ACMD41
211 INIT_CMD55                          ;
212     MOV     #7700h,&SD_CMD_FRM+4    ; $(01 00 00 00 00 77)
213 SEND_CMD55                          ; CMD55 = APP_CMD; expected SPI_R1 response = 1 : idle
214     CALL    #sendCommandIdleRet     ;X
215 SEND_CMD41                          ; CMD41 = APP OPERATING CONDITION
216     MOV     #6940h,&SD_CMD_FRM+4    ; $(01 00 00 00 40 69) (30th bit = HCS = High Capacity Support request)
217     CALL    #WaitIdleBeforeSendCMD  ; wait until idle (needed to pass SanDisk ultra 8GB "HC I") then send Command CMD41
218     JZ      SetBLockLength          ; if SD_Card ready (R1=0)
219     SUB.B   #1,Y                    ; else decr time out delay
220     JNZ     INIT_CMD55              ; then loop back while count of repeat not reached
221     JMP     SD_INIT_ERROR           ; ReturnError on time out : unusable card
222 ; ----------------------------------;
223 setBLockLength                      ; set block = 512 bytes (buffer size), usefull only for FAT16 SD Cards
224 ; ----------------------------------;
225     ADD     S,S                     ; preset error $10 for CMD16
226 SEND_CMD16                          ; CMD16 = SET_BLOCKLEN
227     MOV     #02h,&SD_CMD_FRM+2      ; $(01 00 02 00 ...)
228     MOV     #5000h,&SD_CMD_FRM+4    ; $(01 00 02 00 00 50) 
229     CALL    #WaitIdleBeforeSendCMD  ; wait until idle then send CMD16
230     JNZ     SD_INIT_ERROR           ; if W = R1 <> 0, ReturnError = $20R1 ; send command ko
231 ; ----------------------------------;
232 SetHighSpeed                        ; end of SD init ==> SD_CLK = SMCLK
233 ; ----------------------------------;
234     BIS     #1,&SD_CTLW0            ; Software reset
235     MOV     #0,&SD_BRW              ; UCxxBRW = 0 ==> SPI_CLK = MCLK
236     BIC     #1,&SD_CTLW0            ; release from reset
237 ; ----------------------------------;
238 Read_EBP_FirstSector                ; W=0, BS_FirstSectorHL=0
239 ; ----------------------------------;
240     CALL    #readSectorW            ; read physical first sector
241     MOV     #SD_BUF,Y               ;
242     MOV     454(Y),&BS_FirstSectorL ; so, sectors become logical
243     MOV     456(Y),&BS_FirstSectorH ; 
244     MOV.B   450(Y),W                ; W = partition ID 
245 ; ----------------------------------;
246 TestPartitionID                     ;
247 ; ----------------------------------;
248     MOV     #1,&FATtype             ; preset FAT16
249 FAT16_CHS_LBA_Test                  ;
250     SUB.B   #6,W                    ; ID=06h Partition FAT16 using CHS & LBA ?
251     JZ      Read_MBR_FirstSector    ; W = 0
252 FAT16_LBA_Test                      ;
253     SUB.B   #8,W                    ; ID=0Eh Partition FAT16 using LBA ?
254     JZ      Read_MBR_FirstSector    ; W = 0
255 ; ----------------------------------;
256     MOV     #2,&FATtype             ; set FAT32
257 FAT32_LBA_Test                      ;
258     ADD.B   #2,W                    ; ID=0Ch Partition FAT32 using LBA ?
259     JZ      Read_MBR_FirstSector    ; W = 0
260 FAT32_CHS_LBA_Test                  ;
261     ADD.B   #1,W                    ; ID=0Bh Partition FAT32 using CHS & LBA ?
262     JZ      Read_MBR_FirstSector    ; W = 0
263     ADD     #0200Bh,W               ;
264     MOV     W,S                     ;
265     MOV     #SD_CARD_ID_ERROR,PC    ; S = ReturnError = $20xx with xx = partition ID 
266 ; ----------------------------------; see: https://en.wikipedia.org/wiki/Partition_type
267 Read_MBR_FirstSector                ; read first logical sector
268 ; ----------------------------------;
269     CALL    #readSectorW            ; ...with the good CMD17 bytes/sectors frame ! (good switch FAT16/FAT32)
270 ; ----------------------------------;
271 FATxx_SetFileSystem                 ;
272 ; ----------------------------------;
273     MOV.B   13(Y),&SecPerClus       ;
274     MOV     14(Y),X                 ;3 X = BPB_RsvdSecCnt
275     MOV     X,&OrgFAT1              ;3 set OrgFAT1
276     MOV     22(Y),W                 ; W = BPB_FATsize
277     CMP     #0,W                    ; BPB_FATsize <> 0 ?
278     JNZ     Set_FATsize             ; yes
279     MOV     36(Y),W                 ; W = BPB_FATSz32
280 Set_FATsize                         ;
281     MOV     W,&FATSize              ; limited to 16384 sectors....
282     ADD     W,X                     ;
283     MOV     X,&OrgFAT2              ; X = OrgFAT1 + FATsize = OrgFAT2
284     ADD     W,X                     ; X = OrgFAT2 + FATsize = FAT16 OrgRootDir | FAT32 OrgDatas
285     CMP     #2,&FATtype             ; FAT32?
286     JZ      FATxx_SetFileSystemNext ; yes
287 FAT16_SetRootCluster                ;
288     MOV     X,&OrgRootDIR           ; only FAT16 use, is a sector used by ComputeClusFrstSect
289     ADD     #32,X                   ; OrgRootDir + RootDirSize = OrgDatas
290 FATxx_SetFileSystemNext             ;
291     SUB     &SecPerClus,X           ; OrgDatas - SecPerClus*2 = OrgClusters
292     SUB     &SecPerClus,X           ; no borrow expected
293     MOV     X,&OrgClusters          ; X = virtual cluster 0 address (clusters 0 and 1 don't exist)
294     MOV     &FATtype,&DIRClusterL   ; init DIRcluster as RootDIR
295 ; ----------------------------------;
296
297