change to the mc1322x IRQ handling
since mc1322x lacks a VIC this is a kind of SW VIC with low latency and compatibility to the VIC API in mind.
This commit is contained in:
parent
a1cd29d68e
commit
1e39e7e486
@ -136,8 +136,13 @@ arm_irq_handler:
|
|||||||
MRS R1, CPSR
|
MRS R1, CPSR
|
||||||
MSR SPSR, R1
|
MSR SPSR, R1
|
||||||
|
|
||||||
|
#if CPU != mc1322x
|
||||||
/* jump into vic interrupt */
|
/* jump into vic interrupt */
|
||||||
mov r0, #0xffffff00 /* lpc23xx */
|
mov r0, #0xffffff00 /* lpc23xx */
|
||||||
|
#else
|
||||||
|
/* mc1322x seems to lack a VIC, distinction of IRQ has to be done in SW */
|
||||||
|
ldr r0, =isr /* mc1322x */
|
||||||
|
#endif
|
||||||
|
|
||||||
ldr r0, [r0]
|
ldr r0, [r0]
|
||||||
add lr,pc,#4
|
add lr,pc,#4
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* cpu.c - MC1322X architecture common support functions
|
* cpu.c - MC1322X architecture common support functions
|
||||||
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
|
||||||
|
* Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||||
*
|
*
|
||||||
* This source code is licensed under the GNU Lesser General Public License,
|
* This source code is licensed under the GNU Lesser General Public License,
|
||||||
* Version 2. See the file LICENSE for more details.
|
* Version 2. See the file LICENSE for more details.
|
||||||
@ -10,7 +11,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mc1322x.h"
|
#include "mc1322x.h"
|
||||||
|
#include "cpu.h"
|
||||||
#include "lpm.h"
|
#include "lpm.h"
|
||||||
|
#include "arm_cpu.h"
|
||||||
|
|
||||||
__attribute__((naked,noreturn)) void arm_reset(void)
|
__attribute__((naked,noreturn)) void arm_reset(void)
|
||||||
{
|
{
|
||||||
@ -20,37 +23,25 @@ __attribute__((naked,noreturn)) void arm_reset(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum lpm_mode lpm_set(enum lpm_mode target) {
|
enum lpm_mode lpm_set(enum lpm_mode target) {
|
||||||
|
(void) target;
|
||||||
return LPM_ON;
|
return LPM_ON;
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
** Function name: cpu_install_irq
|
** Function name: install_irq
|
||||||
**
|
**
|
||||||
** Descriptions: Install interrupt handler
|
** Descriptions: Install interrupt handler.
|
||||||
** parameters: Interrupt number, interrupt handler address,
|
** A wrapper to register_isr to be consistant to lpc2387
|
||||||
** interrupt priority
|
** implementation.
|
||||||
** Returned value: true or false, return false if IntNum is out of range
|
** parameters: Interrupt number, interrupt handler address,
|
||||||
|
** interrupt priority
|
||||||
|
** Returned value: true or false, return false if IntNum is out of range
|
||||||
**
|
**
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
#define VIC_BASE_ADDR 0xFFFFF000
|
|
||||||
|
|
||||||
bool cpu_install_irq(int IntNumber, void *HandlerAddr, int Priority)
|
bool install_irq(int int_number, void *handler_addr, int priority)
|
||||||
{
|
{
|
||||||
int *vect_addr;
|
(void) priority;
|
||||||
int *vect_cntl;
|
register_isr(int_number, handler_addr);
|
||||||
|
return (true);
|
||||||
VICIntEnClr = 1 << IntNumber; /* Disable Interrupt */
|
|
||||||
|
|
||||||
if (IntNumber >= VIC_SIZE) {
|
|
||||||
return (false);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* find first un-assigned VIC address for the handler */
|
|
||||||
vect_addr = (int *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber * 4);
|
|
||||||
vect_cntl = (int *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber * 4);
|
|
||||||
*vect_addr = (int)HandlerAddr; /* set interrupt vector */
|
|
||||||
*vect_cntl = Priority;
|
|
||||||
VICIntEnable = 1 << IntNumber; /* Enable Interrupt */
|
|
||||||
return(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,12 +11,31 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "mc1322x.h"
|
#include "mc1322x.h"
|
||||||
|
#include "cpu.h"
|
||||||
#include "hwtimer_arch.h"
|
#include "hwtimer_arch.h"
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
|
|
||||||
/* High level interrupt handler */
|
/* High level interrupt handler */
|
||||||
static void (*int_handler)(int);
|
static void (*int_handler)(int);
|
||||||
|
|
||||||
|
#define TMRx_ANY_INTERRUPT 0xa800
|
||||||
|
|
||||||
|
void tmr_isr(void) {
|
||||||
|
/* detemine which timer caused the interrupt */
|
||||||
|
if (TMR0->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||||
|
int_handler(TMR0_BASE);
|
||||||
|
}
|
||||||
|
else if (TMR1->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||||
|
int_handler(TMR1_BASE);
|
||||||
|
}
|
||||||
|
else if (TMR2->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||||
|
int_handler(TMR2_BASE);
|
||||||
|
}
|
||||||
|
else if (TMR3->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||||
|
int_handler(TMR3_BASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
||||||
/* Reset the timer */
|
/* Reset the timer */
|
||||||
TMRx->ENBL = 0;
|
TMRx->ENBL = 0;
|
||||||
@ -45,8 +64,6 @@ void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
|||||||
TMRx->CTRLbits.OUTPUT_MODE = 0x00; /* OFLAG is asserted while counter is active */
|
TMRx->CTRLbits.OUTPUT_MODE = 0x00; /* OFLAG is asserted while counter is active */
|
||||||
|
|
||||||
TMRx->ENBL = 0xf; /* enable all the timers --- why not? */
|
TMRx->ENBL = 0xf; /* enable all the timers --- why not? */
|
||||||
|
|
||||||
/* TODO: install ISR */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
|
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
|
||||||
@ -59,6 +76,8 @@ void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
|
|||||||
timer_x_init(TMR1);
|
timer_x_init(TMR1);
|
||||||
timer_x_init(TMR2);
|
timer_x_init(TMR2);
|
||||||
timer_x_init(TMR3);
|
timer_x_init(TMR3);
|
||||||
|
|
||||||
|
install_irq(INT_NUM_TMR, &tmr_isr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|||||||
@ -15,10 +15,18 @@
|
|||||||
#ifndef CPU_H
|
#ifndef CPU_H
|
||||||
#define CPU_H
|
#define CPU_H
|
||||||
|
|
||||||
#include <stdint.h>
|
/**
|
||||||
|
* @defgroup mc1322x Freescale mc1322x
|
||||||
|
* @ingroup cpu
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include "arm_cpu.h"
|
#include "arm_cpu.h"
|
||||||
#include "mc1322x.h"
|
#include "mc1322x.h"
|
||||||
|
|
||||||
extern uintptr_t __stack_start; ///< end of user stack memory space
|
extern uintptr_t __stack_start; ///< end of user stack memory space
|
||||||
|
bool install_irq(int int_number, void *handler_addr, int priority);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
#endif /* CPU_H */
|
#endif /* CPU_H */
|
||||||
|
|||||||
@ -415,12 +415,11 @@ enum interrupt_nums {
|
|||||||
x; \
|
x; \
|
||||||
__int_enable(); } while(0)
|
__int_enable(); } while(0)
|
||||||
|
|
||||||
|
extern void register_isr(uint8_t interrupt, void (*isr)(void));
|
||||||
|
|
||||||
extern void tmr0_isr(void) __attribute__((weak));
|
extern void tmr_isr(void) __attribute__((weak));
|
||||||
extern void tmr1_isr(void) __attribute__((weak));
|
|
||||||
extern void tmr2_isr(void) __attribute__((weak));
|
|
||||||
extern void tmr3_isr(void) __attribute__((weak));
|
|
||||||
|
|
||||||
|
extern void crm_isr(void) __attribute__((weak));
|
||||||
extern void rtc_isr(void) __attribute__((weak));
|
extern void rtc_isr(void) __attribute__((weak));
|
||||||
extern void kbi4_isr(void) __attribute__((weak));
|
extern void kbi4_isr(void) __attribute__((weak));
|
||||||
extern void kbi5_isr(void) __attribute__((weak));
|
extern void kbi5_isr(void) __attribute__((weak));
|
||||||
@ -438,4 +437,12 @@ extern void asm_isr(void) __attribute__((weak));
|
|||||||
|
|
||||||
extern void i2c_isr(void) __attribute__((weak));
|
extern void i2c_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
extern void spif_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
extern void ssi_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
extern void adc_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
|
extern void spi_isr(void) __attribute__((weak));
|
||||||
|
|
||||||
#endif /* MC1322X_H */
|
#endif /* MC1322X_H */
|
||||||
|
|||||||
50
cpu/mc1322x/isr.c
Normal file
50
cpu/mc1322x/isr.c
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* isr.c - mc1322x specific isr
|
||||||
|
* Copyright (C) 2013 Thomas Eichinger <thomas.eichinger@fu-berlin.de>
|
||||||
|
*
|
||||||
|
* This source code is licensed under the GNU Lesser General Public License,
|
||||||
|
* Version 2. See the file LICENSE for more details.
|
||||||
|
*
|
||||||
|
* This file is part of RIOT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "mc1322x.h"
|
||||||
|
|
||||||
|
#define MAX_IRQ_INDEX 10
|
||||||
|
#define MAX_IRQ_NUM 11
|
||||||
|
|
||||||
|
static void (*isr_funcs[11])(void) = {
|
||||||
|
asm_isr,
|
||||||
|
uart1_isr,
|
||||||
|
uart2_isr,
|
||||||
|
crm_isr,
|
||||||
|
i2c_isr,
|
||||||
|
tmr_isr,
|
||||||
|
spif_isr,
|
||||||
|
maca_isr,
|
||||||
|
ssi_isr,
|
||||||
|
adc_isr,
|
||||||
|
spi_isr
|
||||||
|
};
|
||||||
|
|
||||||
|
void register_isr(uint8_t interrupt, void (*isr)(void)) {
|
||||||
|
if (interrupt <= MAX_IRQ_INDEX) {
|
||||||
|
isr_funcs[interrupt] = isr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr(void)
|
||||||
|
{
|
||||||
|
/* set irq_num to an invalid value */
|
||||||
|
uint8_t irq_num = MAX_IRQ_NUM;
|
||||||
|
|
||||||
|
/* pending interrupt? */
|
||||||
|
while (ITC->NIPEND) {
|
||||||
|
/* get interrupt source, range 0-10 */
|
||||||
|
irq_num = ITC->NIVECTOR;
|
||||||
|
/* call corresponding ISR */
|
||||||
|
if (isr_funcs[irq_num] != 0) {
|
||||||
|
(isr_funcs[irq_num])();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -176,7 +176,7 @@ SWI_Addr: .word ctx_switch
|
|||||||
PAbt_Addr: .word PABT_Routine
|
PAbt_Addr: .word PABT_Routine
|
||||||
DAbt_Addr: .word DABT_Routine
|
DAbt_Addr: .word DABT_Routine
|
||||||
_not_used: .word not_used
|
_not_used: .word not_used
|
||||||
IRQ_Addr: .word irq
|
IRQ_Addr: .word arm_irq_handler
|
||||||
_fiq: .word fiq
|
_fiq: .word fiq
|
||||||
.balignl 16, 0xdeadbeef
|
.balignl 16, 0xdeadbeef
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user