SD CARD (Deutsch)

From Ethersex_Wiki
Jump to: navigation, search
SD/MMC-Card Reader
Status
Stable
menuconfig I/O->Storage->SD/MMC-Card Reader
Pinning yes
Ecmd yes
Control6 yes
Code https://github.com/ethersex/ethersex/tree/master/hardware/storage/sd_reader

Das Modul basiert auf Roland Riegels MMC/SD/SDHC card library ergänzt um die Anbindung an das Ethersex Virtual File System.

Anschluss

SD-Card Adapter Schaltung
SD-Card Adapter Aufbau
MicroSD-Card Adapter mit Level-Shifter aus China

MMC- und SD-Speicherkarten lassen sich im SPI-Modus relativ einfach mit einem Mikrocontroller ansteuern. Prinzipiell gibt es zwischen SD-Card und MMC nicht viele Unterschiede, allerdings sind SD-Karten weiter verbreitet, in der Regel schneller als MMCs, und haben ein besser implementiertes SPI-Interface. Es existieren diverse Varianten (miniSD, microSD), die zur normalen SD-Card weitgehend kompatibel sind.

Die Karte liest das anliegende Datenbit mit der steigenden Taktflanke ein, als SPI-Modi eignen sich somit Mode 0 und Mode 3. Bei MMCs ist der SPI-Modus nicht genau spezifiziert, somit kommt es durchaus mal vor, dass der SPI-Modus je nach Karte unterschiedlich gewählt werden muss.

SD-Karten werden typischerweise mit 3,3V und Microcontroller oft mit 5V betrieben. Das erzwingt eine Pegelanpassung, weil die Eingangsleitungen zur SD-Karte nicht 5V tolerant sind. Von einer Pegelanpassung mit Widerständen wird abgeraten.

Neben den Leitungen, die zur SD-Karte führen, gibt es noch zwei weitere Leitungen, die auf den SD-Karten-Sockel führen: nämlich die card-detect Leitung und die write-protect Leitung. Sie dienen dazu, wie die Namen schon sagen, das physische Vorhandensein einer Karte im SD-Sockel und die Stellung des Schreibschutzschiebers zu signalisieren.

Wird Hardware-SPI verwendet, muss nur die chip select Leitung konfiguriert werden. Die card-detect Leitung und die write-protect Leitung sind optional und bei MicroSD ohnehin nicht vorhanden.

 ifdef(`conf_SD_READER', `
   /* port the sd-reader CS is attached to */
   pin(SPI_CS_SD_READER, PB2, OUTPUT)
   /* uncomment and edit this if you have connected the CD (card detect) signal */
   pin(SD_READER_AVAILABLE, PD4, INPUT)
   /* uncomment and edit this if you have connected the WP (write protected) signal */
   pin(SD_READER_WR_PROTECT, PD5, INPUT)
 ')

Ein weiteres Problem bei den SD Karten ist die Initialisierung. Schafft es Ethersex nicht in einer bestimmten Zeit zu syncen, so fällt die Karte in den normalen (nicht den SD) Betriebsmodus und kann nicht mehr angesprochen werden. Eine Lösung dafür ist, dass die Karte eine steuerbare Stromversorgung erhält. Dazu definiert man im Pinning nur den Pin

  pin(SD_READER_POWERON, PB3, OUTPUT)

Sockel

Eine günstige Art der Kontaktierung ist wohl das Ausschlachten eines billigen Cardreaders, wenn man keine Kabel direkt an die Karte löten möchte. Einzeln gekaufte Steckverbinder sind meist erheblich teuerer. Man kann auch alte Floppy-Kabel als günstigen Steckverbinder benutzen. Teile von AT-Slots oder Verbinder von 5,25-Zoll-Floppys gehen auch. Notfalls kann man die Karte zwischen 2 Reihen Stiftleiste einklemmen (oder anlöten). Noch günstiger geht es wenn man Mikro- oder Mini-SD-Karten benutzt und den meist beigelegten Adapter anlötet.

Wer jedoch auf einen Selbstbau verzichten will, kann alternativ für relativ schmales Geld einen fertig aufgebauten SD-Adapter zum Anschließen an den AVR käuflich erwerben. Bei diesem Adapter ist bereits eine bidirektionale Pegelanpassung zwischen den 5V-Pegeln der Steuerleitungen des AVR und den 3,3V-Pegel der SD-Karte an Bord. Preiswerter können diese Module über ebay aus China bezogen werden.

Konfiguration

 | |        I/O  --->                                                    | |
 ...
 │ │        Storage  --->                                                │ │ 
 ...
 | |        [*] SD/MMC-Card Reader  --->                                 | |
 ...
 | |        [ ] SDHC support                                             | |
 | |        [*] VFAT LFN support                                         | |
 | |        [ ] Read-only mode                                           | |
 | |        [*] Use read-timeout                                         | |
 | |        [*] Ping-read SD card every 10s                              | |
 | |        --- ECMD Support                                             | |
 | |        [*] info                                                     | |
 | |        [*] dir                                                      | |
 | |        [*] mkdir                                                    | |
 | |        [*] rm                                                       | |
 | |        --- Debugging Flags                                          | |
 | |        [ ] FAT                                                      | |
 | |        [ ] RAW                                                      | |
 | |        [ ] VFS                                                      | |
   
 | |        General Setup  --->                                          | |
 ...
 | |        [*] VFS (Virtual File System) support  --->                  | |
 ...
 | |             [*] SD/MMC-Card Filesystem                              | |

ECMD

Das SD-CARD Modul implementiert eine ECMD Schnittestelle. Siehe ECMD Referenz.

Control6

Das folgende Beispiel schreibt Datum, Uhrzeit und Temperatur per VFS_LOG_ALLOCA (VFS_LOG erfordert UIP) in die Datei "temp.log" sobald sich die Temperatur um mehr als ein Grad zur letzten Messung verändert hat. Für Datum und Uhrzeit muss CLOCK_SUPPORT aktiviert sein.

#include <stdlib.h>

int16_t Temperatur;
int16_t Temperatur_alt;

CONTROL_START

THREAD(read_temp)
  Temperatur = ONEWIRE_GET(10d85594010800eb);
  ON abs(Temperatur-Temperatur_alt)>10 DO
    uint8_t sign = Temperatur<0;
    div_t res = div(abs(Temperatur),10);
    VFS_LOG_ALLOCA("temp.log", 50, "%2d.%2d.%4d %2d:%02d %S%d.%d", CLOCK_DAY, CLOCK_MONTH, CLOCK_YEAR, CLOCK_HOUR, CLOCK_MIN, sign?PSTR("-"):PSTR(""),res.quot,res.rem)
    Temperatur_alt = Temperatur;
  END
  WAIT(15);
THREAD_END(read_temp)

ON STARTUP DO
  Temperatur = Temperatur_alt = 0;
  THREAD_START(read_temp);
END

CONTROL_END