Autor Tema: Driver de SPI para FreeRTOS con at91sam7  (Leído 2101 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
Driver de SPI para FreeRTOS con at91sam7
« en: 14 de Julio de 2009, 23:10:09 »
Siguiendo con los post de drivers para habilitar el AT91SAM7S bajo FreeRTOS, aca dejo el ultimo desarrollo al momento, el driver de SPI con manejo de IRQs, DMA y FreeRTOS.
Lo puse con un ejemplo muy simple para no generar ruido innecesario, ni USART ni pantalla en esta demo, eso lo dejo para el ejemplo de FAT que va a usar este driver (el de CHAN´s FAT) que ya lo estuve probando y anda de PELOS, toda la potencia del driver de FAT con manejo de multiples hilos gracias al manejo del driver de SPI con mutex y semaforos.

Aca dejo el codigo tanto en texto como en un ZIP, asimismo lo subire al SVN de googlecode de sistemasembebidos.

Programa principal
Código: C
  1. /* Scheduler include files. */
  2. #include "FreeRTOS.h"
  3. #include "task.h"
  4.  
  5. /* Hardware specific headers */
  6. #include "board.h"
  7.  
  8. /*Modules Header files*/
  9. #include "spi\spi.h"
  10.  
  11. /*Global const*/
  12.  
  13. /*Defines*/
  14.  
  15. /*Global vars*/
  16. //Data for the demo task
  17. xTaskHandle xSpiDemoHandle;
  18.  
  19. //For the SPI
  20. tSpiRWdata spiData;
  21. portCHAR   buffer[1000];
  22.  
  23. /*Functions and Tasks*/
  24. static void prvSetupHardware( void );
  25. static void vSpiDemo( void *pvParameters );
  26.  
  27. /*Main Program*/
  28. int main( void )
  29. {
  30.     /* Setup the ports */
  31.     prvSetupHardware();
  32.  
  33.     /*Tasks Start-up*/
  34.     xTaskCreate( vSpiDemo, "SpiDemo", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &xSpiDemoHandle );
  35.  
  36.     /*Start the scheduler.
  37.     NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
  38.     The processor MUST be in supervisor mode when vTaskStartScheduler is
  39.     called.  The demo applications included in the FreeRTOS.org download switch
  40.     to supervisor mode prior to main being called.  If you are not using one of
  41.     these demo application projects then ensure Supervisor mode is used here. */
  42.     vTaskStartScheduler();
  43.  
  44.     /* Should never get here! */
  45.     return 0;
  46. }
  47.  
  48. /*A Demo for the spi functionaloty*/
  49. static void vSpiDemo( void *pvParameters )
  50. {
  51.      for ( ; ; )
  52.     {
  53.         /*Initialize peripherial for Chip Select 0*/
  54.         eSpiInit(ChipSelect0);
  55.  
  56.         /*Prepare data for SPI transaction (Read and Write)*/
  57.         spiData.device = ChipSelect0; //Use CHipselect 0
  58.         spiData.holdCS = 0;           //Do NOT maintain selected the Chipselect after the transfer
  59.         spiData.clockDivider = 0xFE;  //Baud = clock / divider;
  60.             spiData.sizeR = 32;           //Bytes to read
  61.             spiData.sizeW = 32;           //Bytes to write
  62.             spiData.dataR = (unsigned portCHAR *) buffer;   //Place to store data
  63.         spiData.dataW = "12345678901234567890123456789012"; //Place from where to get data
  64.         spiData.xBlockTime = 300;                           //Maximum block time
  65.  
  66.         /*Perform action and block till done or when timeout expires*/
  67.         cSpiReadWrite(&spiData);
  68.  
  69.         vTaskDelete(xSpiDemoHandle);
  70.     }
  71. }
  72.  
  73. static void prvSetupHardware( void )
  74. {
  75.     /* When using the JTAG debugger the hardware is not always initialised to
  76.     the correct default state.  This line just ensures that this does not
  77.     cause all interrupts to be masked at the start. */
  78.     AT91C_BASE_AIC->AIC_EOICR = 0;
  79.    
  80.     /* Most setup is performed by the low level init function called from the
  81.     startup asm file.
  82.     */
  83.  
  84.     /* Enable the peripheral clock to the PIO */
  85.     AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOA);
  86. }

Modulo SPI.c
Código: C
  1. /* Scheduler include files. */
  2. #include "FreeRTOS.h"
  3. #include "task.h"
  4.  
  5. /* Hardware specific headers */
  6. #include "board.h"
  7.  
  8. /*Modules Header files*/
  9. #include "spi\spi.h"
  10.  
  11. /*Global const*/
  12.  
  13. /*Defines*/
  14.  
  15. /*Global vars*/
  16. //Data for the demo task
  17. xTaskHandle xSpiDemoHandle;
  18.  
  19. //For the SPI
  20. tSpiRWdata spiData;
  21. portCHAR   buffer[1000];
  22.  
  23. /*Functions and Tasks*/
  24. static void prvSetupHardware( void );
  25. static void vSpiDemo( void *pvParameters );
  26.  
  27. /*Main Program*/
  28. int main( void )
  29. {
  30.     /* Setup the ports */
  31.     prvSetupHardware();
  32.  
  33.     /*Tasks Start-up*/
  34.     xTaskCreate( vSpiDemo, "SpiDemo", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, &xSpiDemoHandle );
  35.  
  36.     /*Start the scheduler.
  37.     NOTE : Tasks run in system mode and the scheduler runs in Supervisor mode.
  38.     The processor MUST be in supervisor mode when vTaskStartScheduler is
  39.     called.  The demo applications included in the FreeRTOS.org download switch
  40.     to supervisor mode prior to main being called.  If you are not using one of
  41.     these demo application projects then ensure Supervisor mode is used here. */
  42.     vTaskStartScheduler();
  43.  
  44.     /* Should never get here! */
  45.     return 0;
  46. }
  47.  
  48. /*A Demo for the spi functionaloty*/
  49. static void vSpiDemo( void *pvParameters )
  50. {
  51.      for ( ; ; )
  52.     {
  53.         /*Initialize peripherial for Chip Select 0*/
  54.         eSpiInit(ChipSelect0);
  55.  
  56.         /*Prepare data for SPI transaction (Read and Write)*/
  57.         spiData.device = ChipSelect0; //Use CHipselect 0
  58.         spiData.holdCS = 0;           //Do NOT maintain selected the Chipselect after the transfer
  59.         spiData.clockDivider = 0xFE;  //Baud = clock / divider;
  60.             spiData.sizeR = 32;           //Bytes to read
  61.             spiData.sizeW = 32;           //Bytes to write
  62.             spiData.dataR = (unsigned portCHAR *) buffer;   //Place to store data
  63.         spiData.dataW = "12345678901234567890123456789012"; //Place from where to get data
  64.         spiData.xBlockTime = 300;                           //Maximum block time
  65.  
  66.         /*Perform action and block till done or when timeout expires*/
  67.         cSpiReadWrite(&spiData);
  68.  
  69.         vTaskDelete(xSpiDemoHandle);
  70.     }
  71. }
  72.  
  73. static void prvSetupHardware( void )
  74. {
  75.     /* When using the JTAG debugger the hardware is not always initialised to
  76.     the correct default state.  This line just ensures that this does not
  77.     cause all interrupts to be masked at the start. */
  78.     AT91C_BASE_AIC->AIC_EOICR = 0;
  79.    
  80.     /* Most setup is performed by the low level init function called from the
  81.     startup asm file.
  82.     */
  83.  
  84.     /* Enable the peripheral clock to the PIO */
  85.     AT91F_PMC_EnablePeriphClock(AT91C_BASE_PMC, 1 << AT91C_ID_PIOA);
  86. }

Modulo SPI.h
Código: C
  1. /*SPI routines*/
  2. #ifndef SPI_H
  3. #define SPI_H
  4.  
  5. /* Scheduler include files. */
  6. #include "FreeRTOS.h"
  7. #include "task.h"
  8. #include "semphr.h"
  9.  
  10. /*Header File*/
  11. #include "..\common\errcode.h"
  12. #include "..\common\osdata.h"
  13.  
  14. /*Device specific headers*/
  15. #include <AT91SAM7S64.H>
  16. #include <lib_AT91SAM7S64.h>
  17.  
  18. /*Configurations*/
  19. #define SPI_SENDRCV_DIS_W_SETTING   0 //The SPI PDC is temporarily disabled while configuring to send / receive
  20.  
  21. /*Definitions*/
  22. #define SPI_MIN_DIVIDER 2
  23.  
  24. /*IO Ports definition*/
  25. /*CS0 only in PA11*/
  26. #define SPI_IO_CS0A  (unsigned int) AT91C_PA11_NPCS0
  27. #define SPI_IO_CS0B  0
  28. /*CS1 in PA31 or in PA9*/
  29. #if SELECT_SPI_IO_CS1 == PA31
  30. #define SPI_IO_CS1A (unsigned int) AT91C_PA31_NPCS1
  31. #define SPI_IO_CS1B 0
  32. #else
  33. #define SPI_IO_CS1A 0
  34. #define SPI_IO_CS1B (unsigned int) AT91C_PA9_NPCS1
  35. #endif
  36. /*CS2 in PA30 or in PA10*/
  37. #if SELECT_SPI_IO_CS2 == PA30
  38. #define SPI_IO_CS2A 0
  39. #define SPI_IO_CS2B (unsigned int) AT91C_PA30_NPCS2
  40. #else
  41. #define SPI_IO_CS2A 0
  42. #define SPI_IO_CS2B (unsigned int) AT91C_PA10_NPCS2
  43. #endif
  44. /*CS3 in PA3, PA5 or PA22*/
  45. #if SELECT_SPI_IO_CS2 == PA3
  46. #define SPI_IO_CS3A 0
  47. #define SPI_IO_CS3B (unsigned int) AT91C_PA3_NPCS3
  48. #elif SELECT_SPI_IO_CS2 == PA5
  49. #define SPI_IO_CS3A 0
  50. #define SPI_IO_CS3B (unsigned int) AT91C_PA5_NPCS3
  51. #else
  52. #define SPI_IO_CS3A 0
  53. #define SPI_IO_CS3B (unsigned int) AT91C_PA22_NPCS3
  54. #endif
  55.  
  56. /*enumerations*/
  57. //Error codes for SPI initialization
  58. typedef enum
  59. {
  60.         spiInitSuccess = 0,
  61.     spiInitMaxCs
  62. } eSpiInitError;
  63.  
  64. typedef enum
  65. {
  66.         ChipSelect0 = 0,
  67.     ChipSelect1 = 1,
  68.     ChipSelect2 = 2,
  69.     ChipSelect3 = 3,
  70.     ChipSelectMax
  71. } eCSDevice;
  72.  
  73. /*Types Definition, unions*/
  74. #pragma anon_unions
  75.  
  76. typedef struct
  77. {
  78.         eCSDevice device;
  79.     struct {unsigned portCHAR holdCS:1, :7; };
  80.     unsigned portCHAR clockDivider;
  81.         unsigned portSHORT sizeR;
  82.         unsigned portSHORT sizeW;
  83.         unsigned portCHAR *dataR;
  84.     const unsigned portCHAR *dataW;
  85.         portTickType xBlockTime;
  86. } tSpiRWdata, *pSpiRWdata;
  87.  
  88. typedef struct
  89. {
  90.     struct {unsigned portCHAR dev_1_Enabled:1, dev_2_Enabled:1, dev_3_Enabled:1, dev_4_Enabled:1, :4; };    
  91.     tOSData  mutex, event;
  92. } tSpiPort;
  93.  
  94. /*Constants*/
  95.  
  96. /*Variable Definition*/
  97. extern tSpiPort spiPort;
  98.  
  99. /*Functionality enabling*/
  100.  
  101. /*Public Functions and procedures Declaration*/
  102. eSpiInitError eSpiInit(eCSDevice device);
  103. unsigned portCHAR cSpiReadWrite(pSpiRWdata pData);
  104. void vSpiClose(eCSDevice device);
  105. void vSpiISR(void);
  106. extern void vSpiISREntry( void ); //Interrupt entry point written in the assembler file serialISR.s
  107. /*Macro definitions*/
  108. #endif //SPI_H

Comentarios, criticas y demases bienvenidos!

Salutes
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/