From f964b56a280b996d81a80f4cf47b6466c5e07873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Thu, 11 Oct 2012 14:57:56 +0000 Subject: [PATCH] unfinished --- BaS_GNU/BaS_GNU/sources/sd_card.c | 610 ++++++++++++++++++++++++++++++ 1 file changed, 610 insertions(+) create mode 100644 BaS_GNU/BaS_GNU/sources/sd_card.c diff --git a/BaS_GNU/BaS_GNU/sources/sd_card.c b/BaS_GNU/BaS_GNU/sources/sd_card.c new file mode 100644 index 0000000..4673854 --- /dev/null +++ b/BaS_GNU/BaS_GNU/sources/sd_card.c @@ -0,0 +1,610 @@ +/********************************************************************/ +// sd card +/********************************************************************/ + +#define __MBAR 0xff000000 +#define MCF_SLT0_SCNT __MBAR + 0x908 +#define MCF_PSC0_PSCTB_8BIT __MBAR + 0x860C +#define MCF_PAD_PAR_DSPI __MBAR + 0xA50 +#define MCF_DSPI_DMCR __MBAR + 0x8A00 //dspi control + +#define dspi_dtar0 0x0c +#define dspi_dsr 0x2c +#define dspi_dtfr 0x34 +#define dspi_drfr 0x38 +#define time1us 1320 + + +void wait_10ms(void) +{ + asm + { +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 + } +} + +void sd_com(void) // byt senden und holen --------------------- +{ + + asm + { + + 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 + } +} + +void sd_get_status(void) // status holen ------------------------------- +{ + asm + { +sd_get_status: + move.b #0xff,d4 + bsr sd_com + cmp.b #0xff,d5 + beq sd_get_status + } +} + +void sd_rcv_info(void) // daten holen ---------------------------- +{ + asm + { + 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,(a2)+ + subq.l #1,d3 + bne sd_rcv_rd_rb + } +} + +void sd_card_idle(void) +{ + + asm + { +// sd idle +// speed =400kHz + move.l #0x082000ff,d4 // tx vorbesetzen + 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 + } +} + +int sd_card_init(void) +{ + + 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�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; +} + +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�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; +}