1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 22:43:50 +01:00

Merge pull request #262 from thomaseichinger/vic

mc1322x change to a VIC like interrupt system
This commit is contained in:
Oleg Hahm 2013-12-18 07:26:19 -08:00
commit 6d2ed29668
8 changed files with 234 additions and 87 deletions

View File

@ -174,7 +174,9 @@ void bootloader(void)
bl_init_clks();
/* initialize bss and data */
#if CPU != mc1322x
bl_init_data();
#endif
/* board specific setup of i/o pins */
bl_init_ports();

View File

@ -136,11 +136,16 @@ arm_irq_handler:
MRS R1, CPSR
MSR SPSR, R1
#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
mov pc, r0
/* restore spsr from stack */

View File

@ -1,6 +1,7 @@
/*
* cpu.c - MC1322X architecture common support functions
* Copyright (C) 2013 Oliver Hahm <oliver.hahm@inria.fr>
* 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.
@ -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,5 +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: install_irq
**
** 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
**
******************************************************************************/
bool install_irq(int int_number, void *handler_addr, int priority)
{
(void) priority;
register_isr(int_number, handler_addr);
return (true);
}

View File

@ -11,15 +11,48 @@
#include <stdint.h>
#include "mc1322x.h"
#include "cpu.h"
#include "hwtimer_arch.h"
#include "irq.h"
#include <stdio.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->SCTRLbits.TCF && TMR0->SCTRLbits.TCFIE) {
TMR0->SCTRLbits.TCF = 0;
TMR0->CSCTRLbits.TCF1 = 0;
TMR0->ENBL &= ~(1<<0);
int_handler(0);
}
else if (TMR1->SCTRLbits.TCF && TMR1->SCTRLbits.TCFIE) {
TMR1->SCTRLbits.TCF = 0;
TMR1->CSCTRLbits.TCF1 = 0;
TMR0->ENBL &= ~(1<<1);
int_handler(1);
}
else if (TMR2->SCTRLbits.TCF && TMR2->SCTRLbits.TCFIE) {
TMR2->SCTRLbits.TCF = 0;
TMR2->CSCTRLbits.TCF1 = 0;
TMR0->ENBL &= ~(1<<2);
int_handler(2);
}
else if (TMR3->SCTRLbits.TCF && TMR3->SCTRLbits.TCFIE) {
TMR3->SCTRLbits.TCF = 0;
TMR3->CSCTRLbits.TCF1 = 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 */
@ -32,21 +65,17 @@ 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 */
TMRx->CTRLbits.PRIMARY_CNT_SOURCE = 0x0f; /* Perip. clock with 128 prescale (for 24MHz = 187500Hz) */
TMRx->CTRLbits.SECONDARY_CNT_SOURCE = 0x00; /* don't need this */
TMRx->CTRLbits.ONCE = 0x00; /* keep counting */
TMRx->CTRLbits.ONCE = 0x01; /* don't keep counting */
TMRx->CTRLbits.LENGTH = 0x00; /* continue counting */
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? */
/* TODO: install ISR */
}
void hwtimer_arch_init(void (*handler)(int), uint32_t fcpu) {
@ -55,10 +84,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);
register_isr(INT_NUM_TMR, &tmr_isr);
hwtimer_arch_enable_interrupt();
}
/*---------------------------------------------------------------------------*/
@ -74,40 +108,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);
}

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 */

45
cpu/mc1322x/isr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* 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
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)
{
/* pending interrupt? */
while (ITC->NIPEND) {
/* get interrupt source, range 0-10 */
/* call corresponding ISR */
if (isr_funcs[ITC->NIVECTOR]) {
(isr_funcs[ITC->NIVECTOR])();
}
}
}

View File

@ -33,7 +33,7 @@
*
*/
/*
The following lincence is for all parts of this code done by
Martin Thomas. Code from others used here may have other license terms.
@ -57,56 +57,63 @@ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* startup.s - mc1322x specific startup code
* 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.
*/
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */
.set MODE_USR, 0x10 /* Normal User Mode */
.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */
.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set USR_MODE, 0x10 /* Normal User Mode */
.set FIQ_MODE, 0x11 /* FIQ Processing Fast Interrupts Mode */
.set IRQ_MODE, 0x12 /* IRQ Processing Standard Interrupts Mode */
.set SVC_MODE, 0x13 /* Supervisor Processing Software Interrupts Mode */
.set ABT_MODE, 0x17 /* Abort Processing memory Faults Mode */
.set UND_MODE, 0x1B /* Undefined Processing Undefined Instructions Mode */
.set SYS_MODE, 0x1F /* System Running Priviledged Operating System Tasks Mode */
.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
.set IRQ_DISABLE, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */
.set FIQ_DISABLE, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */
.section .startup
.section .startup
.set _rom_data_init, 0x108d0
.global _startup
.func _startup
_startup:
b _begin /* reset - _start */
ldr PC, Undef_Addr /* Undefined Instruction */
ldr PC, SWI_Addr /* Software Interrupt */
ldr PC, PAbt_Addr /* Prefetch Abort */
ldr PC, DAbt_Addr /* Data Abort */
nop /* Reserved Vector (holds Philips ISP checksum) */
/* see page 71 of "Insiders Guide to the Philips ARM7-Based Microcontrollers" by Trevor Martin */
/* ldr PC, [PC,#-0x0120] /* Interrupt Request Interrupt (load from VIC) */
ldr PC, IRQ_Addr /* Interrupt Request Interrupt (load from VIC) */
ldr r0, =__fiq_handler /* Fast Interrupt Request Interrupt */
ldr PC, Undef_Addr /* Undefined Instruction */
ldr PC, SWI_Addr /* Software Interrupt */
ldr PC, PAbt_Addr /* Prefetch Abort */
ldr PC, DAbt_Addr /* Data Abort */
ldr PC, _not_used
ldr PC, IRQ_Addr /* Interrupt Request Interrupt (load from VIC) */
ldr PC, _fiq
/* these vectors are used for rom patching */
/* these vectors are used for rom patching */
.org 0x20
.code 16
_RPTV_0_START:
bx lr /* do nothing */
bx lr /* do nothing */
.org 0x60
_RPTV_1_START:
bx lr /* do nothing */
bx lr /* do nothing */
.org 0xa0
_RPTV_2_START:
bx lr /* do nothing */
bx lr /* do nothing */
.org 0xe0
_RPTV_3_START:
bx lr /* do nothing */
bx lr /* do nothing */
.org 0x120
ROM_var_start: .word 0
@ -114,40 +121,40 @@ ROM_var_start: .word 0
ROM_var_end: .word 0
.code 32
.align
_begin:
/* FIQ mode stack */
msr CPSR_c, #(MODE_FIQ | I_BIT | F_BIT)
ldr sp, =__fiq_stack_top__ /* set the FIQ stack pointer */
.align
_begin:
/* FIQ mode stack */
msr CPSR_c, #(FIQ_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__fiq_stack_top__ /* set the FIQ stack pointer */
/* IRQ mode stack */
msr CPSR_c, #(MODE_IRQ | I_BIT | F_BIT)
ldr sp, =__irq_stack_top__ /* set the IRQ stack pointer */
/* IRQ mode stack */
msr CPSR_c, #(IRQ_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__irq_stack_top__ /* set the IRQ stack pointer */
/* Supervisor mode stack */
msr CPSR_c, #(MODE_SVC | I_BIT | F_BIT)
ldr sp, =__svc_stack_top__ /* set the SVC stack pointer */
/* Supervisor mode stack */
msr CPSR_c, #(SVC_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__svc_stack_top__ /* set the SVC stack pointer */
/* Undefined mode stack */
msr CPSR_c, #(MODE_UND | I_BIT | F_BIT)
ldr sp, =__und_stack_top__ /* set the UND stack pointer */
/* Undefined mode stack */
msr CPSR_c, #(UND_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__und_stack_top__ /* set the UND stack pointer */
/* Abort mode stack */
msr CPSR_c, #(MODE_ABT | I_BIT | F_BIT)
ldr sp, =__abt_stack_top__ /* set the ABT stack pointer */
/* Abort mode stack */
msr CPSR_c, #(ABT_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__abt_stack_top__ /* set the ABT stack pointer */
/* System mode stack */
msr CPSR_c, #(MODE_SYS | I_BIT | F_BIT)
ldr sp, =__sys_stack_top__ /* set the SYS stack pointer */
/* System mode stack */
msr CPSR_c, #(SYS_MODE | IRQ_DISABLE | FIQ_DISABLE)
ldr sp, =__sys_stack_top__ /* set the SYS stack pointer */
/* call the rom_data_init function in ROM */
/* initializes ROM_var space defined by ROM_var_start and ROM_var_end */
/* this area is used by ROM functions (e.g. nvm_read) */
ldr r12,=_rom_data_init
mov lr,pc
bx r12
/* call the rom_data_init function in ROM */
/* initializes ROM_var space defined by ROM_var_start and ROM_var_end */
/* this area is used by ROM functions (e.g. nvm_read) */
ldr r12,=_rom_data_init
mov lr,pc
bx r12
msr CPSR_c, #(MODE_SYS)
msr CPSR_c, #(SYS_MODE)
/* Clear BSS */
clear_bss:
@ -160,17 +167,18 @@ clbss_l:
cmp r0, r1
blt clbss_l
b main
bl bootloader
b kernel_init
/* Exception vector handlers branching table */
Undef_Addr: .word UNDEF_Routine /* defined in main.c */
SWI_Addr: .word ctx_switch /* defined in main.c */
PAbt_Addr: .word PABT_Routine /* defined in main.c */
DAbt_Addr: .word DABT_Routine /* defined in main.c */
IRQ_Addr: .word arm_irq_handler /* defined in main.c */
__fiq_handler: .word __fiq /* FIQ */
__fiq: b . /* FIQ */
Undef_Addr: .word UNDEF_Routine
SWI_Addr: .word ctx_switch
PAbt_Addr: .word PABT_Routine
DAbt_Addr: .word DABT_Routine
_not_used: .word not_used
IRQ_Addr: .word arm_irq_handler
_fiq: .word fiq
.balignl 16, 0xdeadbeef
/*
* These are defined in the board-specific linker script.
@ -179,6 +187,17 @@ __fiq: b . /* FIQ */
_bss_start:
.word __bss_start
.globl _bss_end
.globl _bss_end
_bss_end:
.word _end
.align 5
not_used:
.align 5
/*irq:
//
// .align 5*/
fiq:
.align 5