From dc19dcbb94d039769c0878c9e96d7a7a3cdf2615 Mon Sep 17 00:00:00 2001 From: 0xc0170 Date: Mon, 30 Dec 2013 12:19:24 +0100 Subject: [PATCH 1/2] fix - KL46Z cmsis header (v2.2), shared interrupt PORTCD - Ports C and D sharing same interrupt vectors - KL46Z CMSIS header update - InterruptIn methods irq_disable/enable comment update --- libraries/mbed/api/InterruptIn.h | 6 +- .../TARGET_Freescale/TARGET_KL46Z/MKL46Z4.h | 301 +++++++++--------- .../TARGET_KL46Z/gpio_irq_api.c | 43 ++- 3 files changed, 188 insertions(+), 162 deletions(-) diff --git a/libraries/mbed/api/InterruptIn.h b/libraries/mbed/api/InterruptIn.h index 45eb2ffc54..88bc4308e8 100644 --- a/libraries/mbed/api/InterruptIn.h +++ b/libraries/mbed/api/InterruptIn.h @@ -108,11 +108,13 @@ public: */ void mode(PinMode pull); - /** Enable IRQ + /** Enable IRQ. This method depends on hw implementation, might enable one + * port interrupts. For further information, check gpio_irq_enable(). */ void enable_irq(); - /** Disable IRQ + /** Disable IRQ. This method depends on hw implementation, might disable one + * port interrupts. For further information, check gpio_irq_disable(). */ void disable_irq(); diff --git a/libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_KL46Z/MKL46Z4.h b/libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_KL46Z/MKL46Z4.h index 60588932d3..9f975d7d0a 100644 --- a/libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_KL46Z/MKL46Z4.h +++ b/libraries/mbed/targets/cmsis/TARGET_Freescale/TARGET_KL46Z/MKL46Z4.h @@ -12,13 +12,13 @@ ** GNU C Compiler ** IAR ANSI C/C++ Compiler for ARM ** -** Reference manual: KL46P121M48SF4RM, Rev.1 Draft A, Aug 2012 -** Version: rev. 2.0, 2012-12-12 +** Reference manual: KL46P121M48SF4RM, Rev.2, Dec 2012 +** Version: rev. 2.2, 2013-04-12 ** ** Abstract: ** CMSIS Peripheral Access Layer for MKL46Z4 ** -** Copyright: 1997 - 2012 Freescale, Inc. All Rights Reserved. +** Copyright: 1997 - 2013 Freescale, Inc. All Rights Reserved. ** ** http: www.freescale.com ** mail: support@freescale.com @@ -28,14 +28,19 @@ ** Initial version. ** - rev. 2.0 (2012-12-12) ** Update to reference manual rev. 1. +** - rev. 2.1 (2013-04-05) +** Changed start of doxygen comment. +** - rev. 2.2 (2013-04-12) +** SystemInit function fixed for clock configuration 1. +** Name of the interrupt num. 31 updated to reflect proper function. ** ** ################################################################### */ -/** +/*! * @file MKL46Z4.h - * @version 2.0 - * @date 2012-12-12 + * @version 2.2 + * @date 2013-04-12 * @brief CMSIS Peripheral Access Layer for MKL46Z4 * * CMSIS Peripheral Access Layer for MKL46Z4 @@ -48,14 +53,14 @@ * compatible) */ #define MCU_MEM_MAP_VERSION 0x0200u /** Memory map minor version */ -#define MCU_MEM_MAP_VERSION_MINOR 0x0000u +#define MCU_MEM_MAP_VERSION_MINOR 0x0002u /* ---------------------------------------------------------------------------- -- Interrupt vector numbers ---------------------------------------------------------------------------- */ -/** +/*! * @addtogroup Interrupt_vector_numbers Interrupt vector numbers * @{ */ @@ -101,10 +106,10 @@ typedef enum IRQn { LPTimer_IRQn = 28, /**< LPTimer interrupt */ LCD_IRQn = 29, /**< Segment LCD Interrupt */ PORTA_IRQn = 30, /**< Port A interrupt */ - PORTD_IRQn = 31 /**< Port D interrupt */ + PORTC_PORTD_IRQn = 31 /**< Port C and port D interrupt */ } IRQn_Type; -/** +/*! * @} */ /* end of group Interrupt_vector_numbers */ @@ -113,7 +118,7 @@ typedef enum IRQn { -- Cortex M0 Core Configuration ---------------------------------------------------------------------------- */ -/** +/*! * @addtogroup Cortex_Core_Configuration Cortex M0 Core Configuration * @{ */ @@ -127,7 +132,7 @@ typedef enum IRQn { #include "core_cm0plus.h" /* Core Peripheral Access Layer */ #include "system_MKL46Z4.h" /* Device specific configuration file */ -/** +/*! * @} */ /* end of group Cortex_Core_Configuration */ @@ -136,7 +141,7 @@ typedef enum IRQn { -- Device Peripheral Access Layer ---------------------------------------------------------------------------- */ -/** +/*! * @addtogroup Peripheral_access_layer Device Peripheral Access Layer * @{ */ @@ -164,7 +169,7 @@ typedef enum IRQn { -- ADC Peripheral Access Layer ---------------------------------------------------------------------------- */ -/** +/*! * @addtogroup ADC_Peripheral_Access_Layer ADC Peripheral Access Layer * @{ */ @@ -203,7 +208,7 @@ typedef struct { -- ADC Register Masks ---------------------------------------------------------------------------- */ -/** +/*! * @addtogroup ADC_Register_Masks ADC Register Masks * @{ */ @@ -351,7 +356,7 @@ typedef struct { #define ADC_CLM0_CLM0_SHIFT 0 #define ADC_CLM0_CLM0(x) (((uint32_t)(((uint32_t)(x))<ISFR & pmask) { mask |= pmask; uint32_t id = channel_ids[ch_base + i]; - if (id == 0) continue; + if (id == 0) + continue; FGPIO_Type *gpio; gpio_irq_event event = IRQ_NONE; @@ -51,7 +52,13 @@ static void handle_interrupt_in(PORT_Type *port, int ch_base) { break; case IRQ_EITHER_EDGE: - gpio = (port == PORTA) ? (FPTA) : (FPTD); + if (port == PORTA) { + gpio = FPTA; + } else if (port == PORTC) { + gpio = FPTC; + } else { + gpio = FPTD; + } event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL); break; } @@ -62,11 +69,19 @@ static void handle_interrupt_in(PORT_Type *port, int ch_base) { port->ISFR = mask; } -void gpio_irqA(void) {handle_interrupt_in(PORTA, 0);} -void gpio_irqD(void) {handle_interrupt_in(PORTD, 32);} +void gpio_irqA(void) { + handle_interrupt_in(PORTA, 0); +} + +void gpio_irqCD(void) { + /* PORTC and PORTD share same vector */ + handle_interrupt_in(PORTC, 32); + handle_interrupt_in(PORTD, 64); +} int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { - if (pin == NC) return -1; + if (pin == NC) + return -1; irq_handler = handler; @@ -80,12 +95,16 @@ int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32 ch_base = 0; irq_n = PORTA_IRQn; vector = (uint32_t)gpio_irqA; break; + case PortC: + ch_base = 32; irq_n = PORTC_PORTD_IRQn; vector = (uint32_t)gpio_irqCD; + break; + case PortD: - ch_base = 32; irq_n = PORTD_IRQn; vector = (uint32_t)gpio_irqD; + ch_base = 64; irq_n = PORTC_PORTD_IRQn; vector = (uint32_t)gpio_irqCD; break; default: - error("gpio_irq only supported on port A and D\n"); + error("gpio_irq only supported on port A,C and D\n"); break; } NVIC_SetVector(irq_n, vector); @@ -147,15 +166,15 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { void gpio_irq_enable(gpio_irq_t *obj) { if (obj->port == PortA) { NVIC_EnableIRQ(PORTA_IRQn); - } else if (obj->port == PortD) { - NVIC_EnableIRQ(PORTD_IRQn); + } else { + NVIC_EnableIRQ(PORTC_PORTD_IRQn); } } void gpio_irq_disable(gpio_irq_t *obj) { if (obj->port == PortA) { NVIC_DisableIRQ(PORTA_IRQn); - } else if (obj->port == PortD) { - NVIC_DisableIRQ(PORTD_IRQn); + } else { + NVIC_DisableIRQ(PORTC_PORTD_IRQn); } } From aa501c003b3f0acd668f3d1cd687154ca3248553 Mon Sep 17 00:00:00 2001 From: 0xc0170 Date: Tue, 31 Dec 2013 08:34:12 +0100 Subject: [PATCH 2/2] Shared PORT interrupt - check improved - clocks must be enabled and also interrupt detected, otherwise interrupt handler is not invoked. --- .../hal/TARGET_Freescale/TARGET_KL46Z/gpio_irq_api.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL46Z/gpio_irq_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL46Z/gpio_irq_api.c index a71993b7d6..005ae3a367 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL46Z/gpio_irq_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KL46Z/gpio_irq_api.c @@ -73,10 +73,13 @@ void gpio_irqA(void) { handle_interrupt_in(PORTA, 0); } +/* PORTC and PORTD share same vector */ void gpio_irqCD(void) { - /* PORTC and PORTD share same vector */ - handle_interrupt_in(PORTC, 32); - handle_interrupt_in(PORTD, 64); + if ((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) && (PORTC->ISFR)) { + handle_interrupt_in(PORTC, 32); + } else if ((SIM->SCGC5 & SIM_SCGC5_PORTD_MASK) && (PORTD->ISFR)) { + handle_interrupt_in(PORTD, 64); + } } int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {