This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Various patches


Various pending patches for CortexM and one for MIPS.



Index: stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_jtag.ldi
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_jtag.ldi,v
retrieving revision 1.1
diff -u -5 -r1.1 mlt_cortexm_stm3210e_eval_jtag.ldi
--- stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_jtag.ldi	3 Nov 2008 14:53:51 -0000	1.1
+++ stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_jtag.ldi	4 Feb 2009 11:36:05 -0000
@@ -12,10 +12,11 @@
 }
 
 SECTIONS
 {
     SECTIONS_BEGIN
+    SECTION_sram (sram, 0x20000400, LMA_EQ_VMA)
     SECTION_rom_vectors (ram, 0x68000000, LMA_EQ_VMA)
     SECTION_RELOCS (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_text (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_fini (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_rodata (ram, ALIGN(0x8), LMA_EQ_VMA)
Index: stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_ram.ldi
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_ram.ldi,v
retrieving revision 1.2
diff -u -5 -r1.2 mlt_cortexm_stm3210e_eval_ram.ldi
--- stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_ram.ldi	19 Nov 2008 17:47:30 -0000	1.2
+++ stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_ram.ldi	4 Feb 2009 11:36:05 -0000
@@ -12,10 +12,11 @@
 }
 
 SECTIONS
 {
     SECTIONS_BEGIN
+    SECTION_sram (sram, 0x20000400, LMA_EQ_VMA)
     SECTION_rom_vectors (ram, 0x68008000, LMA_EQ_VMA)
     SECTION_RELOCS (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_text (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_fini (ram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_rodata (ram, ALIGN(0x8), LMA_EQ_VMA)
Index: stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi,v
retrieving revision 1.1
diff -u -5 -r1.1 mlt_cortexm_stm3210e_eval_rom.ldi
--- stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi	3 Nov 2008 14:53:51 -0000	1.1
+++ stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_rom.ldi	4 Feb 2009 11:36:05 -0000
@@ -22,10 +22,11 @@
     SECTION_rodata1 (flash, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_fixup (flash, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_gcc_except_table (flash, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_eh_frame (flash, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_got (flash, ALIGN (0x8), LMA_EQ_VMA)
+    SECTION_sram (sram, 0x20000400, LMA_EQ_VMA)
     SECTION_data (ram, 0x68000000, FOLLOWING (.got))
     SECTION_bss (ram, ALIGN (0x8), LMA_EQ_VMA)
     CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
     SECTIONS_END
 }
Index: stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_sram.ldi
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_sram.ldi,v
retrieving revision 1.1
diff -u -5 -r1.1 mlt_cortexm_stm3210e_eval_sram.ldi
--- stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_sram.ldi	3 Nov 2008 14:53:51 -0000	1.1
+++ stm32/stm3210e_eval/current/include/pkgconf/mlt_cortexm_stm3210e_eval_sram.ldi	4 Feb 2009 11:36:05 -0000
@@ -24,10 +24,11 @@
     SECTION_gcc_except_table (sram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_eh_frame (sram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_got (sram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_data (sram, ALIGN (0x8), LMA_EQ_VMA)
     SECTION_bss (sram, ALIGN (0x8), LMA_EQ_VMA)
+    SECTION_sram (sram, ALIGN (0x8), LMA_EQ_VMA)
     CYG_LABEL_DEFN(__heap1) = ALIGN (0x8);
     SECTIONS_END
 }
 
 hal_vsr_table = 0x20000000;
Index: stm32/var/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/var/current/ChangeLog,v
retrieving revision 1.5
diff -u -5 -r1.5 ChangeLog
--- stm32/var/current/ChangeLog	29 Jan 2009 17:49:15 -0000	1.5
+++ stm32/var/current/ChangeLog	4 Feb 2009 11:36:05 -0000
@@ -1,5 +1,15 @@
+2009-02-04  Nick Garnett  <nickg@ecoscentric.com>
+
+	* include/var_intr.h: Various fixes to allow external interrupts
+	to work.
+
+	* include/var_io.h: Add AFIO, DMA, SPI and USB definitions.
+
+	* src/stm32_misc.c (hal_stm32_gpio_set): Refetch bit number for
+	setting pullup/down.
+
 2008-11-24  Nick Garnett  <nickg@ecoscentric.com>
 
 	* include/var_intr.h (CYGNUM_HAL_INTERRUPT_DMA1_CHX): Rename DMA0
 	to DMA1 to match ST's numbering elsewhere.
 
Index: stm32/var/current/include/var_intr.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/var/current/include/var_intr.h,v
retrieving revision 1.3
diff -u -5 -r1.3 var_intr.h
--- stm32/var/current/include/var_intr.h	29 Jan 2009 17:49:15 -0000	1.3
+++ stm32/var/current/include/var_intr.h	4 Feb 2009 11:36:06 -0000
@@ -139,16 +139,13 @@
 #define CYGNUM_HAL_INTERRUPT_EXTI11             ( 7+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
 #define CYGNUM_HAL_INTERRUPT_EXTI12             ( 8+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
 #define CYGNUM_HAL_INTERRUPT_EXTI13             ( 9+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
 #define CYGNUM_HAL_INTERRUPT_EXTI14             (10+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
 #define CYGNUM_HAL_INTERRUPT_EXTI15             (11+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
-#define CYGNUM_HAL_INTERRUPT_EXTI16             (12+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
-#define CYGNUM_HAL_INTERRUPT_EXTI17             (13+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
-#define CYGNUM_HAL_INTERRUPT_EXTI18             (14+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
 
 #define CYGNUM_HAL_ISR_MIN                     0
-#define CYGNUM_HAL_ISR_MAX                     CYGNUM_HAL_INTERRUPT_EXTI18
+#define CYGNUM_HAL_ISR_MAX                     CYGNUM_HAL_INTERRUPT_EXTI15
 #define CYGNUM_HAL_ISR_COUNT                   (CYGNUM_HAL_ISR_MAX + 1)
 
 #define CYGNUM_HAL_VSR_MIN                     0
 #ifndef CYGNUM_HAL_VSR_MAX
 #define CYGNUM_HAL_VSR_MAX                     (CYGNUM_HAL_VECTOR_SYS_TICK+CYGNUM_HAL_INTERRUPT_NVIC_MAX)
@@ -163,109 +160,169 @@
     cyg_int32 __v = -1;                                                 \
                                                                         \
     switch( __vector )                                                  \
     {                                                                   \
     case CYGNUM_HAL_INTERRUPT_EXTI0...CYGNUM_HAL_INTERRUPT_EXTI4:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI0;                              \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI0;                    \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI5...CYGNUM_HAL_INTERRUPT_EXTI9:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI10...CYGNUM_HAL_INTERRUPT_EXTI15:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
         break;                                                          \
                                                                         \
-    case CYGNUM_HAL_INTERRUPT_EXTI16...CYGNUM_HAL_INTERRUPT_EXTI18:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+    case CYGNUM_HAL_INTERRUPT_PVD:                                      \
+        __v =  16;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_RTC_ALARM:                                \
+        __v =  17;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_USB_WAKEUP:                               \
+        __v =  18;                                                      \
         break;                                                          \
     }                                                                   \
                                                                         \
-    if( __v > 0 )                                                       \
+    if( __v >= 0 )                                                      \
     {                                                                   \
         cyg_uint32 __imr;                                               \
         HAL_READ_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
         __imr &= ~CYGHWR_HAL_STM32_EXTI_BIT(__v);                       \
-        HAL_READ_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
+        HAL_WRITE_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
     }                                                                   \
 }
 
 #define HAL_VAR_INTERRUPT_UNMASK( __vector )                            \
 {                                                                       \
     cyg_int32 __v = -1;                                                 \
                                                                         \
     switch( __vector )                                                  \
     {                                                                   \
     case CYGNUM_HAL_INTERRUPT_EXTI0...CYGNUM_HAL_INTERRUPT_EXTI4:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI0;                              \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI0;                    \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI5...CYGNUM_HAL_INTERRUPT_EXTI9:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                \
         HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SER(CYGNUM_HAL_INTERRUPT_EXTI9_5-CYGNUM_HAL_INTERRUPT_EXTERNAL), \
                           CYGARC_REG_NVIC_IBIT(CYGNUM_HAL_INTERRUPT_EXTI9_5-CYGNUM_HAL_INTERRUPT_EXTERNAL) ); \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI10...CYGNUM_HAL_INTERRUPT_EXTI15:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                \
         HAL_WRITE_UINT32( CYGARC_REG_NVIC_BASE+CYGARC_REG_NVIC_SER(CYGNUM_HAL_INTERRUPT_EXTI15_10-CYGNUM_HAL_INTERRUPT_EXTERNAL), \
                           CYGARC_REG_NVIC_IBIT(CYGNUM_HAL_INTERRUPT_EXTI15_10-CYGNUM_HAL_INTERRUPT_EXTERNAL) ); \
         break;                                                          \
                                                                         \
-    case CYGNUM_HAL_INTERRUPT_EXTI16...CYGNUM_HAL_INTERRUPT_EXTI18:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+    case CYGNUM_HAL_INTERRUPT_PVD:                                      \
+        __v =  16;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_RTC_ALARM:                                \
+        __v =  17;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_USB_WAKEUP:                               \
+        __v =  18;                                                      \
         break;                                                          \
     }                                                                   \
                                                                         \
-    if( __v > 0 )                                                       \
+    if( __v >= 0 )                                                      \
     {                                                                   \
         cyg_uint32 __imr;                                               \
         HAL_READ_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
         __imr |= CYGHWR_HAL_STM32_EXTI_BIT(__v);                        \
-        HAL_READ_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
+        HAL_WRITE_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_IMR, __imr ); \
     }                                                                   \
 }
 
 #define HAL_VAR_INTERRUPT_SET_LEVEL( __vector, __level ) CYG_EMPTY_STATEMENT
 
-#define HAL_VAR_INTERRUPT_ACKNOWLEDGE( __vector ) CYG_EMPTY_STATEMENT
+#define HAL_VAR_INTERRUPT_ACKNOWLEDGE( __vector )                       \
+{                                                                       \
+    cyg_int32 __v = -1;                                                 \
+                                                                        \
+    switch( __vector )                                                  \
+    {                                                                   \
+    case CYGNUM_HAL_INTERRUPT_EXTI0...CYGNUM_HAL_INTERRUPT_EXTI4:       \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI0;                    \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_EXTI5...CYGNUM_HAL_INTERRUPT_EXTI9:       \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_EXTI10...CYGNUM_HAL_INTERRUPT_EXTI15:     \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_PVD:                                      \
+        __v =  16;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_RTC_ALARM:                                \
+        __v =  17;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_USB_WAKEUP:                               \
+        __v =  18;                                                      \
+        break;                                                          \
+    }                                                                   \
+                                                                        \
+    if( __v >= 0 )                                                      \
+    {                                                                   \
+        cyg_uint32 __bit = CYGHWR_HAL_STM32_EXTI_BIT(__v);              \
+        HAL_WRITE_UINT32( CYGHWR_HAL_STM32_EXTI+CYGHWR_HAL_STM32_EXTI_PR, __bit ); \
+    }                                                                   \
+}
 
 #define HAL_VAR_INTERRUPT_CONFIGURE( __vector, __level, __up )          \
 {                                                                       \
     cyg_int32 __v = -1;                                                 \
                                                                         \
     switch( __vector )                                                  \
     {                                                                   \
     case CYGNUM_HAL_INTERRUPT_EXTI0...CYGNUM_HAL_INTERRUPT_EXTI4:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI0;                              \
+        __v = __vector - CYGNUM_HAL_INTERRUPT_EXTI0;                    \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI5...CYGNUM_HAL_INTERRUPT_EXTI9:       \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
         break;                                                          \
                                                                         \
     case CYGNUM_HAL_INTERRUPT_EXTI10...CYGNUM_HAL_INTERRUPT_EXTI15:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+        __v =  __vector - CYGNUM_HAL_INTERRUPT_EXTI5 + 5;               \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_PVD:                                      \
+        __v =  16;                                                      \
+        break;                                                          \
+                                                                        \
+    case CYGNUM_HAL_INTERRUPT_RTC_ALARM:                                \
+        __v =  17;                                                      \
         break;                                                          \
                                                                         \
-    case CYGNUM_HAL_INTERRUPT_EXTI16...CYGNUM_HAL_INTERRUPT_EXTI18:     \
-        __v -= CYGNUM_HAL_INTERRUPT_EXTI5 + 5;                          \
+    case CYGNUM_HAL_INTERRUPT_USB_WAKEUP:                               \
+        __v =  18;                                                      \
         break;                                                          \
     }                                                                   \
                                                                         \
-    if( !(__level) )                                                    \
+    if(( __v >= 0 ) && !(__level) )                                     \
     {                                                                   \
         cyg_uint32 __base = CYGHWR_HAL_STM32_EXTI;                      \
         cyg_uint32 __rtsr, __ftsr;                                      \
         cyg_uint32 __bit = CYGHWR_HAL_STM32_EXTI_BIT(__v);              \
         HAL_READ_UINT32( __base+CYGHWR_HAL_STM32_EXTI_RTSR, __rtsr );   \
-        HAL_READ_UINT32( __base+CYGHWR_HAL_STM32_EXTI_RTSR, __ftsr );   \
+        HAL_READ_UINT32( __base+CYGHWR_HAL_STM32_EXTI_FTSR, __ftsr );   \
         if( __up ) __rtsr |= __bit, __ftsr &= ~__bit;                   \
         else __ftsr |= __bit, __rtsr &= ~__bit;                         \
         HAL_WRITE_UINT32( __base+CYGHWR_HAL_STM32_EXTI_RTSR, __rtsr );  \
-        HAL_WRITE_UINT32( __base+CYGHWR_HAL_STM32_EXTI_RTSR, __ftsr );  \
+        HAL_WRITE_UINT32( __base+CYGHWR_HAL_STM32_EXTI_FTSR, __ftsr );  \
     }                                                                   \
 }
 
 
 //----------------------------------------------------------------------------
Index: stm32/var/current/include/var_io.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/var/current/include/var_io.h,v
retrieving revision 1.5
diff -u -5 -r1.5 var_io.h
--- stm32/var/current/include/var_io.h	29 Jan 2009 17:49:15 -0000	1.5
+++ stm32/var/current/include/var_io.h	4 Feb 2009 11:36:06 -0000
@@ -108,12 +108,12 @@
 
 //=============================================================================
 // Device signature and ID registers
 
 #define CYGHWR_HAL_STM32_DEV_SIG                0x1FFFF7E0
-#define CYGHWR_HAL_STM32_DEV_SIG_FSIZE(__s)     (((__s)>>16)&0xFFFF)
-#define CYGHWR_HAL_STM32_DEV_SIG_RSIZE(__s)     ((__s)&0xFFFF)
+#define CYGHWR_HAL_STM32_DEV_SIG_RSIZE(__s)     (((__s)>>16)&0xFFFF)
+#define CYGHWR_HAL_STM32_DEV_SIG_FSIZE(__s)     ((__s)&0xFFFF)
 
 #define CYGHWR_HAL_STM32_MCU_ID                 0xe0042000
 #define CYGHWR_HAL_STM32_MCU_ID_DEV(__x)        ((__x)&0xFFF)
 #define CYGHWR_HAL_STM32_MCU_ID_DEV_MEDIUM      0x410
 #define CYGHWR_HAL_STM32_MCU_ID_DEV_HIGH        0x414
@@ -226,11 +226,12 @@
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_UART2      BIT_(17)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_UART3      BIT_(18)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_UART4      BIT_(19)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_UART5      BIT_(20)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_I2C1       BIT_(21)
-#define CYGHWR_HAL_STM32_RCC_APB1ENR_USB        BIT_(22)
+#define CYGHWR_HAL_STM32_RCC_APB1ENR_I2C2       BIT_(22)
+#define CYGHWR_HAL_STM32_RCC_APB1ENR_USB        BIT_(23)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_CAN        BIT_(25)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_BKP        BIT_(27)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_PWR        BIT_(28)
 #define CYGHWR_HAL_STM32_RCC_APB1ENR_DAC        BIT_(29)
 
@@ -367,10 +368,131 @@
 #define CYGHWR_HAL_STM32_GPIO_SET(__pin ) hal_stm32_gpio_set( __pin )
 #define CYGHWR_HAL_STM32_GPIO_OUT(__pin, __val ) hal_stm32_gpio_out( __pin, __val )
 #define CYGHWR_HAL_STM32_GPIO_IN(__pin,  __val ) hal_stm32_gpio_in( __pin, __val )
 
 //=============================================================================
+// Alternate I/O configuration registers.
+
+#define CYGHWR_HAL_STM32_AFIO_EVCR              0x00
+#define CYGHWR_HAL_STM32_AFIO_MAPR              0x04
+#define CYGHWR_HAL_STM32_AFIO_EXTICR1           0x08
+#define CYGHWR_HAL_STM32_AFIO_EXTICR2           0x0C
+#define CYGHWR_HAL_STM32_AFIO_EXTICR3           0x10
+#define CYGHWR_HAL_STM32_AFIO_EXTICR4           0x14
+
+// The following macro allows the four ETXICR registers to be indexed
+// as CYGHWR_HAL_STM32_AFIO_EXTICR(1) to CYGHWR_HAL_STM32_AFIO_EXTICR(4)
+#define CYGHWR_HAL_STM32_AFIO_EXTICR(__x)       (4*((__x)-1)+0x08)
+
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PIN(__x)     VALUE_(0,(__x))
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PORTA        VALUE_(4,0) 
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PORTB        VALUE_(4,1) 
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PORTC        VALUE_(4,2) 
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PORTD        VALUE_(4,3) 
+#define CYGHWR_HAL_STM32_AFIO_EVCR_PORTE        VALUE_(4,4)
+#define CYGHWR_HAL_STM32_AFIO_EVCR_EVOE         BIT_(7) 
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_SPI1_RMP     BIT_(0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_I2C1_RMP     BIT_(1)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_URT1_RMP     BIT_(2)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_URT2_RMP     BIT_(3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_URT3_NO_RMP  VALUE_(4,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_URT3_P1_RMP  VALUE_(4,1)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_URT3_FL_RMP  VALUE_(4,3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM1_NO_RMP  VALUE_(6,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM1_P1_RMP  VALUE_(6,1)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM1_FL_RMP  VALUE_(6,3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM2_NO_RMP  VALUE_(8,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM2_P1_RMP  VALUE_(8,1)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM2_P2_RMP  VALUE_(8,2)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM2_FL_RMP  VALUE_(8,3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM3_NO_RMP  VALUE_(10,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM3_P2_RMP  VALUE_(10,2)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM3_FL_RMP  VALUE_(10,3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM4_RMP     BIT_(12)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_CAN_NO_RMP   VALUE_(13,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_CAN_FL1_RMP  VALUE_(13,2)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_CAN_FL2_RMP  VALUE_(13,3)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_PD01_RMP     BIT_(15)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_TIM5CH4_RMP  BIT_(16)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_ADC1EINJ_RMP BIT_(17)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_ADC1EREG_RMP BIT_(18)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_ADC2EINJ_RMP BIT_(19)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_ADC2EREG_RMP BIT_(20)
+
+#define CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_FULL     VALUE_(24,0)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_NORST    VALUE_(24,1)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_SWDPEN   VALUE_(24,2)
+#define CYGHWR_HAL_STM32_AFIO_MAPR_SWJ_SWDPDIS  VALUE_(24,4)
+
+// The following macros are used to generate the bitfields for setting up
+// external interrupts.  For example, CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTC(12)
+// will generate the bitfield which when ORed into the EXTICR4 register will
+// set up C12 as the external interrupt pin for the EXTI12 interrupt.
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTA(__x) VALUE_(4*((__x)&3),0)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTB(__x) VALUE_(4*((__x)&3),1)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTC(__x) VALUE_(4*((__x)&3),2)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTD(__x) VALUE_(4*((__x)&3),3)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTE(__x) VALUE_(4*((__x)&3),4)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTF(__x) VALUE_(4*((__x)&3),5)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_PORTG(__x) VALUE_(4*((__x)&3),6)
+#define CYGHWR_HAL_STM32_AFIO_EXTICRX_MASK(__x)  VALUE_(4*((__x)&3),0xF)
+
+//=============================================================================
+// DMA controller register definitions.
+
+#define CYGHWR_HAL_STM32_DMA_ISR                0x00
+#define CYGHWR_HAL_STM32_DMA_IFCR               0x04
+
+// The following macros allow access to the per-channel DMA registers, indexed
+// by channel number.  Valid channel numbers are 1 to 7 for DMA1 and 1 to 5
+// for DMA2.
+#define CYGHWR_HAL_STM32_DMA_CCR(__x)           (0x14*(__x)-0x0C)
+#define CYGHWR_HAL_STM32_DMA_CNDTR(__x)         (0x14*(__x)-0x08)
+#define CYGHWR_HAL_STM32_DMA_CPAR(__x)          (0x14*(__x)-0x04)
+#define CYGHWR_HAL_STM32_DMA_CMAR(__x)          (0x14*(__x))
+
+#define CYGHWR_HAL_STM32_DMA_ISR_GIF(__x)       BIT_(4*(__x)-4)
+#define CYGHWR_HAL_STM32_DMA_ISR_TCIF(__x)      BIT_(4*(__x)-3)
+#define CYGHWR_HAL_STM32_DMA_ISR_HTIF(__x)      BIT_(4*(__x)-2)
+#define CYGHWR_HAL_STM32_DMA_ISR_TEIF(__x)      BIT_(4*(__x)-1)
+#define CYGHWR_HAL_STM32_DMA_ISR_MASK(__x)      VALUE_(4*(__x)-4,0xF)
+
+#define CYGHWR_HAL_STM32_DMA_IFCR_CGIF(__x)     BIT_(4*(__x)-4)
+#define CYGHWR_HAL_STM32_DMA_IFCR_CTCIF(__x)    BIT_(4*(__x)-3)
+#define CYGHWR_HAL_STM32_DMA_IFCR_CHTIF(__x)    BIT_(4*(__x)-2)
+#define CYGHWR_HAL_STM32_DMA_IFCR_CTEIF(__x)    BIT_(4*(__x)-1)
+#define CYGHWR_HAL_STM32_DMA_IFCR_MASK(__x)     VALUE_(4*(__x)-4,0xF)
+
+#define CYGHWR_HAL_STM32_DMA_CCR_EN             BIT_(0)
+#define CYGHWR_HAL_STM32_DMA_CCR_TCIE           BIT_(1)
+#define CYGHWR_HAL_STM32_DMA_CCR_HTIE           BIT_(2)
+#define CYGHWR_HAL_STM32_DMA_CCR_TEIE           BIT_(3)
+#define CYGHWR_HAL_STM32_DMA_CCR_DIR            BIT_(4)
+#define CYGHWR_HAL_STM32_DMA_CCR_CIRC           BIT_(5)
+#define CYGHWR_HAL_STM32_DMA_CCR_PINC           BIT_(6)
+#define CYGHWR_HAL_STM32_DMA_CCR_MINC           BIT_(7)
+#define CYGHWR_HAL_STM32_DMA_CCR_PSIZE8         VALUE_(8,0)
+#define CYGHWR_HAL_STM32_DMA_CCR_PSIZE16        VALUE_(8,1)
+#define CYGHWR_HAL_STM32_DMA_CCR_PSIZE32        VALUE_(8,2)
+#define CYGHWR_HAL_STM32_DMA_CCR_MSIZE8         VALUE_(10,0)
+#define CYGHWR_HAL_STM32_DMA_CCR_MSIZE16        VALUE_(10,1)
+#define CYGHWR_HAL_STM32_DMA_CCR_MSIZE32        VALUE_(10,2)
+#define CYGHWR_HAL_STM32_DMA_CCR_PLLOW          VALUE_(12,0)
+#define CYGHWR_HAL_STM32_DMA_CCR_PLMEDIUM       VALUE_(12,1)
+#define CYGHWR_HAL_STM32_DMA_CCR_PLHIGH         VALUE_(12,2)
+#define CYGHWR_HAL_STM32_DMA_CCR_PLMAX          VALUE_(12,3)
+#define CYGHWR_HAL_STM32_DMA_CCR_MEM2MEM        BIT_(14)
+
+//=============================================================================
 // UARTs
 
 #define CYGHWR_HAL_STM32_UART_SR                0x00
 #define CYGHWR_HAL_STM32_UART_DR                0x04
 #define CYGHWR_HAL_STM32_UART_BRR               0x08
@@ -482,10 +604,161 @@
 __externC void hal_stm32_uart_setbaud( CYG_ADDRESS uart, cyg_uint32 baud );
 
 #endif
 
 //=============================================================================
+// SPI interface register definitions.
+
+#define CYGHWR_HAL_STM32_SPI_CR1                0x00
+#define CYGHWR_HAL_STM32_SPI_CR2                0x04
+#define CYGHWR_HAL_STM32_SPI_SR                 0x08
+#define CYGHWR_HAL_STM32_SPI_DR                 0x0C
+#define CYGHWR_HAL_STM32_SPI_CRCPR              0x10
+#define CYGHWR_HAL_STM32_SPI_RXCRCR             0x14
+#define CYGHWR_HAL_STM32_SPI_TXCRCR             0x18
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR            0x1C
+#define CYGHWR_HAL_STM32_SPI_I2SPR              0x20
+
+#define CYGHWR_HAL_STM32_SPI_CR1_CPHA           BIT_(0)
+#define CYGHWR_HAL_STM32_SPI_CR1_CPOL           BIT_(1)
+#define CYGHWR_HAL_STM32_SPI_CR1_MSTR           BIT_(2)
+#define CYGHWR_HAL_STM32_SPI_CR1_BR(__x)        VALUE_(3,(__x))
+#define CYGHWR_HAL_STM32_SPI_CR1_SPE            BIT_(6)
+#define CYGHWR_HAL_STM32_SPI_CR1_LSBFIRST       BIT_(7)
+#define CYGHWR_HAL_STM32_SPI_CR1_SSI            BIT_(8)
+#define CYGHWR_HAL_STM32_SPI_CR1_SSM            BIT_(9)
+#define CYGHWR_HAL_STM32_SPI_CR1_RXONLY         BIT_(10)
+#define CYGHWR_HAL_STM32_SPI_CR1_DFF            BIT_(11)
+#define CYGHWR_HAL_STM32_SPI_CR1_CRCNEXT        BIT_(12)
+#define CYGHWR_HAL_STM32_SPI_CR1_CRCEN          BIT_(13)
+#define CYGHWR_HAL_STM32_SPI_CR1_BIDIOE         BIT_(14)
+#define CYGHWR_HAL_STM32_SPI_CR1_BIDIMODE       BIT_(15)
+
+#define CYGHWR_HAL_STM32_SPI_CR2_RXDMAEN        BIT_(0)
+#define CYGHWR_HAL_STM32_SPI_CR2_TXDMAEN        BIT_(1)
+#define CYGHWR_HAL_STM32_SPI_CR2_SSOE           BIT_(2)
+#define CYGHWR_HAL_STM32_SPI_CR2_ERRIE          BIT_(5)
+#define CYGHWR_HAL_STM32_SPI_CR2_RXNEIE         BIT_(6)
+#define CYGHWR_HAL_STM32_SPI_CR2_TXEIE          BIT_(7)
+
+#define CYGHWR_HAL_STM32_SPI_SR_RXNE            BIT_(0)
+#define CYGHWR_HAL_STM32_SPI_SR_TXE             BIT_(1)
+#define CYGHWR_HAL_STM32_SPI_SR_CHSIDE          BIT_(2)
+#define CYGHWR_HAL_STM32_SPI_SR_UDR             BIT_(3)
+#define CYGHWR_HAL_STM32_SPI_SR_CRCERR          BIT_(4)
+#define CYGHWR_HAL_STM32_SPI_SR_MODF            BIT_(5)
+#define CYGHWR_HAL_STM32_SPI_SR_OVR             BIT_(6)
+#define CYGHWR_HAL_STM32_SPI_SR_BSY             BIT_(7)
+
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_CHLEN      BIT_(0)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_DATLEN16   VALUE_(1,0)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_DATLEN24   VALUE_(1,1)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_DATLEN32   VALUE_(1,2)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_CKPOL      BIT_(3)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SSTDPHL  VALUE_(4,0)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SSTDMSB  VALUE_(4,1)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SSTDLSB  VALUE_(4,2)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SSTDPCM  VALUE_(4,3)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_PCMSYNC    BIT_(7)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SCFGST   VALUE_(8,0)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SCFGSR   VALUE_(8,1)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SCFGMT   VALUE_(8,2)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SCFGMR   VALUE_(8,3)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2SE       BIT_(10)
+#define CYGHWR_HAL_STM32_SPI_I2SCFGR_I2MOD      BIT_(11)
+
+#define CYGHWR_HAL_STM32_SPI_I2SPR_I2SDIV(__x)  VALUE_(0,(__x))
+#define CYGHWR_HAL_STM32_SPI_I2SPR_ODD          BIT_(8)
+#define CYGHWR_HAL_STM32_SPI_I2SPR_MCKOE        BIT_(9)
+
+//=============================================================================
+// USB interface register definitions.
+
+#define CYGHWR_HAL_STM32_USB_EP0R               0x00 
+#define CYGHWR_HAL_STM32_USB_EP1R               0x04 
+#define CYGHWR_HAL_STM32_USB_EP2R               0x08 
+#define CYGHWR_HAL_STM32_USB_EP3R               0x0C 
+#define CYGHWR_HAL_STM32_USB_EP4R               0x10 
+#define CYGHWR_HAL_STM32_USB_EP5R               0x14 
+#define CYGHWR_HAL_STM32_USB_EP6R               0x18 
+#define CYGHWR_HAL_STM32_USB_EP7R               0x1C 
+
+#define CYGHWR_HAL_STM32_USB_CNTR               0x40
+#define CYGHWR_HAL_STM32_USB_ISTR               0x44
+#define CYGHWR_HAL_STM32_USB_FNR                0x48
+#define CYGHWR_HAL_STM32_USB_DADDR              0x4C
+#define CYGHWR_HAL_STM32_USB_BTABLE             0x50
+
+// The following macro allows the USB endpoint registers to be indexed as
+// CYGHWR_HAL_STM32_USB_EPXR(0) to CYGHWR_HAL_STM32_USB_EPXR(7).
+#define CYGHWR_HAL_STM32_USB_EPXR(__x)          ((__x)*4)
+
+#define CYGHWR_HAL_STM32_USB_EPXR_EA(__x)       VALUE_(0,(__x))
+#define CYGHWR_HAL_STM32_USB_EPXR_STATTX_DIS    VALUE_(4,0)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATTX_STALL  VALUE_(4,1)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATTX_NAK    VALUE_(4,2)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATTX_VALID  VALUE_(4,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATTX_MASK   VALUE_(4,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_DTOGTX        BIT_(6)
+#define CYGHWR_HAL_STM32_USB_EPXR_SWBUFRX       BIT_(6)
+#define CYGHWR_HAL_STM32_USB_EPXR_CTRTX         BIT_(7)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPKIND        BIT_(8)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_BULK   VALUE_(9,0)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_CTRL   VALUE_(9,1)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_ISO    VALUE_(9,2)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_INTR   VALUE_(9,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_EPTYPE_MASK   VALUE_(9,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_SETUP         BIT_(11)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATRX_DIS    VALUE_(12,0)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATRX_STALL  VALUE_(12,1)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATRX_NAK    VALUE_(12,2)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATRX_VALID  VALUE_(12,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_STATRX_MASK   VALUE_(12,3)
+#define CYGHWR_HAL_STM32_USB_EPXR_DTOGRX        BIT_(14)
+#define CYGHWR_HAL_STM32_USB_EPXR_SWBUFTX       BIT_(14)
+#define CYGHWR_HAL_STM32_USB_EPXR_CTRRX         BIT_(15)
+
+#define CYGHWR_HAL_STM32_USB_CNTR_FRES          BIT_(0)
+#define CYGHWR_HAL_STM32_USB_CNTR_PDWN          BIT_(1)
+#define CYGHWR_HAL_STM32_USB_CNTR_LPMODE        BIT_(2)
+#define CYGHWR_HAL_STM32_USB_CNTR_FSUSP         BIT_(3)
+#define CYGHWR_HAL_STM32_USB_CNTR_RESUME        BIT_(4)
+#define CYGHWR_HAL_STM32_USB_CNTR_ESOFM         BIT_(8)
+#define CYGHWR_HAL_STM32_USB_CNTR_SOFM          BIT_(9)
+#define CYGHWR_HAL_STM32_USB_CNTR_RESETM        BIT_(10)
+#define CYGHWR_HAL_STM32_USB_CNTR_SUSPM         BIT_(11)
+#define CYGHWR_HAL_STM32_USB_CNTR_WKUPM         BIT_(12)
+#define CYGHWR_HAL_STM32_USB_CNTR_ERRM          BIT_(13)
+#define CYGHWR_HAL_STM32_USB_CNTR_PMAOVRM       BIT_(14)
+#define CYGHWR_HAL_STM32_USB_CNTR_CTRM          BIT_(15)
+
+#define CYGHWR_HAL_STM32_USB_ISTR_EPID(__x)     VALUE_(0,(__x))
+#define CYGHWR_HAL_STM32_USB_ISTR_EPID_MASK     MASK_(0,4)
+#define CYGHWR_HAL_STM32_USB_ISTR_DIR           BIT_(4)
+#define CYGHWR_HAL_STM32_USB_ISTR_ESOF          BIT_(8)
+#define CYGHWR_HAL_STM32_USB_ISTR_SOF           BIT_(9)
+#define CYGHWR_HAL_STM32_USB_ISTR_RESET         BIT_(10)
+#define CYGHWR_HAL_STM32_USB_ISTR_SUSP          BIT_(11)
+#define CYGHWR_HAL_STM32_USB_ISTR_WKUP          BIT_(12)
+#define CYGHWR_HAL_STM32_USB_ISTR_ERR           BIT_(13)
+#define CYGHWR_HAL_STM32_USB_ISTR_PMAOVR        BIT_(14)
+#define CYGHWR_HAL_STM32_USB_ISTR_CTR           BIT_(15)
+
+#define CYGHWR_HAL_STM32_USB_FNR_FN_MASK        MASK_(0,11)
+#define CYGHWR_HAL_STM32_USB_FNR_LSOF_LSOF0     VALUE_(11,0)
+#define CYGHWR_HAL_STM32_USB_FNR_LSOF_LSOF1     VALUE_(11,1)
+#define CYGHWR_HAL_STM32_USB_FNR_LSOF_LSOF2     VALUE_(11,2)
+#define CYGHWR_HAL_STM32_USB_FNR_LSOF_LSOFN     VALUE_(11,3)
+#define CYGHWR_HAL_STM32_USB_FNR_LSOF_MASK      MASK_(11,2)
+#define CYGHWR_HAL_STM32_USB_FNR_LCK            BIT_(13)
+#define CYGHWR_HAL_STM32_USB_FNR_RXDM           BIT_(14)
+#define CYGHWR_HAL_STM32_USB_FNR_RXDP           BIT_(15)
+
+#define CYGHWR_HAL_STM32_USB_DADDR_ADD(__x)     VALUE_(0,(__x))
+#define CYGHWR_HAL_STM32_USB_DADDR_EF           BIT_(7)
+
+//=============================================================================
 // Timers
 //
 // This currently only defines the basic registers and functionality
 // common to all timers.
 
Index: stm32/var/current/src/stm32_misc.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/cortexm/stm32/var/current/src/stm32_misc.c,v
retrieving revision 1.4
diff -u -5 -r1.4 stm32_misc.c
--- stm32/var/current/src/stm32_misc.c	29 Jan 2009 17:49:15 -0000	1.4
+++ stm32/var/current/src/stm32_misc.c	4 Feb 2009 11:36:06 -0000
@@ -280,10 +280,11 @@
     // the appropriate pullup/down resistor.
     if( cm == (CYGHWR_HAL_STM32_GPIO_MODE_IN|CYGHWR_HAL_STM32_GPIO_CNF_PULL) )
     {
         cyg_uint32 odr;
         port = CYGHWR_HAL_STM32_GPIO_PORT( pin );
+        bit = CYGHWR_HAL_STM32_GPIO_BIT(pin);
         HAL_READ_UINT32( port+CYGHWR_HAL_STM32_GPIO_ODR, odr );
         if( pin & CYGHWR_HAL_STM32_GPIO_PULLUP )
             odr |= (1<<bit);
         else
             odr &= ~(1<<bit);
Index: ChangeLog
===================================================================
RCS file: ChangeLog
diff -N ChangeLog
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ChangeLog	4 Feb 2009 11:41:17 -0000
@@ -0,0 +1,31 @@
+2009-01-30  Nick Garnett  <nickg@ecoscentric.com>
+
+	* cdl/spi_stm32.cdl: 
+	* include/spi_stm32.h: 
+	* src/spi_stm32.c: 
+	* src/spi_stm32_init.cxx:
+	New package, STM32 SPI driver contributed by Chris Holgate.
+
+//===========================================================================
+// ####GPLCOPYRIGHTBEGIN####                                                
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// This program is free software; you can redistribute it and/or modify     
+// it under the terms of the GNU General Public License as published by     
+// the Free Software Foundation; either version 2 or (at your option) any   
+// later version.                                                           
+//
+// This program is distributed in the hope that it will be useful, but      
+// WITHOUT ANY WARRANTY; without even the implied warranty of               
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU        
+// General Public License for more details.                                 
+//
+// You should have received a copy of the GNU General Public License        
+// along with this program; if not, write to the                            
+// Free Software Foundation, Inc., 51 Franklin Street,                      
+// Fifth Floor, Boston, MA  02110-1301, USA.                                
+// -------------------------------------------                              
+// ####GPLCOPYRIGHTEND####                                                  
+//===========================================================================
Index: cdl/spi_stm32.cdl
===================================================================
RCS file: cdl/spi_stm32.cdl
diff -N cdl/spi_stm32.cdl
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ cdl/spi_stm32.cdl	4 Feb 2009 11:41:17 -0000
@@ -0,0 +1,211 @@
+##=============================================================================
+##
+##      spi_stm32.cdl
+##
+##      STM32 SPI driver configuration options.
+##
+##=============================================================================
+## ####ECOSGPLCOPYRIGHTBEGIN####                                            
+## -------------------------------------------                              
+## This file is part of eCos, the Embedded Configurable Operating System.   
+## Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+##
+## eCos is free software; you can redistribute it and/or modify it under    
+## the terms of the GNU General Public License as published by the Free     
+## Software Foundation; either version 2 or (at your option) any later      
+## version.                                                                 
+##
+## eCos is distributed in the hope that it will be useful, but WITHOUT      
+## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+## FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+## for more details.                                                        
+##
+## You should have received a copy of the GNU General Public License        
+## along with eCos; if not, write to the Free Software Foundation, Inc.,    
+## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+##
+## As a special exception, if other files instantiate templates or use      
+## macros or inline functions from this file, or you compile this file      
+## and link it with other works to produce a work based on this file,       
+## this file does not by itself cause the resulting work to be covered by   
+## the GNU General Public License. However the source code for this file    
+## must still be made available in accordance with section (3) of the GNU   
+## General Public License v2.                                               
+##
+## This exception does not invalidate any other reasons why a work based    
+## on this file might be covered by the GNU General Public License.         
+## -------------------------------------------                              
+## ####ECOSGPLCOPYRIGHTEND####                                              
+##=============================================================================
+#######DESCRIPTIONBEGIN####
+##
+## Author(s):   Chris Holgate
+## Date:        2008-11-27
+## Purpose:     Configure STM32 SPI driver.
+##
+######DESCRIPTIONEND####
+##
+##=============================================================================
+
+cdl_package CYGPKG_DEVS_SPI_CORTEXM_STM32 {
+    display       "ST STM32 SPI driver"
+    description   "
+        This package provides SPI driver support for the ST STM32 series
+        of microcontrollers.
+    "
+    parent        CYGPKG_IO_SPI
+    active_if     CYGPKG_IO_SPI
+    requires      CYGPKG_HAL_CORTEXM_STM32 
+    hardware
+    include_dir   cyg/io
+    compile       spi_stm32.c
+    compile       -library=libextras.a spi_stm32_init.cxx
+
+cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE {
+    display       "Pin toggle rate"
+    description   "
+        Selects the pin toggle rate in MHz to be used for the SPI interfaces.  Higher toggle
+        rates allow increased baud rates at the expense of power and EMI.
+    "
+    flavor        data
+    default_value { 2 }
+    legal_values  { 2 10 50 }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1 {
+    display       "ST STM32 SPI bus 1"
+    description   "
+        Enable SPI bus 1 on the STM32 device.
+    "
+    flavor        bool
+    default_value false
+
+    cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1_CS_GPIOS {
+        display       "SPI chip selects"
+        description   "
+            This is a comma separated list of GPIOs which are to be used as chip
+            select lines for the SPI bus.  For the purposes of specifying
+            which GPIOs to use, they are numbered consecutively from 0 (A0)
+            through 16 (B0) to 111 (G15).
+        "
+        flavor        data
+        default_value { "4" }
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE {
+        display       "Bounce buffer size"
+        description   "
+            DMA bounce buffers are required when running out of external
+            memory.  Set this to the maximum SPI packet size which will be
+            used to enable the DMA bounce buffers.  Set to 0 to disable
+            bounce buffers when running from on-chip memory.
+        "
+        flavor        data 
+        default_value 0
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_TXINTR_PRI {
+        display       "Transmit DMA interrupt priority"
+        flavor        data
+        default_value 5
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_RXINTR_PRI {
+        display       "Receive DMA interrupt priority"
+        flavor        data
+        default_value 6
+    }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2 {
+    display       "ST STM32 SPI bus 2"
+    description   "
+        Enable SPI bus 2 on the STM32 device.
+    "
+    flavor        bool
+    default_value false
+
+    cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2_CS_GPIOS {
+        display       "SPI chip selects"
+        description   "
+            This is a comma separated list of GPIOs which are to be used as chip
+            select lines for the SPI bus.  For the purposes of specifying
+            which GPIOs to use, they are numbered consecutively from 0 (A0)
+            through 16 (B0) to 111 (G15).
+        "
+        flavor        data
+        default_value { "28" }
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE {
+        display       "Bounce buffer size"
+        description   "
+            DMA bounce buffers are required when running out of external
+            memory.  Set this to the maximum SPI packet size which will be
+            used to enable the DMA bounce buffers.  Set to 0 to disable
+            bounce buffers when running from on-chip memory.
+        "
+        flavor        data 
+        default_value 0
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_TXINTR_PRI {
+        display       "Transmit DMA interrupt priority"
+        flavor        data
+        default_value 7
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_RXINTR_PRI {
+        display       "Receive DMA interrupt priority"
+        flavor        data
+        default_value 8
+    }
+}
+
+cdl_component CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3 {
+    display       "ST STM32 SPI bus 3"
+    description   "
+        Enable SPI bus 3 on the STM32 device.
+    "
+    flavor        bool
+    default_value false
+
+    cdl_option CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_CS_GPIOS {
+        display       "SPI chip selects"
+        description   "
+            This is a comma separated list of GPIOs which are to be used as chip
+            select lines for the SPI bus.  For the purposes of specifying
+            which GPIOs to use, they are numbered consecutively from 0 (A0)
+            through 16 (B0) to 111 (G15).
+        "
+        flavor        data
+        default_value { "15" }
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE {
+        display       "Bounce buffer size"
+        description   "
+            DMA bounce buffers are required when running out of external
+            memory.  Set this to the maximum SPI packet size which will be
+            used to enable the DMA bounce buffers.  Set to 0 to disable
+            bounce buffers when running from on-chip memory.
+        "
+        flavor        data 
+        default_value 0
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_TXINTR_PRI {
+        display       "Transmit DMA interrupt priority"
+        flavor        data
+        default_value 9
+    }
+
+    cdl_option CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_RXINTR_PRI {
+        display       "Receive DMA interrupt priority"
+        flavor        data
+        default_value 10
+    }
+}
+
+}
+# EOF spi_stm32.cdl
Index: include/spi_stm32.h
===================================================================
RCS file: include/spi_stm32.h
diff -N include/spi_stm32.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ include/spi_stm32.h	4 Feb 2009 11:41:17 -0000
@@ -0,0 +1,145 @@
+#ifndef CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+#define CYGONCE_DEVS_SPI_CORTEXM_STM32_H
+//=============================================================================
+//
+//      spi_stm32.h
+//
+//      Header definitions for STM32 SPI driver.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-11-27
+// Purpose:     STM32 SPI driver definitions.
+// Description: 
+// Usage:       #include <cyg/io/spi_stm32.h>
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <pkgconf/hal.h>
+#include <pkgconf/io_spi.h>
+#include <pkgconf/devs_spi_cortexm_stm32.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/hal/drv_api.h>
+#include <cyg/io/spi.h>
+
+//-----------------------------------------------------------------------------
+// STM32 SPI bus configuration and state.
+
+typedef struct cyg_spi_cortexm_stm32_bus_setup_s
+{
+    cyg_uint32        apb_freq;        // Peripheral bus frequency (fp).
+    cyg_haladdress    spi_reg_base;    // Base address of SPI register block.
+    cyg_haladdress    dma_reg_base;    // Base address of DMA register block.
+    cyg_uint8         dma_tx_channel;  // TX DMA channel for this bus.
+    cyg_uint8         dma_rx_channel;  // RX DMA channel for this bus.
+    cyg_uint8         cs_gpio_num;     // Number of chip selects for this bus.
+    const cyg_uint8*  cs_gpio_list;    // List of GPIOs used as chip selects.
+    const cyg_uint8*  spi_gpio_list;   // List of GPIOs used by the SPI interface.
+    cyg_vector_t      dma_tx_intr;     // Interrupt used for DMA transmit.
+    cyg_vector_t      dma_rx_intr;     // Interrupt used for DMA receive.
+    cyg_priority_t    dma_tx_intr_pri; // Interrupt priority for DMA transmit.
+    cyg_priority_t    dma_rx_intr_pri; // Interrupt priority for DMA receive.
+    cyg_uint32        bbuf_size;       // Size of bounce buffers.
+    cyg_uint8*        bbuf_tx;         // Pointer to transmit bounce buffer.
+    cyg_uint8*        bbuf_rx;         // Pointer to receive bounce buffer.
+
+} cyg_spi_cortexm_stm32_bus_setup_t;
+
+typedef struct cyg_spi_cortexm_stm32_bus_s
+{
+    // ---- Upper layer data ----
+    cyg_spi_bus       spi_bus;         // Upper layer SPI bus data.
+
+    // ---- Bus configuration constants ----
+    const cyg_spi_cortexm_stm32_bus_setup_t* setup;
+
+    // ---- Driver state (private) ----
+    cyg_interrupt     tx_intr_data;    // DMA interrupt data (TX).
+    cyg_interrupt     rx_intr_data;    // DMA interrupt data (RX).
+    cyg_handle_t      tx_intr_handle;  // DMA interrupt handle (TX).
+    cyg_handle_t      rx_intr_handle;  // DMA interrupt handle (RX).
+    cyg_drv_mutex_t   mutex;           // Transfer mutex.
+    cyg_drv_cond_t    condvar;         // Transfer condition variable.
+    cyg_bool          tx_dma_done;     // Flags used to signal completion.
+    cyg_bool          rx_dma_done;     // Flags used to signal completion.
+    cyg_bool          cs_up;           // Chip select asserted flag.
+
+} cyg_spi_cortexm_stm32_bus_t;
+
+//-----------------------------------------------------------------------------
+// STM32 SPI device.
+
+typedef struct cyg_spi_cortexm_stm32_device_s
+{
+    // ---- Upper layer data ----
+    cyg_spi_device spi_device;  // Upper layer SPI device data.
+
+    // ---- Device setup (user configurable) ----
+    cyg_uint8  dev_num;         // Device number.
+    cyg_uint8  bus_16bit;       // Use 16 bit (1) or 8 bit (0) transfers.
+    cyg_uint8  cl_pol;          // Clock polarity (0 or 1).
+    cyg_uint8  cl_pha;          // Clock phase    (0 or 1).
+    cyg_uint32 cl_brate;        // Clock baud rate.
+    cyg_uint16 cs_up_udly;      // Minimum delay in us between CS up and transfer start.
+    cyg_uint16 cs_dw_udly;      // Minimum delay in us between transfer end and CS down.
+    cyg_uint16 tr_bt_udly;      // Minimum delay in us between two transfers.
+
+    // ---- Device state (private) ----
+    cyg_uint32 spi_cr1_val;     // SPI configuration register (initialised to 0). 
+
+} cyg_spi_cortexm_stm32_device_t;
+
+//-----------------------------------------------------------------------------
+// Exported bus data structures.
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus1;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2;
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus3;
+#endif
+
+//=============================================================================
+#endif // CYGONCE_DEVS_SPI_CORTEXM_STM32_H
Index: src/spi_stm32.c
===================================================================
RCS file: src/spi_stm32.c
diff -N src/spi_stm32.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/spi_stm32.c	4 Feb 2009 11:41:18 -0000
@@ -0,0 +1,784 @@
+//=============================================================================
+//
+//      spi_stm32.c
+//
+//      SPI driver implementation for STM32
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-11-27
+// Purpose:     STM32 SPI driver implementation
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/hal/hal_io.h>
+#include <cyg/hal/hal_if.h>
+#include <cyg/hal/hal_intr.h>
+#include <cyg/hal/drv_api.h>
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/cyg_ass.h>
+#include <cyg/infra/diag.h>
+
+#include <cyg/io/spi.h>
+#include <cyg/io/spi_stm32.h>
+
+#include <pkgconf/devs_spi_cortexm_stm32.h>
+
+#include <string.h>
+
+//-----------------------------------------------------------------------------
+// Work out the bus clock frequencies.
+
+#define APB1_FREQ ((CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_MUL) / \
+  (CYGHWR_HAL_CORTEXM_STM32_CLOCK_HCLK_DIV * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PCLK1_DIV)) 
+#define APB2_FREQ ((CYGARC_HAL_CORTEXM_STM32_INPUT_CLOCK * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PLL_MUL) / \
+  (CYGHWR_HAL_CORTEXM_STM32_CLOCK_HCLK_DIV * CYGHWR_HAL_CORTEXM_STM32_CLOCK_PCLK2_DIV)) 
+
+//-----------------------------------------------------------------------------
+// API function call forward references.
+
+static void stm32_transaction_begin    (cyg_spi_device*);
+static void stm32_transaction_transfer (cyg_spi_device*, cyg_bool, cyg_uint32, const cyg_uint8*, cyg_uint8*, cyg_bool);
+static void stm32_transaction_tick     (cyg_spi_device*, cyg_bool, cyg_uint32);
+static void stm32_transaction_end      (cyg_spi_device*);
+static int  stm32_get_config           (cyg_spi_device*, cyg_uint32, void*, cyg_uint32*);
+static int  stm32_set_config           (cyg_spi_device*, cyg_uint32, const void*, cyg_uint32*);
+
+//-----------------------------------------------------------------------------
+// Null data source and sink must be placed in the on-chip SRAM.  This is
+// either done explicitly (bounce buffers instantiated) or implicitly (no
+// bounce buffers implies that the data area is already on SRAM).
+
+#if (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)) || \
+  (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)) || \
+  (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3) && (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0))
+static cyg_uint16 dma_tx_null __attribute__((section (".sram"))) = 0xFFFF;
+static cyg_uint16 dma_rx_null __attribute__((section (".sram"))) = 0xFFFF;
+
+#elif (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1)) || \
+  (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2)) || \
+  (defined (CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3))
+static cyg_uint16 dma_tx_null = 0xFFFF;
+static cyg_uint16 dma_rx_null = 0xFFFF;
+#endif
+
+//-----------------------------------------------------------------------------
+// Instantiate the bus state data structures.
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+static const cyg_uint8 bus1_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1_CS_GPIOS };
+static const cyg_uint8 bus1_spi_gpio_list[] = { 0x05, 0x06, 0x07 };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)
+static cyg_uint8 bus1_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE] 
+  __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus1_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE] 
+  __attribute__((aligned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus1_setup = {
+  .apb_freq                         = APB2_FREQ,
+  .spi_reg_base                     = CYGHWR_HAL_STM32_SPI1,
+  .dma_reg_base                     = CYGHWR_HAL_STM32_DMA1,
+  .dma_tx_channel                   = 3,
+  .dma_rx_channel                   = 2,
+  .cs_gpio_num                      = sizeof (bus1_cs_gpio_list),
+  .cs_gpio_list                     = bus1_cs_gpio_list,
+  .spi_gpio_list                    = bus1_spi_gpio_list,
+  .dma_tx_intr                      = CYGNUM_HAL_INTERRUPT_DMA1_CH3,
+  .dma_rx_intr                      = CYGNUM_HAL_INTERRUPT_DMA1_CH2,
+  .dma_tx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_TXINTR_PRI,
+  .dma_rx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_RXINTR_PRI,
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE > 0)
+  .bbuf_size                        = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS1_BBUF_SIZE,
+  .bbuf_tx                          = bus1_tx_bbuf,
+  .bbuf_rx                          = bus1_rx_bbuf,
+#else
+  .bbuf_size                        = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus1 = {
+  .spi_bus.spi_transaction_begin    = stm32_transaction_begin,
+  .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+  .spi_bus.spi_transaction_tick     = stm32_transaction_tick,
+  .spi_bus.spi_transaction_end      = stm32_transaction_end,
+  .spi_bus.spi_get_config           = stm32_get_config,
+  .spi_bus.spi_set_config           = stm32_set_config,
+  .setup                            = &bus1_setup,
+  .cs_up                            = false
+};
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+static const cyg_uint8 bus2_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2_CS_GPIOS };
+static const cyg_uint8 bus2_spi_gpio_list[] = { 0x1D, 0x1E, 0x1F };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)
+static cyg_uint8 bus2_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE] 
+  __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus2_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE] 
+  __attribute__((aligned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus2_setup = {
+  .apb_freq                         = APB1_FREQ,
+  .spi_reg_base                     = CYGHWR_HAL_STM32_SPI2,
+  .dma_reg_base                     = CYGHWR_HAL_STM32_DMA1,
+  .dma_tx_channel                   = 5,
+  .dma_rx_channel                   = 4,
+  .cs_gpio_num                      = sizeof (bus2_cs_gpio_list),
+  .cs_gpio_list                     = bus2_cs_gpio_list,
+  .spi_gpio_list                    = bus2_spi_gpio_list,
+  .dma_tx_intr                      = CYGNUM_HAL_INTERRUPT_DMA1_CH5,
+  .dma_rx_intr                      = CYGNUM_HAL_INTERRUPT_DMA1_CH4,
+  .dma_tx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_TXINTR_PRI,
+  .dma_rx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_RXINTR_PRI,
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE > 0)
+  .bbuf_size                        = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS2_BBUF_SIZE,
+  .bbuf_tx                          = bus2_tx_bbuf,
+  .bbuf_rx                          = bus2_rx_bbuf,
+#else
+  .bbuf_size                        = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2 = {
+  .spi_bus.spi_transaction_begin    = stm32_transaction_begin,
+  .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+  .spi_bus.spi_transaction_tick     = stm32_transaction_tick,
+  .spi_bus.spi_transaction_end      = stm32_transaction_end,
+  .spi_bus.spi_get_config           = stm32_get_config,
+  .spi_bus.spi_set_config           = stm32_set_config,
+  .setup                            = &bus2_setup,
+  .cs_up                            = false
+};
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+static const cyg_uint8 bus3_cs_gpio_list[] = { CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3_CS_GPIOS };
+static const cyg_uint8 bus3_spi_gpio_list[] = { 0x13, 0x14, 0x15 };
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0)
+static cyg_uint8 bus3_tx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE] 
+  __attribute__((aligned (2), section (".sram"))) = { 0 };
+static cyg_uint8 bus3_rx_bbuf [CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE] 
+  __attribute__((alugned (2), section (".sram"))) = { 0 };
+#endif
+
+static const cyg_spi_cortexm_stm32_bus_setup_t bus3_setup = {
+  .apb_freq                         = APB1_FREQ,
+  .spi_reg_base                     = CYGHWR_HAL_STM32_SPI3,
+  .dma_reg_base                     = CYGHWR_HAL_STM32_DMA2,
+  .dma_tx_channel                   = 2,
+  .dma_rx_channel                   = 1
+  .cs_gpio_num                      = sizeof (bus3_cs_gpio_list),
+  .cs_gpio_list                     = bus3_cs_gpio_list,
+  .spi_gpio_list                    = bus3_spi_gpio_list,
+  .dma_tx_intr                      = CYGNUM_HAL_INTERRUPT_DMA2_CH2,
+  .dma_rx_intr                      = CYGNUM_HAL_INTERRUPT_DMA2_CH1,
+  .dma_tx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_TXINTR_PRI,
+  .dma_rx_intr_pri                  = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_RXINTR_PRI,
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE > 0)
+  .bbuf_size                        = CYGNUM_DEVS_SPI_CORTEXM_STM32_BUS3_BBUF_SIZE,
+  .bbuf_tx                          = bus3_tx_bbuf,
+  .bbuf_rx                          = bus3_rx_bbuf,
+#else
+  .bbuf_size                        = 0,
+#endif
+};
+
+cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus3 = {
+  .spi_bus.spi_transaction_begin    = stm32_transaction_begin,
+  .spi_bus.spi_transaction_transfer = stm32_transaction_transfer,
+  .spi_bus.spi_transaction_tick     = stm32_transaction_tick,
+  .spi_bus.spi_transaction_end      = stm32_transaction_end,
+  .spi_bus.spi_get_config           = stm32_get_config,
+  .spi_bus.spi_set_config           = stm32_set_config,
+  .setup                            = &bus3_setup,
+  .cs_up                            = false
+};
+#endif
+
+//-----------------------------------------------------------------------------
+// Useful GPIO macros for 'dynamic' pin setup.
+
+static const cyg_uint32 stm32_gpio_port_offsets[] = {
+  CYGHWR_HAL_STM32_GPIOA - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOB - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOC - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOD - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOE - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOF - CYGHWR_HAL_STM32_GPIOA,
+  CYGHWR_HAL_STM32_GPIOG - CYGHWR_HAL_STM32_GPIOA
+};
+
+#define STM32_GPIO_PINSPEC(__port, __bit, __mode, __cnf )          \
+  (stm32_gpio_port_offsets[__port] | (__bit<<16) |                 \
+  (CYGHWR_HAL_STM32_GPIO_MODE_##__mode) |                          \
+  (CYGHWR_HAL_STM32_GPIO_CNF_##__cnf))
+
+#if (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 2)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_2MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 10)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_10MHZ
+
+#elif (CYGNUM_DEVS_SPI_CORTEXM_STM32_PIN_TOGGLE_RATE == 50)
+#define CYGHWR_HAL_STM32_GPIO_MODE_OUT_SPI CYGHWR_HAL_STM32_GPIO_MODE_OUT_50MHZ
+
+#else
+#error "Invalid SPI bus toggle rate."
+#endif
+
+//-----------------------------------------------------------------------------
+// Configure a GPIO pin as a SPI chip select line.
+
+static inline void stm32_spi_gpio_cs_setup
+  (cyg_uint32 gpio_num)
+{
+  cyg_uint32 port, pin, pinspec;
+
+  // Check that the pin number is in range (16 pins per port).
+  pin = gpio_num & 0xF;
+  port = gpio_num >> 4;
+  CYG_ASSERT (port < 7, "STM32 SPI : Invalid GPIO number in chip select list."); 
+
+  // Generate the pin setup specification and configure it.
+  pinspec = STM32_GPIO_PINSPEC (port, pin, OUT_SPI, OUT_PUSHPULL);
+  CYGHWR_HAL_STM32_GPIO_SET (pinspec);
+  CYGHWR_HAL_STM32_GPIO_OUT (pinspec, 1);
+}
+
+//-----------------------------------------------------------------------------
+// Drive a GPIO pin as a SPI chip select line.
+
+static inline void stm32_spi_chip_select
+  (cyg_uint32 gpio_num, cyg_bool assert)
+{
+  cyg_uint32 port, pin, pinspec;
+
+  // Check that the pin number is in range (16 pins per port).
+  pin = gpio_num & 0xF;
+  port = gpio_num >> 4;
+  CYG_ASSERT (port < 7, "STM32 SPI : Invalid GPIO number in chip select list."); 
+
+  // Generate the pin setup specification and drive it.
+  pinspec = STM32_GPIO_PINSPEC (port, pin, OUT_SPI, OUT_PUSHPULL);
+  CYGHWR_HAL_STM32_GPIO_OUT (pinspec, assert ? 0 : 1);
+}
+
+//-----------------------------------------------------------------------------
+// Implement DMA ISRs.  These disable the DMA channel, mask the interrupt 
+// condition and schedule their respective DSRs.
+
+static cyg_uint32 stm32_tx_ISR 
+  (cyg_vector_t vector, cyg_addrword_t data)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+  cyg_uint32 chan = stm32_bus->setup->dma_tx_channel;
+  cyg_haladdress reg_addr;
+
+  // Disable the DMA channel.
+  cyg_drv_isr_lock ();
+  reg_addr = stm32_bus->setup->dma_reg_base + CYGHWR_HAL_STM32_DMA_CCR (chan);
+  HAL_WRITE_UINT32 (reg_addr, 0);
+
+  // Clear down the interrupts.
+  reg_addr = stm32_bus->setup->dma_reg_base + CYGHWR_HAL_STM32_DMA_IFCR;
+  HAL_WRITE_UINT32 (reg_addr, CYGHWR_HAL_STM32_DMA_IFCR_MASK (chan));
+
+  cyg_drv_interrupt_acknowledge (vector);
+  cyg_drv_interrupt_mask (vector);
+  cyg_drv_isr_unlock ();
+
+  return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+static cyg_uint32 stm32_rx_ISR 
+  (cyg_vector_t vector, cyg_addrword_t data)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+  cyg_uint32 chan = stm32_bus->setup->dma_rx_channel;
+  cyg_haladdress reg_addr;
+
+  // Disable the DMA channel.
+  cyg_drv_isr_lock ();
+  reg_addr = stm32_bus->setup->dma_reg_base + CYGHWR_HAL_STM32_DMA_CCR (chan);
+  HAL_WRITE_UINT32 (reg_addr, 0);
+
+  // Clear down the interrupts.
+  reg_addr = stm32_bus->setup->dma_reg_base + CYGHWR_HAL_STM32_DMA_IFCR;
+  HAL_WRITE_UINT32 (reg_addr, CYGHWR_HAL_STM32_DMA_IFCR_MASK (chan));
+
+  cyg_drv_interrupt_acknowledge (vector);
+  cyg_drv_interrupt_mask (vector);
+  cyg_drv_isr_unlock ();
+
+  return (CYG_ISR_CALL_DSR | CYG_ISR_HANDLED);
+}
+
+//-----------------------------------------------------------------------------
+// Implement DMA DSRs.  These clear down the interrupt conditions and assert 
+// their respective 'transaction complete' flags.
+
+static void stm32_tx_DSR 
+  (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+
+  cyg_drv_dsr_lock ();
+  stm32_bus->tx_dma_done = true;
+  cyg_drv_cond_signal (&stm32_bus->condvar);
+  cyg_drv_dsr_unlock ();
+}
+
+static void stm32_rx_DSR 
+  (cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) data;
+ 
+  cyg_drv_dsr_lock ();
+  stm32_bus->rx_dma_done = true;
+  cyg_drv_cond_signal (&stm32_bus->condvar);
+  cyg_drv_dsr_unlock ();
+}
+
+//-----------------------------------------------------------------------------
+// Set up a new SPI bus on initialisation.
+
+static void stm32_spi_bus_setup 
+  (cyg_spi_cortexm_stm32_bus_t* stm32_bus)
+{
+  int i;
+  cyg_haladdress reg_addr;
+  cyg_uint32 pin, pinspec, reg_data;
+
+  // Set up the GPIOs for use as chip select lines.
+  for (i = 0; i < stm32_bus->setup->cs_gpio_num; i ++) {
+    stm32_spi_gpio_cs_setup (stm32_bus->setup->cs_gpio_list[i]);
+  }
+
+  // Configure the SPI clock output pin.
+  pin = stm32_bus->setup->spi_gpio_list[0];
+  pinspec = STM32_GPIO_PINSPEC ((pin >> 4), (pin & 0xF), OUT_SPI, ALT_PUSHPULL);
+  CYGHWR_HAL_STM32_GPIO_SET (pinspec);
+
+  // Configure the SPI MISO input.
+  pin = stm32_bus->setup->spi_gpio_list[1];
+  pinspec = STM32_GPIO_PINSPEC ((pin >> 4), (pin & 0xF), IN, PULLUP);
+  CYGHWR_HAL_STM32_GPIO_SET (pinspec);
+
+  // Configure the SPI MOSI output.  
+  pin = stm32_bus->setup->spi_gpio_list[2];
+  pinspec = STM32_GPIO_PINSPEC ((pin >> 4), (pin & 0xF), OUT_SPI, ALT_PUSHPULL);
+  CYGHWR_HAL_STM32_GPIO_SET (pinspec);
+
+  // Set up SPI default configuration.
+  reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR2;
+  reg_data = CYGHWR_HAL_STM32_SPI_CR2_TXDMAEN | CYGHWR_HAL_STM32_SPI_CR2_RXDMAEN;
+  HAL_WRITE_UINT32 (reg_addr, reg_data);
+
+  // Ensure that the DMA clocks are enabled.
+  reg_addr = CYGHWR_HAL_STM32_RCC + CYGHWR_HAL_STM32_RCC_AHBENR;
+  HAL_READ_UINT32 (reg_addr, reg_data);
+  if (stm32_bus->setup->dma_reg_base == CYGHWR_HAL_STM32_DMA1)
+    reg_data |= CYGHWR_HAL_STM32_RCC_AHBENR_DMA1;
+  else
+    reg_data |= CYGHWR_HAL_STM32_RCC_AHBENR_DMA2;
+  HAL_WRITE_UINT32 (reg_addr, reg_data);
+
+  // Initialise the synchronisation primitivies.
+  cyg_drv_mutex_init (&stm32_bus->mutex);
+  cyg_drv_cond_init (&stm32_bus->condvar, &stm32_bus->mutex);
+
+  // Hook up the ISRs and DSRs.
+  cyg_drv_interrupt_create (stm32_bus->setup->dma_tx_intr, stm32_bus->setup->dma_tx_intr_pri, 
+    (cyg_addrword_t) stm32_bus, stm32_tx_ISR, stm32_tx_DSR, &stm32_bus->tx_intr_handle, 
+    &stm32_bus->tx_intr_data);
+  cyg_drv_interrupt_attach (stm32_bus->tx_intr_handle);
+
+  cyg_drv_interrupt_create (stm32_bus->setup->dma_rx_intr, stm32_bus->setup->dma_rx_intr_pri, 
+    (cyg_addrword_t) stm32_bus, stm32_rx_ISR, stm32_rx_DSR, &stm32_bus->rx_intr_handle, 
+    &stm32_bus->rx_intr_data);
+  cyg_drv_interrupt_attach (stm32_bus->rx_intr_handle);
+
+  // Call upper layer bus init.
+  CYG_SPI_BUS_COMMON_INIT(&stm32_bus->spi_bus);
+}
+
+//-----------------------------------------------------------------------------
+// Set up a DMA channel.
+
+static void dma_channel_setup
+  (cyg_spi_device* device, cyg_uint8* data_buf, cyg_uint32 count, cyg_bool is_tx, cyg_bool polled)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  cyg_uint32 chan, reg_data;
+  cyg_haladdress dma_reg_base, spi_reg_base, dma_addr, reg_addr;
+
+  // Extract address and channel information.
+  dma_reg_base = stm32_bus->setup->dma_reg_base;
+  spi_reg_base = stm32_bus->setup->spi_reg_base;
+  chan = is_tx ? stm32_bus->setup->dma_tx_channel : stm32_bus->setup->dma_rx_channel;
+
+  // Default options for the DMA channel.
+  reg_data = CYGHWR_HAL_STM32_DMA_CCR_EN;
+
+  // Do not enable interrupts in polled mode.
+  if (!polled)
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_TCIE | CYGHWR_HAL_STM32_DMA_CCR_TEIE;
+
+  // Set DMA channel direction and priority level.  The receive channel has higher
+  // priority so that the inbound buffer is always cleared first.
+  if (is_tx) 
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_DIR | CYGHWR_HAL_STM32_DMA_CCR_PLMEDIUM;
+  else 
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_PLHIGH;
+ 
+  // Set the correct transfer size.
+  if (stm32_device->bus_16bit)
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_PSIZE16 | CYGHWR_HAL_STM32_DMA_CCR_MSIZE16;
+  else 
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_PSIZE8 | CYGHWR_HAL_STM32_DMA_CCR_MSIZE8;
+
+  // Do not use memory address incrementing for dummy data.
+  if (data_buf != NULL) {
+    reg_data |= CYGHWR_HAL_STM32_DMA_CCR_MINC;
+    dma_addr = (cyg_haladdress) data_buf;
+  }
+  else 
+    dma_addr = (cyg_haladdress) (is_tx ? &dma_tx_null : &dma_rx_null);
+
+  // Program up the DMA memory address.
+  reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CMAR (chan);
+  HAL_WRITE_UINT32 (reg_addr, dma_addr);
+  
+  // Program up the peripheral memory address.
+  dma_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_DR;
+  reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CPAR (chan);
+  HAL_WRITE_UINT32 (reg_addr, dma_addr);
+
+  // Program up the data buffer size.
+  reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CNDTR (chan);
+  HAL_WRITE_UINT32 (reg_addr, count);
+
+  // Enable the DMA via the configuration register.
+  reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CCR (chan);
+  HAL_WRITE_UINT32 (reg_addr, reg_data);
+}
+
+//-----------------------------------------------------------------------------
+// Initiate a DMA transfer over the SPI interface.
+
+static void spi_transaction_dma 
+  (cyg_spi_device* device, cyg_bool tick_only, cyg_bool polled, cyg_uint32 count, 
+  const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  cyg_haladdress reg_addr;
+  cyg_uint32 chan, reg_data;
+
+  cyg_haladdress dma_reg_base = stm32_bus->setup->dma_reg_base;
+  cyg_haladdress spi_reg_base = stm32_bus->setup->spi_reg_base;
+
+  // Ensure the chip select is asserted, inserting inter-transaction guard 
+  // time if required.  Note that when ticking the device we do not touch the CS.
+  if (!stm32_bus->cs_up && !tick_only) {
+    CYGACC_CALL_IF_DELAY_US (stm32_device->tr_bt_udly);
+    stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], true);        
+    stm32_bus->cs_up = true;
+    CYGACC_CALL_IF_DELAY_US (stm32_device->cs_up_udly);
+  }
+
+  // Set up the DMA channels.
+  dma_channel_setup (device, (cyg_uint8*) tx_data, count, true, polled);
+  dma_channel_setup (device, rx_data, count, false, polled);
+
+  // Run the DMA (polling for completion).
+  if (polled) {
+    cyg_bool transfer_done = false;
+
+    // Enable the SPI controller.
+    reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+    HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val | CYGHWR_HAL_STM32_SPI_CR1_SPE);
+
+    // Spin waiting on both DMA status flags.  Trap bus errors and assert in
+    // debug builds or return garbage in production builds.
+    reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_ISR;
+    do {
+      HAL_READ_UINT32 (reg_addr, reg_data);
+      if ((reg_data & CYGHWR_HAL_STM32_DMA_ISR_TEIF (stm32_bus->setup->dma_tx_channel)) ||
+          (reg_data & CYGHWR_HAL_STM32_DMA_ISR_TEIF (stm32_bus->setup->dma_rx_channel))) {
+        CYG_ASSERT (false, "STM32 SPI : DMA bus fault - enable bounce buffers.");
+        transfer_done = true;
+      }
+      if ((reg_data & CYGHWR_HAL_STM32_DMA_ISR_TCIF (stm32_bus->setup->dma_tx_channel)) &&
+          (reg_data & CYGHWR_HAL_STM32_DMA_ISR_TCIF (stm32_bus->setup->dma_rx_channel))) {
+        transfer_done = true;
+      }
+    } while (!transfer_done);
+
+    // Disable the DMA channels on completion and clear the status flags.
+    chan = stm32_bus->setup->dma_tx_channel;
+    reg_data = CYGHWR_HAL_STM32_DMA_IFCR_MASK (chan);
+    reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CCR (chan);
+    HAL_WRITE_UINT32 (reg_addr, 0);
+
+    chan = stm32_bus->setup->dma_rx_channel;
+    reg_data |= CYGHWR_HAL_STM32_DMA_IFCR_MASK (chan);
+    reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_CCR (chan);
+    HAL_WRITE_UINT32 (reg_addr, 0);
+
+    reg_addr = dma_reg_base + CYGHWR_HAL_STM32_DMA_IFCR;
+    HAL_WRITE_UINT32 (reg_addr, reg_data);
+  }
+
+  // Run the DMA (interrupt driven).
+  else {
+    cyg_drv_mutex_lock (&stm32_bus->mutex);
+    cyg_drv_dsr_lock ();
+    stm32_bus->tx_dma_done = false;
+    stm32_bus->rx_dma_done = false;
+
+    cyg_drv_interrupt_unmask (stm32_bus->setup->dma_tx_intr);
+    cyg_drv_interrupt_unmask (stm32_bus->setup->dma_rx_intr);
+
+    // Enable the SPI controller.
+    reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+    HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val | CYGHWR_HAL_STM32_SPI_CR1_SPE);
+
+    // Sit back and wait for the ISR/DSRs to signal completion.
+    do {
+      cyg_drv_cond_wait (&stm32_bus->condvar);
+    } while (!(stm32_bus->tx_dma_done && stm32_bus->rx_dma_done));
+
+    cyg_drv_dsr_unlock ();
+    cyg_drv_mutex_unlock (&stm32_bus->mutex);
+  }
+
+  // Disable the SPI controller.
+  reg_addr = spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+  HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+        
+  // Deassert the chip select.
+  if (drop_cs && !tick_only) {
+    CYGACC_CALL_IF_DELAY_US (stm32_device->cs_dw_udly);
+    stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], false);        
+    stm32_bus->cs_up = false;
+  }     
+}
+
+//-----------------------------------------------------------------------------
+// Initialise SPI interfaces on startup.
+
+void cyg_spi_cortexm_stm32_init 
+  (void)
+{
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS1
+  stm32_spi_bus_setup (&cyg_spi_stm32_bus1);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS2
+  stm32_spi_bus_setup (&cyg_spi_stm32_bus2);
+#endif
+
+#ifdef CYGHWR_DEVS_SPI_CORTEXM_STM32_BUS3
+  stm32_spi_bus_setup (&cyg_spi_stm32_bus3);
+#endif
+}
+
+//-----------------------------------------------------------------------------
+// Start a SPI transaction.
+
+static void stm32_transaction_begin    
+  (cyg_spi_device* device)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  cyg_haladdress reg_addr;
+  cyg_uint32 reg_data, divided_clk, br;
+
+  // On the first transaction, generate the values to be programmed into the
+  // SPI configuration registers for this device and cache them.  This avoids
+  // having to recalculate the prescaler for every transaction.
+  if (!stm32_device->spi_cr1_val) {
+    reg_data = CYGHWR_HAL_STM32_SPI_CR1_MSTR | 
+      CYGHWR_HAL_STM32_SPI_CR1_SSI | CYGHWR_HAL_STM32_SPI_CR1_SSM;
+    if (stm32_device->cl_pol)
+      reg_data |= CYGHWR_HAL_STM32_SPI_CR1_CPOL;
+    if (stm32_device->cl_pha)
+      reg_data |= CYGHWR_HAL_STM32_SPI_CR1_CPHA;
+    if (stm32_device->bus_16bit)
+      reg_data |= CYGHWR_HAL_STM32_SPI_CR1_DFF;
+
+    // Calculate the maximum viable bus speed.
+    divided_clk = stm32_bus->setup->apb_freq / 2;
+    for (br = 0; (br < 7) && (divided_clk > stm32_device->cl_brate); br++)
+      divided_clk >>= 1;
+    CYG_ASSERT (divided_clk <= stm32_device->cl_brate, 
+      "STM32 SPI : Cannot run bus slowly enough for peripheral.");
+    reg_data |= CYGHWR_HAL_STM32_SPI_CR1_BR (br);
+
+    // Cache the configuration register settings.
+    stm32_device->spi_cr1_val = reg_data;
+  }
+
+  // Set up the SPI controller.
+  reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+  HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+}
+
+//-----------------------------------------------------------------------------
+// Run a transaction transfer.
+
+static void stm32_transaction_transfer 
+  (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count, 
+  const cyg_uint8* tx_data, cyg_uint8* rx_data, cyg_bool drop_cs)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  // Check for unsupported transactions.
+  CYG_ASSERT (count > 0, "STM32 SPI : Null transfer requested.");
+
+  // We check that the buffers are half-word aligned and that count is a 
+  // multiple of two in order to carry out the 16-bit transfer.
+  if (stm32_device->bus_16bit) {
+    CYG_ASSERT (!(count & 1) && !((cyg_uint32) tx_data & 1) && !((cyg_uint32) rx_data & 1),   
+      "STM32 SPI : Misaligned data in 16-bit transfer.");
+  }
+
+  // Perform transfer via the bounce buffers.  
+  if (stm32_bus->setup->bbuf_size != 0) {
+    cyg_uint8* tx_local = NULL;
+    cyg_uint8* rx_local = NULL;
+
+    // If the requested transfer is too large for the bounce buffer we assert 
+    // in debug builds and truncate in production builds.
+    if (count > stm32_bus->setup->bbuf_size) {
+      CYG_ASSERT (false, "STM32 SPI : Transfer exceeds bounce buffer size.");
+      count = stm32_bus->setup->bbuf_size;
+    }
+    if (tx_data != NULL) {
+      tx_local = stm32_bus->setup->bbuf_tx;        
+      memcpy (tx_local, tx_data, count);
+    }
+    if (rx_data != NULL) {
+      rx_local = stm32_bus->setup->bbuf_rx;        
+    }
+    spi_transaction_dma (device, false, polled, count, tx_local, rx_local, drop_cs);
+    if (rx_data != NULL) {
+      memcpy (rx_data, rx_local, count);
+    }
+  }
+
+  // Perform conventional transfer.
+  else {
+    spi_transaction_dma (device, false, polled, count, tx_data, rx_data, drop_cs);
+  }
+}
+
+//-----------------------------------------------------------------------------
+// Carry out a bus tick operation - this just pushes the required number of
+// zeros onto the bus, leaving the chip select in its current state.
+
+static void stm32_transaction_tick 
+  (cyg_spi_device* device, cyg_bool polled, cyg_uint32 count)
+{
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  // Check for unsupported transactions.
+  CYG_ASSERT (count > 0, "STM32 SPI : Null transfer requested.");
+
+  // We check that count is a multiple of two in order to carry out the 16-bit transfer.
+  if (stm32_device->bus_16bit) {
+    CYG_ASSERT (!(count & 1),   
+      "STM32 SPI : Misaligned data in 16-bit transfer.");
+  }
+
+  // Perform null transfer.
+  spi_transaction_dma (device, true, polled, count, NULL, NULL, false);
+}
+
+//-----------------------------------------------------------------------------
+// Terminate a SPI transaction, disabling the SPI controller.
+
+static void stm32_transaction_end 
+  (cyg_spi_device* device)
+{
+  cyg_spi_cortexm_stm32_bus_t* stm32_bus = (cyg_spi_cortexm_stm32_bus_t*) device->spi_bus;
+  cyg_spi_cortexm_stm32_device_t* stm32_device = (cyg_spi_cortexm_stm32_device_t*) device;
+
+  cyg_haladdress reg_addr;
+
+  // Ensure that the chip select is deasserted.
+  if (stm32_bus->cs_up) {
+    CYGACC_CALL_IF_DELAY_US (stm32_device->cs_dw_udly);
+    stm32_spi_chip_select (stm32_bus->setup->cs_gpio_list[stm32_device->dev_num], false);   
+    stm32_bus->cs_up = false;
+  }     
+
+  // Ensure the SPI controller is disabled.
+  reg_addr = stm32_bus->setup->spi_reg_base + CYGHWR_HAL_STM32_SPI_CR1;
+  HAL_WRITE_UINT32 (reg_addr, stm32_device->spi_cr1_val);
+}
+
+//-----------------------------------------------------------------------------
+// Note that no dynamic configuration options are currently defined.
+
+static int stm32_get_config 
+  (cyg_spi_device* dev, cyg_uint32 key, void* buf, cyg_uint32* len)
+{
+    return -1;
+}
+
+static int stm32_set_config 
+  (cyg_spi_device* dev, cyg_uint32 key, const void* buf, cyg_uint32* len)
+{
+    return -1;
+}
+
+//=============================================================================
Index: src/spi_stm32_init.cxx
===================================================================
RCS file: src/spi_stm32_init.cxx
diff -N src/spi_stm32_init.cxx
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/spi_stm32_init.cxx	4 Feb 2009 11:41:18 -0000
@@ -0,0 +1,63 @@
+//=============================================================================
+//
+//      spi_stm32_init.c
+//
+//      SPI driver startup for STM32
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-11-27
+// Purpose:     STM32 SPI driver startup
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+
+externC void cyg_spi_cortexm_stm32_init (void);
+
+class cyg_spi_cortexm_stm32_init_class {
+public:
+  cyg_spi_cortexm_stm32_init_class (void) {
+    cyg_spi_cortexm_stm32_init ();
+  }
+};
+
+static cyg_spi_cortexm_stm32_init_class spi_cortexm_stm32_init CYGBLD_ATTRIB_INIT_PRI(CYG_INIT_IO);
+
+//=============================================================================
Index: tests/loopback.c
===================================================================
RCS file: tests/loopback.c
diff -N tests/loopback.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/loopback.c	4 Feb 2009 11:41:18 -0000
@@ -0,0 +1,185 @@
+//=============================================================================
+//
+//      loopback.c
+//
+//      Standalone SPI loopback test.
+//
+//=============================================================================
+// ####ECOSGPLCOPYRIGHTBEGIN####                                            
+// -------------------------------------------                              
+// This file is part of eCos, the Embedded Configurable Operating System.   
+// Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+//
+// eCos is free software; you can redistribute it and/or modify it under    
+// the terms of the GNU General Public License as published by the Free     
+// Software Foundation; either version 2 or (at your option) any later      
+// version.                                                                 
+//
+// eCos is distributed in the hope that it will be useful, but WITHOUT      
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
+// for more details.                                                        
+//
+// You should have received a copy of the GNU General Public License        
+// along with eCos; if not, write to the Free Software Foundation, Inc.,    
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
+//
+// As a special exception, if other files instantiate templates or use      
+// macros or inline functions from this file, or you compile this file      
+// and link it with other works to produce a work based on this file,       
+// this file does not by itself cause the resulting work to be covered by   
+// the GNU General Public License. However the source code for this file    
+// must still be made available in accordance with section (3) of the GNU   
+// General Public License v2.                                               
+//
+// This exception does not invalidate any other reasons why a work based    
+// on this file might be covered by the GNU General Public License.         
+// -------------------------------------------                              
+// ####ECOSGPLCOPYRIGHTEND####                                              
+//=============================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):   Chris Holgate
+// Date:        2008-11-27
+// Purpose:     STM32 SPI loopback test
+// Description: Standalone SPI loopback test.
+// Usage:       Compile as a standalone application.
+//
+//####DESCRIPTIONEND####
+//
+//=============================================================================
+
+//=============================================================================
+// This is a quick loopback test for the STM32 SPI driver.  It only checks
+// the data transfer functionality - chip select handling will require
+// testing with external devices.  In order to run the test, the MOSI and
+// MISO pins for the test port need to be shorted together to provide an
+// external loopback.  Don't do this on a bus which has external devices
+// attached unless you first make sure that none of them are connected to
+// the chip select used by the test harness.
+// The default port and chip select used for this test are SPI bus 1,
+// chip select 0.  These can be changed by editing the loopback_device
+// data structure directly.
+// Note that this is intended to be run as a standalone test and not as part
+// of the standard board tests since it requires a hardware modification.
+//=============================================================================
+
+#include <cyg/infra/cyg_type.h>
+#include <cyg/infra/testcase.h>         // Test macros
+#include <cyg/infra/cyg_ass.h>          // Assertion macros
+#include <cyg/infra/diag.h>             // Diagnostic output
+
+#include <cyg/hal/hal_arch.h>           // CYGNUM_HAL_STACK_SIZE_TYPICAL
+#include <cyg/kernel/kapi.h>
+
+#include <cyg/io/spi.h>                 // Common SPI API
+#include <cyg/io/spi_stm32.h>           // STM32 data structures
+
+#include <string.h>
+
+//---------------------------------------------------------------------------
+// Thread data structures.
+
+cyg_uint8 stack [CYGNUM_HAL_STACK_SIZE_TYPICAL];
+cyg_thread thread_data;
+cyg_handle_t thread_handle;
+
+externC cyg_spi_cortexm_stm32_bus_t cyg_spi_stm32_bus2;
+
+//---------------------------------------------------------------------------
+// SPI loopback device driver data structures.
+
+cyg_spi_cortexm_stm32_device_t loopback_device = {
+    .spi_device.spi_bus = &cyg_spi_stm32_bus1.spi_bus,
+    .dev_num = 0 ,                      // Only 1 device. 
+    .cl_pol = 1,
+    .cl_pha = 1,
+    .cl_brate = 8000000,                // Nominal 8Mhz.
+    .cs_up_udly = 1,
+    .cs_dw_udly = 1,
+    .tr_bt_udly = 1,
+    .bus_16bit = false,
+};
+
+//---------------------------------------------------------------------------
+
+const char tx_data[] = "Testing, testing, 12, 123.";
+const char tx_data1[] = "Testing extended API...";
+const char tx_data2[] = "Testing extended API for a second transaction.";
+
+char rx_data [sizeof(tx_data)];
+char rx_data1 [sizeof(tx_data1)];
+char rx_data2 [sizeof(tx_data2)];
+
+//---------------------------------------------------------------------------
+// Run single loopback transaction using simple transfer API call.
+
+void run_test_1 (cyg_bool polled)
+{
+    diag_printf ("Test 1 : Simple transfer test (polled = %d).\n", polled ? 1 : 0);
+    cyg_spi_transfer (&loopback_device.spi_device, polled, sizeof (tx_data), 
+        (const cyg_uint8*) &tx_data[0], (cyg_uint8*) &rx_data[0]);
+
+    diag_printf ("    Tx data : %s\n", tx_data);
+    diag_printf ("    Rx data : %s\n", rx_data);
+    CYG_ASSERT (memcmp (tx_data, rx_data, sizeof (tx_data)) == 0,
+        "Simple transfer loopback failed - mismatched data.\n");
+}
+
+//---------------------------------------------------------------------------
+// Run two loopback transactions using extended transfer API.
+
+void run_test_2 (cyg_bool polled)
+{
+    diag_printf ("Test 2 : Extended API test (polled = %d).\n", polled ? 1 : 0);
+    cyg_spi_transaction_begin (&loopback_device.spi_device);
+    cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data1), 
+        (const cyg_uint8*) &tx_data1[0], (cyg_uint8*) &rx_data1[0], false);
+    cyg_spi_transaction_transfer (&loopback_device.spi_device, polled, sizeof (tx_data2), 
+        (const cyg_uint8*) &tx_data2[0], (cyg_uint8*) &rx_data2[0], false);
+    cyg_spi_transaction_end (&loopback_device.spi_device);
+
+    diag_printf ("    Tx data 1 : %s\n", tx_data1);
+    diag_printf ("    Rx data 1 : %s\n", rx_data1);
+    diag_printf ("    Tx data 2 : %s\n", tx_data2);
+    diag_printf ("    Rx data 2 : %s\n", rx_data2);
+    CYG_ASSERT (memcmp (tx_data1, rx_data1, sizeof (tx_data1)) == 0,
+        "Simple transfer loopback failed - mismatched data (transfer 1).\n");
+    CYG_ASSERT (memcmp (tx_data2, rx_data2, sizeof (tx_data2)) == 0,
+        "Simple transfer loopback failed - mismatched data (transfer 2).\n");
+}
+
+//---------------------------------------------------------------------------
+// Run all PL022 SPI interface loopback tests.
+
+void run_tests (void)
+{
+    diag_printf ("Running STM32 SPI driver loopback tests.\n");
+    run_test_1 (true); 
+    run_test_1 (false); 
+    run_test_2 (true); 
+    run_test_2 (false); 
+    CYG_TEST_PASS_FINISH ("Loopback tests ran OK");
+}
+
+//---------------------------------------------------------------------------
+// User startup - tests are run in their own thread.
+
+void cyg_user_start(void)
+{
+    CYG_TEST_INIT();
+    cyg_thread_create(
+        10,                                   // Arbitrary priority
+        (cyg_thread_entry_t*) run_tests,      // Thread entry point
+        0,                                    // 
+        "test_thread",                        // Thread name
+        &stack[0],                            // Stack
+        CYGNUM_HAL_STACK_SIZE_TYPICAL,        // Stack size
+        &thread_handle,                       // Thread handle
+        &thread_data                          // Thread data structure
+    );
+    cyg_thread_resume(thread_handle);
+    cyg_scheduler_start();
+}
+
+//=============================================================================
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/ChangeLog,v
retrieving revision 1.203
diff -u -5 -r1.203 ChangeLog
--- ChangeLog	29 Jan 2009 17:47:51 -0000	1.203
+++ ChangeLog	4 Feb 2009 11:46:32 -0000
@@ -1,5 +1,9 @@
+2009-02-04  Nick Garnett  <nickg@ecoscentric.com>
+
+	* ecos.db: Add STM32 SPI driver.
+
 2009-01-08  John Dallaway  <john@dallaway.org.uk>
 
 	* ecosadmin.tcl, pkgconf/fixhtml.tcl: Specify script interpreter via
 	/usr/bin/env.
 
Index: ecos.db
===================================================================
RCS file: /cvs/ecos/ecos/packages/ecos.db,v
retrieving revision 1.188
diff -u -5 -r1.188 ecos.db
--- ecos.db	29 Jan 2009 17:47:51 -0000	1.188
+++ ecos.db	4 Feb 2009 11:46:33 -0000
@@ -6886,10 +6886,19 @@
         description "
         This package contains hardware support for the internal FLASH memory
         on the ST STM32 devices."
 }
 
+package CYGPKG_DEVS_SPI_CORTEXM_STM32 {
+    alias         { "STM32 SPI driver" }
+    hardware
+    directory     devs/spi/cortexm/stm32
+    script        spi_stm32.cdl
+    description   "This package provides a driver for the SPI interfaces found on 
+                  the ST STM32 microcontroller family."
+}
+
 package CYGPKG_DEVS_WALLCLOCK_STM32 {
         alias           { "ST STM32 RTC wallclock support" wallclock_stm32 }
         directory       devs/wallclock/cortexm/stm32
         script          wallclock_stm32.cdl
         hardware
@@ -6905,10 +6914,12 @@
                    CYGPKG_HAL_CORTEXM_STM32_STM3210E_EVAL
                    CYGPKG_DEVS_FLASH_AMD_AM29XXXXX_V2
                    CYGPKG_DEVS_FLASH_STM32
                    CYGPKG_IO_SERIAL_CORTEXM_STM32
                    CYGPKG_DEVS_WALLCLOCK_STM32
+                   CYGPKG_IO_SPI
+                   CYGPKG_DEVS_SPI_CORTEXM_STM32
                  }
         description "The stm3210e_eval target provides the packages needed
         to run eCos on the STM3210E EVAL board."
 }
 
Index: arch/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/mips/arch/current/ChangeLog,v
retrieving revision 1.75
diff -u -5 -r1.75 ChangeLog
--- arch/current/ChangeLog	29 Jan 2009 17:49:24 -0000	1.75
+++ arch/current/ChangeLog	4 Feb 2009 11:30:36 -0000
@@ -1,5 +1,10 @@
+2009-02-04  Nick Garnett  <nickg@ecoscentric.com>
+
+	* include/hal_arch.h: Ifdef bit index macros to allow them to be
+	overridden by variant or platform HAL.
+
 2004-05-27  Gary Thomas  <gary@mlbassoc.com>
 
 	* src/redboot_linux_exec.c (do_exec): Be sensitive to value in
 	"entry_address" as this can indicate if the image to be executed
 	is valid (the "load" functions set it to "NO_MEMORY" when invalid)
Index: arch/current/include/hal_arch.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/mips/arch/current/include/hal_arch.h,v
retrieving revision 1.19
diff -u -5 -r1.19 hal_arch.h
--- arch/current/include/hal_arch.h	29 Jan 2009 17:49:24 -0000	1.19
+++ arch/current/include/hal_arch.h	4 Feb 2009 11:30:36 -0000
@@ -123,17 +123,21 @@
 externC void cyg_hal_deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
 
 //--------------------------------------------------------------------------
 // Bit manipulation macros
 
+#ifndef CYGHWR_HAL_BIT_INDEXES_DEFINED
+
 externC cyg_uint32 hal_lsbit_index(cyg_uint32 mask);
 externC cyg_uint32 hal_msbit_index(cyg_uint32 mask);
 
 #define HAL_LSBIT_INDEX(index, mask) index = hal_lsbit_index(mask);
 
 #define HAL_MSBIT_INDEX(index, mask) index = hal_msbit_index(mask);
 
+#endif
+
 //--------------------------------------------------------------------------
 // Context Initialization
 
 
 // Optional FPU context initialization
Index: mips32/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/mips/mips32/current/ChangeLog,v
retrieving revision 1.13
diff -u -5 -r1.13 ChangeLog
--- mips32/current/ChangeLog	3 Feb 2009 18:02:44 -0000	1.13
+++ mips32/current/ChangeLog	4 Feb 2009 11:30:36 -0000
@@ -1,5 +1,10 @@
+2009-02-04  Nick Garnett  <nickg@ecoscentric.com>
+
+	* include/var_arch.h (HAL_LSBIT_INDEX, HAL_MSBIT_INDEX): Provide
+	overrides for these macros that use the clz instruction.
+
 2009-01-31  Bart Veer <bartv@ecoscentric.com>
 
 	* cdl/hal_mips_mips32.cdl: update compiler flags for gcc 4.x
 
 2005-06-10  Jonathan Larmour  <jifl@eCosCentric.com>
Index: mips32/current/include/var_arch.h
===================================================================
RCS file: /cvs/ecos/ecos/packages/hal/mips/mips32/current/include/var_arch.h,v
retrieving revision 1.6
diff -u -5 -r1.6 var_arch.h
--- mips32/current/include/var_arch.h	29 Jan 2009 17:49:26 -0000	1.6
+++ mips32/current/include/var_arch.h	4 Feb 2009 11:30:36 -0000
@@ -83,10 +83,47 @@
         HAL_GET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )
 #define HAL_SET_CP0_REGISTER_64( _regval_, _cp0_regno_, _cp0_regsel_ ) \
         HAL_SET_CP0_REGISTER_32( _regval_, _cp0_regno_, _cp0_regsel_ )
 
 //--------------------------------------------------------------------------
+// Bit manipulation macros
+
+#ifndef CYGHWR_HAL_BIT_INDEXES_DEFINED
+
+//--------------------------------------------------------
+// Determine the index of the ls bit of the supplied mask.
+
+#define HAL_LSBIT_INDEX(_index_, _mask_)                                \
+    CYG_MACRO_START                                                     \
+    unsigned _reg_;                                                     \
+                                                                        \
+    _reg_ = (_mask_);                                                   \
+    _reg_ &= -_reg_;                                                    \
+    asm volatile ("clz    %0, %1\n"                                     \
+               : "=r" (_reg_)                                           \
+               : "r" (_reg_) );                                         \
+    (_index_) = 31 - _reg_;                                             \
+    CYG_MACRO_END
+
+//--------------------------------------------------------
+// Determine the index of the ms bit of the supplied mask.
+
+#define HAL_MSBIT_INDEX(_index_, _mask_)                                \
+    CYG_MACRO_START                                                     \
+    unsigned _reg_;                                                     \
+                                                                        \
+    _reg_ = (_mask_);                                                   \
+    asm volatile ("clz    %0, %1\n"                                     \
+             : "=r" (_reg_)                                             \
+             : "r" (_reg_) );                                           \
+    (_index_) = 31 - _reg_;                                             \
+    CYG_MACRO_END
+
+#define CYGHWR_HAL_BIT_INDEXES_DEFINED
+#endif
+
+//--------------------------------------------------------------------------
 
 #ifdef CYGARC_HAL_COMMON_EXPORT_CPU_MACROS
 /* System Control Coprocessor (CP0) exception processing registers */
 /* These supplement the definitions in mips-regs.h */
 #define C0_INDEX        $0              /* Index into TLB Array - 4Kc core */


-- 
Nick Garnett                                      eCos Kernel Architect
eCosCentric Limited    http://www.eCosCentric.com      The eCos experts
Barnwell House, Barnwell Drive, Cambridge, UK.     Tel: +44 1223 245571
Registered in England and Wales:                        Reg No: 4422071

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]