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
|
||||
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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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
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
|
||||
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
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user