mbed library sources: Modified to operate FRDM-KL25Z at 48MHz from internal 32kHz oscillator (nothing else changed).

Fork of mbed-src by mbed official

The only file that changed is: mbed-src-FLL48/targets/cmsis/TARGET_Freescale/TARGET_KL25Z/system_MKL25Z4.h

Committer:
bogdanm
Date:
Tue Sep 10 15:14:19 2013 +0300
Revision:
20:4263a77256ae
Sync with git revision 171dda705c947bf910926a0b73d6a4797802554d

Who changed what in which revision?

UserRevisionLine numberNew contents of line
bogdanm 20:4263a77256ae 1 /* mbed Microcontroller Library
bogdanm 20:4263a77256ae 2 * Copyright (c) 2006-2013 ARM Limited
bogdanm 20:4263a77256ae 3 *
bogdanm 20:4263a77256ae 4 * Licensed under the Apache License, Version 2.0 (the "License");
bogdanm 20:4263a77256ae 5 * you may not use this file except in compliance with the License.
bogdanm 20:4263a77256ae 6 * You may obtain a copy of the License at
bogdanm 20:4263a77256ae 7 *
bogdanm 20:4263a77256ae 8 * http://www.apache.org/licenses/LICENSE-2.0
bogdanm 20:4263a77256ae 9 *
bogdanm 20:4263a77256ae 10 * Unless required by applicable law or agreed to in writing, software
bogdanm 20:4263a77256ae 11 * distributed under the License is distributed on an "AS IS" BASIS,
bogdanm 20:4263a77256ae 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
bogdanm 20:4263a77256ae 13 * See the License for the specific language governing permissions and
bogdanm 20:4263a77256ae 14 * limitations under the License.
bogdanm 20:4263a77256ae 15 */
bogdanm 20:4263a77256ae 16 #include <stddef.h>
bogdanm 20:4263a77256ae 17 #include "cmsis.h"
bogdanm 20:4263a77256ae 18
bogdanm 20:4263a77256ae 19 #include "gpio_irq_api.h"
bogdanm 20:4263a77256ae 20 #include "error.h"
bogdanm 20:4263a77256ae 21
bogdanm 20:4263a77256ae 22 #define CHANNEL_NUM 64 // 31 pins on 2 ports
bogdanm 20:4263a77256ae 23
bogdanm 20:4263a77256ae 24 static uint32_t channel_ids[CHANNEL_NUM] = {0};
bogdanm 20:4263a77256ae 25 static gpio_irq_handler irq_handler;
bogdanm 20:4263a77256ae 26
bogdanm 20:4263a77256ae 27 #define IRQ_DISABLED (0)
bogdanm 20:4263a77256ae 28 #define IRQ_RAISING_EDGE PORT_PCR_IRQC(9)
bogdanm 20:4263a77256ae 29 #define IRQ_FALLING_EDGE PORT_PCR_IRQC(10)
bogdanm 20:4263a77256ae 30 #define IRQ_EITHER_EDGE PORT_PCR_IRQC(11)
bogdanm 20:4263a77256ae 31
bogdanm 20:4263a77256ae 32 static void handle_interrupt_in(PORT_Type *port, int ch_base) {
bogdanm 20:4263a77256ae 33 uint32_t mask = 0, i;
bogdanm 20:4263a77256ae 34
bogdanm 20:4263a77256ae 35 for (i = 0; i < 32; i++) {
bogdanm 20:4263a77256ae 36 uint32_t pmask = (1 << i);
bogdanm 20:4263a77256ae 37 if (port->ISFR & pmask) {
bogdanm 20:4263a77256ae 38 mask |= pmask;
bogdanm 20:4263a77256ae 39 uint32_t id = channel_ids[ch_base + i];
bogdanm 20:4263a77256ae 40 if (id == 0) continue;
bogdanm 20:4263a77256ae 41
bogdanm 20:4263a77256ae 42 FGPIO_Type *gpio;
bogdanm 20:4263a77256ae 43 gpio_irq_event event = IRQ_NONE;
bogdanm 20:4263a77256ae 44 switch (port->PCR[i] & PORT_PCR_IRQC_MASK) {
bogdanm 20:4263a77256ae 45 case IRQ_RAISING_EDGE:
bogdanm 20:4263a77256ae 46 event = IRQ_RISE;
bogdanm 20:4263a77256ae 47 break;
bogdanm 20:4263a77256ae 48
bogdanm 20:4263a77256ae 49 case IRQ_FALLING_EDGE:
bogdanm 20:4263a77256ae 50 event = IRQ_FALL;
bogdanm 20:4263a77256ae 51 break;
bogdanm 20:4263a77256ae 52
bogdanm 20:4263a77256ae 53 case IRQ_EITHER_EDGE:
bogdanm 20:4263a77256ae 54 gpio = (port == PORTA) ? (FPTA) : (FPTB);
bogdanm 20:4263a77256ae 55 event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL);
bogdanm 20:4263a77256ae 56 break;
bogdanm 20:4263a77256ae 57 }
bogdanm 20:4263a77256ae 58 if (event != IRQ_NONE) {
bogdanm 20:4263a77256ae 59 irq_handler(id, event);
bogdanm 20:4263a77256ae 60 }
bogdanm 20:4263a77256ae 61 }
bogdanm 20:4263a77256ae 62 }
bogdanm 20:4263a77256ae 63 port->ISFR = mask;
bogdanm 20:4263a77256ae 64 }
bogdanm 20:4263a77256ae 65
bogdanm 20:4263a77256ae 66 /* IRQ only on PORTA and PORTB */
bogdanm 20:4263a77256ae 67 void gpio_irqA(void) {
bogdanm 20:4263a77256ae 68 handle_interrupt_in(PORTA, 0);
bogdanm 20:4263a77256ae 69 }
bogdanm 20:4263a77256ae 70
bogdanm 20:4263a77256ae 71 void gpio_irqB(void) {
bogdanm 20:4263a77256ae 72 handle_interrupt_in(PORTB, 32);
bogdanm 20:4263a77256ae 73 }
bogdanm 20:4263a77256ae 74
bogdanm 20:4263a77256ae 75 int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) {
bogdanm 20:4263a77256ae 76 if (pin == NC) return -1;
bogdanm 20:4263a77256ae 77
bogdanm 20:4263a77256ae 78 irq_handler = handler;
bogdanm 20:4263a77256ae 79
bogdanm 20:4263a77256ae 80 obj->port = pin >> PORT_SHIFT;
bogdanm 20:4263a77256ae 81 obj->pin = (pin & 0x7F) >> 2;
bogdanm 20:4263a77256ae 82
bogdanm 20:4263a77256ae 83 uint32_t ch_base, vector;
bogdanm 20:4263a77256ae 84 IRQn_Type irq_n;
bogdanm 20:4263a77256ae 85 switch (obj->port) {
bogdanm 20:4263a77256ae 86 case PortA:
bogdanm 20:4263a77256ae 87 ch_base = 0;
bogdanm 20:4263a77256ae 88 irq_n = PORTA_IRQn;
bogdanm 20:4263a77256ae 89 vector = (uint32_t)gpio_irqA;
bogdanm 20:4263a77256ae 90 break;
bogdanm 20:4263a77256ae 91
bogdanm 20:4263a77256ae 92 case PortB:
bogdanm 20:4263a77256ae 93 ch_base = 32;
bogdanm 20:4263a77256ae 94 irq_n = PORTB_IRQn;
bogdanm 20:4263a77256ae 95 vector = (uint32_t)gpio_irqB;
bogdanm 20:4263a77256ae 96 break;
bogdanm 20:4263a77256ae 97
bogdanm 20:4263a77256ae 98 default:
bogdanm 20:4263a77256ae 99 error("gpio_irq only supported on Port A and B\n");
bogdanm 20:4263a77256ae 100 break;
bogdanm 20:4263a77256ae 101 }
bogdanm 20:4263a77256ae 102 NVIC_SetVector(irq_n, vector);
bogdanm 20:4263a77256ae 103 NVIC_EnableIRQ(irq_n);
bogdanm 20:4263a77256ae 104
bogdanm 20:4263a77256ae 105 obj->ch = ch_base + obj->pin;
bogdanm 20:4263a77256ae 106 channel_ids[obj->ch] = id;
bogdanm 20:4263a77256ae 107
bogdanm 20:4263a77256ae 108 return 0;
bogdanm 20:4263a77256ae 109 }
bogdanm 20:4263a77256ae 110
bogdanm 20:4263a77256ae 111 void gpio_irq_free(gpio_irq_t *obj) {
bogdanm 20:4263a77256ae 112 channel_ids[obj->ch] = 0;
bogdanm 20:4263a77256ae 113 }
bogdanm 20:4263a77256ae 114
bogdanm 20:4263a77256ae 115 void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) {
bogdanm 20:4263a77256ae 116 PORT_Type *port = (PORT_Type *)(PORTA_BASE + 0x1000 * obj->port);
bogdanm 20:4263a77256ae 117
bogdanm 20:4263a77256ae 118 uint32_t irq_settings = IRQ_DISABLED;
bogdanm 20:4263a77256ae 119
bogdanm 20:4263a77256ae 120 switch (port->PCR[obj->pin] & PORT_PCR_IRQC_MASK) {
bogdanm 20:4263a77256ae 121 case IRQ_DISABLED:
bogdanm 20:4263a77256ae 122 if (enable) {
bogdanm 20:4263a77256ae 123 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_FALLING_EDGE);
bogdanm 20:4263a77256ae 124 }
bogdanm 20:4263a77256ae 125 break;
bogdanm 20:4263a77256ae 126
bogdanm 20:4263a77256ae 127 case IRQ_RAISING_EDGE:
bogdanm 20:4263a77256ae 128 if (enable) {
bogdanm 20:4263a77256ae 129 irq_settings = (event == IRQ_RISE) ? (IRQ_RAISING_EDGE) : (IRQ_EITHER_EDGE);
bogdanm 20:4263a77256ae 130 } else {
bogdanm 20:4263a77256ae 131 if (event == IRQ_FALL)
bogdanm 20:4263a77256ae 132 irq_settings = IRQ_RAISING_EDGE;
bogdanm 20:4263a77256ae 133 }
bogdanm 20:4263a77256ae 134 break;
bogdanm 20:4263a77256ae 135
bogdanm 20:4263a77256ae 136 case IRQ_FALLING_EDGE:
bogdanm 20:4263a77256ae 137 if (enable) {
bogdanm 20:4263a77256ae 138 irq_settings = (event == IRQ_FALL) ? (IRQ_FALLING_EDGE) : (IRQ_EITHER_EDGE);
bogdanm 20:4263a77256ae 139 } else {
bogdanm 20:4263a77256ae 140 if (event == IRQ_RISE)
bogdanm 20:4263a77256ae 141 irq_settings = IRQ_FALLING_EDGE;
bogdanm 20:4263a77256ae 142 }
bogdanm 20:4263a77256ae 143 break;
bogdanm 20:4263a77256ae 144
bogdanm 20:4263a77256ae 145 case IRQ_EITHER_EDGE:
bogdanm 20:4263a77256ae 146 if (enable) {
bogdanm 20:4263a77256ae 147 irq_settings = IRQ_EITHER_EDGE;
bogdanm 20:4263a77256ae 148 } else {
bogdanm 20:4263a77256ae 149 irq_settings = (event == IRQ_RISE) ? (IRQ_FALLING_EDGE) : (IRQ_RAISING_EDGE);
bogdanm 20:4263a77256ae 150 }
bogdanm 20:4263a77256ae 151 break;
bogdanm 20:4263a77256ae 152 }
bogdanm 20:4263a77256ae 153
bogdanm 20:4263a77256ae 154 // Interrupt configuration and clear interrupt
bogdanm 20:4263a77256ae 155 port->PCR[obj->pin] = (port->PCR[obj->pin] & ~PORT_PCR_IRQC_MASK) | irq_settings | PORT_PCR_ISF_MASK;
bogdanm 20:4263a77256ae 156 }