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:
Thomas Eichinger 2013-10-24 13:53:09 +02:00
parent a1cd29d68e
commit 1e39e7e486
7 changed files with 113 additions and 33 deletions

View File

@ -136,8 +136,13 @@ arm_irq_handler:
MRS R1, CPSR
MSR SPSR, R1
#if CPU != mc1322x
/* jump into vic interrupt */
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]
add lr,pc,#4

View File

@ -1,6 +1,7 @@
/*
* cpu.c - MC1322X architecture common support functions
* 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,
* Version 2. See the file LICENSE for more details.
@ -10,7 +11,9 @@
*/
#include "mc1322x.h"
#include "cpu.h"
#include "lpm.h"
#include "arm_cpu.h"
__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) {
(void) target;
return LPM_ON;
}
/******************************************************************************
** Function name: cpu_install_irq
** Function name: install_irq
**
** Descriptions: Install interrupt handler
** parameters: Interrupt number, interrupt handler address,
** interrupt priority
** Returned value: true or false, return false if IntNum is out of range
** Descriptions: Install interrupt handler.
** A wrapper to register_isr to be consistant to lpc2387
** implementation.
** 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;
int *vect_cntl;
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);
}
(void) priority;
register_isr(int_number, handler_addr);
return (true);
}

View File

@ -11,12 +11,31 @@
#include <stdint.h>
#include "mc1322x.h"
#include "cpu.h"
#include "hwtimer_arch.h"
#include "irq.h"
/* High level interrupt handler */
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) {
/* Reset the timer */
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->ENBL = 0xf; /* enable all the timers --- why not? */
/* TODO: install ISR */
}
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(TMR2);
timer_x_init(TMR3);
install_irq(INT_NUM_TMR, &tmr_isr, 0);
}
/*---------------------------------------------------------------------------*/

View File

@ -15,10 +15,18 @@
#ifndef CPU_H
#define CPU_H
#include <stdint.h>
/**
* @defgroup mc1322x Freescale mc1322x
* @ingroup cpu
* @{
*/
#include <stdbool.h>
#include "arm_cpu.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 */

View File

@ -415,12 +415,11 @@ enum interrupt_nums {
x; \
__int_enable(); } while(0)
extern void register_isr(uint8_t interrupt, void (*isr)(void));
extern void tmr0_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 tmr_isr(void) __attribute__((weak));
extern void crm_isr(void) __attribute__((weak));
extern void rtc_isr(void) __attribute__((weak));
extern void kbi4_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 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 */

50
cpu/mc1322x/isr.c Normal file
View 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])();
}
}
}

View File

@ -176,7 +176,7 @@ SWI_Addr: .word ctx_switch
PAbt_Addr: .word PABT_Routine
DAbt_Addr: .word DABT_Routine
_not_used: .word not_used
IRQ_Addr: .word irq
IRQ_Addr: .word arm_irq_handler
_fiq: .word fiq
.balignl 16, 0xdeadbeef