Forum: Mikrocontroller und Digitale Elektronik FATFS Datei erstellen und beschreiben


von Chris H. (hoc)


Lesenswert?

Hallo!

Ich arbeite derzeit an einem Projekt eine Art Datenlogger zu bauen. 
Dabei sollen zyklisch immer wieder Daten auf eine microSDHC-Karte 
geschrieben werden.

Ich verwende Elm Chans FAT Bibliothek und diese funktioniert ja auch 
teilweise nicht so schlecht. Die Funktionen disk_initialize, disk_read 
und disk_write habe ich geschrieben und scheinen auch zu 
funktionieren.Die Funktionen disk_status und disk_ioctl habe ich derzeit 
noch nicht geschrieben, da diese meiner Meinung nach für mich nicht 
notwendig sind.

Nun zum eigentlich Problem:
Ich mit dem Befehl f_open() eine Datei erzeugen. Möchte in diese Datei 
dann aber auch gleich Daten rein schreiben, bekomme ich als return value 
2 (FR_INT_ERR, Definition siehe unten)* zurück.
Erzeuge ich die Datei mit dem f_open() Befehl, nimm dann die Karte 
stecke sie in den Computer und verändere die Datei und probier dann 
wieder Daten mit dem Mikrocontroller in die Datei zuschreiben, 
funktioniert es. Auch das Auslesen einer Datei mittels f_read() und das 
Speichern der gelesen Daten, in einer zuvor am Computer bearbeiten 
Datei, funktioniert.

Ich kann mir den Fehler leider nicht wirklich erklären und auch die 
Suchfunktion hat mich leider noch nicht zur Lösung geführt.

Vielleicht hatte von euch schon jemand einmal dieses Problem oder kann 
mir generell Tipps geben, woran es liegen könnte.

*Definition von FR_INT_ERR:
Assertion failed. An insanity is detected in the internal process. One 
of the following possibilities is suspected.
- Work area (file system object, file object or etc...) is broken by 
stack overflow or any other application. This is the reason in most 
case.
- There is any error of the FAT structure on the volume.

Note that if once this error occured at any operation to an open file, 
the file object is aborted and all operations to the file except for 
close will be rejected.

1
<snip>
2
3
volatile uint8_t status_mount = 60;
4
volatile uint8_t status_open = 60;
5
volatile uint8_t status_close = 60;
6
volatile int8_t status_write = 60;
7
volatile uint8_t status_read = 60;
8
uint16_t written = 0;
9
uint16_t read = 0;
10
FATFS fatfs = {0};
11
FIL test_file = {0};
12
volatile void read_buff[20];
13
  
14
status_mount = f_mount(&fatfs, "", 0);
15
if(status_mount == 0)
16
{
17
  status_open = f_open(&test_file, "daten.txt", FA_WRITE | FA_READ);
18
    
19
  if(status_open == 0)
20
  {
21
    status_read = f_read(&test_file, &read_buff, 20, &read);
22
    status_close = f_close(&test_file);
23
  }
24
  
25
  status_open = f_open(&test_file, "test5.txt", FA_WRITE | FA_READ | FA_CREATE_ALWAYS);
26
27
  if(status_open == 0)
28
    status_write = f_write(&test_file, "Das ist nur ein Test!", 21, &written);
29
30
  status_close = f_close(&test_file);
31
}
32
33
<snip>

LG Christoph

: Bearbeitet durch User
von Chris H. (hoc)


Lesenswert?

Update:

Ich habe mir nun mit dem Debugger mal angeschaut, woher im Code die 
Fehlermeldung kommt
1
<snip>  
2
  case FS_FAT16 :
3
    if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) 
4
      break;
5
    p = &fs->win[clst * 2 % SS(fs)];
6
    return LD_WORD(p);
7
8
  case FS_FAT32 :
9
    if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) 
10
      break;
11
    p = &fs->win[clst * 4 % SS(fs)];
12
    if(LD_DWORD(p) & 0x0FFFFFFF) //<- diese Bedingung wird nicht erfüllt
13
      return LD_DWORD(p) & 0x0FFFFFFF;
14
15
  default:
16
    return 1;  //<- somit wird 1 zurückgegeben
17
  }
18
<snip>

Jedoch verstehe ich nicht was hier genau passiert bzw. passieren sollte.

Ich werde mich noch weiter damit beschäftigen, aber vielleicht kann mir 
von euch ja jemand eine Menge Zeit sparen.

LG Chris

von Falk B. (falk)


Lesenswert?

>volatile void* read_buff[20];

Das scheint mir komisch, das ist ein Array von Pointern! Eher so

>volatile uint8_t read_buff[20];

Du musst nicht in den Innereien vom FATfs rumstochern, das passt schon. 
Wie sieht dein Hardwareaufbau aus?

von Chris H. (hoc)


Angehängte Dateien:

Lesenswert?

>Das scheint mir komisch

Da hast du recht... schon ausgebessert

Bei meinem Hardwareaufbau ist einfach jede Datenleitung(MISO, MOSI, und 
auch die unbenutzten "Datenleitungen") und auch die CLK-Leitung über 
einen Pullup-Widerstand mit 3,3V verbunden. Die Versorgung erfolgt über 
den das Mikrocontrollerboard, welches über ein JTAG-Interface gespeist 
wird.
Die Datenleitungen sind dann über einen einfachen Buchsenstecker und 
Stiftleiste mit dem Controller verbunden.

Die Leitungen rechts waren nur für die ersten Versuche um ein 
Oszilloskop anzuschließen.

LG Christoph

von Falk B. (falk)


Lesenswert?

@Christoph H. (hoc)

>Bei meinem Hardwareaufbau ist einfach jede Datenleitung(MISO, MOSI, und
>auch die unbenutzten "Datenleitungen") und auch die CLK-Leitung über

Naja, nicht wirklich gut aber auch nicht wirklich schlecht.

Aber warum öffnest du mit FA_WRITE | FA_READ | FA_CREATE_ALWAYS, wenn du 
nur schrieben willst. Probier erstmal nur

FA_WRITE | FA_CREATE_ALWAYS

Letztens hatte jemand Probleme mit schlechter Hardware.

von Chris H. (hoc)


Lesenswert?

Ich werd es dann gleich mal ausprobieren, aber ich denke mal, dass das 
FA_READ nur von einem anderen Versuch übergeblieben ist.

Dies ist nur eine Übergangslösung. Heute bzw. morgen sollte mein PCB 
kommen und dann fällt auch dieser schwindelige Aufbau weg.

Was noch vergessen habe zu sagen... momentan habe ich es mit zwei 
verschiedenen Kartenherstellern probiert und bei beiden tritt der 
gleiche Fehler auf. Kann es vielleicht doch sein, dass sich in den von 
mir geschriebenen Funktionen ein Fehler eingeschlichen hat?
Code folgt natürlich noch

LG Christoph

von Grundschüler (Gast)


Lesenswert?

Christoph H. schrieb:
> Kann es vielleicht doch sein, dass sich in den von
> mir geschriebenen Funktionen ein Fehler eingeschlichen hat?

Selbst das ist nicht völlig auszuschließen…

Es gibt keinen Grund, FAT- Funktionen selbst zu schreiben. Nimm das 
komplette Projekt von Elm-Chan in der neuesten Version 10b. Dann 
funktioniert das auch.

von Finnsnes (Gast)


Lesenswert?

Grundschüler schrieb:
> Es gibt keinen Grund, FAT- Funktionen selbst zu schreiben. Nimm das
> komplette Projekt von Elm-Chan in der neuesten Version 10b. Dann
> funktioniert das auch.

Was für ein Blödsinn, die Hardwareanbindung muss er deswegen trotzdem 
schreiben, das nimmt ihm das Projekt nicht ab.

von Chris H. (hoc)


Lesenswert?

Hier ist nun mal der Code zu den Funktionen
1
DRESULT disk_read (
2
  BYTE pdrv,    /* Physical drive number (0..) */
3
  BYTE *buff,    /* Data buffer to store read data */
4
  DWORD sector,  /* Sector address (LBA) */
5
  UINT count    /* Number of sectors to read (1..128) */
6
)
7
{
8
  DRESULT res = 0;
9
  uint8_t response = 0x00;
10
  uint16_t counter = 0;
11
  uint16_t block_num = 0;
12
13
  //res = disk_status check!!! should be here
14
  //if(res == STA_NOINIT)
15
  //  return RES_NOTRDY;
16
17
  if(!count)
18
    return RES_PARERR;
19
  
20
  nextCmd();
21
  if(count == 1)
22
  {
23
    //single block read
24
    sdSendCmd(READ_SINGLE_BLOCK, sector, DUMMY_FF);
25
    response = sdGetResponse();
26
    res = checkResponseR1(response);
27
    if( res != 0)
28
      return res;                  //FIXME -> data error token
29
30
    if(sdGetResponse() == DATA_START_TOKEN_S)
31
    {
32
      for(counter = 0; counter < 512; counter++)
33
      {
34
        buff[counter] = sendByteSPI(DUMMY_FF);
35
      }
36
      sendByteSPI(DUMMY_FF);
37
      sendByteSPI(DUMMY_FF);    //2 Byte CRC16
38
    }
39
  }
40
  else //multiple block read
41
  {
42
    sdSendCmd(READ_MULTIPLE_BLOCK, sector, DUMMY_FF);
43
    response = sdGetResponse();
44
    res = checkResponseR1(response);
45
    if( res != 0)
46
      return res;                  //FIXME -> Data error token
47
48
    for(block_num = 0; block_num < count; block_num++)
49
    {
50
      if(sdGetResponse() == DATA_START_TOKEN_S)
51
      {
52
        for(counter = 0; counter < 512; counter++)
53
        {
54
          buff[512*block_num + counter] = sendByteSPI(DUMMY_FF);
55
        }
56
      }
57
      sendByteSPI(DUMMY_FF);
58
      sendByteSPI(DUMMY_FF);    //2 Byte CRC16
59
    }
60
    sendByteSPI(DUMMY_FF);
61
    sdSendCmd(STOP_TRANSMISSION, 0, DUMMY_FF);
62
    sendByteSPI(DUMMY_FF);            //last transmitted data byte
63
    response = sdGetResponse();
64
    res = checkResponseR1(response);
65
    if( res != 0)
66
    {
67
      checkBusy();
68
      return res;
69
    }
70
  }
71
  SD_CS_HIGH;
72
  return res;
73
74
}

und noch die write Funktion
1
DRESULT disk_write (
2
  BYTE pdrv,      /* Physical drive nmuber (0..) */
3
  const BYTE *buff,  /* Data to be written */
4
  DWORD sector,    /* Sector address (LBA) */
5
  UINT count      /* Number of sectors to write (1..128) */
6
)
7
{
8
  DRESULT res;
9
  int counter;
10
  int block_num = 0;
11
  char response = 0x00;
12
13
  //res = disk_status check!!! should be there
14
  //if(res == STA_NOINIT)
15
  //  return RES_NOTRDY;
16
17
  if(!count)
18
    return RES_PARERR;
19
20
  nextCmd();
21
22
  if(count == 1)
23
  {
24
    sdSendCmd(WRITE_SINGLE_BLOCK, sector, DUMMY_FF);
25
    response = sdGetResponse();
26
    res = checkResponseR1(response);
27
    if(res != 0)
28
      return res;
29
30
    for(counter = 0; counter < 8;counter++)
31
    {
32
      sendByteSPI(DUMMY_FF);
33
    }
34
35
    sendByteSPI(DATA_START_TOKEN_S);
36
37
    for(counter = 0; counter < 512; counter++)
38
    {
39
      sendByteSPI(buff[counter]);
40
    }
41
    sendByteSPI(DUMMY_FF);
42
    sendByteSPI(DUMMY_FF); //2 times CRC16
43
44
    if(sendByteSPI(DUMMY_FF) & 0x08)  //check data response token
45
      return RES_ERROR;
46
47
  checkBusy();
48
  }
49
  else
50
  {
51
    sdSendCmd(WRITE_MULTIPLE_BLOCK, sector, DUMMY_FF);
52
    response = sdGetResponse();
53
    res = checkResponseR1(response);
54
    if(res != 0)
55
      return res;
56
57
    for(block_num = 0; block_num < count; block_num++)
58
    {
59
      for(counter = 0; counter < 8;counter++)
60
      {
61
        sendByteSPI(DUMMY_FF);
62
      }
63
64
      sendByteSPI(DATA_START_TOKEN_M);
65
66
      for(counter = 0; counter < 512; counter++)
67
      {
68
        sendByteSPI(buff[block_num*512 + counter]);
69
      }
70
      sendByteSPI(DUMMY_FF);
71
      sendByteSPI(DUMMY_FF); //2 times CRC16
72
73
      if(sendByteSPI(DUMMY_FF) & 0x08)  //check data response token
74
        return RES_ERROR;
75
76
      checkBusy();
77
    }
78
    for(counter = 0; counter < 8;counter++)
79
    {
80
      sendByteSPI(DUMMY_FF);
81
    }
82
    sendByteSPI(DATA_STOP_TOKEN);
83
84
    checkBusy(); //while(!sendByteSPI(DUMMY_FF));
85
86
87
  }
88
  SD_CS_HIGH;
89
  return res;
90
}

Ich ahbe den Code nun auch mit

FA_WRITE | FA_CREATE_ALWAYS

ausprobiert und bin leider nur zum gleichen Ergebnis (FR_INT_ERR) 
gekommen.

Was könnte man an der Hardware besser machen?
Auf meinem eigentlich Board gibt es noch eine Spule in der 
Versorgungsleitung, sowie einen Kondensator parallel dazu. Eigentlich 
der fast der gleiche Aufbau, wie ich ihn hier im Forum 
(Beitrag "Re: SD-Karte abschalten durch Trennen der Versorgung funktioniert nicht") gefunden habe.

von Falk B. (falk)


Lesenswert?

@ Christoph H. (hoc)

>Hier ist nun mal der Code zu den Funktionen

Was soll das? Dort liegt der Fehler nicht.

von Chris H. (hoc)


Lesenswert?

Ich hätte an einen 1-by-off error gedacht, so dass der Treiber dann 
vielleicht eine Information zu einer Datei nicht findet und diese so 
nicht beschrieben kann.

Ich gebe leider zu ich habe keine Ahnung vom Dateisystem FAT32, aber ich 
finde auch im Internet relativ wenig dazu.

von Chris H. (hoc)


Angehängte Dateien:

Lesenswert?

Ich habe den Code nun auch mit

FA_WRITE | FA_CREATE_ALWAYS

ausprobiert und bin leider nur zum gleichen Ergebnis (FR_INT_ERR)
gekommen.

Was könnte man an der Hardware besser machen?
Auf meinem eigentlich Board gibt es noch eine Spule in der
Versorgungsleitung, sowie einen Kondensator parallel dazu. Eigentlich
der fast der gleiche Aufbau, wie ich ihn hier im Forum
(Beitrag "Re: SD-Karte abschalten durch Trennen der Versorgung funktioniert nicht") gefunden habe.

Im Anhang findet sich der Code für meine Funktionen...

LG Christoph

edit: Ich kann den letzten Beitrag von mir leider nicht löschen. Sorry, 
für die unschöne Form, welche der Beitrag dadurch erhalten hat

: Bearbeitet durch User
von Grundschüler (Gast)


Lesenswert?

Finnsnes schrieb:
> Was für ein Blödsinn, die Hardwareanbindung muss er deswegen trotzdem
> schreiben, das nimmt ihm das Projekt nicht ab.

Die Hardwareanbindung muss er nicht selbst schreiben sondern allenfalls 
das Pinout und die Spi-Schnittstelle anpassen.

Der einfachste und sicherste Weg ist - wie der Name sagt - chans 
avr_foolproof. Da müssen nur die Definitionen für das Bitbanging 
geändert werden. Wenn das nicht funktioniert, liegt es an der Hardware. 
Wenn es funktioniert kann der lowlevel-Teil ersetzt werden. Im Prinzip 
besteht der zu ändernde lowlevel Teil nur aus spi_xmit und spi_rsvr. An 
den Funktionen
disk_initialize, disk_read und disk_write muss man nichts ändern.

Die Pullups an sck, mosi und cs sind völlig sinnlos und eher schädlich, 
weil der uc dagegen anarbeiten muss. Über den pullup an miso kann man 
geteilter Meinung sein. Normalerweise reicht der interne uc-pullup 
völlig aus.

von Falk B. (falk)


Lesenswert?

@Grundschüler (Gast)

>Die Pullups an sck, mosi und cs sind völlig sinnlos und eher schädlich,
>weil der uc dagegen anarbeiten muss.

Quark. Es sind Pull-Ups, keine Leistungswiderstände. Dort sind ein paar 
Dutzend kOhm dran, das interessiert den AVR keine Sekunde.
Ausserdem braucht CS einen externen Pull-Up, damit die SD-Karte still 
ist, wenn der AVR per ISP programmiert wird!

> Über den pullup an miso kann man
>geteilter Meinung sein.

Nein, das kann man NICHT!

> Normalerweise reicht der interne uc-pullup völlig aus.

Schon wieder falsch! Nicht nur, dass die Spezifikation einen eher 
niederohmigen Pull-Up verlangt, eben weil dieser Ausgang vor der 
Initialaisierung ein Open Drain Ausgang ist, nein auch praktisch zeigt 
sich, dass mit 30-50kOhm internen Pull-Up das Ganze nur sehr 
unzuverlässig funktioniert.

Ergo. Mach deinem Namen Ehre und geh nochmal zu elektronischen 
Grundschule.

von L. R. (keyboard)


Lesenswert?

hei,
hast du im Sourcecode die 4 define für die Port's entsprechen deiner 
Hardware angepaßt?
schönen Tag

mal auf die schnelle

#define CS_LOW()
#define CS_HIGH()

: Bearbeitet durch User
von Chris H. (hoc)


Lesenswert?

OK... also ich verwende leider keinen AVR sondern einen Controller aus 
der MSP430 Familie. Ob damit das Portieren von avr_foolproof noch so 
einfach geht?

Falls es doch geht: @Grundschüler:

Also muss ich da eigentlich nur ein Software SPI realisieren in dem ich 
einfach meine Ports in den Definition austausche? Da kommt dann aber 
noch das F_CPU... Was soll ich da eintragen... das ist mir gerade nicht 
klar.

@Falk:

Ich verwende, wie oben schon einmal gezeigt, die Schaltung aus den 
Beitrag und habe somit 47k Ohm als Pullups. Meinst du sollte ich hier 
einen niedrigeren Wert verwende?

@L.R.
Ich habe in der importierten Bibliothek kein CS_LOW() oder CS_HIGH().
SD_CS_HIGH und SD_CS_LOW habe ich selber definiert und die funktionieren 
auch.


Mich wundert einfach nur, dass ich eigentlich alles machen kann, aber 
ich kann einfach nicht in ein leeres z.B. Textdokument schreiben. Sobald 
ich einmal einen Buchstaben im File habe, kann ich alles machen.

von holger (Gast)


Lesenswert?

>Also muss ich da eigentlich nur ein Software SPI realisieren in dem ich
>einfach meine Ports in den Definition austausche?

Nein, wozu? Wenn dein Hardware SPI läuft ist doch alles gut.

von L. R. (keyboard)


Lesenswert?

hei,

läuft bei mir auf einem PIC32MX..

Beispiele waren nur auf die schnelle.

Steht bei mir in der mmcPIC32 ..

Hatte es sofort nach den Anpassungen zum laufen gebracht.

schönen Abend

von Falk B. (falk)


Lesenswert?

@Christoph H. (hoc)

>der MSP430 Familie. Ob damit das Portieren von avr_foolproof noch so
>einfach geht?

Ich denke schon.

>Also muss ich da eigentlich nur ein Software SPI realisieren in dem ich
>einfach meine Ports in den Definition austausche?

Wenn deine Software schon fast alles kann, ist das sinnlos. Das Problem 
liegt woanders.

>Ich verwende, wie oben schon einmal gezeigt, die Schaltung aus den
>Beitrag und habe somit 47k Ohm als Pullups. Meinst du sollte ich hier
>einen niedrigeren Wert verwende?

Für MISO sollte man 2-10k nehmen.

>ich kann einfach nicht in ein leeres z.B. Textdokument schreiben. Sobald
>ich einmal einen Buchstaben im File habe, kann ich alles machen.

Komisch.

von Chris H. (hoc)


Lesenswert?

Ich werde jetzt zuerst noch einmal die Portierung vom avr_foolproof 
probieren und dann geh ich an die Hardware und werde den Pullup ändern.

Danke schon einmal für die zahlreichen Antworten :)

von Grundschüler (Gast)


Lesenswert?

Falk Brunner schrieb:
> Ergo. Mach deinem Namen Ehre und geh nochmal zu elektronischen
> Grundschule.

Gerne. Erklär doch mal, was der Pullup an sck bewirken soll. Bei 
Spi-mode0 ist der Ruhezustand 0. Der Pullup an sck ist definitiv falsch, 
steht nicht in der Spezifikation und widerspricht dem bei Chan zu 
findenden Schema.

Christoph H. schrieb:
> Also muss ich da eigentlich nur ein Software SPI realisieren in dem ich
> einfach meine Ports in den Definition austausche? Da kommt dann aber
> noch das F_CPU... Was soll ich da eintragen... das ist mir gerade nicht
> klar.

F_CPU ist für den software-spi egal, weil er eh sehr langsam ist. Ich 
habe es bei einem 168Mhz-F4 auspropiert. Du kannst aber auch jeden 
einzelnen Takt verzögern, indem du bei ck_h/l delays einbaust:
1
#define ck_port    C
2
#define ck_pin    10
3
#define do_port    C
4
#define do_pin    11
5
#define di_port    C
6
#define di_pin    12
7
#define cs_port    C
8
#define cs_pin    9
9
10
//sck
11
#define CK_INIT()  pinDIRout(ck_port,ck_pin)  /* Initialize port for MMC SCLK as output */
12
#define CK_H()    pinSET(ck_port,ck_pin)//;_delay_us(1);ledg_on
13
#define  CK_L()    pinCLR(ck_port,ck_pin)//;_delay_us(1);ledg_off
14
15
...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Christoph H. schrieb:
> Erzeuge ich die Datei mit dem f_open() Befehl, nimm dann die Karte
> stecke sie in den Computer und verändere die Datei und probier dann
> wieder Daten mit dem Mikrocontroller in die Datei zuschreiben,
> funktioniert es. Auch das Auslesen einer Datei mittels f_read() und das

 Wahrscheinlich ein Problem mit FAT #2, aber nur zur Sicherheit -
 wie gross sind deine SD-Karten ?

von Chris H. (hoc)


Lesenswert?

Mit der Portierung tu ich mir leider gerade doch etwas schwer. Hatte 
aber gestern fast keine Zeit mich damit zu beschäftigen.
Habe mich jetzt aber doch für den Hardwae SPI entschieden, da dieser ja 
ohne Probleme funktioniert.

Der Pullup an der Clock-Leitung war ein Fehler von mir. Habe beim 
"abkupfern" der Schaltung einen Fehler gemacht. Der Pullup wurde aber 
gestern noch gegen einen Pulldown ausgetauscht, was aber keinerlei 
Unterschied macht, Fehler bleibt der gleiche.

Es wäre aber doch auch ziemlich komisch, wenn ich alles schreiben und 
lesen kann (unter den genannten Vorraussetzungen) , dass es an der 
Beschaltung liegt?!

@Vesely:
Die karten sind eine Transcend 8GB und eine SanDisk 8GB und 4GB.
Bei allen tritt das gleiche Problem auf.

von Falk B. (falk)


Lesenswert?

@ Chris H. (hoc)

>Es wäre aber doch auch ziemlich komisch, wenn ich alles schreiben und
>lesen kann (unter den genannten Vorraussetzungen) , dass es an der
>Beschaltung liegt?!

Ja. Es kann auch ein Konfigurationsproblem im FatFs sein.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Chris H. schrieb:
> Die karten sind eine Transcend 8GB und eine SanDisk 8GB und 4GB.
> Bei allen tritt das gleiche Problem auf.

 Probiere es mit 1GB, nur um sicher zu gehen.

von Grundschüler (Gast)


Angehängte Dateien:

Lesenswert?

Chris H. schrieb:
> Habe beim "abkupfern" der Schaltung einen Fehler gemacht.

die Pullups - mit nur 47k - sind sicher nicht das Problem. Es ist aber 
immerhin interesssant, dass dein sck-Pulldown auf die 
Schaltungsempfehlung von chan aus 2010 zurückgeht. Inzwischen hat chan 
das geändert. Es gibt keinen sck-pulldown mehr. Vermutlich hat er sich 
etwas dabei gedacht.

Chris H. schrieb:
> Die Funktionen disk_initialize, disk_read
> und disk_write habe ich geschrieben

Da du an diesen Funktionen zumindest etwas geändert hast, liegt der 
Fehler am wahrscheinlichsten an deinen Änderungen. Solche Fehler zu 
finden, ist extrem schwierig weil man deine Änderungen nachvollziehen 
müsste. Deswegen die Empfehlung, Original-Chan neu zu installieren. Ob 
sw- oder hw-spi ist relativ egal. Hauptsache es ist der Code von Chan 
ohne Änderungen von dir, die über die Anpassung des lowlevel-pinouts 
hinausgehen.

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.