mbed library sources
Dependents: frdm_kl05z_gpio_test
Fork of mbed-src by
Diff: targets/hal/TARGET_NORDIC/TARGET_NRF51822/gpio_irq_api.c
- Revision:
- 85:e1a8e879a6a9
- Child:
- 104:a6a92e2e5a92
diff -r f54042cbc282 -r e1a8e879a6a9 targets/hal/TARGET_NORDIC/TARGET_NRF51822/gpio_irq_api.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/targets/hal/TARGET_NORDIC/TARGET_NRF51822/gpio_irq_api.c Fri Feb 07 18:00:11 2014 +0000 @@ -0,0 +1,125 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include <stddef.h> +#include "cmsis.h" + +#include "gpio_irq_api.h" +#include "error.h" + +#define CHANNEL_NUM 31 + +static uint32_t channel_ids[CHANNEL_NUM] = {0}; //each pin will be given an id, if id is 0 the pin can be ignored. +static uint8_t channel_enabled[CHANNEL_NUM] = {0}; +static uint32_t portRISE= 0; +static uint32_t portFALL= 0; +static gpio_irq_handler irq_handler; + +#ifdef __cplusplus +extern "C" { +#endif +void GPIOTE_IRQHandler(void){ + volatile uint32_t newVal = NRF_GPIO->IN; + + if ( (NRF_GPIOTE->EVENTS_PORT != 0) && ( (NRF_GPIOTE->INTENSET & GPIOTE_INTENSET_PORT_Msk) != 0) ){ + NRF_GPIOTE->EVENTS_PORT = 0; + + for(uint8_t i=0;i<31;i++){ + if(channel_ids[i]>0){ + if(channel_enabled[i]){ + if( ((newVal>>i)&1) && ( ( (NRF_GPIO->PIN_CNF[i] >>GPIO_PIN_CNF_SENSE_Pos) & GPIO_PIN_CNF_SENSE_Low) != GPIO_PIN_CNF_SENSE_Low) && ( (portRISE>>i)&1) ){ + irq_handler(channel_ids[i], IRQ_RISE); + } + else if( ( ((newVal>>i)&1) == 0) && ( ( (NRF_GPIO->PIN_CNF[i] >>GPIO_PIN_CNF_SENSE_Pos)&GPIO_PIN_CNF_SENSE_Low) == GPIO_PIN_CNF_SENSE_Low) && ( (portFALL>>i)&1) ){ + irq_handler(channel_ids[i], IRQ_FALL); + } + } + + if(NRF_GPIO->PIN_CNF[i] &GPIO_PIN_CNF_SENSE_Msk){ + NRF_GPIO->PIN_CNF[i] &= ~(GPIO_PIN_CNF_SENSE_Msk); + + if(newVal>>i &1){ + NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos) ; + } + else{ + NRF_GPIO->PIN_CNF[i] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ; + } + } + } + } + } +} +#ifdef __cplusplus +} +#endif + +int gpio_irq_init(gpio_irq_t *obj, PinName pin, gpio_irq_handler handler, uint32_t id) { + if (pin == NC) { + return -1; + } + + irq_handler = handler; + obj->ch = pin; + NRF_GPIOTE->EVENTS_PORT = 0; + channel_ids[pin] = id; + channel_enabled[pin] = 1; + NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Set<<GPIOTE_INTENSET_PORT_Pos; + + NVIC_SetPriority(GPIOTE_IRQn, 3); + NVIC_EnableIRQ (GPIOTE_IRQn); + return 0; +} + +void gpio_irq_free(gpio_irq_t *obj) { + channel_ids[obj->ch] = 0; +} + +void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable) { + NRF_GPIO->PIN_CNF[obj->ch] &= ~(GPIO_PIN_CNF_SENSE_Msk); + if(enable){ + if(event == IRQ_RISE){ + portRISE |= (1<<obj->ch); + } + else if(event == IRQ_FALL){ + portFALL |= (1<<obj->ch); + } + } + else{ + if(event == IRQ_RISE){ + portRISE &= ~(1<<obj->ch); + } + else if(event == IRQ_FALL){ + portFALL &= ~(1<<obj->ch); + } + + } + + if( ( (portRISE>>obj->ch) & 1) || ( (portFALL>>obj->ch) & 1) ){ + if((NRF_GPIO->IN>>obj->ch)&1){ + NRF_GPIO->PIN_CNF[obj->ch] |= (GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos);// | (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos); + } + else{ + NRF_GPIO->PIN_CNF[obj->ch] |= (GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos) ;//| (GPIO_PIN_CNF_PULL_Disabled << GPIO_PIN_CNF_PULL_Pos); + } + } +} + +void gpio_irq_enable(gpio_irq_t *obj) { + channel_enabled[obj->ch] = 1; +} + +void gpio_irq_disable(gpio_irq_t *obj) { + channel_enabled[obj->ch] = 0; +}