Files
FireBee_SVN/BaS_GNU/sources/sd_card_asm.S
Markus Fröschle dd8135df4b fixed typo
2012-10-24 14:17:02 +00:00

440 lines
8.7 KiB
ArmAsm

/********************************************************************/
// sd card
/********************************************************************/
#define dspi_dtar0 0x0c
#define dspi_dsr 0x2c
#define dspi_dtfr 0x34
#define dspi_drfr 0x38
#define LONGASC(a, b, c, d) ((a << 24) | (b << 16) | (c << 8) | (d))
#define MCF_PAD_PAR_DSPI (__MBAR+0xA50)
#define MCF_PSC0_PSCTB_8BIT (__MBAR+0x860C)
#define MCF_DSPI_DMCR (__MBAR+0x8A00)
#define MCF_SLT0_SCNT (__MBAR + 0x908)
.text
warte_10ms:
move.l d0,-(sp)
move.l MCF_SLT0_SCNT,d0
sub.l #1320000,d0
warte_d6:
cmp.l MCF_SLT0_SCNT,d0
bcs warte_d6
move.l (sp)+,d0
rts
warte_1ms:
move.l d0,-(sp)
move.l MCF_SLT0_SCNT,d0
sub.l #132000,d0
warte_d5:
cmp.l MCF_SLT0_SCNT,d0
bcs warte_d5
move.l (sp)+,d0
rts
.global sd_idle
.global sd_init
sd_init:
lea MCF_PSC0_PSCTB_8BIT,a6
move.l #LONGASC('S', 'D', '-', 'C'),(a6)
move.l #LONGASC('a', 'r', 'd', ' '),(a6)
move.l buffer,a5 // basis addresse (diesen bereich brauchen wir nicht mehr!)
move.l #0x1fffffff,d0 // normal dspi
move.l d0,MCF_PAD_PAR_DSPI
lea MCF_DSPI_DMCR,a0
move.l #0x800d3c00,(a0) // 8 bit cs5 on
move.l #0x38558897,d0
move.l d0,dspi_dtar0(a0) // 400kHz
move.l #0x082000ff,d4 // tx vorbesetzen
mov3q.l #-1,dspi_dsr(a0)
bsr.l warte_1ms
move.l #0xc00d3c00,(a0) // 8 bit 4MHz clocken cs off
bsr.l warte_10ms
move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
bsr sd_com
move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off
clr.b d4
bsr sd_com
bsr sd_com
move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on
move.b #0xff,d4
bsr sd_com
bsr sd_com
move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off
bsr.l warte_10ms
// sd idle
move.l #100,d6 // 100 versuche
move.l #10,d3 // 10 versuche
sd_idle:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x40,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x95,d4
bsr sd_com
move.b #0xff,d4 // receive byt
bsr sd_com
cmp.b #0x01,d5
beq idle_end
bsr sd_com
cmp.b #0x01,d5
beq idle_end
bsr sd_com
cmp.b #0x01,d5
beq idle_end
bsr sd_com
cmp.b #0x01,d5
beq idle_end
bsr sd_com
cmp.b #0x01,d5
beq idle_end
bsr sd_com
cmp.b #0x01,d5
beq idle_end
subq.l #1,d6
beq sd_not
bra sd_idle
idle_end:
// cdm 8
read_ic:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x48,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x01,d4
bsr sd_com
move.b #0xaa,d4
bsr sd_com
move.b #0x87,d4
bsr sd_com
bsr sd_get_status
cmp.b #5,d5
beq sd_v1
cmp.b #1,d5
bne read_ic
move.b #0xff,d4
bsr sd_com
move.b d5,d0
bsr sd_com
move.b d5,d1
bsr sd_com
move.b d5,d2
bsr sd_com
cmp.b #0xaa,d5
bne sd_testd3
move.l #LONGASC('S', 'D', 'H', 'C'),(a6)
move.b #' ',(a6)
sd_v1:
// cdm 58
read_ocr:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x7a,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x01,d4
bsr sd_com
bsr sd_get_status
move.l #LONGASC('V', 'e', 'r', '1'),d6
cmp.b #5,d5
beq read_ocr
cmp.b #1,d5
bne read_ocr
move.b #0xff,d4
bsr sd_com
move.b d5,d0
bsr sd_com
move.b d5,d1
bsr sd_com
move.b d5,d2
bsr sd_com
// acdm 41
move.l #20000,d6 // 20000 versuche ready can bis 1 sec gehen
wait_of_aktiv:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x77,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x95,d4
bsr sd_com
bsr sd_get_status
cmp.b #0x05,d5
beq wait_of_aktiv
wait_of_aktiv2:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x69,d4
bsr sd_com
move.b #0x40,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x95,d4
bsr sd_com
bsr sd_get_status
tst.b d5
beq sd_init_ok
cmp.b #0x05,d5
beq wait_of_aktiv2
subq.l #1,d6
bne wait_of_aktiv
sd_testd3:
subq.l #1,d3
bne sd_idle
bra sd_error
sd_init_ok:
// cdm 10
read_cid:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x4a,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x95,d4
bsr sd_com
move.l a5,a4 // adresse setzen
bsr sd_rcv_info
// name ausgeben
lea 1(a5),a4
moveq #7,d7
sd_nam_loop:
move.b (a4)+,(a6)
subq.l #1,d7
bne sd_nam_loop
move.b #' ',(a6)
// cdm 9
read_csd:
move.b #0xff,d4 // receive byt
bsr sd_com
move.b #0x49,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x00,d4
bsr sd_com
move.b #0x01,d4
bsr sd_com
move.l a5,a4 // adresse setzen
bsr sd_rcv_info
mvz.b (a5),d0
lsr.l #6,d0
bne sd_csd2 // format v2
move.l 6(a5),d1
moveq #14,d0 // bit 73..62 c_size
lsr.l d0,d1 // bits extrahieren
and.l #0xfff,d1 // 12 bits
addq.l #1,d1
mvz.w 9(a5),d0
lsr.l #7,d0 // bits 49..47
and.l #0x7,d0 // 3 bits
moveq.l #8,d2 // x256 (dif v1 v2)
sub.l d0,d2
lsr.l d2,d1
bra sd_print_size
sd_csd2:
mvz.w 8(a5),d1
addq.l #1,d1
sd_print_size:
swap d1
lsl.l #1,d1
bcc sd_16G
move.l #LONGASC('3', '2', 'G', 'B'),(a6)
bra sd_ok
sd_16G:
lsl.l #1,d1
bcc sd_8G
move.l #LONGASC('1', '6', 'G', 'B'),(a6)
bra sd_ok
sd_8G:
lsl.l #1,d1
bcc sd_4G
move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
bra sd_ok
sd_4G:
lsl.l #1,d1
bcc sd_2G
move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
bra sd_ok
sd_2G:
lsl.l #1,d1
bcc sd_1G
move.l #LONGASC(' ', '2', 'G', 'B'),(a6)
bra sd_ok
sd_1G:
lsl.l #1,d1
bcc sd_512M
move.l #LONGASC(' ', '1', 'G', 'B'),(a6)
bra sd_ok
sd_512M:
lsl.l #1,d1
bcc sd_256M
move.b #'5',(a6)
move.l #LONGASC('1', '2', 'M', 'B'),(a6)
bra sd_ok
sd_256M:
lsl.l #1,d1
bcc sd_128M
move.b #'2',(a6)
move.l #LONGASC('5', '6', 'M', 'B'),(a6)
bra sd_ok
sd_128M:
lsl.l #1,d1
bcc sd_64M
move.b #'1',(a6)
move.l #LONGASC('2', '8', 'M', 'B'),(a6)
bra sd_ok
sd_64M:
lsl.l #1,d1
bcc sd_32M
move.l #LONGASC('6', '4', 'M', 'B'),(a6)
bra sd_ok
sd_32M:
lsl.l #1,d1
bcc sd_16M
move.l #LONGASC('3', '2', 'M', 'B'),(a6)
bra sd_ok
sd_16M:
lsl.l #1,d1
bcc sd_8M
move.l #LONGASC('1', '6', 'M', 'B'),(a6)
bra sd_ok
sd_8M:
move.l #LONGASC('<', '9', 'M', 'B'),(a6)
sd_ok:
move.l #LONGASC(' ', 'O', 'K', '!'),(a6)
move.l #0x0a0d,(a6)
halt
halt
rts
// subs ende -------------------------------
sd_V1:
move.l #LONGASC('n', 'o', 'n', '!'),(a6)
move.l #0x0a0d,(a6)
halt
halt
rts
sd_error:
move.l #LONGASC('E', 'r', 'r', 'o'),(a0)
move.l #LONGASC('r', '!', '', ''), (a0)
move.l #0x0a0d,(a6)
halt
halt
rts
sd_not:
move.l #LONGASC('n', 'o', 'n', '!'),(a0)
move.l #0x0a0d,(a6)
halt
halt
rts
// status holen -------------------------------
sd_get_status:
move.b #0xff,d4
bsr sd_com
cmp.b #0xff,d5
beq sd_get_status
rts
// byt senden und holen ---------------------
sd_com:
move.l d4,dspi_dtfr(a0)
wait_auf_complett:
btst.b #7,dspi_dsr(a0)
beq wait_auf_complett
move.l dspi_drfr(a0),d5
mov3q.l #-1,dspi_dsr(a0) // clr status register
rts
// daten holen ----------------------------
sd_rcv_info:
moveq #18,d3 // 16 byts + 2 byts crc
move.b #0xff,d4
sd_rcv_rb_w:
bsr sd_get_status
cmp.b #0xfe,d5 // daten bereit?
bne sd_rcv_rb_w // nein->
sd_rcv_rd_rb:
bsr sd_com
move.b d5,(a4)+
subq.l #1,d3
bne sd_rcv_rd_rb
rts
/******************************************/
.data
buffer: dc.l 0, 0, 0, 0, 0, 0, 0, 0