OSDN Git Service

bug bug bug...
[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 FORMATTING
24 ; ===========================================================
25 ; FAT16/FAT32 selection is done via the ID of partition in EBP, because SD must be always FAT16 and SDHC must be always FAT32
26 ; So we assume that the SD_Card FAT16/FAT32 formatting was done well !
27
28
29 ; ===========================================================
30 ; 1- Init eUSCI dedicated to SD_Card SPI driver
31 ; ===========================================================
32
33     MOV     #0A981h,&SD_CTLW0       ; UCxxCTL1  = CKPH, MSB, MST, SPI_3, SMCLK  + UCSWRST
34     MOV     #FREQUENCY*3,&SD_BRW    ; UCxxBRW init SPI CLK = 333 kHz ( < 400 kHz) for SD_Card init
35
36
37     .IFDEF MSP_EXP430FR5739 
38
39 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
40
41 ; P2.2 - RF.16                  <--- CD  SD_CardAdapter (Card Detect)
42 SD_CD           .equ  4
43 SD_CDIN         .equ  P2IN
44 ; P2.3 - RF.10                  ---> CS  SD_CardAdapter (Card Select)
45 SD_CS           .equ  8
46 SD_CSOUT        .equ  P2OUT
47     BIS.B #SD_CS,&P2DIR ; SD_CS output high
48
49 ; P2.4 - RF.14 UCA1 CLK         ---> CLK SD_CardAdapter (SCK)  
50 ; P2.5 - RF.7  UCA1 TXD/SIMO    ---> SDI SD_CardAdapter (MOSI)
51 ; P2.6 - RF.5  UCA1 RXD/SOMI    <--- SDO SD_CardAdapter (MISO)
52     BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
53                         ; P2DIR.x is controlled by eUSCI_A0 module
54     BIC.B #070h,&P2REN  ; disable pullup resistors for SIMO/SOMI/SCK pins
55
56     .ENDIF
57     .IFDEF MSP_EXP430FR5969 
58
59 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
60
61 ; P4.2                <--- SD_CD (Card Detect)
62 SD_CD           .equ  4
63 SD_CDIN         .equ  P4IN
64 ; P4.3                ---> SD_CS (Card Select)
65 SD_CS           .equ  8
66 SD_CSOUT        .equ  P4OUT
67     BIS.B #SD_CS,&P4DIR  ; SD_CS output high
68
69 ; P2.4  UCA1     CLK  ---> SD_CLK
70 ; P2.5  UCA1 TX/SIMO  ---> SD_SDI
71 ; P2.6  UCA1 RX/SOMI  <--- SD_SDO
72     BIS.B   #070h,  &P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
73                             ; P2DIR.x is controlled by eUSCI_A0 module
74     BIC.B   #070h,  &P2REN  ; disable pullup resistors for SIMO/SOMI/SCK pins
75
76     .ENDIF
77     .IFDEF MSP_EXP430FR5994 
78
79 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
80
81 ; P7.2/UCB2CLK                        - SD_CD (Card Detect)
82 SD_CD           .equ  4 ; P7.2
83 SD_CDIN         .equ  P7IN
84 ; P4.0/A8                             - SD_CS (Card Select)
85 SD_CS           .equ  1 ; P4.0
86 SD_CSOUT        .equ  P4OUT
87     BIS.B #SD_CS,&P4DIR ; SD_CS output high
88
89 ; P2.2/TB0.2/UCB0CLK                  - SD_CLK
90 ; P1.6/TB0.3/UCB0SIMO/UCB0SDA/TA0.0   - SD_SDI
91 ; P1.7/TB0.4/UCB0SOMI/UCB0SCL/TA1.0   - SD_SDO
92     BIS #04C0h,&PASEL1  ; Configure UCB0 pins P1.6 as UCB0SIMO, P1.7 as UCB0SOMI& UCB0 pins P2.2 as UCB0CLK
93                         ; PxDIR.x is controlled by eUSCI_A0 module
94     BIC #04C0h,&PAREN   ; disable pullup resistors for SIMO/SOMI/SCK pins
95
96     .ENDIF
97     .IFDEF MSP_EXP430FR6989 
98
99 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
100
101 ; P2.7                <--- SD_CD (Card Detect)
102 SD_CD           .equ  80h
103 SD_CDIN         .equ  P2IN
104 ; P2.6                ---> SD_CS (Card Select)
105 SD_CS           .equ  40h
106 SD_CSOUT        .equ  P2OUT
107     BIS.B #SD_CS,&P2DIR ; SD_CS output high
108
109 ; P2.2  UCA0     CLK  ---> SD_CLK
110 ; P2.0  UCA0 TX/SIMO  ---> SD_SDI
111 ; P2.2  UCA0 RX/SOMI  <--- SD_SDO
112     BIS.B #007h,&P2SEL0 ; Configure UCA1 pins P2.2 as UCA0CLK, P2.0 as UCA0SIMO & P2.1 as UCA0SOMI
113                         ; P2DIR.x is controlled by eUSCI_A0 module
114     BIC.B #007h,&P2REN  ; disable pullup resistors for SIMO/SOMI/SCK pins
115
116     .ENDIF
117     .IFDEF MSP_EXP430FR4133 
118
119 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
120
121 ; P8.0                <--- SD_CD (Card Detect)
122 SD_CD           .equ  1
123 SD_CDIN         .equ  P8IN
124 ; P8.1                ---> SD_CS (Card Select)
125 SD_CS           .equ  2
126 SD_CSOUT        .equ  P8OUT
127     BIS.B #SD_CS,&P8DIR ; SD_CS output high
128
129 ; P5.1  UCB0     CLK  ---> SD_CLK
130 ; P5.2  UCB0 TX/SIMO  ---> SD_SDI
131 ; P5.3  UCB0 RX/SOMI  <--- SD_SDO
132     BIS.B   #00Eh,&P5SEL0   ; Configure UCB0 pins P5.1 as CLK, P5.2 as SIMO & P5.3 as SOMI
133                             ; P2DIR.x is controlled by eUSCI_A0 module
134     BIC.B   #00Eh,&P5REN    ; disable pullup resistors for SIMO/SOMI/SCK pins
135
136     .ENDIF
137     .IFDEF CHIPSTICK_FR2433 
138
139 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
140
141 ; P2.3                <--- SD_CD (Card Detect)
142 SD_CD           .equ  8
143 SD_CDIN         .equ  P2IN
144 ; P2.2                ---> SD_CS (Card Select)
145 SD_CS           .equ  4
146 SD_CSOUT        .equ  P2OUT
147     BIS.B #SD_CS,&P2DIR ; SD_CS output high
148
149 ; P1.1  UCB0     CLK  ---> SD_CLK
150 ; P1.2  UCB0 TX/SIMO  ---> SD_SDI
151 ; P1.3  UCB0 RX/SOMI  <--- SD_SDO
152     BIS.B   #00Eh,&P1SEL0   ; Configure UCB0 pins P1.1 as CLK, P1.2 as SIMO & P1.3 as SOMI
153                             ; P1DIR.x is controlled by eUSCI_B0 module
154     BIC.B   #00Eh,&P1REN    ; disable pullup resistors for SIMO/SOMI/SCK pins
155
156     .ENDIF
157     .IFDEF MY_MSP430FR5738
158
159 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
160
161 ; P2.3 as SD_CD
162 SD_CD           .equ  08h
163 SD_CDIN         .equ  P2IN
164 ; P2.4 as SD_CS
165 SD_CS           .equ  10h
166 SD_CSOUT        .equ  P2OUT
167     BIS.B #SD_CS,&P2DIR ; SD_CS output high
168
169 ; P2.2/UCB0CLK                ---> SD_CardAdapter CLK (SCK)   default value
170 ; P1.6/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_CardAdapter SDI (MOSI)  default value
171 ; P1.7/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_CardAdapter SDO (MISO)  default value
172     BIS #04C0h,&PASEL1  ; Configure UCB0 pins P2.2 as UCB0CLK, P1.6 as UCB0SIMO & P1.7 as UCB0SOMI
173                         ; P2DIR.x is controlled by eUSCI_B0 module
174     BIC #04C0h,&PAREN   ; disable pullup resistors for SIMO/SOMI/CLK pins
175
176     .ENDIF
177     .IFDEF MY_MSP430FR5738_1
178
179 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
180
181 ; P2.3 as SD_CD
182 SD_CD           .equ  08h
183 SD_CDIN         .equ  P2IN
184 ; P2.4 as SD_CS
185 SD_CS           .equ  10h
186 SD_CSOUT        .equ  P2OUT
187     BIS.B #SD_CS,&P2DIR ; SD_CS output high
188
189 ; P2.2/UCB0CLK                ---> SD_CardAdapter CLK (SCK)   default value
190 ; P1.6/UCB0SIMO/UCB0SDA/TA0.0 ---> SD_CardAdapter SDI (MOSI)  default value
191 ; P1.7/UCB0SOMI/UCB0SCL/TA1.0 <--- SD_CardAdapter SDO (MISO)  default value
192     BIS #04C0h,&PASEL1  ; Configure UCB0 pins P2.2 as UCB0CLK, P1.6 as UCB0SIMO & P1.7 as UCB0SOMI
193                         ; P2DIR.x is controlled by eUSCI_B0 module
194     BIC #04C0h,&PAREN   ; disable pullup resistors for SIMO/SOMI/CLK pins
195
196     .ENDIF
197     .IFDEF MY_MSP430FR5948 
198
199 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
200
201 ; P2.3                <--- SD_CD (Card Detect)
202 SD_CD           .equ  08h
203 SD_CDIN         .equ  P2IN 
204 ; P2.7                ---> SD_CS (Card Select)
205 SD_CS           .equ  80h
206 SD_CSOUT        .equ  P2OUT
207     BIS.B #SD_CS,&P2DIR ; SD_CS output high
208
209 ; P2.4  UCA1     CLK  ---> SD_CLK
210 ; P2.5  UCA1 TX/SIMO  ---> SD_SDI
211 ; P2.6  UCA1 RX/SOMI  <--- SD_SDO
212     BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
213                         ; P2DIR.x is controlled by eUSCI_A0 module
214     BIC.B #070h,&P2REN  ; disable pullup resistors for SIMO/SOMI/SCK pins
215
216     .ENDIF
217     .IFDEF MY_MSP430FR5948_1 ; = new version of MY_MSP430FR5948
218
219 ; COLD default state : Px{DIR,SEL0,SEL1,SELC,IE,IFG,IV} = 0 ; PX{OUT,REN} = 1 ; Px{IN,IES} = ?
220
221 ; P2.7                ---> SD_CD (Card Detect)
222 SD_CD           .equ  80h
223 SD_CDIN         .equ  P2IN
224 ; P2.3                <--- SD_CS (Card Select)
225 SD_CS           .equ  08h
226 SD_CSOUT        .equ  P2OUT
227     BIS.B #SD_CS,&P2DIR ; SD_CS output high
228
229 ; P2.4  UCA1     CLK  ---> SD_CLK
230 ; P2.5  UCA1 TX/SIMO  ---> SD_SDI
231 ; P2.6  UCA1 RX/SOMI  <--- SD_SDO
232     BIS.B #070h,&P2SEL1 ; Configure UCA1 pins P2.4 as UCA1CLK, P2.5 as UCA1SIMO & P2.6 as UCA1SOMI
233                         ; P2DIR.x is controlled by eUSCI_A0 module
234     BIC.B #070h,&P2REN  ; disable pullup resistors for SIMO/SOMI/SCK pins
235
236     .ENDIF
237
238     BIC     #1,&SD_CTLW0            ; release eUSCI from reset
239
240 ; ===========================================================
241 ; 2- Init to 0 all SD_Card variables, handles and SDIB buffer
242 ; ===========================================================
243
244 InitSDdata
245     MOV     #SD_ORG_DATA,X          ;
246 InitSDdataLoop                      ;
247     MOV     #0,0(X)                 ;
248     ADD     #2,X                    ;
249     CMP     #SD_END_DATA,X          ;
250     JNE     InitSDdataLoop          ;
251
252
253 ; ===========================================================
254 ; 3- Init SD_Card
255 ; ===========================================================
256
257 SD_POWER_ON
258     MOV     #8,X                    ; send 64 clk on SD_clk
259     CALL    #SPI_X_GET              ;
260     BIC.B   #SD_CS,&SD_CSOUT        ; preset SD_CS output low to switch in SPI mode
261     MOV     #4,S                    ; preset error 4R1
262 ; ----------------------------------;
263 INIT_CMD0                           ;
264 ; ----------------------------------;
265     MOV     #95h,&SD_CMD_FRM        ; $(95 00 00 00 00 00)
266     MOV     #4000h,&SD_CMD_FRM+4    ; $(95 00 00 00 00 40); send CMD0 
267 ; ----------------------------------;
268 SEND_CMD0                           ; CMD0 : GO_IDLE_STATE
269 ; ----------------------------------;
270     MOV     #1,W                    ; expected SPI_R1 response = 1 = idle state
271     CALL    #sendCommand            ;X
272     JZ      INIT_CMD8               ; if idle state
273 SD_INIT_ERROR                       ;
274     MOV     #SD_CARD_ERROR,PC       ; ReturnError = $04R1, case of defectuous card (or insufficient SD_POWER_ON clk)
275 ; ----------------------------------;
276 INIT_CMD8                           ; mandatory if SD_Card >= V2.x [11:8]supply voltage(VHS)
277 ; ----------------------------------;
278     CALL    #SPI_GET                ; (needed to pass SanDisk ultra 8GB "HC I")
279     CMP.B   #-1,W                   ; FFh expected value <==> MISO = high level
280     JNE     INIT_CMD8               ; loop back while yet busy
281     MOV     #0AA87h,&SD_CMD_FRM     ; $(87 AA ...)  (CRC:CHECK PATTERN)
282     MOV     #1,&SD_CMD_FRM+2        ; $(87 AA 01 00 ...)  (CRC:CHECK PATTERN:VHS set as 2.7to3.6V:0)
283     MOV     #4800h,&SD_CMD_FRM+4    ; $(87 AA 01 00 00 48)
284 ; ----------------------------------;
285 SEND_CMD8                           ; CMD8 = SEND_IF_COND
286 ; ----------------------------------;
287     MOV     #1,W                    ; expected R1 response (first byte of SPI R7) = 01h : idle state
288     CALL    #sendCommand            ; time out occurs with SD_Card V1.x (and all MMC_card) 
289 ; ----------------------------------;
290     MOV     #4,X                    ; skip end of SD_Card V2.x type R7 response (4 bytes), because useless
291     CALL    #SPI_X_GET              ;WX
292 ; ----------------------------------;
293 INIT_ACMD41                         ;
294 ; ----------------------------------;
295     MOV     #1,&SD_CMD_FRM          ; $(01 00 ...   set stop bit
296     MOV     #0,&SD_CMD_FRM+2        ; $(01 00 00 00 ...
297 ;    MOV.B   #16,Y                   ; init 16 * ACMD41 repeats (power on fails with SanDisk ultra 8GB "HC I" and Transcend 2GB)
298 ;    MOV.B   #32,Y                   ; init 32 * ACMD41 repeats  ==> ~400ms
299     MOV.B   #-1,Y                   ; init 255 * ACMD41 repeats ==> 3 s
300 ; ----------------------------------;
301 SEND_ACMD41                         ; send CMD55+CMD41
302 ; ----------------------------------;
303     MOV     #8,S                    ; preset error 8R1 for ACMD41
304 INIT_CMD55                          ;
305     MOV     #7700h,&SD_CMD_FRM+4    ; $(01 00 00 00 00 77)
306 SEND_CMD55                          ; CMD55 = APP_CMD
307     MOV     #1,W                    ; expected R1 response = 1 : idle
308     CALL    #sendCommand            ;
309 SEND_CMD41                          ; CMD41 = APP OPERATING CONDITION
310     MOV     #6940h,&SD_CMD_FRM+4    ; $(01 00 00 00 40 69) (30th bit = HCS = High Capacity Support request)
311     CALL    #WaitIdleBeforeSendCMD  ; wait until idle (needed to pass SanDisk ultra 8GB "HC I") then send Command CMD41
312     JZ      SetBLockLength          ; if SD_Card ready (R1=0)
313     SUB.B   #1,Y                    ; else decr time out delay
314     JNZ     INIT_CMD55              ; then loop back while count of repeat not reached
315     JMP     SD_INIT_ERROR           ; ReturnError on time out : unusable card
316 ; ----------------------------------;
317 setBLockLength                      ; set block = 512 bytes (buffer size), usefull only for FAT16 SD Cards
318 ; ----------------------------------;
319     ADD     S,S                     ; preset error $10 for CMD16
320 SEND_CMD16                          ; CMD16 = SET_BLOCKLEN
321     MOV     #02h,&SD_CMD_FRM+2      ; $(01 00 02 00 ...)
322     MOV     #5000h,&SD_CMD_FRM+4    ; $(01 00 02 00 00 50) 
323     CALL    #WaitIdleBeforeSendCMD  ; wait until idle then send CMD16
324     JNZ     SD_INIT_ERROR           ; if W = R1 <> 0, ReturnError = $20R1 ; send command ko
325 ; ----------------------------------;
326 SetHighSpeed                        ; end of SD init ==> SD_CLK = SMCLK
327 ; ----------------------------------;
328     BIS     #1,&SD_CTLW0            ; Software reset
329     MOV     #0,&SD_BRW              ; UCxxBRW = 0 ==> SPI_CLK = MCLK
330     BIC     #1,&SD_CTLW0            ; release from reset
331 ; ----------------------------------;
332 Read_EBP_FirstSector                ; W=0, BS_FirstSectorHL=0
333 ; ----------------------------------;
334     CALL    #readSectorW            ; read physical first sector
335     MOV     #BUFFER,Y               ;
336     MOV     454(Y),&BS_FirstSectorL ; so, sectors become logical
337     MOV     456(Y),&BS_FirstSectorH ; 
338     MOV.B   450(Y),W                ; W = partition ID 
339 ; ----------------------------------;
340 TestPartitionID                     ;
341 ; ----------------------------------;
342     MOV     #1,&FATtype             ; preset FAT16
343 FAT16_CHS_LBA_Test                  ;
344     SUB.B   #6,W                    ; ID=06h Partition FAT16 using CHS & LBA ?
345     JZ      Read_MBR_FirstSector    ; with W = 0
346 FAT16_LBA_Test                      ;
347     SUB.B   #8,W                    ; ID=0Eh Partition FAT16 using LBA ?
348     JZ      Read_MBR_FirstSector    ; with W = 0
349 ; ----------------------------------;
350     MOV     #2,&FATtype             ; set FAT32
351 FAT32_LBA_Test                      ;
352     ADD.B   #2,W                    ; ID=0Ch Partition FAT32 using LBA ?
353     JZ      Read_MBR_FirstSector    ; with W = 0
354 FAT32_CHS_LBA_Test                  ;
355     ADD.B   #1,W                    ; ID=0Bh Partition FAT32 using CHS & LBA ?
356     JZ      Read_MBR_FirstSector    ; with W = 0
357     ADD     #0200Bh,W               ;
358     MOV     W,S                     ;
359     MOV     #SD_CARD_ID_ERROR,PC    ; S = ReturnError = $20xx with xx = partition ID 
360 ; ----------------------------------; see: https://en.wikipedia.org/wiki/Partition_type
361 Read_MBR_FirstSector                ; read first logical sector
362 ; ----------------------------------;
363     CALL    #readSectorW            ; ...with the good CMD17 bytes/sectors (FAT16/FAT32) frame !
364 ; ----------------------------------;
365 FATxx_SetFileSystem                 ;
366 ; ----------------------------------;
367     MOV.B   13(Y),&SecPerClus       ;
368     MOV     14(Y),X                 ;3 X = BPB_RsvdSecCnt
369     MOV     X,&OrgFAT1              ;3 set OrgFAT1
370     MOV     22(Y),W                 ; W = BPB_FATsize
371     CMP     #0,W                    ; BPB_FATsize <> 0 ?
372     JNZ     Set_FATsize             ; yes
373     MOV     36(Y),W                 ; W = BPB_FATSz32
374 Set_FATsize                         ;
375     MOV     W,&FATSize              ; limited to 16384 sectors....
376     ADD     W,X                     ;
377     MOV     X,&OrgFAT2              ; X = OrgFAT1 + FATsize = OrgFAT2
378     ADD     W,X                     ; X = OrgFAT2 + FATsize = FAT16 OrgRootDir | FAT32 OrgDatas
379     CMP     #2,&FATtype             ; FAT32?
380     JZ      FATxx_SetFileSystemNext ; yes
381 FAT16_SetRootCluster                ;
382     MOV     X,&OrgRootDIR           ; only FAT16 use, is a sector used by ComputeClusFrstSect
383     ADD     #32,X                   ; OrgRootDir + RootDirSize = OrgDatas
384 FATxx_SetFileSystemNext             ;
385     SUB     &SecPerClus,X           ; OrgDatas - SecPerClus*2 = OrgClusters
386     SUB     &SecPerClus,X           ; no borrow expected
387     MOV     X,&OrgClusters          ; X = virtual cluster 0 address (clusters 0 and 1 don't exist)
388     MOV     &FATtype,&DIRClusterL   ; init DIRcluster as RootDIR
389 ; ----------------------------------;
390
391