mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Committer:
mbed_official
Date:
Tue Mar 25 09:30:07 2014 +0000
Revision:
134:4fb64af58963
Parent:
113:65a335a675de
Child:
158:3121b9889f7b
Synchronized with git revision d4c04e866e041b272b75d9ee61ff446dc5efebfd

Full URL: https://github.com/mbedmicro/mbed/commit/d4c04e866e041b272b75d9ee61ff446dc5efebfd/

Create a platform specific file to override WEAK Handlers and pre-main hook mbed_sdk_init

I thought about a better solution for this problem, but I couldn't find one, so this is fine. Just one comment: I wouldn't name that file 'platform_init.c'. First, it might contain other code than just initialization code (for example, mbed_die is also declared as a weak function and we'll need to override it for NRF51822). Second, it doesn't realy send the "this file is special and should be treated as such" message. I'd call it something like 'mbed_overrides.c'. But I'll make this change later. Thanks for the pull request!

Who changed what in which revision?

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