Forum: Mikrocontroller und Digitale Elektronik Hilfe bei ARM LPC2138 mit EFSL SD Card Anwendung


von Christian J. (Gast)


Lesenswert?

Hallo,

vielleicht rettet mich mal jemand, bevor ich das Demoboard von Olimex 
aus dem Fenster peffere :-(

Ich habe eine SD Karte mit Pull Ups an die Pins des LPC2138 der SPI0 
angeschlossen. Sieht soweit alles richtig aus.

Für die EFSL von Sourceforge Net habe ich mich entschieden, weil die am 
besten dokumentiert ist, andere mögen bessere Codes haben aber die sind 
teilweise kaum lesbar oder lassen sich nicht durchkompilieren ohne 
tausend Änderungen.

Ich habe einiges umgeschrieben, da ich Debug Infos nicht über die Uart 
ausgeben will (weiss auch nicht wie ich printf auf uart umsetzen soll) 
sondern die debug_printf Funktion von Crossworks, die direkt auf ein 
internes Terminal der Oberfläche ausgibt.

Die Karte initialisiert nicht einmal, bricht sofort ab, reagiert nicht 
auf CMD0. Soweit das auf dem Oszi zu sehen ist klickern da aber Daten.

Was mich wundert:

In der ESL wird bei Benutzung von SPI0 jedesmal vor dem Senden eines 
Bytes der Chipselect gezogen. Wieso das? Bei meiner PIC Implemenation 
war Chipselect dauert unten solange Daten liefen.

Ne Frage: Hat das schonmal jemand auf einem Olimex LPC Board, vielleicht 
sogar mit Rowley Crossworks hinbekommen?

Gruss,
Christian

von Christian J. (elektroniker1968)


Lesenswert?

Hallo,

ich lege nochmal nach, nachdem es gestern nacht 3.40 Uhr wurde bevor mir 
die Augen zufielen.

Bei der Durchsicht diverser im Netz kursierender Sourcen fiel mir 
einiges auf:

Ulrich Radig: Webbox:
1
// setup MISO pin P05
2
  PCB_PINSEL0 &= ~(3<<10);
3
  PCB_PINSEL0 |= (1<<10);
4
  // setup MOSI pin P06
5
  PCB_PINSEL0 &= ~(3<<12);
6
  PCB_PINSEL0 |= (1<<12);
7
  // setup SSEL pin P07        // WICHTIG: auch wenn es nicht benutzt wird...
8
  PCB_PINSEL0 &= ~(3<<14);    // ansonsten läuft die ganze SPI nicht

Er behauptet, dass die SPI0 des LPC2xxxx nicht funktioniert, wenn er 
nicht den SSEL Pin als "Slave Select" konfiguriert. Ich wage das zu 
bezweifeln, denn im ARM LPC Manual von NXP heisst es, dass dieser Pin 
nicht von der Hardware gesteuert wird und manuell gesetzt werden muss, 
indem der Pin als normales I/O gesetzt werden muss. Wird er als SSEL 
gesetzt wird es ein Eingang, der den ARM als Slave konfuguriert, wenn 
der Pin low gezogen wird.
Ulrich hat den Pin daher lieber gar nicht verwendet, aber auf Eingang 
gestellt, was ich für gefährlich halte ohne Pull Up.

EFSL Code von Martin  auf "ARM Projects":
1
uint8 if_spiSend(hwInterface *iface, euint8 outgoing)
2
{
3
  euint8 incoming;
4
5
#if ( HW_ENDPOINT_LPC2000_SPINUM == 0 )
6
  SELECT_CARD();
7
  S0SPDR = outgoing;
8
  while( !(S0SPSR & (1<<SPIF)) ) ;
9
  incoming = S0SPDR;
10
  UNSELECT_CARD();
11
#endif
12
13
#if ( HW_ENDPOINT_LPC2000_SPINUM == 1 )
14
  // SELECT_CARD();  // done by hardware
15
  while( !(SSPSR & (1<<TNF)) ) ;
16
  SSPDR = outgoing;
17
  while( !(SSPSR & (1<<RNE)) ) ;
18
  incoming = SSPDR;
19
  // UNSELECT_CARD();  // done by hardware
20
#endif

Für SPI0 wird hier ganz klar Chip Select manuell gezogen und zwar bei 
jedem gesendetem Byte. Das ist defintiv falsch, CS bei der SD Karte muss 
während des gesamten Frames unten sein, weil es ein Microwire Protokoll 
ist. Für Microwire lässt sich nur SPI1 konfugurieren, da ist es aber 
richtig gemacht.

Des weiteren:

Bei Ulrich Radig wird CPOL=1 gesetzt, also idle = Clock High, active = 
Clock low. Bei Maartin ist CPOL = 0 gesetzt.

Beides kann aber nicht sein, nur eines ist richtig und ich meine CPOL=1.

Was meinen die Cracks?

von Daniel S. (dschwab)


Lesenswert?

Hi

Hier hat es eine Anleitung zu deinem Problem:
http://arm.hsz-t.ch/wiki/bin/view/Main/SoftwareARMBoard

Bye, Daniel

von Christian J. (Gast)


Lesenswert?

Hallo,

danke für den Tip:

Da steht
1
PINSEL0 = PINSEL0 | 0x00000100;                 // SCK 0  Port 0.4
2
PINSEL0 = PINSEL0 | 0x00000400;                 // MISO 0  Port 0.5
3
PINSEL0 = PINSEL0 | 0x00001000;                 // MOSI 0  Port 0.6
4
PINSEL0 = PINSEL0 | 0x00004000;                 // SSEL 0  Port 0.7
5
IO1DIR = IO1DIR   | SPI_CS;                     // Port als Output definieren
6
                                                // GPIO CS   Port 1.25 (Chip Select wird mit einem GPIO gemacht)
7
                                                // Muss bei Masterbetrieb auf HIGH sein, Pin auf 3.3V legen.

Card Select wird da auch mit einem anderen Pin gemacht. P1.25. SSEL wird 
als solcher definiert. Also die Konfiguration wo ich nicht mehr ins SPI 
Register schreiben kann, weil es nie "leer" wird.

Was ich jetzt nicht verstehe ist, warum SSEL erst auf Output gesetzt 
wird und dann ein Widerstand gegen Vcc gelegt wird. Das macht ja wenig 
Sinn.

von Daniel S. (dschwab)


Lesenswert?

Hi

SSEL muss bei Masterbetrieb (wenn der Mikrocontroller der Chef auf der 
Leitung ist) auf HIGH sein. Sonst läuft die SPI nicht.

Das CS (Chip Select) kann irgend ein GPIO sein, da das CS nichts mit dem 
SPI zu tun hat.

PINSEL0 sagt, welcher GPIO umfunktioniert werden soll und hat nichts 
damit zu tun, ob der GPIO als Input oder Output läuft.

Dies gehört zur SPI:
SCK, MOSI, MISO, SSEL

Dies gehört zur MMC/SD-Card:
SCK, MOSI, MISO, SSEL, CS (Chip Select), WR (Write Protected), CDS (Card 
Detect Switch)

Wie du siehst, braucht die MMC/SD-Card 3 Leitungen mehr und die werden 
an normale GPIO angeschlossen.

Man kann es auch so lösen, dass man WR und CDS gar nicht an GPIO's 
anschliesst und die Fehler dann via die Softwarekommandos abfängt. Hängt 
nur ein Peripherie am SPI kann man sich den CS auch sparen.

bye, Daniel

von Christian J. (elektroniker1968)


Lesenswert?

Hi,

ach so, Du bist der Autor, klasse !!
1
#include "lpc22xx.h"
2
#include "system.h"
3
#include "spi.h"
4
5
void spi0_initialisierung (void)
6
{
7
unsigned char Register;
8
9
PINSEL0 = PINSEL0 | 0x00000100;                 // SCK 0  Port 0.4
10
PINSEL0 = PINSEL0 | 0x00000400;                 // MISO 0  Port 0.5
11
PINSEL0 = PINSEL0 | 0x00001000;                 // MOSI 0  Port 0.6
12
PINSEL0 = PINSEL0 | 0x00004000;                 // SSEL 0  Port 0.7
13
IO1DIR = IO1DIR   | SPI_CS;                     // Port als Output definieren
14
                                                // GPIO CS   Port 1.25 (Chip Select wird mit einem GPIO gemacht)
15
                                                // Muss bei Masterbetrieb auf HIGH sein, Pin auf 3.3V legen.
16
spi_speed(SPI_LOW_SPEED);                       // Clock Counter
17
18
S0SPCR   = 0x00;                // Control Register Löschen
19
S0SPCR   = S0SPCR | 0x80;       // Interrupt Einschalten
20
S0SPCR   = S0SPCR | 0x20;       // Master mode
21
S0SPCR   = S0SPCR | 0x10;       // Clock LOW aktiv
22
23
if (S0SPINT & 0x01)            // Wenn das Interruptflag gesetzt ist
24
        {
25
        S0SPINT = 0x01;        // Interruptflag zurück setzen
26
        }
27
28
// Statusregister laden
29
Register   = S0SPSR;      // Register lesen
30
Register   = S0SPDR;      // Empfangene Daten Speichern
31
}

ich versuche nochmal zu verstehen:

SSEL Pin wird auch als solcher zur SPI gehörig ausgewählt im PINSEL. Ist 
es dann Ausgang oder Eingang?

SSEL heisst "Slave Select" und da ist meine Frage: Wer selected hier 
wen? Wenn die SPI Master ist hat kein Slave was zu melden, also 
vielleicht doch ein Ausgang?

IODIR muss bei den Funktionspins also nicht gesetzt werdem, das macht 
der ARM von allein, richtig?

Die beiden Leitungen, die Du nennst sind bei mir nicht kontaktiert, da 
ich die SD Karte in einen ISA Slot schiebe. Ging bisher auch ohne diese. 
Das sind wohl die dünnen Pins links und rechts.

PS: Ich habe vergessen das zweite GND anzuschliessen, vermutlich daher 
auch keine Antwort. Werde ich heute nacht mal testen, jetzt leider keine 
zeit, Kinder kommen gleich aus dem KiGa.

Wenn die Hardwareschicht läuft hoffe ich mal, dass der efsl Protokoll 
Layer fehlerfrei arbeitet, da der ohne Kenntnis des Fat Systems schwer 
zu verstehen ist. Wenn es scheiter werde ich mal Deine Lösung versuchen 
mit Rowley zu kompilieren, wobei es ärgerlich ist, dass jeder Hersteller 
andere Registernamen verwendet als die, die im ARM Handbuch vorgegeben 
sind.

Die Idee mit SDRAM werde ich wohl vergessen müssen, ohne jeglöiche 
Messmittel kann das zum Drama werden das ans Laufen zu bekommen, wenn 
ich den LPC2478 verwende.

von Daniel S. (dschwab)


Lesenswert?

Hi

Das SSEL ist ein Aktiv LOW Input. Wenn du ihn also auf HIGH legst, ist 
deine SPI Schnittstelle im Masterbetrieb. Die MMC/SD-Card arbeitet immer 
im Slavebetrieb, somit ist dein LPC2138 immer im Masterbetrieb und 
kannst den GPIO auch gleich fest verdrahten auf HIGH.

Die Kommunikation läuft über MOSI und MISO, das so viel heisst wie: MOSI 
(Master Out, Slave In) und MISO (Master In, Slave Out)

Nun zu deiner Frage, was der LPC2138 denn richtig macht: Kopierst du 1 
Byte nach S0SPDR, dann sendet und empfangt der LPC2138 1 Byte an Daten. 
Ein Kommando für die MMC/SD-Card besteht aber aus einer Folge von 
Datenbytes. Ausserdem muss erst in den SPI Mode umgeschalten werden.

Wichtig sind nur diese Leitungen: SCK, MOSI, MISO, SSEL

Die Pinbelegung findest du hier:
http://arm.hsz-t.ch/wiki/bin/view/Main/ApplikationenMMC

bye, Daniel

von Dennis Schulz (Gast)


Lesenswert?

Hi,

also ich hätte da ein Crossworks-Projekt das funktioniert mit meinem 
LPC-P2148, bei Interesse meldest dich einfach.

Pantheron"at"googlemail dot com


Gruß Dennis

von Christian J. (Gast)


Lesenswert?

Hi,

kann mich leider noch nicht melden, da ich keinen Mail Client auf Linux 
derzeit habe (alles zu seiner Zeit... ich kämpfe noch) aber kannst mir 
gern schonmal das Projekt an admin_at_der-scirocco.de senden :-) Bitte 
auch angeben auf welchem Source das basiert oder ob komplett 
selbstgeschrieben.

Gruss,
Christian

von Christian J. (elektroniker1968)


Lesenswert?

Hallo,

hat sich erledigt, nach der Änderung mit dem Pin auf HIGH Potetial und 
des Anschliessens des 2.ten GND Pins lief die efsl sofort auf Anhieb, 
schrieb die Testdateien auf die Karte und gab das Verzeichnis aus. Ich 
wundere mich wirklich, da ich auf "gut Glück" den Code erheblich 
verschlankt habe, tausend #ifdefs für andere Controller raus und die SD 
Raw Routinen berichtigt.

So, wie das da zum Runterladen bei sourceforge.net steht läuft es 
jedenfalls nicht auf dem ARM, ich vermute mal dass die es auch nie 
wirklich getestet haben, sonst hätten sie den Fehler mit dem Chip Select 
und CPOL=1 bemerkt.

Ich werde den Code jetzt noch testen, eindeutschen und sauber 
formatieren, dann hier in die Codesammlung stellen.

Gruss,
Christian

von Christian J. (Gast)


Lesenswert?

Hallo,

bei den ersten Test mit der efsl 0.2... fiel mir auf, dass die Ausgabe 
eines Verzeichnisses nicht die tatsächlichen Dateinamen ausgibt sondern 
dass die Punkte zwischen Namen und Extension weggelassen werden, bzw 
werden Spaces im Rückgabestring eingefügt, wenn der Dateiname keine 8 
Zeichen hat. Das ergibt natürlich wenig Sinn, wenn ich die Dateinamen 
weiterverwenden will, also zB suchen und dann öffnen.

zB

text1.txt
text2.txt

als Ausgabe im String

text1   txt
text2   txt

Weiss jemand warum? Bzw wie man das ändern kann?

von holger (Gast)


Lesenswert?

>text1.txt
>text2.txt
>
>als Ausgabe im String
>
>text1   txt
>text2   txt
>
>Weiss jemand warum? Bzw wie man das ändern kann?

Das was da ausgegeben wird steht so tatsächlich
auf der Karte. Der '.' wird im Verzeichniseintrag
nicht gespeichert. Füg doch einfach einen ein ;)

von Christian J. (Gast)


Lesenswert?

Moment...

also wenn ich eine Datei "pups.txt" suche muss ich, bevor ich sie öffne 
erstmal die spaces entfernen, dann einen Punkt einsetzen, damit ich sie 
mit fopen öffnen kann, was eben "pups.txt" erwartet. Habe grad mal mit 
Diskedit nachgeschaut, Tatsache, die stehen da so.

PS: Holger Klabunde?

von holger (Gast)


Lesenswert?

>also wenn ich eine Datei "pups.txt" suche muss ich, bevor ich sie öffne
>erstmal die spaces entfernen, dann einen Punkt einsetzen, damit ich sie
>mit fopen öffnen kann, was eben "pups.txt" erwartet.

Genau so.

>PS: Holger Klabunde?

Möglicherweise ;)

von Christian J. (Gast)


Lesenswert?

>PS: Holger Klabunde?
>>Möglicherweise ;)

Was macht das Laserjammer Projekt? Rohbau war ja fertig ;-)

von holger (Gast)


Lesenswert?

>Was macht das Laserjammer Projekt? Rohbau war ja fertig ;-)

Ds ist nicht von mir. War wohl ein anderer holger.

von Christian J. (Gast)


Lesenswert?

http://www.holger-klabunde.de/
1
Ich entwerfe in der Regel keine Schaltungen oder Programme für
2
andere. Dazu fehlt mir einfach die Zeit. Schon gar nicht Radar- oder 
3
Blitzlichtstörgeräte. Auf sowas antworte ich gar nicht erst.

:-)))

von holger (Gast)


Lesenswert?

@ Christian J.

>Ich entwerfe in der Regel keine Schaltungen oder Programme für
>andere. Dazu fehlt mir einfach die Zeit. Schon gar nicht Radar- oder
>Blitzlichtstörgeräte. Auf sowas antworte ich gar nicht erst.

Und das stimmt auch so. Ich habe solche Geräte nicht gebaut
und würde sie auch nicht bauen.

von Christian J. (elektroniker1968)


Lesenswert?

Nicht tragisch... hier sass der "Richtige" dafür:

http://www.fingers-welt.de/home.htm

Feiner Kerl :-)

von holger klabunde (Gast)


Lesenswert?

An die Moderatoren:

Könnte man den Blödsinn mit dem Laserjammer
unter meinem Namen hier bitte mal löschen?

Danke.

von wolfgang (Gast)


Lesenswert?

Hallo Christian,

du schriebest:
SSEL heisst "Slave Select" und da ist meine Frage: Wer selected hier
wen? Wenn die SPI Master ist hat kein Slave was zu melden, also
vielleicht doch ein Ausgang?....

Also: Ich habe das schon durch: Die Controller von NXP sind in vielen 
Details schlecht konstruiert und auch schlecht dokumentiert. Die 
SPI-Schnittstellen funktionieren allesamt NICHT, wenn man das lt. Doku 
für einen reinen Master-Betrieb unnötige SSEL für etwas anderes benutzen 
will.
Du mußt also das zugehörige Portbein als SSEL konfigurieren und per 
Widerstand statisch auf den für den Master-betrieb nötigen Pegen (war 
glaub ich High) legen. Dieses Pin ist für jede andere Verwendung 
VERLOREN!

Ich hatte es in einem meiner Entwürfe woanders verwenden müssen und als 
Konsequenz daraus den ganzen SD-Kartenverkehr per Software machen 
müssen. Ist aber auch nicht viel langsamer als mit der SPI-Hardware, da 
man ja bei EFSL immer auf jede Aktion warten muß.

Alles Gute
Wolfgang

von Christian J. (Gast)


Lesenswert?

Hallo Wolfgang,

das mit dem widerstand weiss ich schon, es stand in einer Homepage, die 
das Thema SPI gut erklärte. Ich habe mich totgesucht, bis ich drauf 
gekommen bin warum die verf... SPI nicht lief.

Die EFSL funzt bei mir super nachdem ich alles rausgestriohen habe was 
nicht mit dem ARM zu tun hat, ausserdem waren da noch Fehler 
hinsichtlich der SPI Bedienung drin, erst danach lief es.

von holger (Gast)


Lesenswert?

>SSEL heisst "Slave Select" und da ist meine Frage: Wer selected hier
>wen? Wenn die SPI Master ist hat kein Slave was zu melden, also
>vielleicht doch ein Ausgang?....

Der Master selected den Slave. Ergo ist SSEL ein Eingang.

>Also: Ich habe das schon durch: Die Controller von NXP sind in vielen
>Details schlecht konstruiert und auch schlecht dokumentiert. Die
>SPI-Schnittstellen funktionieren allesamt NICHT, wenn man das lt. Doku
>für einen reinen Master-Betrieb unnötige SSEL für etwas anderes benutzen
>will.
>>Du mußt also das zugehörige Portbein als SSEL konfigurieren und per
>Widerstand statisch auf den für den Master-betrieb nötigen Pegen (war
>glaub ich High) legen. Dieses Pin ist für jede andere Verwendung
>VERLOREN!

Nö, musst du nicht. Du definierst den SSEL Pin einfach als
Ausgang und benutzt ihn als z.B. /CS für die SD Karte.
Funktioniert bei mir super.

Wenn du die SSEL Funktion für den Pin einstellst ist SSEL eben
ein Eingang, der wenn er auf 0 gezogen wird den uC auf Slave
umschaltet. Falls der uC der einzige Master ist macht es
keinen Sinn diesen Pin auf die SSEL Funktion zu programmieren.

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.