use generalized libopencm3 functions in cmsis
This commit is contained in:
parent
3a2e1c45aa
commit
a818dbe729
@ -4,14 +4,15 @@
|
|||||||
* particularly unimplemented features are FIXME'd extra
|
* 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
|
#ifndef OPENCMSIS_CORECM3_H
|
||||||
#define OPENCMSIS_CORECM3_H
|
#define OPENCMSIS_CORECM3_H
|
||||||
|
|
||||||
/* needed in various places where we rather should include libopencm3 functionality */
|
#include <libopencm3/cm3/common.h>
|
||||||
#define MMIO32(addr) (*(volatile uint32_t *)(addr))
|
#include <libopencm3/cm3/memorymap.h>
|
||||||
|
#include <libopencm3/cm3/systick.h>
|
||||||
/* the original core_cm3.h is nonfree by arm; this provides libopencm3 variant of the symbols efm32lib needs of CMSIS. */
|
#include <libopencm3/cm3/scb.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
/* needed by system_efm32.h:196, guessing */
|
/* needed by system_efm32.h:196, guessing */
|
||||||
#define __INLINE inline
|
#define __INLINE inline
|
||||||
@ -27,11 +28,12 @@
|
|||||||
/* -> style access for what is defined in libopencm3/stm32/f1/scb.h /
|
/* -> 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 */
|
* cm3/memorymap.h, as it's needed by efm32lib/inc/efm32_emu.h */
|
||||||
|
|
||||||
/* from stm32/f1/scb.h */
|
/* from cm3/scb.h */
|
||||||
#define SCB_SCR_SLEEPDEEP_Msk (1 << 2)
|
#define SCB_SCR_SLEEPDEEP_Msk SCB_SCR_SLEEPDEEP
|
||||||
|
|
||||||
/* structure as in, for example,
|
/* structure as in, for example,
|
||||||
* DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from
|
* DeviceSupport/EnergyMicro/EFM32/efm32tg840f32.h, data from
|
||||||
* libopencm3/stm32/f1/scb.h. FIXME incomplete. */
|
* libopencm3/cm3/scb.h. FIXME incomplete. */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
__IO uint32_t CPUID;
|
__IO uint32_t CPUID;
|
||||||
@ -44,10 +46,6 @@ typedef struct
|
|||||||
__IO uint32_t SHCSR;
|
__IO uint32_t SHCSR;
|
||||||
} SCB_TypeDef;
|
} SCB_TypeDef;
|
||||||
#define SCB ((SCB_TypeDef *) SCB_BASE)
|
#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
|
/* needed by efm32_emu.h, guessing and taking the implementation used in
|
||||||
* lightswitch-interrupt.c */
|
* lightswitch-interrupt.c */
|
||||||
@ -72,24 +70,17 @@ typedef struct
|
|||||||
|
|
||||||
/* stubs for efm32_dma */
|
/* 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)
|
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)
|
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)
|
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
|
/* 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.
|
* 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 */
|
/* from d0002_efm32_cortex-m3_reference_manual.pdf section 4.4 */
|
||||||
typedef struct
|
typedef struct
|
||||||
@ -151,21 +141,16 @@ typedef struct
|
|||||||
} SysTick_TypeDef;
|
} SysTick_TypeDef;
|
||||||
#define SysTick ((SysTick_TypeDef *) SYS_TICK_BASE)
|
#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)
|
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;
|
if (n_ticks & ~0x00FFFFFF) return 1;
|
||||||
SysTick->LOAD = n_ticks;
|
|
||||||
|
|
||||||
SysTick->CTRL |= (STK_CTRL_CLKSOURCE_AHB << STK_CTRL_CLKSOURCE_LSB);
|
systick_set_reload(n_ticks);
|
||||||
|
systick_set_clocksource(true);
|
||||||
SysTick->CTRL |= STK_CTRL_TICKINT;
|
systick_interrupt_enable();
|
||||||
|
systick_counter_enable();
|
||||||
SysTick->CTRL |= STK_CTRL_ENABLE;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -182,20 +167,10 @@ typedef struct
|
|||||||
/* blink.h expects the isr for systicks to be named SysTick_Handler. with this,
|
/* 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
|
* its Systick_Handler function gets renamed to the weak symbol exported by
|
||||||
* vector.c */
|
* vector.c */
|
||||||
|
|
||||||
#define SysTick_Handler sys_tick_handler
|
#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 */
|
#include <libopencmsis/dispatch/irqhandlers.h>
|
||||||
#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
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
17
include/libopencmsis/dispatch/irqhandlers.h
Normal file
17
include/libopencmsis/dispatch/irqhandlers.h
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#if defined(STM32F1)
|
||||||
|
# include <libopencmsis/stm32/f1/irqhandlers.h>
|
||||||
|
#elif defined(STM32F2)
|
||||||
|
# include <libopencmsis/stm32/f2/irqhandlers.h>
|
||||||
|
#elif defined(STM32F4)
|
||||||
|
# include <libopencmsis/stm32/f4/irqhandlers.h>
|
||||||
|
|
||||||
|
#elif defined(TINYGECKO)
|
||||||
|
# include <libopencmsis/efm32/tinygecko/irqhandlers.h>
|
||||||
|
|
||||||
|
#elif defined(LPC43XX)
|
||||||
|
# include <libopencmsis/lpc43xx/irqhandlers.h>
|
||||||
|
|
||||||
|
#else
|
||||||
|
# warning"no chipset defined; user interrupts are not redirected"
|
||||||
|
|
||||||
|
#endif
|
@ -99,7 +99,19 @@ template_vector_nvic_c = '''\
|
|||||||
{vectortableinitialization}
|
{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)
|
data = yaml.load(infile)
|
||||||
|
|
||||||
irq2name = list(enumerate(data['irqs']) if isinstance(data['irqs'], list) else data['irqs'].items())
|
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['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['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['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_nvic.write(template_nvic_h.format(**data))
|
||||||
outfile_vectornvic.write(template_vector_nvic_c.format(**data))
|
outfile_vectornvic.write(template_vector_nvic_c.format(**data))
|
||||||
|
outfile_cmsis.write(template_cmsis_h.format(**data))
|
||||||
|
|
||||||
def makeparentdir(filename):
|
def makeparentdir(filename):
|
||||||
try:
|
try:
|
||||||
@ -131,11 +145,13 @@ def main():
|
|||||||
raise ValueError("Arguent must match ./include/libopencm3/**/irq.yaml")
|
raise ValueError("Arguent must match ./include/libopencm3/**/irq.yaml")
|
||||||
nvic_h = infile.replace('irq.yaml', 'nvic.h')
|
nvic_h = infile.replace('irq.yaml', 'nvic.h')
|
||||||
vector_nvic_c = infile.replace('./include/libopencm3/', './lib/').replace('irq.yaml', 'vector_nvic.c')
|
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(nvic_h)
|
||||||
makeparentdir(vector_nvic_c)
|
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user