From a818dbe7293b0f7235f866c43e60e54b2da9fb86 Mon Sep 17 00:00:00 2001 From: chrysn Date: Fri, 19 Oct 2012 00:04:07 +0200 Subject: [PATCH] use generalized libopencm3 functions in cmsis --- include/libopencmsis/core_cm3.h | 69 +++++++-------------- include/libopencmsis/dispatch/irqhandlers.h | 17 +++++ scripts/irq2nvic_h | 20 +++++- 3 files changed, 57 insertions(+), 49 deletions(-) create mode 100644 include/libopencmsis/dispatch/irqhandlers.h diff --git a/include/libopencmsis/core_cm3.h b/include/libopencmsis/core_cm3.h index 5ad13279..292a4564 100644 --- a/include/libopencmsis/core_cm3.h +++ b/include/libopencmsis/core_cm3.h @@ -4,14 +4,15 @@ * particularly unimplemented features are FIXME'd extra * */ +/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */ + #ifndef OPENCMSIS_CORECM3_H #define OPENCMSIS_CORECM3_H -/* needed in various places where we rather should include libopencm3 functionality */ -#define MMIO32(addr) (*(volatile uint32_t *)(addr)) - -/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */ -#include +#include +#include +#include +#include /* needed by system_efm32.h:196, guessing */ #define __INLINE inline @@ -27,11 +28,12 @@ /* -> style access for what is defined in libopencm3/stm32/f1/scb.h / * cm3/memorymap.h, as it's needed by efm32lib/inc/efm32_emu.h */ -/* from stm32/f1/scb.h */ -#define SCB_SCR_SLEEPDEEP_Msk (1 << 2) +/* from cm3/scb.h */ +#define SCB_SCR_SLEEPDEEP_Msk SCB_SCR_SLEEPDEEP + /* structure as in, for example, * DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from - * libopencm3/stm32/f1/scb.h. FIXME incomplete. */ + * libopencm3/cm3/scb.h. FIXME incomplete. */ typedef struct { __IO uint32_t CPUID; @@ -44,10 +46,6 @@ typedef struct __IO uint32_t SHCSR; } SCB_TypeDef; #define SCB ((SCB_TypeDef *) SCB_BASE) -/* from libopencm3/cm3/memorymap.h */ -#define PPBI_BASE 0xE0000000 -#define SCS_BASE (PPBI_BASE + 0xE000) -#define SCB_BASE (SCS_BASE + 0x0D00) /* needed by efm32_emu.h, guessing and taking the implementation used in * lightswitch-interrupt.c */ @@ -72,24 +70,17 @@ typedef struct /* stubs for efm32_dma */ -/* also used by the clock example. code taken from stm32's nvic.[hc], FIXME until - * the generic cm3 functionality is moved out from stm32 and can be used here - * easily (nvic_clear_pending_irq, nvic_enable_irq, nvic_disable_irq). */ -#define NVIC_BASE (SCS_BASE + 0x0100) -#define NVIC_ISER(iser_id) MMIO32(NVIC_BASE + 0x00 + (iser_id * 4)) -#define NVIC_ICER(icer_id) MMIO32(NVIC_BASE + 0x80 + (icer_id * 4)) -#define NVIC_ICPR(icpr_id) MMIO32(NVIC_BASE + 0x180 + (icpr_id * 4)) static inline void NVIC_ClearPendingIRQ(uint8_t irqn) { - NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); + nvic_clear_pending_irq(irqn); } static inline void NVIC_EnableIRQ(uint8_t irqn) { - NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); + nvic_enable_irq(irqn); } static inline void NVIC_DisableIRQ(uint8_t irqn) { - NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); + nvic_disable_irq(irqn); } /* stubs for efm32_int. FIXME: how do they do that? nvic documentation in the @@ -139,7 +130,6 @@ typedef struct * * modified for CMSIS style array as the powertest example needs it. * */ -#define SYS_TICK_BASE (SCS_BASE + 0x0010) /* from d0002_efm32_cortex-m3_reference_manual.pdf section 4.4 */ typedef struct @@ -151,21 +141,16 @@ typedef struct } SysTick_TypeDef; #define SysTick ((SysTick_TypeDef *) SYS_TICK_BASE) -#define STK_CTRL_TICKINT (1 << 1) -#define STK_CTRL_ENABLE (1 << 0) - -#define STK_CTRL_CLKSOURCE_LSB 2 -#define STK_CTRL_CLKSOURCE_AHB 1 static inline uint32_t SysTick_Config(uint32_t n_ticks) { + /* constant from systick_set_reload -- as this returns something that's + * not void, this is the only possible error condition */ if (n_ticks & ~0x00FFFFFF) return 1; - SysTick->LOAD = n_ticks; - SysTick->CTRL |= (STK_CTRL_CLKSOURCE_AHB << STK_CTRL_CLKSOURCE_LSB); - - SysTick->CTRL |= STK_CTRL_TICKINT; - - SysTick->CTRL |= STK_CTRL_ENABLE; + systick_set_reload(n_ticks); + systick_set_clocksource(true); + systick_interrupt_enable(); + systick_counter_enable(); return 0; } @@ -182,20 +167,10 @@ typedef struct /* blink.h expects the isr for systicks to be named SysTick_Handler. with this, * its Systick_Handler function gets renamed to the weak symbol exported by * vector.c */ + #define SysTick_Handler sys_tick_handler +/* FIXME: this needs to be done for all of the 14 hard vectors */ -/* likewise, clock.c defines GPIO_ODD_IRQHandler and GPIO_EVEN_IRQHandler */ -#define GPIO_ODD_IRQHandler gpio_odd_isr -#define GPIO_EVEN_IRQHandler gpio_even_isr -#define RTC_IRQHandler rtc_isr - -/* for inttemp (i should really get a list and convert them all) */ - -#define ADC0_IRQHandler adc0_isr - -/* for the lightsense example */ - -#define LESENSE_IRQHandler lesense_isr -#define PCNT0_IRQHandler pcnt0_isr +#include #endif diff --git a/include/libopencmsis/dispatch/irqhandlers.h b/include/libopencmsis/dispatch/irqhandlers.h new file mode 100644 index 00000000..1f6b02af --- /dev/null +++ b/include/libopencmsis/dispatch/irqhandlers.h @@ -0,0 +1,17 @@ +#if defined(STM32F1) +# include +#elif defined(STM32F2) +# include +#elif defined(STM32F4) +# include + +#elif defined(TINYGECKO) +# include + +#elif defined(LPC43XX) +# include + +#else +# warning"no chipset defined; user interrupts are not redirected" + +#endif diff --git a/scripts/irq2nvic_h b/scripts/irq2nvic_h index f84c88e4..6e45fa21 100755 --- a/scripts/irq2nvic_h +++ b/scripts/irq2nvic_h @@ -99,7 +99,19 @@ template_vector_nvic_c = '''\ {vectortableinitialization} ''' -def convert(infile, outfile_nvic, outfile_vectornvic): +template_cmsis_h = '''\ +/* This file is part of the libopencm3 project. + * + * It was generated by the irq2nvic_h script. + * + * These definitions bend every interrupt handler that is defined CMSIS style + * to the weak symbol exported by libopenmc3. + */ + +{cmsisbends} +''' + +def convert(infile, outfile_nvic, outfile_vectornvic, outfile_cmsis): data = yaml.load(infile) irq2name = list(enumerate(data['irqs']) if isinstance(data['irqs'], list) else data['irqs'].items()) @@ -114,9 +126,11 @@ def convert(infile, outfile_nvic, outfile_vectornvic): data['isrprototypes'] = "\n".join('void WEAK %s_isr(void);'%name.lower() for name in irqnames) data['isrpragmas'] = "\n".join('#pragma weak %s_isr = blocking_handler'%name.lower() for name in irqnames) data['vectortableinitialization'] = ', \\\n '.join('[NVIC_%s_IRQ] = %s_isr'%(name.upper(), name.lower()) for name in irqnames) + data['cmsisbends'] = "\n".join("#define %s_IRQHandler %s_isr"%(name.upper(), name.lower()) for name in irqnames) outfile_nvic.write(template_nvic_h.format(**data)) outfile_vectornvic.write(template_vector_nvic_c.format(**data)) + outfile_cmsis.write(template_cmsis_h.format(**data)) def makeparentdir(filename): try: @@ -131,11 +145,13 @@ def main(): raise ValueError("Arguent must match ./include/libopencm3/**/irq.yaml") nvic_h = infile.replace('irq.yaml', 'nvic.h') vector_nvic_c = infile.replace('./include/libopencm3/', './lib/').replace('irq.yaml', 'vector_nvic.c') + cmsis = infile.replace('irq.yaml', 'irqhandlers.h').replace('/libopencm3/', '/libopencmsis/') makeparentdir(nvic_h) makeparentdir(vector_nvic_c) + makeparentdir(cmsis) - convert(open(infile), open(nvic_h, 'w'), open(vector_nvic_c, 'w')) + convert(open(infile), open(nvic_h, 'w'), open(vector_nvic_c, 'w'), open(cmsis, 'w')) if __name__ == "__main__": main()