mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
fixed interrupt handling for hwtimer
This commit is contained in:
parent
1e39e7e486
commit
1fcb47f9ed
@ -139,13 +139,13 @@ arm_irq_handler:
|
||||
#if CPU != mc1322x
|
||||
/* jump into vic interrupt */
|
||||
mov r0, #0xffffff00 /* lpc23xx */
|
||||
ldr r0, [r0]
|
||||
add lr,pc,#4
|
||||
#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
|
||||
mov pc, r0
|
||||
|
||||
/* restore spsr from stack */
|
||||
|
@ -15,6 +15,8 @@
|
||||
#include "hwtimer_arch.h"
|
||||
#include "irq.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* High level interrupt handler */
|
||||
static void (*int_handler)(int);
|
||||
|
||||
@ -22,23 +24,31 @@ static void (*int_handler)(int);
|
||||
|
||||
void tmr_isr(void) {
|
||||
/* detemine which timer caused the interrupt */
|
||||
if (TMR0->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||
int_handler(TMR0_BASE);
|
||||
if (TMR0->SCTRLbits.TCF && TMR0->SCTRLbits.TCFIE) {
|
||||
TMR0->SCTRLbits.TCF = 0;
|
||||
TMR0->ENBL &= ~(1<<0);
|
||||
int_handler(0);
|
||||
}
|
||||
else if (TMR1->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||
int_handler(TMR1_BASE);
|
||||
else if (TMR1->SCTRLbits.TCF && TMR1->SCTRLbits.TCFIE) {
|
||||
TMR1->SCTRLbits.TCF = 0;
|
||||
TMR0->ENBL &= ~(1<<1);
|
||||
int_handler(1);
|
||||
}
|
||||
else if (TMR2->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||
int_handler(TMR2_BASE);
|
||||
else if (TMR2->SCTRLbits.TCF && TMR2->SCTRLbits.TCFIE) {
|
||||
TMR2->SCTRLbits.TCF = 0;
|
||||
TMR0->ENBL &= ~(1<<2);
|
||||
int_handler(2);
|
||||
}
|
||||
else if (TMR3->SCTRL & TMRx_ANY_INTERRUPT) {
|
||||
int_handler(TMR3_BASE);
|
||||
else if (TMR3->SCTRLbits.TCF && TMR3->SCTRLbits.TCFIE) {
|
||||
TMR3->SCTRLbits.TCF = 0;
|
||||
TMR0->ENBL &= ~(1<<3);
|
||||
int_handler(3);
|
||||
}
|
||||
}
|
||||
|
||||
void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
||||
/* Reset the timer */
|
||||
TMRx->ENBL = 0;
|
||||
|
||||
/* Clear status */
|
||||
TMRx->SCTRL = 0;
|
||||
/* disable interrupt */
|
||||
@ -51,7 +61,7 @@ void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
||||
TMRx->CMPLD1 = 0;
|
||||
|
||||
/* set counter to zero */
|
||||
TMRx->CNTR = 0;
|
||||
TMRx->CNTR = TMRx->LOAD;
|
||||
|
||||
/* set timer control bits */
|
||||
TMRx->CTRLbits.COUNT_MODE = 1; /* use rising edge of primary source */
|
||||
@ -62,8 +72,6 @@ void timer_x_init(volatile struct TMR_struct* const TMRx) {
|
||||
TMRx->CTRLbits.DIR = 0x00; /* count up */
|
||||
TMRx->CTRLbits.CO_INIT = 0x00; /* other counters cannot force a reinitialization of this counter*/
|
||||
TMRx->CTRLbits.OUTPUT_MODE = 0x00; /* OFLAG is asserted while counter is active */
|
||||
|
||||
TMRx->ENBL = 0xf; /* enable all the timers --- why not? */
|
||||
}
|
||||
|
||||
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
|
||||
@ -72,12 +80,15 @@ void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
|
||||
/* TODO: do scaling voodoo */
|
||||
(void) fcpu;
|
||||
|
||||
/* disable all timers */
|
||||
TMR0->ENBL = 0;
|
||||
timer_x_init(TMR0);
|
||||
timer_x_init(TMR1);
|
||||
timer_x_init(TMR2);
|
||||
timer_x_init(TMR3);
|
||||
|
||||
install_irq(INT_NUM_TMR, &tmr_isr, 0);
|
||||
register_isr(INT_NUM_TMR, &tmr_isr);
|
||||
hwtimer_arch_enable_interrupt();
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -93,40 +104,44 @@ void hwtimer_arch_disable_interrupt(void) {
|
||||
/* this disables timer interrupts in general by using the ITC.
|
||||
* Timer specific interrupt control is given by the TMRx structs. */
|
||||
//disable_irq(INT_NUM_TMR);
|
||||
ITC->INTENABLEbits.TMR = 1;
|
||||
ITC->INTENABLEbits.TMR = 0;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void hwtimer_arch_set(unsigned long offset, short timer) {
|
||||
/* get corresponding struct for the given ::timer parameter */
|
||||
struct TMR_struct* tmr = (void *) TMR_BASE + (timer + TMR_OFFSET);
|
||||
struct TMR_struct* tmr = (void *) TMR_BASE + (timer * TMR_OFFSET);
|
||||
|
||||
/* disable IRQs and save the status register */
|
||||
unsigned long cpsr = disableIRQ();
|
||||
|
||||
uint32_t cpsr = disableIRQ();
|
||||
|
||||
TMR0->ENBL &= ~(1<<timer); /* disable timer */
|
||||
tmr->COMP1 = tmr->CNTR + offset; /* load the current value + offset into the compare register */
|
||||
tmr->CSCTRLbits.TCF1 = 0; /* reset compare flag */
|
||||
tmr->CSCTRLbits.TCF1EN = 1; /* enable intterupts when TCF1 is set \ */
|
||||
TMR0->ENBL |= (1<<timer); /* enable timer */
|
||||
tmr->SCTRLbits.TCFIE = 1; /* enable interrupts when TCF is one - do we need both?*/
|
||||
|
||||
/* restor status register */
|
||||
/* restore status register */
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void hwtimer_arch_set_absolute(unsigned long value, short timer) {
|
||||
/* get corresponding struct for the given ::timer parameter */
|
||||
struct TMR_struct* tmr = (void *) TMR_BASE + (timer + TMR_OFFSET);
|
||||
struct TMR_struct* tmr = (void *) TMR_BASE + (timer * TMR_OFFSET);
|
||||
|
||||
/* disable IRQs and save the status register */
|
||||
unsigned long cpsr = disableIRQ();
|
||||
uint32_t cpsr = disableIRQ();
|
||||
|
||||
TMR0->ENBL &= ~(1<<timer); /* disable timer */
|
||||
tmr->COMP1 = value; /* load the value into the compare register */
|
||||
tmr->CSCTRLbits.TCF1 = 0; /* reset compare flag */
|
||||
tmr->CSCTRLbits.TCF1EN = 1; /* enable interrupts when TCF1 is set \ */
|
||||
TMR0->ENBL |= (1<<timer); /* enable timer */
|
||||
tmr->SCTRLbits.TCFIE = 1; /* enable interrupts when TCF is one - do we need both?*/
|
||||
|
||||
/* restor status register */
|
||||
/* restore status register */
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "mc1322x.h"
|
||||
|
||||
#define MAX_IRQ_INDEX 10
|
||||
#define MAX_IRQ_NUM 11
|
||||
|
||||
static void (*isr_funcs[11])(void) = {
|
||||
asm_isr,
|
||||
@ -35,16 +34,12 @@ void register_isr(uint8_t interrupt, void (*isr)(void)) {
|
||||
|
||||
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])();
|
||||
if (isr_funcs[ITC->NIVECTOR]) {
|
||||
(isr_funcs[ITC->NIVECTOR])();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user