mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-11 18:33:16 +01:00
dm36x: Support user-registered interrupt handlers via archISRInstall().
This commit is contained in:
@@ -30,9 +30,12 @@
|
||||
#ifndef __ATOM_PORT_PRIVATE_H
|
||||
#define __ATOM_PORT_PRIVATE_H
|
||||
|
||||
/* ISR handler prototype used for registration of interuppt handlers */
|
||||
typedef void (*ISR_FUNC)(void);
|
||||
|
||||
/* Function prototypes */
|
||||
extern void archIRQHandler (void);
|
||||
extern int archISRInstall (int int_vector, ISR_FUNC isr_func);
|
||||
|
||||
/* Platform-specific interrupt dispatcher called on receipt of IRQ */
|
||||
extern void __interrupt_dispatcher (void);
|
||||
|
||||
@@ -45,6 +45,20 @@ extern int main(void);
|
||||
#define TIMER0_REG(offset) *(volatile uint32_t *)(DM36X_TIMER0_BASE + offset)
|
||||
#define INTC_REG(offset) *(volatile uint32_t *)(DM36X_INTC_BASE + offset)
|
||||
|
||||
/**
|
||||
* Table of registered ISR handlers: pre-initialised
|
||||
* with all disabled except the Atomthreads timer tick ISR.
|
||||
*/
|
||||
static ISR_FUNC isr_handlers[DM36X_INTC_MAX_VEC + 1] =
|
||||
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
atomTimerTick, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
|
||||
|
||||
/**
|
||||
* \b _mainCRTStartup
|
||||
@@ -136,14 +150,49 @@ low_level_init (void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b archISRInstall
|
||||
*
|
||||
* Register an interrupt handler to be called if a particular
|
||||
* interrupt vector occurs.
|
||||
*
|
||||
* Note that all registered ISRs are called within atomIntEnter()
|
||||
* and atomIntExit() calls, which means they can use OS services
|
||||
* that do not block (e.g. atomSemPut()).
|
||||
*
|
||||
* @param[in] int_vector Interrupt vector to install handler for
|
||||
* @param[in] isr_func Handler to call when specified int occurs
|
||||
*
|
||||
* @retval ATOM_OK Success
|
||||
* @retval ATOM_ERROR Error
|
||||
*/
|
||||
int archISRInstall (int int_vector, ISR_FUNC isr_func)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Check vector is valid */
|
||||
if ((int_vector < 0) || (int_vector > DM36X_INTC_MAX_VEC))
|
||||
{
|
||||
/* Invalid vector number */
|
||||
status = ATOM_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Valid vector, install it in the ISR table */
|
||||
isr_handlers[int_vector] = isr_func;
|
||||
status = ATOM_OK;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \b __interrupt_dispatcher
|
||||
*
|
||||
* Interrupt dispatcher: determines the source of the IRQ and calls
|
||||
* the appropriate ISR.
|
||||
*
|
||||
* Currently only the OS system tick ISR is implemented.
|
||||
*
|
||||
* Note that any ISRs which call Atomthreads OS routines that can
|
||||
* cause rescheduling of threads must be surrounded by calls to
|
||||
* atomIntEnter() and atomIntExit().
|
||||
@@ -163,14 +212,14 @@ __interrupt_dispatcher (void)
|
||||
{
|
||||
/* Spurious interrupt */
|
||||
uart_write_halt ("Spurious IRQ\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Translate from vector address to vector number */
|
||||
vector = (INTC_REG(DM36X_INTC_IRQENTRY) / 4) - 1;
|
||||
|
||||
/* TIMER0:12 tick interrupt (call Atomthreads timer tick ISR) */
|
||||
if (vector == DM36X_INTC_VEC_TINT0)
|
||||
/* Check vector number is valid */
|
||||
if ((vector > 0) && (vector <= DM36X_INTC_MAX_VEC) && (isr_handlers[vector] != NULL))
|
||||
{
|
||||
/* Ack the interrupt immediately, could get scheduled out below */
|
||||
INTC_REG(((vector >= 32) ? DM36X_INTC_IRQ1 : DM36X_INTC_IRQ0)) = (1 << ((vector >= 32) ? (vector - 32) : vector));
|
||||
@@ -181,8 +230,8 @@ __interrupt_dispatcher (void)
|
||||
*/
|
||||
atomIntEnter();
|
||||
|
||||
/* Call the OS system tick handler */
|
||||
atomTimerTick();
|
||||
/* Call the registered ISR */
|
||||
isr_handlers[vector]();
|
||||
|
||||
/* Call the interrupt exit routine */
|
||||
atomIntExit(TRUE);
|
||||
@@ -193,7 +242,7 @@ __interrupt_dispatcher (void)
|
||||
uart_write_halt ("Unexpected IRQ vector\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -230,7 +230,17 @@
|
||||
#define DM36X_INTC_PRI6 0x48
|
||||
#define DM36X_INTC_PRI7 0x4C
|
||||
/** Interrupt controller vector offsets */
|
||||
#define DM36X_INTC_VEC_TINT0 32
|
||||
#define DM36X_INTC_VEC_VPSSINT0 0
|
||||
#define DM36X_INTC_VEC_VPSSINT1 1
|
||||
#define DM36X_INTC_VEC_VPSSINT2 2
|
||||
#define DM36X_INTC_VEC_VPSSINT3 3
|
||||
#define DM36X_INTC_VEC_VPSSINT4 4
|
||||
#define DM36X_INTC_VEC_VPSSINT5 5
|
||||
#define DM36X_INTC_VEC_VPSSINT6 6
|
||||
#define DM36X_INTC_VEC_VPSSINT7 7
|
||||
#define DM36X_INTC_VEC_VPSSINT8 8
|
||||
#define DM36X_INTC_VEC_TINT0 32
|
||||
#define DM36X_INTC_MAX_VEC 63
|
||||
|
||||
|
||||
/** UART registers */
|
||||
|
||||
Reference in New Issue
Block a user