Forum: Compiler & IDEs SD-Lib Daniel R.: seltsamer Fehler auf AVR32


von Theo (Gast)


Lesenswert?

Hey,

ich versuche die FAT-Lib von Daniel R. aus der Codesammlung hier auf 
einen
AT32UC3A1512 zu portieren. Die SPI-Routinen funktionieren. Ein Problem 
tritt an anderer Stelle auf:

(aus der Datei fat.c in Funktion fat_loadFatData)
...
usart_write_line(&AVR32_USART3,"1 ");

vsector=&fat.sector[14];
fat.fatSec=*((unsigned short*)vsector);

usart_write_line(&AVR32_USART3,"2 ");
vsector=&fat.sector[17];
rootEntCnt=*((unsigned short*)vsector);

usart_write_line(&AVR32_USART3,"3 ");
vsector=&fat.sector[22];
fatSz16=*((unsigned short*)vsector);

usart_write_line(&AVR32_USART3,"4 ");
...

"vsector" ist ein unbestimmter Zeiger (*void). "fat.sector" ist ein 
char[512].

Die usart_write_line() habe ich eingefügt, um den Fehler einzugrenzen.
Auf meinem Terminalprogramm erhalte ich die Ausgabe "1 2".
Vor Punkt3 bleibt der AVR32 stehen. Wenn ich eine andere (sinnlose) 
Zuweisung eintrage, läuft er durch bis 4.
Das Problem muss also etwas mit der gecasteten Zuweisung zu tun haben, 
obwohl darunter und darüber das gleiche nochmal gemacht wird!
Eine Änderung in "rootEntCnt=*((unsigned short*)vsector);", also nur die 
Klammer mehr, bringt auch nichts (endet wieder vor Punkt 3). Beim 
Compiler sind alle Optimierungen abgeschaltet. Ich verwende den 
gnu-toolchain 2.4.2.
Was ist da los?

von Theo (Gast)


Lesenswert?

Ups, ich habe euch meine Änderungen statt dem Orginal-Code gepostet, der 
muss heißen:

...
usart_write_line(&AVR32_USART3,"1 ");

vsector=&fat.sector[14];
fat.fatSec=*(unsigned short*)vsector;

usart_write_line(&AVR32_USART3,"2 ");
vsector=&fat.sector[17];
rootEntCnt=*(unsigned short*)vsector;

usart_write_line(&AVR32_USART3,"3 ");
vsector=&fat.sector[22];
fatSz16=*(unsigned short*)vsector;

usart_write_line(&AVR32_USART3,"4 ");
...

von Werner B. (werner-b)


Lesenswert?

Der AVR32 ist ein BIG ENDIAN Prozessor. Das FAT Dateisystem ist für den 
LITTLE ENDIAN 8086 ausgelegt (und auch der AVR wird als LITTLE ENDIAN 
"betrieben"). Du musst also die Reihenfolge der Bytes beim/nach dem Cast 
aus/in die Struktur(en) umdrehen.

<mitleid state="on">
Da hast du etwas Größeres vor dir
Viel Spass
</mitleid>

Referenzen:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=520357
http://en.wikipedia.org/wiki/AVR32
http://en.wikipedia.org/wiki/Atmel_AVR

von Theo (Gast)


Lesenswert?

Du hast nichts verstanden...
Die Daten sind nicht vertauscht, der Prozessr bleibt stehen!

>>Der AVR32 ist ein BIG ENDIAN Prozessor
Der AP-Prozessor ist ein  BIG ENDIAN, UC3A-Core ist ein Little-Endian!
Andernfalls würde der Schnippsel hier:

char d[2] = {0x01, 0xFF};
void* R = &d[0];
char mess[20];
U16 T = *((U16*)R);
sprintf(&mess, "T: %d",T);
usart_write_line(&AVR32_USART3,mess);

kein 511, sondern ein 65281 aufs Terminal zaubern.

Wenn du schon keine Ahnung hast, solltest du wenigstens das hier 
beachten:
http://www.mikrocontroller.net/articles/Netiquett

von Werner B. (werner-b)


Lesenswert?

Theo schrieb:
> UC3A-Core ist ein Little-Endian!

Dann weisst du mehr als Atmel.

Auszug aus doc32000.pdf "AVR32
Architecture
Document" Kapitel 2.2

Download über 
http://www.atmel.com/dyn/products/product_card.asp?part_id=4122

------------------------------------------------------------------------ 
---
2.2 Data Organization
Data is usually stored in a big-endian way, see Figure 2-1 on page 5. 
This means that when
multi-byte data is stored in memory, the most significant byte is stored 
at the lowest address. All
instructions are interpreted as being big-endian. However, in order to 
support data transfers that
are little-endian, special endian-translating load and store 
instructions are defined.
------------------------------------------------------------------------ 
---

P.S. Abgesehen davon finde ich es ein Frechheit von dir jemanden so 
anzufahren der dir nur helfen will. Siehe erst einmal in den Spiegel.

von Theo (Gast)


Lesenswert?

>> <mitleid state="on">
>> Da hast du etwas Größeres vor dir
>> Viel Spass
>> </mitleid>

Das keine Hilfe, das ist reiner Hohn!
Bevor du bei anderen von Frechheit sprichst, ließ mal, was du 
geschrieben hast.

von Werner B. (werner-b)


Lesenswert?

Das heisst nix anderes als dass ich mitleid habe weil du so einen riesen 
brocken arbeit vor dir hast.
Nix reininterpretieren.
Im übrigen bestätigt dein Beispiel dass es ein Big Endian Proz ist.

char d[2] = {0x01, 0xFF};  // == 511 in big endian

Definition Big-Endian: "the most significant byte is stored at the 
lowest address."

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Falls es nicht unbedingt die besagte Library aus der Codesammlung sein 
muss:

- Zumindest in einem der von Atmel angebotenen Softwarepackete für AVR32 
ist FAT-Code inkl. "Treibern" für Speicherkarten drin 
(atmel.com->AVR32->Software-Package o.ä.). War sogar beim letzten Mal 
drüberschauen (länger her) für FreeRTOS vorbereitet.

- ChaN's FAT-code (google: chan fatfs) kann per Makro auf "Byte-by-byte 
access" konfiguriert werden. Damit sollte es keine Probleme mit 
endianess oder aligments geben. Zumindest einen Test wert.

von Thomas D. (t0mmy)


Lesenswert?

Ich habe vor einiger Zeit auch viele FAT-Libs auf einem AT32UC3A0512 
ausprobiert, die ich hier so gefunden hab. Keine hat funktioniert.
Ich hab dann in den sauren Apfen gebissen und mich durch die 
FAT-Routinen des Framework gekämpft. Hab es damit dann auch zum laufen 
bekommen.

Vielleicht hast du damit ja auch mehr Erfolg?

Grüße
Thomas

von R. F. (rfr)


Lesenswert?

In der Procyon-lib ist das lauffähig für den Atmel enthalten.
Gruss
Robert

von Theo (Gast)


Lesenswert?

>>Zumindest in einem der von Atmel angebotenen Softwarepackete für AVR32
>>ist FAT-Code inkl. "Treibern" für Speicherkarten drin
>>(atmel.com->AVR32->Software-Package o.ä.). War sogar beim letzten Mal
>>drüberschauen (länger her) für FreeRTOS vorbereitet.

Ja, die kenne ich. Ich fand die von Daniel R. übersichtlicher, deshalb 
wolte ich sie probieren.

>>- ChaN's FAT-code (google: chan ) kann per Makro auf "Byte-by-byte
>>access" konfiguriert werden. Damit sollte es keine Probleme mit
>>endianess oder aligments geben. Zumindest einen Test wert.
Du meinst damit die "große" FAT-Lib von Chan?
Die versuche ich gerade umzuschreiben, indem ich den Beispiel-AVR-Code 
anpassen. Hoffentlich sitze ich da nicht dem Endian-Pferd auf.
Das ARM-Beispiel nutzt leider nicht SPI, sonst würde ich mich daran 
orientieren. Auf der anderen Seite: Wenn Thomas sagt, dass die Atmel-Lib 
bei ihm gut funktioniert, dann werde ich mich auch lieber daran halten.

>>Ich hab dann in den sauren Apfen gebissen und mich durch die
>>FAT-Routinen des Framework gekämpft. Hab es damit dann auch zum laufen
>>bekommen.
Könntest du mir deine conf_access.h als Orientierung zur Verfügung 
stellen? Das Beispiel von Atmel behandelt statt einer SD-Karte einen 
at45dbx-Flash, was man wohl in conf_access.h umstellen kann(?). Wäre 
sehr nett von dir.

>>In der Procyon-lib ist das lauffähig für den Atmel enthalten.
Ich habe das mal gegoogelt und eine ältere Version für die 8-Bitter 
gefunden. Gibt es die auch für die 32-Bitter?

von weißgradnich (Gast)


Lesenswert?

>> Das ARM-Beispiel nutzt leider nicht SPI, sonst würde ich mich daran
>> orientieren.

Auf der WinARM-Seite von M. Thomas gibt's was für ARM & SPI.
Einmal für SAM7: 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html

für Cortex M3 
http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html#stm32_memcard

mfg

von weißgradnich (Gast)


Lesenswert?

...sollte auch nicht unerwähnt bleiben: 
http://embdev.net/articles/ARM_MP3/AAC_Player

mfg

von Thomas D. (t0mmy)


Angehängte Dateien:

Lesenswert?

So hier mal mein CONFIG-Ordner. Fragt mich nicht, ob ich das 
Ordnungsgemäß gemacht hab oder nicht. Es funktioniert bei mir 
jedenfalls.

Zugreifen auf das ganze tu ich dann so:
1
extern "C"
2
{
3
  #include "gpio.h"
4
  #include "spi.h"
5
  #include "sd_mmc_spi.h"
6
  #include "fsaccess.h"
7
}
8
9
  [spi-config hier]
10
  spi_enable(SD_MMC_SPI);
11
  ready = sd_mmc_spi_init(spiOptions, FPBA);
12
  b_fsaccess_init();
13
14
  OpenForRead((char*)"A:\\bla.txt")

von Theo (Gast)


Lesenswert?

Hey,

Danke für die Libs. Ich weiß nicht, was ich falsch mache, aber bei mir 
nutzt er den falschen NCPS-Pin. Ich habe in der Board.h auf meine eigene 
Board-Datei verwiesen. In der steht folgendes:

#define SD_MMC_CARD_DETECT_PIN      AVR32_PIN_PB13
#define SD_MMC_WRITE_PROTECT_PIN    AVR32_PIN_PB14
#define SD_MMC_SPI                  (&AVR32_SPI1)
#define SD_MMC_SPI_NPCS             1 //AVR32_SPI1_NPCS_1_0_PIN
#define SD_MMC_SPI_SCK_PIN          AVR32_SPI1_SCK_0_0_PIN
#define SD_MMC_SPI_SCK_FUNCTION     AVR32_SPI1_SCK_0_0_FUNCTION
#define SD_MMC_SPI_MISO_PIN         AVR32_SPI1_MISO_0_0_PIN
#define SD_MMC_SPI_MISO_FUNCTION    AVR32_SPI1_MISO_0_0_FUNCTION
#define SD_MMC_SPI_MOSI_PIN         AVR32_SPI1_MOSI_0_0_PIN
#define SD_MMC_SPI_MOSI_FUNCTION    AVR32_SPI1_MOSI_0_0_FUNCTION
#define SD_MMC_SPI_NPCS_PIN         AVR32_SPI1_NPCS_1_0_PIN
#define SD_MMC_SPI_NPCS_FUNCTION    AVR32_SPI1_NPCS_1_0_FUNCTION

trotzdem löscht er den 2 oder 3 NCPS-Pin (kann ich nicht unterscheiden, 
sehe es aber am am Oszi). Ich erhalte auch keine Warnung ala 
"SD_MMC_SPI_NPCS redefined".
Im Prinzip besteht mein Programm im Moment nur aus

while(1)
{
  nav_reset();
  nav_drive_set(0);
  nav_partition_mount();

  nav_file_create("Start.txt");
  file_open("Start.txt");
  file_close();
  gpio_tgl_gpio_pin(AVR32_PIN_PB21);
};

Die Initialisierung des SPI geschieht in einer eigenen, vorher 
aufgerufenen Funktion.
Die aber kann nicht so falsch sein, denn für die andere Komponente an 
dem (selben) SPI-Bus klapp das bestens.


...
int  SD_spi_opt = 0 << AVR32_SPI_CSR1_CPOL_OFFSET| //Inaktiver Takt Low;
        1 << AVR32_SPI_CSR1_NCPHA_OFFSET | // Aktive Flanke ist 1
        0  << AVR32_SPI_CSR1_CSNAAT_OFFSET |
       1 << AVR32_SPI_CSR1_CSAAT_OFFSET | // Deselektiere Baustein 
nicht!
        0 << AVR32_SPI_CSR1_BITS_OFFSET | //  8Bit Modus
        200 << AVR32_SPI_CSR1_SCBR_OFFSET | //langsamer Takt: PBA/200
        10 << AVR32_SPI_CSR1_DLYBS_OFFSET | // 11zyklen, nach fall von 
Cs
        10 << AVR32_SPI_CSR1_DLYBCT_OFFSET;

AVR32_SPI1.csr1 = SD_spi_opt;
...

Wenn jemand eine Idee hat, warum der den falschen CS-Pin löscht, bitte 
schreiben.

von Theo (Gast)


Lesenswert?

So, Problem ist behoben, die FAT-Lib läuft! Allerdings arbeitet sie 
nicht mit SDHC-Karten, was komisch ist, weil die Routinen vorhanden 
sind...
Kennt jemand das Problem?

Ansonsten bedanke ich mich für die Hilfestellungen und die Dateien!

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.