Forum: Projekte & Code MMC/SD CRC7 R8C/M16C/M32C


von Sascha Pypke (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, mache zur Zeit privat eine kleine Entwicklung für MMC/SD 
Flashkarten
und habe niergends im WEB eine Routine für CRC7 gefunden.
Deshalb mal kurz selber gemacht.....

Zwei Methoden einmal eine langsamere aber dafür Code schonend, und eine 
schnelle. Die schnelle könnte man theoretish um einen Befehl noch 
verkürzen, wenn man die Tabelle dafür ändert....

Die Routinen habe ich für M32C geschrieben, müssten aber auch auf R8C 
und M16C ohne Probleme auch gehen.

Bei Fehler oder Fragen mail an mich, steht im source code....
Gruß Sascha

von Joachim (Gast)


Lesenswert?

In welchem Modus bereibst Du die Karte?
SD-Modus macht eigentlich nur Sinn im 4Bit-Modus.
Bei Verwendung einer SPI-Schnittstelle (die zudem bei den M16/M32 sehr 
lahm ist) kann die Karte auch im SPI-Mode betrieben werden.
Und da brauchts keine CRC.
Eine manuelle Berechnung der CRC wird die Karte im SD-Mode langsamer 
machen, als im SPI-Mode ohne CRC.

von Sascha Pypke (Gast)


Lesenswert?

Ja, im SPI Mode ist prinzipiell die CRC nach CMD00 aus.
Aber ich verwende trotzdem die CRC um gegen Fehler vorzubeugen.
(schalte die CRC also wieder ein...)
Die CRC16 ist kein Problem, das macht der Kontroller in Hardware.
Und die CRC7 geht auch recht flott.
Die Übertragung könnte schneller sein, aber bei meinem M32C85 ist es 
immerhin
noch 16MHz das reicht mir.

Klar 4bit Mode und neuerdings 8bit wäre besser. Bei 8bit könnte man die 
DMA einsetzen.

Wenns etwas mehr kosten darf nehme ich halt einen CPLD als Interface....
In meiner Aplication geht es nicht unbedingt um Multimedia sondern um 
Datenrecording. Das ganze mobil, also kann die Karte schon mal 
Kontaktprobleme im Sockel (Kartenhalter) bekommen, deshalb CRC.

Aber bei 25MHz hört der ganze Spaß doch eh auf ???? (highspeed Mode 52 
MHz ???)

Gruß Sascha

von Hans H. (hanshein)


Lesenswert?

Anbei eine kleine crc7 (X^7 + X^3 + 1) ohne Schleifen und ohne Tabellen
fuer den guten alten 8051.Die crc7 wurde dabei algebraisch partiell
evaluiert. Die Bits wurden bereits so gelegt wie sie in der MMC
Uebertragung erwartet werden, sprich letztes Byte = CRC7 . 1, daher muss
es auch so initialisiert werden. Benutze ich die Sascha's 
Tabellenvariante,
ist Sascha (auf 8051) 3 mal schneller. (Hint: Die Routine (~30 Bytes)
ist dadurch zustande gekommen, dass ich mir Sascha's Code angesehen habe
und mit "das geht auch kuerzer" meinen Rechner hochgefahren habe ;-)

-Hans

PS: Dankeschoen Sascha, fuer die Tabellenroutine!
PPS: In Klammern die Cycles auf dem '51er.
PPPS: Alle 32768 Varianten (7Bit CRC, 8Bit Eingabe) wurden mit
    Sascha's Routine (maschinell) crossgechecked
    (Vergleich: (Sascha-CRC<<1 bit-or 00000001b) == Hans-crc7 ).
PPPPS: Ich bin mir fast sicher, dass man mit einer "7-Bit" Tabelle
    bei Sascha auskommen muesste. Diese Symetrien! Any ideas?
    (Das war die urspruengliche Motivation :-)


-x-x-x- snip -x-x-x-x-

; CRC7-Code: X^7 + X^3 + 1
; (C)Hans Hein, GPL license, please find the text of the license using:
; http://www.gnu.org/licenses/gpl-2.0.html
; initial Idea originating from: Sascha Pypke,
; see Beitrag "MMC/SD CRC7 R8C/M16C/M32C"
; crc7 in memory, incomming data in Acc A
; crc7(ABCDEFG) is layouted as follows:  A.B.C.D  E.F.G.1 (static 1)
; need High Speed: use table method, medium speed: use this code 
(29cycls),
; low speed: loop method, but check memory requirements as low
; speed and more code is some sort of stupid.

         .equ    crc7,0x40

crc7_init:
        mov     crc7,#00000001b
        ret

crc7:   xrl     a,crc7  ; (1)
        cpl     acc.0   ; (1)
        mov     r0,a    ; (1)
        anl     a,#0xf0 ; (2)
        mov     r1,a    ; (1)
        mov     a,r0    ; (1)
        setb    c       ; (1)
        rlc     a       ; (1)
        jnc     crc71   ; (2) ; need to xor-bit Carry bit, but
        cpl     acc.1   ; (1) ; 8051 only has BIT- cpl, or, and, set, 
clr
crc71:  xrl     a,r1    ; (1)
        xch     a,r0    ; (1)
        swap    a       ; (1)
        mov     r1,a    ; (1)
        anl     a,#0xf0 ; (2)
        xrl     a,r0    ; (1)
        xch     a,r1    ; (1)
        anl     a,#07h  ; (2)
        rl      a       ; (1)
        xrl     a,r1    ; (1)
        mov     crc7,a  ; (1) crc= 7BitCRC.1
        ret             ; (2) (LCALL=2)

-x-x-x-x- snip -x-x-x-x-xx-

Zum Checken (Response of CMD17):
  mov  crc7,#00000001b
  mov  a,#0x11
  lcall  crc7
  mov  a,#0x00
  lcall  crc7
  mov  a,#0x00
  lcall  crc7
  mov  a,#0x09
  lcall  crc7
  mov  a,#0x00
  lcall  crc7
  ljmp  MONITOR-ODER-AUSGABE-von-crc7

        rauskommen muss: CRC7=0110011.(1) = 0x67

von Hans H. (hanshein)


Lesenswert?

Ok, so geht es mit einer 128-Byte Tabelle. Jeder zweite Eintrag
war mit 00001001 ge-xored --- d.h. in Abhaengigkeit von Bit0
des Inputs. Beim 8051 faengt man sich durch die Kuerzung der
Tabelle ein Plus von 2 Cycles pro Durchgang ein... Sascha wins :-)

Viele Gruesse,
Hans

; MMC/SD CRC Polynom X^7 + X^3 + 1
crc7taba:
        mov     dptr,#CRC7_TABA  ; (2)
  clr  c    ; (1)
  rrc  a    ; (1)
  xrl  a,crc7ta  ; (1)
        movc    a,@a+dptr  ; (2)
  jnc  crc7m    ; (2)
  xrl  a,#00001001b  ; (1)
crc7m:  mov  crc7ta,a  ; (1)
  ret      ; (2) (LCALL=2)

CRC7_TABA:
  .byte 0x00,0x12,0x24,0x36,0x48,0x5a,0x6c,0x7e
  .byte 0x19,0x0b,0x3d,0x2f,0x51,0x43,0x75,0x67
  .byte 0x32,0x20,0x16,0x04,0x7a,0x68,0x5e,0x4c
  .byte 0x2b,0x39,0x0f,0x1d,0x63,0x71,0x47,0x55
  .byte 0x64,0x76,0x40,0x52,0x2c,0x3e,0x08,0x1a
  .byte 0x7d,0x6f,0x59,0x4b,0x35,0x27,0x11,0x03
  .byte 0x56,0x44,0x72,0x60,0x1e,0x0c,0x3a,0x28
  .byte 0x4f,0x5d,0x6b,0x79,0x07,0x15,0x23,0x31
  .byte 0x41,0x53,0x65,0x77,0x09,0x1b,0x2d,0x3f
  .byte 0x58,0x4a,0x7c,0x6e,0x10,0x02,0x34,0x26
  .byte 0x73,0x61,0x57,0x45,0x3b,0x29,0x1f,0x0d
  .byte 0x6a,0x78,0x4e,0x5c,0x22,0x30,0x06,0x14
  .byte 0x25,0x37,0x01,0x13,0x6d,0x7f,0x49,0x5b
  .byte 0x3c,0x2e,0x18,0x0a,0x74,0x66,0x50,0x42
  .byte 0x17,0x05,0x33,0x21,0x5f,0x4d,0x7b,0x69
  .byte 0x0e,0x1c,0x2a,0x38,0x46,0x54,0x62,0x70

von Sascha Pypke (Gast)


Lesenswert?

Ja Super,
finde ich klasse, besonders die Methode mit reiner schaltalgebra, die 
ist auch für VHDL und Verilog sehr Intressant.
Werde die Tage den 8051 Code auf meinen M16C übersetzten.
Gruß Sascha

von Sascha Pypke (Gast)


Angehängte Dateien:

Lesenswert?

So und hier die Version von Hans Hein übersetzt auf R8C/M16C mit einer
Tebelle mit 128 Einträge.
Gruß Sascha

von Jochen A. (jochenadler)


Lesenswert?

Wenn man eine SD-Karte im SPI-Modus betreibt, dann muss man eigentlich 
keine CRC-Prüfsumme über die Kommandos berechnen. Es gibt allerdings 
zwei Ausnahmen: CMD0 und CMD8.
Bei CMD0 ist die CRC immer die gleiche und auch in den DOCs angegeben 
($40, $00, $00, $00, $00, $95).
Beim CMD8 muss man es selbst berechnen. Ich habe dies mal für ein 
Kommando, das für 2,7-3,6V ist, berechnet:
$48 ,$00, $00, $01, $aa, $87

von Olaf (Gast)


Lesenswert?

> Wenn man eine SD-Karte im SPI-Modus betreibt, dann muss man eigentlich
> keine CRC-Prüfsumme über die Kommandos berechnen.

Wenn man den ueblichen Mist entwickelt der bei Aldi an der Kasse 
rumliegt, dann nicht. Wenn man ernsthaft arbeitet und Datensicherheit 
von Bedeutung ist, dann schon.

Olaf

von Devil Elec (Gast)


Lesenswert?

Hallo,

ich möchte mit meinem R8C13 Messdaten auf eine SD-Card schreiben.
Kann aber mit dem Code der Datei CRC7_128T.a30 nichts anfangen.

Gibt es vielleicht jemanden der seinen Programmcode zur Verfügung 
stellt?

Wäre sehr nett.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.