Timer interrupts work; examples/ostest passes
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1849 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
9f5d0084f7
commit
a66e4faf0b
@ -1,7 +1,7 @@
|
||||
/************************************************************************************
|
||||
* arch/arm/include/str71x/irq.h
|
||||
*
|
||||
* Copyright (C) 2008 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -79,7 +79,8 @@ static void _up_dumponexit(FAR _TCB *tcb, FAR void *arg)
|
||||
int i;
|
||||
#endif
|
||||
|
||||
sdbg(" TCB=%p name=%s\n", tcb, tcb->argv[0]);
|
||||
sdbg(" TCB=%p name=%s pid=%d\n", tcb, tcb->argv[0], tcb->pid);
|
||||
sdbg(" priority=%d state=%d\n", tcb->sched_priority, tcb->task_state);
|
||||
|
||||
#if CONFIG_NFILE_DESCRIPTORS > 0
|
||||
if (tcb->filelist)
|
||||
|
@ -87,15 +87,19 @@
|
||||
void up_decodeirq(uint32 *regs)
|
||||
{
|
||||
#ifdef CONFIG_SUPPRESS_INTERRUPTS
|
||||
up_ledon(LED_INIRQ);
|
||||
lib_lowprintf("Unexpected IRQ\n");
|
||||
current_regs = regs;
|
||||
PANIC(OSERR_ERREXCEPTION);
|
||||
#else
|
||||
unsigned int irq;
|
||||
|
||||
/* Read the IRQ number from the IVR register (Could probably get the same
|
||||
* info from CIC register without the setup.
|
||||
*/
|
||||
|
||||
unsigned int irq = getreg32(STR71X_EIC_IVR);
|
||||
up_ledon(LED_INIRQ);
|
||||
irq = getreg32(STR71X_EIC_IVR);
|
||||
|
||||
/* Verify that the resulting IRQ number is valid */
|
||||
|
||||
@ -105,8 +109,13 @@ void up_decodeirq(uint32 *regs)
|
||||
* current_regs is also used to manage interrupt level context switches.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(current_regs == NULL);
|
||||
current_regs = regs;
|
||||
|
||||
/* Mask and acknowledge the interrupt */
|
||||
|
||||
up_maskack_irq(irq);
|
||||
|
||||
/* Deliver the IRQ */
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
@ -114,6 +123,10 @@ void up_decodeirq(uint32 *regs)
|
||||
/* Indicate that we are no long in an interrupt handler */
|
||||
|
||||
current_regs = NULL;
|
||||
|
||||
/* Unmask the last interrupt (global interrupts are still disabled) */
|
||||
|
||||
up_enable_irq(irq);
|
||||
}
|
||||
#if CONFIG_DEBUG
|
||||
else
|
||||
@ -121,5 +134,6 @@ void up_decodeirq(uint32 *regs)
|
||||
PANIC(OSERR_ERREXCEPTION); /* Normally never happens */
|
||||
}
|
||||
#endif
|
||||
up_ledoff(LED_INIRQ);
|
||||
#endif
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/****************************************************************************
|
||||
* arch/arm/src/str71x/str71x_timerisr.c
|
||||
*
|
||||
* Copyright (C) 2007, 2008 Gregory Nutt. All rights reserved.
|
||||
* Copyright (C) 2007-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <spudmonkey@racsa.co.cr>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -125,10 +125,25 @@
|
||||
|
||||
int up_timerisr(int irq, uint32 *regs)
|
||||
{
|
||||
/* Process timer interrupt */
|
||||
uint16 ocar;
|
||||
|
||||
sched_process_timer();
|
||||
return 0;
|
||||
/* Clear all the output compare A interrupt status bit */
|
||||
|
||||
putreg16(~STR71X_TIMERSR_OCFA, STR71X_TIMER0_SR);
|
||||
|
||||
/* Set up for the next compare match. We could either reset
|
||||
* the OCAR and CNTR to restart, or simply update the OCAR as
|
||||
* follows to that the match occurs later without resetting:
|
||||
*/
|
||||
|
||||
ocar = getreg16(STR71X_TIMER0_OCAR);
|
||||
ocar += OCAR_VALUE;
|
||||
putreg16(ocar, STR71X_TIMER0_OCAR);
|
||||
|
||||
/* Process timer interrupt */
|
||||
|
||||
sched_process_timer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -142,32 +157,29 @@ int up_timerisr(int irq, uint32 *regs)
|
||||
|
||||
void up_timerinit(void)
|
||||
{
|
||||
uint16 cr1;
|
||||
uint16 cr2;
|
||||
irqstate_t flags;
|
||||
|
||||
/* Make sure that timer0 is disabled */
|
||||
|
||||
flags = irqsave();
|
||||
putreg16(0x0000, STR71X_TIMER0_CR1);
|
||||
putreg16(0x0000, STR71X_TIMER0_CR2);
|
||||
putreg16(0x0000, STR71X_TIMER0_SR);
|
||||
|
||||
/* Start The TIM0 Counter */
|
||||
|
||||
cr1 = STR71X_TIMERCR1_EN;
|
||||
putreg16(cr1, STR71X_TIMER0_CR1);
|
||||
|
||||
/* Configure TIM0 so that it is clocked by the internal APB2 frequency (PCLK2)
|
||||
* divided by the above prescaler value (1) -- versus an external Clock.
|
||||
* -- Nothing to do because STR71X_TIMERCR1_ECKEN is already cleared.
|
||||
*
|
||||
*
|
||||
* Select a divisor to reduce the frequency of clocking. This must be
|
||||
* done so that the entire timer interval can fit in the 16-bit OCAR register.
|
||||
* (see the discussion above).
|
||||
*/
|
||||
|
||||
cr2 = PCLK2_DIVIDER;
|
||||
putreg16(cr2, STR71X_TIMER0_CR2);
|
||||
putreg16(STR71X_TIMERCR2_OCAIE | (PCLK2_DIVIDER - 1), STR71X_TIMER0_CR2);
|
||||
|
||||
/* Start The TIM0 Counter and enable the output comparison A */
|
||||
|
||||
putreg16(STR71X_TIMERCR1_EN | STR71X_TIMERCR1_OCAE, STR71X_TIMER0_CR1);
|
||||
|
||||
/* Setup output compare A for desired interrupt frequency. Note that
|
||||
* the OCAE and OCBE bits are cleared and the pins are available for other
|
||||
@ -175,12 +187,7 @@ void up_timerinit(void)
|
||||
*/
|
||||
|
||||
putreg16(OCAR_VALUE, STR71X_TIMER0_OCAR);
|
||||
putreg16(0, STR71X_TIMER0_CNTR);
|
||||
|
||||
/* Enable TIM0 Output Compare A interrupt */
|
||||
|
||||
cr2 |= STR71X_TIMERCR2_OCAIE;
|
||||
putreg16(cr2, STR71X_TIMER0_CR2);
|
||||
putreg16(0xfffc, STR71X_TIMER0_CNTR);
|
||||
|
||||
/* Set the IRQ interrupt priority */
|
||||
|
||||
@ -193,4 +200,5 @@ void up_timerinit(void)
|
||||
/* And enable the timer interrupt */
|
||||
|
||||
up_enable_irq(STR71X_IRQ_SYSTIMER);
|
||||
irqrestore(flags);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user