Autor Tema: Ayuda con SPI en el AT91SAM7S  (Leído 2111 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Darukur

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 464
    • Informacion, recursos y ejemplos para desarrollos con microcontroladores
Ayuda con SPI en el AT91SAM7S
« en: 06 de Julio de 2009, 17:12:37 »
Estoy empezando a mirar el SPI en el AT91SAM7S y aunque le he puesto tiempo no logro hacerlo funcionar, me gustaria separar un problema de codigo de un problema de hard.

Si alguien miro la datasheet del SPI o tiene alguna info, bienvenido sea.

Aca el codigo de ejemplo que arme, para la incializacion del SPI.
Código: C
  1. eSpiInitError eSpiInit(eCSDevice device)
  2. {
  3.     unsigned portLONG ulConfig = (unsigned int) AT91C_PA12_MISO | (unsigned int) AT91C_PA13_MOSI | (unsigned int) AT91C_PA14_SPCK;
  4.        
  5.     /*Enable Pull ups*/
  6.     AT91F_PIO_CfgPullup(AT91C_BASE_PIOA, AT91C_PA12_MISO|AT91C_PA13_MOSI|AT91C_PA14_SPCK );
  7.    
  8.     /*Enable SPI Clocks*/
  9.     AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_SPI);
  10.  
  11.     /*Enable SPI module*/
  12.     AT91F_SPI_Enable(AT91C_BASE_SPI);
  13.  
  14.     /*Enable SPI PIO (SI, SO, SCK, CS)*/
  15.     switch (device)
  16.     {
  17.         case ChipSelect0: ulConfig |= (unsigned int) AT91C_PA11_NPCS0; break;
  18.         case ChipSelect1: ulConfig |= (unsigned int) AT91C_PA31_NPCS1; break;
  19.         case ChipSelect2: ulConfig |= (unsigned int) AT91C_PA10_NPCS2; break;
  20.         case ChipSelect3: ulConfig |= (unsigned int) AT91C_PA22_NPCS3; break;
  21.         default: return spiInitMaxCs;
  22.     }
  23.  
  24.     AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA, ulConfig, 0);
  25.  
  26.     /*Reset the module*/
  27.     AT91F_SPI_Reset(AT91C_BASE_SPI);
  28.    
  29.     /*Configure Master mode comunication with Variable Peripheral Select and Chip select w/o decode*/
  30.     AT91F_SPI_CfgMode(AT91C_BASE_SPI, AT91C_SPI_MSTR | AT91C_SPI_PS_VARIABLE);
  31.      
  32.     /*Disable SPI*/
  33.     //AT91F_PMC_DisablePeriphClock(AT91C_BASE_PMC, ((unsigned int) 1 << AT91C_ID_SPI));
  34.     //AT91F_SPI_Disable (AT91C_BASE_SPI);
  35.    
  36.     /*Mark module as enabled, store config data*/
  37.     spiPort[device].enabled = 1;
  38.  
  39.     return   spiInitSuccess;
  40. }

Rutina de transmision por DMA (no miren que bloquea en el while, es solamente para probar que anda, despues se usara ints y servicios del RTOS).

Código: C
  1. unsigned portCHAR cSpiReadWrite(pSpiRWdata pData)
  2. {
  3. unsigned portCHAR errCode;  
  4. volatile int nRDR;
  5. unsigned portCHAR bHoldCS = 0;
  6.    
  7.     if (pData->holdCS) {bHoldCS = AT91C_SPI_CSAAT;}
  8.  
  9.     /*Configure for the selected Chip Select, the clock phase, bits per transfer, baud rate and
  10.       if Chip Select Active After Transfer
  11.     */
  12.     AT91F_SPI_CfgCs(AT91C_BASE_SPI, pData->device, AT91C_SPI_CPOL | AT91C_SPI_BITS_8 | (pData->clockDivider << 8) | (bHoldCS));
  13.  
  14.     /*Open the PDC module*/
  15.     AT91F_PDC_Open(AT91C_BASE_PDC_SPI);
  16.  
  17.     /*Disable Spi activity during PDC initialization*/
  18.     AT91F_PDC_DisableRx(AT91C_BASE_PDC_SPI);
  19.     AT91F_PDC_DisableTx(AT91C_BASE_PDC_SPI);
  20.  
  21.     /*Has bytes to write*/
  22.     if (pData->sizeW == 0)
  23.     {
  24.         AT91F_SPI_SendFrame (AT91C_BASE_SPI, (char *) pData->dataR, pData->sizeR, 0, 0);
  25.     }
  26.     else
  27.     {
  28.         AT91F_SPI_SendFrame (AT91C_BASE_SPI, (char *) pData->dataW, pData->sizeW, 0, 0);
  29.     }  
  30.    
  31.     /*Has bytes to read*/
  32.     if (pData->sizeR > 0)
  33.     {
  34.       AT91F_SPI_ReceiveFrame (AT91C_BASE_SPI, (char*) pData->dataR, pData->sizeR, 0, 0);
  35.       AT91F_PDC_EnableRx (AT91C_BASE_PDC_SPI);
  36.     }
  37.    
  38.     /*Enable Transmission*/
  39.     AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
  40.  
  41.     /*Configure and enable interrupts*/
  42.     //AT91F_AIC_ConfigureIt(AT91C_BASE_AIC, AT91C_ID_SPI, AT91C_AIC_PRIOR_LOWEST + 1, AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, ( void (*)(void) ) vSpiISREntry);
  43.     //AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SPI);
  44.  
  45.     /*Test: wait to complete*/
  46.     while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXBUFE) == 0 || (AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) == 0);
  47.  
  48.     AT91F_PDC_Close (AT91C_BASE_PDC_SPI);
  49.  
  50.     /* Flush SPI RDR buffer (in case there is pending data)*/
  51.     nRDR = AT91F_SPI_GetChar (AT91C_BASE_SPI);
  52.  
  53.     return errCode;
  54. }

No logro siquiera que maneje la linea de CS, (que lo deberia hacer por hardware), ademas el codigo bloquea sobre el while y nunca sigue.
Alguen tiene un ejemplo sobre KEIL?
El que no sabe lo que busca no entiende lo que encuentra.
Mi Pagina Web:  http://www.sistemasembebidos.com.ar
Mi foro:             http://www.sistemasembebidos.com.ar/foro/

Desconectado Darukur

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 464
    • Informacion, recursos y ejemplos para desarrollos con microcontroladores
Re: Ayuda con SPI en el AT91SAM7S
« Respuesta #1 en: 13 de Julio de 2009, 11:33:55 »
Ya lo resolvi, tome como ejemplo la FatFs para at91sam7 con Gnu arm compile tools y la portie para Keil + freertos.
Tenia cruzados MISO con MOSI con la MMC, ya que se llaman igual (SI/SO) y me equivoque.
Despues el PDC (dma) lo tenia mal configurado y los chip select automaticamente manejados por el SPI no me funcionaban.
Cuando tenga todo prolijo como me gusta lo posteo con un ejemplo.
Hasta ahora monte un fs, lei archivos origen y copie a un destino como si nada a traves de dma, ahora me falta ponerle manejo de RTOS a HAL del diskio que pide Fatfs.

Saludos!

PD: Despues probare la tasa de transferencia que logra...
El que no sabe lo que busca no entiende lo que encuentra.
Mi Pagina Web:  http://www.sistemasembebidos.com.ar
Mi foro:             http://www.sistemasembebidos.com.ar/foro/


 

anything