From 39c69166c568f5f0a3acd594e3bbbafdf846d0d6 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Thu, 17 Oct 2013 13:28:52 +0200 Subject: [PATCH 1/8] fixes startup code and adds proper irq handler for mc1322x --- cpu/arm_common/bootloader.c | 2 + cpu/mc1322x/isr.c | 75 ++++++++++++++ cpu/mc1322x/startup.s | 197 ++++++++++++++---------------------- 3 files changed, 155 insertions(+), 119 deletions(-) create mode 100644 cpu/mc1322x/isr.c diff --git a/cpu/arm_common/bootloader.c b/cpu/arm_common/bootloader.c index 14813ae8bb..57707d4205 100644 --- a/cpu/arm_common/bootloader.c +++ b/cpu/arm_common/bootloader.c @@ -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(); diff --git a/cpu/mc1322x/isr.c b/cpu/mc1322x/isr.c new file mode 100644 index 0000000000..2d465489dc --- /dev/null +++ b/cpu/mc1322x/isr.c @@ -0,0 +1,75 @@ +/* + * isr.c - mc1322x specific isr + * Copyright (C) 2013 Thomas Eichinger + * + * 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" + +static void (*tmr_isr_funcs[4])(void) = { + tmr0_isr, + tmr1_isr, + tmr2_isr, + tmr3_isr +}; + +void irq_register_timer_handler(int timer, void (*isr)(void)) +{ + tmr_isr_funcs[timer] = isr; +} + + +__attribute__ ((section (".irq"))) +__attribute__ ((interrupt("IRQ"))) +void irq(void) +{ + while ((ITC->NIPEND)) { + + if(ITC->NIPENDbits.TMR) { + /* dispatch to individual timer isrs if they exist */ + /* timer isrs are responsible for determining if they */ + /* caused an interrupt */ + /* and clearing their own interrupt flags */ + if (tmr_isr_funcs[0] != 0) { (tmr_isr_funcs[0])(); } + if (tmr_isr_funcs[1] != 0) { (tmr_isr_funcs[1])(); } + if (tmr_isr_funcs[2] != 0) { (tmr_isr_funcs[2])(); } + if (tmr_isr_funcs[3] != 0) { (tmr_isr_funcs[3])(); } + } + + if(ITC->NIPENDbits.MACA) { + if(maca_isr != 0) { maca_isr(); } + } + if(ITC->NIPENDbits.UART1) { + if(uart1_isr != 0) { uart1_isr(); } + } + if(ITC->NIPENDbits.UART2) { + if(uart2_isr != 0) { uart2_isr(); } + } + if(ITC->NIPENDbits.CRM) { + // if(rtc_wu_evt() && (rtc_isr != 0)) { rtc_isr(); } + // if(kbi_evnt(4) && (kbi4_isr != 0)) { kbi4_isr(); } + // if(kbi_evnt(5) && (kbi5_isr != 0)) { kbi5_isr(); } + // if(kbi_evnt(6) && (kbi6_isr != 0)) { kbi6_isr(); } + // if(kbi_evnt(7) && (kbi7_isr != 0)) { kbi7_isr(); } + + if (CRM->STATUSbits.CAL_DONE && CRM->CAL_CNTLbits.CAL_IEN && cal_isr) + { + CRM->STATUSbits.CAL_DONE = 0; + cal_isr(); + } + } + if(ITC->NIPENDbits.ASM) { + if(asm_isr != 0) { asm_isr(); } + } + if (ITC->NIPENDbits.I2C) { + if (i2c_isr != 0) { i2c_isr(); } + } + + ITC->INTFRC = 0; /* stop forcing interrupts */ + + } +} diff --git a/cpu/mc1322x/startup.s b/cpu/mc1322x/startup.s index 30edd9a37c..4ebc294e54 100644 --- a/cpu/mc1322x/startup.s +++ b/cpu/mc1322x/startup.s @@ -1,112 +1,59 @@ /* - * Copyright (c) 2010, Mariano Alvira and other contributors - * to the MC1322x project (http:/*mc1322x.devl.org) and Contiki. - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki OS. + * startup.s - mc1322x specific startup code + * Copyright (C) 2013 Thomas Eichinger * + * 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. */ - - -/* -The following lincence is for all parts of this code done by -Martin Thomas. Code from others used here may have other license terms. - -Copyright (C) 2004 Martin THOMAS - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -! The above copyright notice and this permission notice shall be included in all -! copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -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. -*/ - + /* 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 +61,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 +107,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 irq +_fiq: .word fiq + .balignl 16, 0xdeadbeef /* * These are defined in the board-specific linker script. @@ -179,6 +127,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 From 8aeaea6fdc1fd52dbec2f61901ca70fb99b657ba Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Fri, 18 Oct 2013 11:06:27 +0200 Subject: [PATCH 2/8] changed CFLAGS to CFLAGS_BASIC (no -mthumb flag) --- cpu/mc1322x/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cpu/mc1322x/Makefile b/cpu/mc1322x/Makefile index 706aac84a5..9af5768212 100644 --- a/cpu/mc1322x/Makefile +++ b/cpu/mc1322x/Makefile @@ -8,6 +8,8 @@ ifneq (,$(findstring mc1322x_asm,$(USEMODULE))) DIRS += asm endif +CFLAGS = $(CFLAGS_BASIC) + all: $(BINDIR)$(MODULE).a @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; From a26b7ac4bac7e08a42cd37c146c3cb3ad41d136f Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Tue, 22 Oct 2013 12:57:09 +0200 Subject: [PATCH 3/8] remove isr.c to change interrupt handling to VIC model --- cpu/mc1322x/Makefile | 2 -- cpu/mc1322x/isr.c | 75 ------------------------------------------- cpu/mc1322x/startup.s | 60 ++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 77 deletions(-) delete mode 100644 cpu/mc1322x/isr.c diff --git a/cpu/mc1322x/Makefile b/cpu/mc1322x/Makefile index 9af5768212..706aac84a5 100644 --- a/cpu/mc1322x/Makefile +++ b/cpu/mc1322x/Makefile @@ -8,8 +8,6 @@ ifneq (,$(findstring mc1322x_asm,$(USEMODULE))) DIRS += asm endif -CFLAGS = $(CFLAGS_BASIC) - all: $(BINDIR)$(MODULE).a @for i in $(DIRS) ; do "$(MAKE)" -C $$i ; done ; diff --git a/cpu/mc1322x/isr.c b/cpu/mc1322x/isr.c deleted file mode 100644 index 2d465489dc..0000000000 --- a/cpu/mc1322x/isr.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * isr.c - mc1322x specific isr - * Copyright (C) 2013 Thomas Eichinger - * - * 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" - -static void (*tmr_isr_funcs[4])(void) = { - tmr0_isr, - tmr1_isr, - tmr2_isr, - tmr3_isr -}; - -void irq_register_timer_handler(int timer, void (*isr)(void)) -{ - tmr_isr_funcs[timer] = isr; -} - - -__attribute__ ((section (".irq"))) -__attribute__ ((interrupt("IRQ"))) -void irq(void) -{ - while ((ITC->NIPEND)) { - - if(ITC->NIPENDbits.TMR) { - /* dispatch to individual timer isrs if they exist */ - /* timer isrs are responsible for determining if they */ - /* caused an interrupt */ - /* and clearing their own interrupt flags */ - if (tmr_isr_funcs[0] != 0) { (tmr_isr_funcs[0])(); } - if (tmr_isr_funcs[1] != 0) { (tmr_isr_funcs[1])(); } - if (tmr_isr_funcs[2] != 0) { (tmr_isr_funcs[2])(); } - if (tmr_isr_funcs[3] != 0) { (tmr_isr_funcs[3])(); } - } - - if(ITC->NIPENDbits.MACA) { - if(maca_isr != 0) { maca_isr(); } - } - if(ITC->NIPENDbits.UART1) { - if(uart1_isr != 0) { uart1_isr(); } - } - if(ITC->NIPENDbits.UART2) { - if(uart2_isr != 0) { uart2_isr(); } - } - if(ITC->NIPENDbits.CRM) { - // if(rtc_wu_evt() && (rtc_isr != 0)) { rtc_isr(); } - // if(kbi_evnt(4) && (kbi4_isr != 0)) { kbi4_isr(); } - // if(kbi_evnt(5) && (kbi5_isr != 0)) { kbi5_isr(); } - // if(kbi_evnt(6) && (kbi6_isr != 0)) { kbi6_isr(); } - // if(kbi_evnt(7) && (kbi7_isr != 0)) { kbi7_isr(); } - - if (CRM->STATUSbits.CAL_DONE && CRM->CAL_CNTLbits.CAL_IEN && cal_isr) - { - CRM->STATUSbits.CAL_DONE = 0; - cal_isr(); - } - } - if(ITC->NIPENDbits.ASM) { - if(asm_isr != 0) { asm_isr(); } - } - if (ITC->NIPENDbits.I2C) { - if (i2c_isr != 0) { i2c_isr(); } - } - - ITC->INTFRC = 0; /* stop forcing interrupts */ - - } -} diff --git a/cpu/mc1322x/startup.s b/cpu/mc1322x/startup.s index 4ebc294e54..07f2c08a14 100644 --- a/cpu/mc1322x/startup.s +++ b/cpu/mc1322x/startup.s @@ -1,3 +1,63 @@ +/* + * Copyright (c) 2010, Mariano Alvira and other contributors + * to the MC1322x project (http:/*mc1322x.devl.org) and Contiki. + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki OS. + * + * + */ + + +/* +The following lincence is for all parts of this code done by +Martin Thomas. Code from others used here may have other license terms. + +Copyright (C) 2004 Martin THOMAS + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +! The above copyright notice and this permission notice shall be included in all +! copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +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 From a1cd29d68e3efaab56966bf61e50a4d7a4ba5370 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Mon, 21 Oct 2013 14:12:29 +0200 Subject: [PATCH 4/8] added basic install_irq function --- cpu/mc1322x/cpu.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/cpu/mc1322x/cpu.c b/cpu/mc1322x/cpu.c index 93f90d3a95..7e90e141b7 100644 --- a/cpu/mc1322x/cpu.c +++ b/cpu/mc1322x/cpu.c @@ -22,3 +22,35 @@ __attribute__((naked,noreturn)) void arm_reset(void) enum lpm_mode lpm_set(enum lpm_mode target) { return LPM_ON; } + +/****************************************************************************** +** Function name: cpu_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 +** +******************************************************************************/ +#define VIC_BASE_ADDR 0xFFFFF000 + +bool cpu_install_irq(int IntNumber, void *HandlerAddr, 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); + } +} From 1e39e7e486eedd57a41a34ab281690e079efe28c Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Thu, 24 Oct 2013 13:53:09 +0200 Subject: [PATCH 5/8] 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. --- cpu/arm_common/common.s | 5 ++++ cpu/mc1322x/cpu.c | 39 +++++++++++---------------- cpu/mc1322x/hwtimer_cpu.c | 23 ++++++++++++++-- cpu/mc1322x/include/cpu.h | 12 +++++++-- cpu/mc1322x/include/mc1322x.h | 15 ++++++++--- cpu/mc1322x/isr.c | 50 +++++++++++++++++++++++++++++++++++ cpu/mc1322x/startup.s | 2 +- 7 files changed, 113 insertions(+), 33 deletions(-) create mode 100644 cpu/mc1322x/isr.c diff --git a/cpu/arm_common/common.s b/cpu/arm_common/common.s index 66646adef4..9b3164a356 100644 --- a/cpu/arm_common/common.s +++ b/cpu/arm_common/common.s @@ -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 diff --git a/cpu/mc1322x/cpu.c b/cpu/mc1322x/cpu.c index 7e90e141b7..456a5e7a08 100644 --- a/cpu/mc1322x/cpu.c +++ b/cpu/mc1322x/cpu.c @@ -1,6 +1,7 @@ /* * cpu.c - MC1322X architecture common support functions * Copyright (C) 2013 Oliver Hahm + * Thomas Eichinger * * 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); } diff --git a/cpu/mc1322x/hwtimer_cpu.c b/cpu/mc1322x/hwtimer_cpu.c index 4f53f4d42a..6e37f800a2 100644 --- a/cpu/mc1322x/hwtimer_cpu.c +++ b/cpu/mc1322x/hwtimer_cpu.c @@ -11,12 +11,31 @@ #include #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); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/mc1322x/include/cpu.h b/cpu/mc1322x/include/cpu.h index f37db452d5..82b307bf4a 100644 --- a/cpu/mc1322x/include/cpu.h +++ b/cpu/mc1322x/include/cpu.h @@ -15,10 +15,18 @@ #ifndef CPU_H #define CPU_H -#include +/** + * @defgroup mc1322x Freescale mc1322x + * @ingroup cpu + * @{ + */ + +#include #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 */ diff --git a/cpu/mc1322x/include/mc1322x.h b/cpu/mc1322x/include/mc1322x.h index 20409bf445..d8c7c74e0d 100644 --- a/cpu/mc1322x/include/mc1322x.h +++ b/cpu/mc1322x/include/mc1322x.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 */ diff --git a/cpu/mc1322x/isr.c b/cpu/mc1322x/isr.c new file mode 100644 index 0000000000..533f21729b --- /dev/null +++ b/cpu/mc1322x/isr.c @@ -0,0 +1,50 @@ +/* + * isr.c - mc1322x specific isr + * Copyright (C) 2013 Thomas Eichinger + * + * 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])(); + } + } +} diff --git a/cpu/mc1322x/startup.s b/cpu/mc1322x/startup.s index 07f2c08a14..c454a6cd80 100644 --- a/cpu/mc1322x/startup.s +++ b/cpu/mc1322x/startup.s @@ -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 From 1fcb47f9ed019f9bc84de1106758e149760e2b13 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Mon, 11 Nov 2013 12:30:06 +0100 Subject: [PATCH 6/8] fixed interrupt handling for hwtimer --- cpu/arm_common/common.s | 4 +-- cpu/mc1322x/hwtimer_cpu.c | 57 ++++++++++++++++++++++++--------------- cpu/mc1322x/isr.c | 9 ++----- 3 files changed, 40 insertions(+), 30 deletions(-) diff --git a/cpu/arm_common/common.s b/cpu/arm_common/common.s index 9b3164a356..d8bd1310f0 100644 --- a/cpu/arm_common/common.s +++ b/cpu/arm_common/common.s @@ -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 */ diff --git a/cpu/mc1322x/hwtimer_cpu.c b/cpu/mc1322x/hwtimer_cpu.c index 6e37f800a2..f2f7be5f90 100644 --- a/cpu/mc1322x/hwtimer_cpu.c +++ b/cpu/mc1322x/hwtimer_cpu.c @@ -15,6 +15,8 @@ #include "hwtimer_arch.h" #include "irq.h" +#include + /* 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<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<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<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<SCTRLbits.TCFIE = 1; /* enable interrupts when TCF is one - do we need both?*/ - /* restor status register */ + /* restore status register */ restoreIRQ(cpsr); } diff --git a/cpu/mc1322x/isr.c b/cpu/mc1322x/isr.c index 533f21729b..5023ecef5b 100644 --- a/cpu/mc1322x/isr.c +++ b/cpu/mc1322x/isr.c @@ -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])(); } } } From 1d2f1479b699e44ac1c60ffcc46594a3e1bbb934 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Thu, 14 Nov 2013 12:05:06 +0100 Subject: [PATCH 7/8] hwtimer_wait issue fixed --- cpu/mc1322x/hwtimer_cpu.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cpu/mc1322x/hwtimer_cpu.c b/cpu/mc1322x/hwtimer_cpu.c index f2f7be5f90..6107426d96 100644 --- a/cpu/mc1322x/hwtimer_cpu.c +++ b/cpu/mc1322x/hwtimer_cpu.c @@ -26,21 +26,25 @@ 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); } @@ -67,7 +71,7 @@ void timer_x_init(volatile struct TMR_struct* const TMRx) { 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*/ From 0afb992fc7287bbc19469981693c125e3b1ab8e2 Mon Sep 17 00:00:00 2001 From: Thomas Eichinger Date: Wed, 18 Dec 2013 11:16:41 +0100 Subject: [PATCH 8/8] changed copyright statement --- cpu/mc1322x/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpu/mc1322x/cpu.c b/cpu/mc1322x/cpu.c index 456a5e7a08..c937b107ed 100644 --- a/cpu/mc1322x/cpu.c +++ b/cpu/mc1322x/cpu.c @@ -1,7 +1,7 @@ /* * cpu.c - MC1322X architecture common support functions * Copyright (C) 2013 Oliver Hahm - * Thomas Eichinger + * Copyright (C) 2013 Thomas Eichinger * * This source code is licensed under the GNU Lesser General Public License, * Version 2. See the file LICENSE for more details.