SD-kaart SPI probleem

Ik ben bezig met een groot projekt in MikroE Basic Pro waarin met een PIC24 een flinke hoeveelheid gelogde data (ca. 1 MB) uit een SPI-flash chip overgezet moet worden op een FAT32-geformatteerd opslagmedium. In eerste instantie had ik daarvoor USB-OTG in gedachten, maar daar zaten nogal wat haken en ogen aan, en na advies van Arco besloten om voor een SD-kaart te gaan.

Ik werk met een oude Transcend micro SD-kaart van 128 MB geformatteerd in FAT32, maar een 8 GB Lexar en een 32 GB Samsung zij ook getest.

Ik ben nu zover dat de SD-kaart geinitialiseerd wordt op 250 kHz, dan na een paar CMDs aangeeft dat hij niet mee "idle" is en op 512 byte blok-grootte wordt ingesteld voor FAT32. De FAT32_Init routine geeft OK als resultaat bij alle 3 de kaartjes. Zie onderstaande Logic Analyser screenshot.

Hierna is het stil. Wat ik ook doe, FAT32_Dir, FAT32_GetFreeSpace(), FAT32_MakeDir(), geen reactie, zelfs de SD_CS lijn wordt niet meer laag gemaakt (!). Maar als ik een bv. FAT32_Exists() aanroep om te zien of een filenaam al bestaat, dat volgt er een CMD18 (read multiple block), waarna de zaak hangt en de PIC miljoenen 255-bytes uit de sd-kaart blijft lezen (MISO blijft gewoon hoog en er blijven klokpulsen komen uit de PIC)

De FAT32 library van MikroE is heel simpel opgezet, en in de voorbeelden wordt echt alleen maar CS gedefinieerd, SPI_Init en FAT32_Init() gegeven en dan is de boel klaar voor gebruik.

Wat zie ik over het hoofd? Waarom slaat de boel vast na de gelukte initialisatie? Is de initialisatie niet compleet?

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Arco

Special Member

Kun je een stukje code laten zien? (zou probleemloos moeten werken)
Ik gebruik deze code voor initialisering (pic24 op 32MHz):

pic basic code:


'========================================================================================
Sub Function SD_Init() As Word                                      'Init SD card.
'========================================================================================
  Dim lCnt As Word                              Result = 0          '
  '--------------------------------------------------------------------------------------
  If MMC_Card_Detect = _YES Then                                    'SPI at low speed
    Spi1_Init_Advanced(_SPI_MASTER,                                 '
                       _SPI_8_BIT,                                  '
                       _SPI_PRESCALE_SEC_1,                         '
                       _SPI_PRESCALE_PRI_64,                        '
                       _SPI_SS_DISABLE,                             '
                       _SPI_DATA_SAMPLE_MIDDLE,                     '
                       _SPI_CLK_IDLE_HIGH,                          '
                       _SPI_ACTIVE_2_IDLE)                          '
    For lCnt = 0 To 10                                              '
      If Mmc_Init() = 0 Then                                        'If SD init success
        delay_ms(10)                                                'switch SPI to high
        Spi1_Init_Advanced(_SPI_MASTER,                             'speed
                           _SPI_8_BIT,                              '
                           _SPI_PRESCALE_SEC_1,                     '
                           _SPI_PRESCALE_PRI_4,                     '
                           _SPI_SS_DISABLE,                         '
                           _SPI_DATA_SAMPLE_MIDDLE,                 '
                           _SPI_CLK_IDLE_HIGH,                      '
                           _SPI_ACTIVE_2_IDLE)                      '
        Result = 1                                                  '
        Break                                                       '
      End If                                                        '
      Delay_ms(10)                                                  '
    Next lCnt                                                       '
  End If                                                            '
End Sub                                                             '

[Bericht gewijzigd door Arco op dinsdag 12 april 2022 20:37:24 (95%)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

pic basic code:

'--------------------------------------------------------------------------------------------------------------------------------------------------------------
module SDcard
'--------------------------------------------------------------------------------------------------------------------------------------------------------------
include "Variables"
include "Readout"
include "Utilities"
'--------------------------------------------------------------------------------------------------------------------------------------------------------------
dim MMC_Chip_Select as sbit at LATA.1
dim MMC_Chip_Select_Direction as sbit at TRISA.1
dim err as byte

sub procedure SDcopy
'--------------------------------------------------------------------------------------------------------------------------------------------------------------
implements
'--------------------------------------------------------------------------------------------------------------------------------------------------------------
sub procedure SDcopy
 dim filename as string[32]
     nbr as string[5]
     i as byte

 filename=""
 
 ReadOutBusy=1 'voorkom dat flashgeheugen ergens anders wordt aangesproken
 
 'Gebruik UART1 voor debug output
 UART_Set_Active(@UART1_Read, @UART1_Write, @UART1_Data_Ready, @UART1_Tx_Idle)

 'initialiseer SPI1 op FC/64 (=250 kHz)
 SPI1_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, _SPI_PRESCALE_SEC_1, _SPI_PRESCALE_PRI_64, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE)

 UART_Write_text(cr+lf+"Card init... ")

 err=FAT32_Dev_Init()
 if err=OK_F32 then
 	UART_Write_text("OK"+cr+lf)
 else
 	UART_Write_text("ERROR"+cr+lf) goto F32_End
 end if

 err=FAT32_Dir
 if err=OK_F32 then
 	UART_Write_text("Dir contents listed"+cr+lf)
 else	
 	UART_Write_text("ERROR displaying dir") goto F32_end
 end if

 filename="TEST"

 err=FAT32_Exists(@filename)
 if err=OK_F32 then
 	UART_Write_text("Folder doesn't exist yet"+cr+lf)
 else
 	UART_Write_text("ERROR checking folder") goto F32_end
 end if

 err=FAT32_MakeDir(@filename)
 if err=OK_F32 then
 	UART_Write_text("Folder created"+cr+lf)
 else
 	UART_Write_text("ERROR creating folder") goto F32_End
 end if

 err=FAT32_ChangeDir(@filename)
 if err=OK_F32 then
 	UART1_Write_text("Changed folder"+cr+lf)
 else
 	UART1_Write_text("ERROR changing folder") goto F32_End
 end if


F32_end:

 shorttostr(FAT32_GetError(),nbr) UART_Write_text(cr+lf+"GetError="+nbr)

 ReadOutBusy=0
end sub

end.

Nou ben ik door de tientallen pogingen de draad een beetje kwijt, dus ik weet niet 100% zeker of deze code ook deze debug output geeft, maar dit is dus 1 van de pogingen:

Card init... OK

Dir contents listed
Folder doesn't exist yet
ERROR creating folder
GetError= -12

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Arco

Special Member

Ik gebruik FAT helaas nooit. (ik schrijf alles 'raw' naar de kaart. Ik gebruik het ook voor een bootloader)
De SD_Init() doet het zoals in de specs: eerst 10 initialisatiepogingen op lage snelheid, daarna over op hoge snelheid.
(het is niet zeker dat init al in 1 poging lukt, kan meerdere pogingen nodig hebben)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com

De FAT32_Init routine heeft dat al ingebouwd, en doet bij een koude start soms al >100 pogingen om een bepaald antwoord te krijgen. Dat duurt soms 150-200 ms, maar lukt altijd in 1 keer.

Raw data schrijven is bij mij geen optie, het doel van dit is nu juist dat je zonder apparatuur het zaakje kunt uitlezen en de data naar een PC kunt overzetten. Dat kan nu alleen nog met een FTDI-kabeltje op 1 Mbaud, maar je moet dus dan een notebook bij je hebben en die aansluiten.

Mijn echte naam: Joris | Mijn elektronica website: Fuzzcraft.com
Arco

Special Member

Raw data schrijven is bij mij geen optie, het doel van dit is nu juist dat je zonder apparatuur het zaakje kunt uitlezen en de data naar een PC kunt overzetten.

Dat kan bij mij ook; ik maak de PC software ook zelf... ;)

Arco - "Simplicity is a prerequisite for reliability" - hard-, firm-, en software ontwikkeling: www.arcovox.com