This is the mail archive of the
ecos-patches@sourceware.org
mailing list for the eCos project.
Various patches
- From: Nick Garnett <nickg at ecoscentric dot com>
- To: ecos-patches at ecos dot sourceware dot org
- Date: 04 Feb 2009 11:54:53 +0000
- Subject: 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