included original sd_card routines instead of dummys

This commit is contained in:
Markus Fröschle
2012-10-24 13:02:07 +00:00
parent aeeb933f7f
commit bb44af66f0
2 changed files with 48 additions and 608 deletions

View File

@@ -5,589 +5,22 @@
#include <stdint.h> #include <stdint.h>
#include <MCF5475.h> #include <MCF5475.h>
#define dspi_dtar0 0x0c
#define dspi_dsr 0x2c
#define dspi_dtfr 0x34
#define dspi_drfr 0x38
#define time1us 1320
uint8_t sd_com(uint32_t cmd)
{
uint8_t res;
MCF_DSPI_DTFR = cmd;
while (! (MCF_DSPI_DSR & (1 << 7)));
res = MCF_DSPI_DRFR;
MCF_DSPI_DSR = -1L;
return res;
}
/*
* fetch status from SD controller
*/
uint8_t sd_get_status(void)
{
uint8_t res;
while ((res = sd_com(0xff)) == 0xff);
return res;
}
void sd_rcv_info(uint8_t *buf, uint32_t size)
{
uint32_t rcvd = 0;
while (sd_get_status() != 0xfe); /* loop until data available */
do {
*buf++ = sd_com(0x18);
rcvd++;
} while (rcvd <= size);
}
void sd_card_idle(void) void sd_card_idle(void)
{ {
__asm__ __volatile__ (
#ifdef _NOT_USED_ ".extern sd_idle\n\t"
asm "bsr sd_idle\n\t"
{ /* input */ :
// sd idle /* output */:
// speed =400kHz /* clobber */: "a0","a1","a2","a3","a4","a5","a6",
move.l #0x082000ff,d4 // tx vorbesetzen "d0","d1","d2","d3","d4","d5","d6","d7","memory"
lea MCF_DSPI_DMCR,a0 );
move.l #0x38558897,d0
move.l d0,dspi_dtar0(a0) // 400kHz
move.b #0xff,d4
bsr sd_com // clocks
move.b #0x40,d4 // cmd idle
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
}
#endif
} }
int sd_card_init(void) int sd_card_init(void)
{ {
return 0; /* for now, just to make the compiler happy */
#ifdef _NOT_USED_
long az_sectors;
asm
{
lea MCF_PSC0_PSCTB_8BIT,a1
move.l #'SD-C',(a1)
move.l #'ard ',(a1)
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 #0x802d3c00,(a0) // 8 bit cs off clear fifo
move.l #0x38558897,d0
move.l d0,dspi_dtar0(a0) // 400kHz
move.l #0x082000ff,d4 // tx vorbesetzen
move.l d4,dspi_dtfr // und setzen
mov3q.l #-1,dspi_dsr(a0) // status register l<>schen
move.l #0xc00d3c00,(a0) // clock on cs ist on
bsr wait_10ms
move.l #0x802d3c00,(a0) // clock off cs off
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 #0x800d3c00,(a0) // cs on
bsr sd_com
bsr sd_com
move.l #0x802d3c00,(a0) // cs off
bsr sd_com
bsr sd_com
bsr wait_10ms
// sd idle
move.l #100,d6 // 100 versuche
move.l #10,d3 // 10 versuche
sd_idle:
bsr sd_card_idle
move.l #10,d7
move.b #0xff,d4
sd_idle_leeren:
bsr sd_com
cmp.b #0x01,d5
beq idle_end
subq.l #1,d7
bne sd_idle_leeren
subq.l #1,d6
beq sd_not
bra sd_idle
idle_end:
// cdm 8
read_ic:
move.b #0xff,d4 // clocks
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
bsr sd_com // 4byts zum wegwerfen
bsr sd_com
bsr sd_com
bsr sd_com
cmp.b #0xaa,d5 // pattern zur<75>ckgekommen?
bne sd_testd3 // nein ->
move.l #'SDHC',(a1)
move.b #' ',(a1)
sd_v1:
// cdm 58
read_ocr:
move.b #0xff,d4 // clocks
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 #'Ver1',d6
cmp.b #5,d5
beq read_ocr
cmp.b #1,d5
bne read_ocr
bsr sd_com // 4 byts zum wegwerfen
bsr sd_com
bsr sd_com
bsr sd_com
// acdm 41
move.l #20000,d6 // 20000 versuche ready can bis 1 sec gehen
wait_of_aktiv:
move.b #0xff,d4 // clocks
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 // clocks
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:
// fullspeed
move.l #0x38551120,d0 // 22Mbit/sec
move.l d0,dspi_dtar0(a0) // setzen
// cdm 10
read_cid:
move.b #0xff,d4 // clocks
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,a2 // adresse setzen
bsr sd_rcv_info
// name ausgeben
lea 1(a5),a2
moveq #7,d7
sd_nam_loop:
move.b (a2)+,(a1)
subq.l #1,d7
bne sd_nam_loop
move.b #' ',(a1)
// cdm 9
read_csd:
move.b #0xff,d4 // clocks
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,a2 // 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
move.l d1,d3
lsr.l #6,d3 //x65636 /64 -> anzahl sectors
move.l d3,az_sectors
lsl.l #1,d1
bcc sd_16G
move.l #'32GB',(a1)
bra sd_ok
sd_16G:
lsl.l #1,d1
bcc sd_8G
move.l #'16GB',(a1)
bra sd_ok
sd_8G:
lsl.l #1,d1
bcc sd_4G
move.l #' 8GB',(a1)
bra sd_ok
sd_4G:
lsl.l #1,d1
bcc sd_2G
move.l #' 4GB',(a1)
bra sd_ok
sd_2G:
lsl.l #1,d1
bcc sd_1G
move.l #' 2GB',(a1)
bra sd_ok
sd_1G:
lsl.l #1,d1
bcc sd_512M
move.l #' 1GB',(a1)
bra sd_ok
sd_512M:
lsl.l #1,d1
bcc sd_256M
move.b #'5',(a1)
move.l #'12MB',(a1)
bra sd_ok
sd_256M:
lsl.l #1,d1
bcc sd_128M
move.b #'2',(a1)
move.l #'56MB',(a1)
bra sd_ok
sd_128M:
lsl.l #1,d1
bcc sd_64M
move.b #'1',(a1)
move.l #'28MB',(a1)
bra sd_ok
sd_64M:
lsl.l #1,d1
bcc sd_32M
move.l #'64MB',(a1)
bra sd_ok
sd_32M:
lsl.l #1,d1
bcc sd_16M
move.l #'32MB',(a1)
bra sd_ok
sd_16M:
lsl.l #1,d1
bcc sd_8M
move.l #'16MB',(a1)
bra sd_ok
sd_8M:
move.l #'<9MB',(a1)
sd_ok:
move.l #' OK!',(a1)
move.l #0x0a0d,(a1)
bra sd_c_ok
// subs ende -------------------------------
sd_error:
move.l #'Erro',(a1)
move.l #'r!',(a1)
move.l #0x0a0d,(a1)
bra sd_c_error
sd_not:
move.l #'non!',(a1)
move.l #0x0a0d,(a1)
bra sd_c_not
buffer: dc.l 0,0,0,0,0,0,0,0
}
sd_c_ok:
return az_sectors;
sd_c_not:
return -2;
sd_c_error:
return -1;
#endif /* _NOT_USED_ */
} }
#ifdef _NOT_USED_
void sd_rcv_sector(void) // 1 sector daten holen ----------------------------
{
if (sd_get_status() == 0xfe)
{
for (i = 0; i < 512; i++)
}
}
asm
{
bsr sd_get_status
cmp.b #0xfe,d5 // daten bereit?
bne sd_rs_end // nein-> error
move.l #512,d3 // sonst 512 byts abholen
sd_rs_loop:
bsr sd_com
move.b d5,(a2)+
subq.l #1,d3
bne sd_rs_loop
// crc holen
bsr sd_com
bsr sd_com
clr.l d5 // alles ok
sd_rs_end:
}
}
int sd_card_sector_read(long sec_nr,long buf_adr)
{
int status ;
asm
{
lea MCF_DSPI_DMCR,a0
move.l #0x082000ff,d4 // tx vorbesetzen
move.l sec_nr,d0
move.l buf_adr,a2
lsl.l #8,d0
add.l d0,d0 // x 512 !
move.l d0,d1 // byts kehren
swap d1
move.l d1,d2
lsr.l #8,d1
move.b #0xff,d4 // clocks
bsr sd_com
move.b #0x51,d4
bsr sd_com
move.b d1,d4
bsr sd_com
move.b d2,d4
bsr sd_com
move.l d0,d2
lsr.l #8,d2
move.b d2,d4
bsr sd_com
move.b d0,d4
bsr sd_com
move.b #0x01,d4
bsr sd_com
clr.l d5 // alles auf no error
clr.l status
bsr sd_get_status // status holen
tst.b d5
bne sd_csr_end // wenn nicht ok -> weg
// sector holen
bsr sd_rcv_sector
sd_csr_end:
tst.b d5
beq sd_csr_ok
neg.l d5 // wenn nicht ok status auf negativ
move.l d5,status
sd_csr_ok:
}
return status;
}
void sd_send_sector(void) // 1 sector daten senden ----------------------------
{
asm
{
move.l #512,d3
move.b #0xfe,d4 // start token
bsr sd_com // senden
sd_send_wr_wb:
move.b (a2)+,d4 // data
bsr sd_com // senden
subq.l #1,d3
bne sd_send_wr_wb
// send crc
move.b #1,d4
bsr sd_com // crc 1.byt
move.b #1,d4
bsr sd_com // crc 2.byt
sd_send_wr_ww:
bsr sd_get_status
and.l #0x1f,d5
clr.l d6 //status auf OK
cmp.b #5,d5 //data accepted?
beq sd_send_end //ja ->
move.l d5,d6 //sonst status sichern
sd_send_end:
bsr sd_com
tst.b d5 // warte auf geschrieben
beq sd_send_end
move.l d6,d5 // status zur<75>ck
}
}
int sd_card_sector_write(long sec_nr,long buf_adr)
{
int status;
asm
{
lea MCF_DSPI_DMCR,a0
move.l #0x082000ff,d4 // tx vorbesetzen
move.l sec_nr,d0
move.l buf_adr,a2
lsl.l #8,d0
add.l d0,d0 // x 512 !
move.l d0,d1 // byts kehren
swap d1
move.l d1,d2
lsr.l #8,d1
move.b #0xff,d4 // clocks
bsr sd_com
move.b #0x58,d4
bsr sd_com
move.b d1,d4
bsr sd_com
move.b d2,d4
bsr sd_com
move.l d0,d2
lsr.l #8,d2
move.b d2,d4
bsr sd_com
move.b d0,d4
bsr sd_com
move.b #0x01,d4
bsr sd_com
clr.l d5 // alles auf no error
clr.l status
bsr sd_get_status // status holen
tst.b d5
bne sd_csw_end // wenn nicht ok -> weg
// sector schreiben
bsr sd_send_sector
sd_csw_end:
tst.b d5
beq sd_csw_ok
neg.l d5 // wenn nicht ok status auf negativ
move.l d5,status
sd_csw_ok:
}
return status;
}
#endif /* _NOT_USED */

View File

@@ -1,18 +1,26 @@
/********************************************************************/ /********************************************************************/
// sd card // sd card
/********************************************************************/ /********************************************************************/
#define dspi_dtar0 0x0c #define dspi_dtar0 0x0c
#define dspi_dsr 0x2c #define dspi_dsr 0x2c
#define dspi_dtfr 0x34 #define dspi_dtfr 0x34
#define dspi_drfr 0x38 #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)
.text
.global sd_idle
.text
sd_test: sd_test:
lea MCF_PSC0_PSCTB_8BIT,a6 lea MCF_PSC0_PSCTB_8BIT,a6
move.l #'SD-C',(a6) move.l #LONGASC('S', 'D', '-', 'A'),(a6)
move.l #'ard ',(a6) move.l #LONGASC('a', 'r', 'd', ' '),(a6)
move.l #__Bas_base,a5 // basis addresse (diesen bereich brauchen wir nicht mehr!) move.l #_Bas_base,a5 // basis addresse (diesen bereich brauchen wir nicht mehr!)
move.l #0x1fffffff,d0 // normal dspi move.l #0x1fffffff,d0 // normal dspi
move.l d0,MCF_PAD_PAR_DSPI move.l d0,MCF_PAD_PAR_DSPI
lea MCF_DSPI_DMCR,a0 lea MCF_DSPI_DMCR,a0
@@ -22,9 +30,9 @@ sd_test:
move.l #0x082000ff,d4 // tx vorbesetzen move.l #0x082000ff,d4 // tx vorbesetzen
mov3q.l #-1,dspi_dsr(a0) mov3q.l #-1,dspi_dsr(a0)
bsr warte_1ms bsr.l _wait_1ms
move.l #0xc00d3c00,(a0) // 8 bit 4MHz clocken cs off move.l #0xc00d3c00,(a0) // 8 bit 4MHz clocken cs off
bsr warte_10ms bsr.l _wait_10ms
move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on move.l #0x800d3c00,(a0) // 8 bit 4MHz normal cs on
bsr sd_com bsr sd_com
bsr sd_com bsr sd_com
@@ -45,7 +53,7 @@ sd_test:
bsr sd_com bsr sd_com
bsr sd_com bsr sd_com
move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off move.l #0x802d3c00,(a0) // 8 bit 4MHz normal cs off
bsr warte_10ms bsr.l _wait_10ms
// sd idle // sd idle
move.l #100,d6 // 100 versuche move.l #100,d6 // 100 versuche
@@ -122,8 +130,7 @@ read_ic:
bsr sd_com bsr sd_com
cmp.b #0xaa,d5 cmp.b #0xaa,d5
bne sd_testd3 bne sd_testd3
move.l #LONGASC('S', 'D', 'H', 'C'),(a6)
move.l #'SDHC',(a6)
move.b #' ',(a6) move.b #' ',(a6)
sd_v1: sd_v1:
@@ -145,7 +152,7 @@ read_ocr:
bsr sd_com bsr sd_com
bsr sd_get_status bsr sd_get_status
move.l #'Ver1',d6 move.l #LONGASC('V', 'e', 'r', '1'),d6
cmp.b #5,d5 cmp.b #5,d5
beq read_ocr beq read_ocr
cmp.b #1,d5 cmp.b #1,d5
@@ -283,90 +290,90 @@ sd_print_size:
swap d1 swap d1
lsl.l #1,d1 lsl.l #1,d1
bcc sd_16G bcc sd_16G
move.l #'32GB',(a6) move.l #LONGASC('3', '2', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_16G: sd_16G:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_8G bcc sd_8G
move.l #'16GB',(a6) move.l #LONGASC('1', '6', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_8G: sd_8G:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_4G bcc sd_4G
move.l #' 8GB',(a6) move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_4G: sd_4G:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_2G bcc sd_2G
move.l #' 4GB',(a6) move.l #LONGASC(' ', '4', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_2G: sd_2G:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_1G bcc sd_1G
move.l #' 2GB',(a6) move.l #LONGASC(' ', '2', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_1G: sd_1G:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_512M bcc sd_512M
move.l #' 1GB',(a6) move.l #LONGASC(' ', '1', 'G', 'B'),(a6)
bra sd_ok bra sd_ok
sd_512M: sd_512M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_256M bcc sd_256M
move.b #'5',(a6) move.b #'5',(a6)
move.l #'12MB',(a6) move.l #LONGASC('1', '2', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_256M: sd_256M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_128M bcc sd_128M
move.b #'2',(a6) move.b #'2',(a6)
move.l #'56MB',(a6) move.l #LONGASC('5', '6', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_128M: sd_128M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_64M bcc sd_64M
move.b #'1',(a6) move.b #'1',(a6)
move.l #'28MB',(a6) move.l #LONGASC('2', '8', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_64M: sd_64M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_32M bcc sd_32M
move.l #'64MB',(a6) move.l #LONGASC('6', '4', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_32M: sd_32M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_16M bcc sd_16M
move.l #'32MB',(a6) move.l #LONGASC('3', '2', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_16M: sd_16M:
lsl.l #1,d1 lsl.l #1,d1
bcc sd_8M bcc sd_8M
move.l #'16MB',(a6) move.l #LONGASC('1', '6', 'M', 'B'),(a6)
bra sd_ok bra sd_ok
sd_8M: sd_8M:
move.l #'<9MB',(a6) move.l #LONGASC('<', '9', 'M', 'B'),(a6)
sd_ok: sd_ok:
move.l #' OK!',(a6) move.l #LONGASC(' ', 'O', 'K', '!'),(a6)
move.l #0x0a0d,(a6) move.l #0x0a0d,(a6)
halt halt
halt halt
rts rts
// subs ende ------------------------------- // subs ende -------------------------------
sd_V1: sd_V1:
move.l #'non!',(a6) move.l #LONGASC('n', 'o', 'n', '!'),(a6)
move.l #0x0a0d,(a6) move.l #0x0a0d,(a6)
halt halt
halt halt
rts rts
sd_error: sd_error:
move.l #'Erro',(a6) move.l #LONGASC('E', 'r', 'r', 'o'),(a0)
move.l #'r!',(a6) move.l #LONGASC('r', '!', '', ''), (a0)
move.l #0x0a0d,(a6) move.l #0x0a0d,(a6)
halt halt
halt halt
rts rts
sd_not: sd_not:
move.l #'non!',(a6) move.l #LONGASC('n', 'o', 'n', '!'),(a0)
move.l #0x0a0d,(a6) move.l #0x0a0d,(a6)
halt halt
halt halt