Forum: Mikrocontroller und Digitale Elektronik Hänger beim Initialisieren der SD-Card (AT91SAM7S256)


von Peter Pippinger (Gast)


Lesenswert?

Hallo NG,

ich versuche gerade die Initialisierung einer SD-Card in den SPI-Modus.
Leider hängt das Programm schon bei der Sequenz, wo man mit CS-High 10x 
0xff an die Karte sendet. Leider kann ich keinen Fehler finden. 
Vielleicht sieht ja von euch jemand auf Anhieb, woran es liegt. 
Wahrscheinlich ist SPI noch nicht richtig aktiviert...

(Könnte mir vielleicht jemand gerade fürs Initialisieren von SPI ein 
paar Tips geben? Bei RS232 kann ich einfach mein Hyperterminal befragen, 
und sehe, ob die Ausgabe klappt oder nicht. Aber bei SPI habe ich keinen 
Schimmer, wie ich ohne viel Aufwand die Funktion überprüfen kann.)

Vielen Dank für jeden Tip.
Peter

(Hier der Auszug von Main)

// 
----------------------------------------------------------------------
// Pins fuer Kartenleser initialisieren

  BL  init_cp_wp
  BL  blink_yellow      // *** BLINK 3

// 
----------------------------------------------------------------------
// SPI fuer Kartenleser initialisieren

  BL  init_spi
  BL  blink_yellow      // *** BLINK 4

// 
----------------------------------------------------------------------
// Start SD-Card-Init

  BL  init_sdcard /* HIER HÄNGT ER DANN (in spi_send_byte) */



(Hier die Defs)

// 
----------------------------------------------------------------------
// Basis- und Offsetadressen definieren

#define ASM_BASE  0x202000

#define PIO_BASE  0xFFFFF400
#define PIO_PER    0x00
#define PIO_PDR    0x04
#define PIO_OER    0x10
#define PIO_ODR    0x14

#define PIO_SODR  0x30
#define PIO_CODR  0x34
#define PIO_PDSR  0x3C

#define PIO_ODSR  0x38
#define PIO_PUDR  0x60
#define PIO_ASR    0x70
#define PIO_BSR    0x74
#define PIO_OWER  0xA0

#define SPI_BASE  0xFFFE0000
#define SPI_CR    0x00
#define SPI_MR    0x04
#define SPI_RDR    0x08
#define SPI_TDR    0x0C
#define SPI_SR    0x10
#define SPI_CSR0  0x30
#define SPI_PTCR  0x120

#define SPI_RDRF  0x1 << 0 // (SPI) Receive Data Register Full
#define SPI_TDRE  0x1 << 1 // (SPI) Transmit Data Register Empty


#define PMC_BASE  0xFFFFFC00
#define PMC_PCER  0x10


#define USART_BASE  0xFFFC0000
#define USART_US_CR  0x00
#define USART_US_MR  0x04
#define USART_US_CSR  0x14
#define USART_US_THR  0x1C
#define USART_US_BRGR  0x20
#define USART_US_TTGR  0x28

#define PDC_BASE  0xFFFC0100
#define PDC_PTCR  0x20

// 
----------------------------------------------------------------------
// Hilfsdefinitionen

#define AT91C_PDC_RXTEN  0x1 << 0
#define AT91C_PDC_TXTEN  0x1 << 8

#define  BIT0    0x00000001
#define  BIT1    0x00000002
#define  BIT2    0x00000004
#define  BIT3    0x00000008
#define  BIT4    0x00000010
#define  BIT5    0x00000020
#define  BIT6    0x00000040
#define  BIT7    0x00000080
#define  BIT8    0x00000100
#define  BIT9    0x00000200
#define  BIT10    0x00000400
#define  BIT11    0x00000800
#define  BIT12    0x00001000
#define  BIT13    0x00002000
#define  BIT14    0x00004000
#define  BIT15    0x00008000
#define  BIT16    0x00010000
#define  BIT17    0x00020000
#define  BIT18    0x00040000
#define  BIT19    0x00080000
#define  BIT20    0x00100000
#define  BIT21    0x00200000
#define  BIT22    0x00400000
#define  BIT23    0x00800000
#define  BIT24    0x01000000
#define  BIT25    0x02000000
#define  BIT26    0x04000000
#define  BIT27    0x08000000
#define  BIT28    0x10000000
#define  BIT29    0x20000000
#define  BIT30    0x40000000
#define  BIT31    0x80000000



(Hier die SD-Card-Funktionen)

init_sdcard:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1, r14}

  // Debug Ausgabe an RS232
  LDR  r7, =ASM_BASE + str_init_sdcard
  RS232_STRING  r7
  RS232_NL      // neue Zeile

  // CS auf High
  BL  cs_high

  // 10 x 0xff mit CS-High senden
  LDR  r0, =10

sd_loop1:

  // Debug Ausgabe an RS232
  LDR  r7, =ASM_BASE + str_sdcard_loop
  RS232_STRING  r7

  // 0xff ueber SPI senden
  BL  spi_send_byte

  SUBS  r0, r0, #1
  BNE  sd_loop1

  // CS auf Low
  BL  cs_low



  // urspruengliche Register vom Stack holen
  POP  {r0, r1, r14}

  // Zurueck aus Subroutine
  MOV  pc, r14

// 
----------------------------------------------------------------------

spi_send_byte:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1}

  // Basisadresse setzen
  LDR  r0, =SPI_BASE

spi_send_byte_loop1

  // warten, bis Daten gesendet wurden
  LDR  r1, [r0, #SPI_SR]
  ANDS  r1, r1, #SPI_TDRE
  BEQ  spi_send_byte_loop1

  // Daten senden
  LDR  r1, =0xffff
  STR  r1, [r0, #SPI_TDR]

spi_send_byte_loop2

  // warten, bis Daten gesendet wurden
  LDR  r1, [r0, #SPI_SR]
  ANDS  r1, r1, #SPI_RDRF
  BEQ  spi_send_byte_loop2

  // Daten holen
  LDR  r1, [r0, #SPI_RDR]

  // urspruengliche Register vom Stack holen
  POP  {r0, r1}

  // Zurueck aus Subroutine
  MOV  pc, r14

// 
----------------------------------------------------------------------

cs_high:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1}

  // Basisadresse setzen
  LDR  r0, =PIO_BASE

  // CS auf High
  LDR  r1, =100000000000b
  STR  r1, [r0, #PIO_SODR]

  // urspruengliche Register vom Stack holen
  POP  {r0, r1}

  // Zurueck aus Subroutine
  MOV  pc, r14

// 
----------------------------------------------------------------------

cs_low:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1}

  // Basisadresse setzen
  LDR  r0, =PIO_BASE

  // CS auf High
  LDR  r1, =100000000000b
  STR  r1, [r0, #PIO_CODR]

  // urspruengliche Register vom Stack holen
  POP  {r0, r1}

  // Zurueck aus Subroutine
  MOV  pc, r14

// 
----------------------------------------------------------------------

init_spi:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1}

  // Basisadresse setzen
  LDR  r0, =PIO_BASE

  // den entsprechenden PINS die Funktion zuweisen
  LDR  r1, =BIT11 | BIT12 | BIT13 | BIT14
  STR  r1, [r0, #PIO_PDR]
  STR  r1, [r0, #PIO_ASR]
  LDR  r1, =0
  STR  r1, [r0, #PIO_BSR]

  // Basisadresse setzen
  LDR  r0, =PIO_BASE

  // enable SPI-Clock (ID=5)
  LDR  r1, =1 << 5
  STR  r1, [r0, #PMC_PCER]

  // Basisadresse setzen
  LDR  r0, =SPI_BASE

  // SPI-MODE: fixed
  LDR  r1, =0x81;      // SPI Enable, Software Reset
  STR  r1, [r0, #SPI_CR]
  LDR  r1, =0x01;      // SPI Enable
  STR  r1, [r0, #SPI_CR]
  LDR  r1, =0xE0011;      // Master Mode, Fixed Select
  STR  r1, [r0, #SPI_MR]
  LDR  r1, =0x4A02;      // 8bit, CPOL: 0, ClockPhase: 1,
  STR  r1, [r0, #SPI_CSR0]    // SCLK: 200kHz

  // Basisadresse setzen
  LDR  r0, =PDC_BASE
  LDR  r1, =AT91C_PDC_TXTEN | AT91C_PDC_RXTEN
  STR  r1, [r0, #PDC_PTCR]

  // Basisadresse setzen
  LDR  r0, =SPI_BASE
  STR  r1, [r0, #SPI_PTCR]

  // urspruengliche Register vom Stack holen
  POP  {r0, r1}

  // Zurueck aus Subroutine
  MOV  pc, r14


// 
----------------------------------------------------------------------

init_cp_wp:

  // verwendete Register auf Stack legen
  PUSH  {r0, r1}

  // Basisadresse setzen
  LDR  r0, =PIO_BASE

  // Pull-Up-Widerstaende ausschalten
  LDR  r1, =0xffffffff
  STR  r1, [r0, #PIO_PUDR]

  // Karte-verfuegbar-Pin als Input
  LDR  r1, =BIT15
  STR  r1, [r0, #PIO_ODR]
  STR  r1, [r0, #PIO_PER]

  // Karte-schreibgeschuetzt-Pin als Input
  LDR  r1, =BIT16
  STR  r1, [r0, #PIO_ODR]
  STR  r1, [r0, #PIO_PER]

  // urspruengliche Register vom Stack holen
  POP  {r0, r1}

  // Zurueck aus Subroutine
  MOV  pc, r14

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.