diff --git a/hw/mcu/nordic/nrf51xxx/pkg.yml b/hw/mcu/nordic/nrf51xxx/pkg.yml index 9c77756bae..ca001456dd 100644 --- a/hw/mcu/nordic/nrf51xxx/pkg.yml +++ b/hw/mcu/nordic/nrf51xxx/pkg.yml @@ -27,8 +27,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - - "@apache-mynewt-core/hw/cmsis-core" - - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" pkg.ign_files.'!MCU_COMMON_STARTUP || SPLIT_LOADER': - gcc_startup_cm0.s diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c b/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c deleted file mode 100644 index 29edbc90ff..0000000000 --- a/hw/mcu/nordic/nrf51xxx/src/hal_gpio.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 "hal/hal_gpio.h" -#include "mcu/cmsis_nvic.h" -#include "nrf51.h" -#include "nrf51_bitfields.h" -#include - -/* XXX: - * 1) The code probably does not handle "re-purposing" gpio very well. - * "Re-purposing" means changing a gpio from input to output, or calling - * gpio_init_in and expecting previously enabled interrupts to be stopped. - * - */ - -/* GPIO pin mapping */ -#define HAL_GPIO_MASK(pin) (1 << pin) - -/* GPIO interrupts */ -#define HAL_GPIO_MAX_IRQ (4) - -/* Storage for GPIO callbacks. */ -struct hal_gpio_irq { - hal_gpio_irq_handler_t func; - void *arg; -}; - -static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; - -/** - * gpio init in - * - * Initializes the specified pin as an input - * - * @param pin Pin number to set as input - * @param pull pull type - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_in(int pin, hal_gpio_pull_t pull) -{ - uint32_t conf; - - switch (pull) { - case HAL_GPIO_PULL_UP: - conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_DOWN: - conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_NONE: - default: - conf = 0; - break; - } - - NRF_GPIO->PIN_CNF[pin] = conf; - NRF_GPIO->DIRCLR = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * gpio init out - * - * Initialize the specified pin as an output, setting the pin to the specified - * value. - * - * @param pin Pin number to set as output - * @param val Value to set pin - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_out(int pin, int val) -{ - if (val) { - NRF_GPIO->OUTSET = HAL_GPIO_MASK(pin); - } else { - NRF_GPIO->OUTCLR = HAL_GPIO_MASK(pin); - } - NRF_GPIO->PIN_CNF[pin] = GPIO_PIN_CNF_DIR_Output | - (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); - NRF_GPIO->DIRSET = HAL_GPIO_MASK(pin); - return 0; -} - -/** - * Deinitialize the specified pin to revert to default configuration - * - * @param pin Pin number to unset - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_deinit(int pin) -{ - NRF_GPIO->PIN_CNF[pin] = GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos; - return 0; -} - -/** - * gpio write - * - * Write a value (either high or low) to the specified pin. - * - * @param pin Pin to set - * @param val Value to set pin (0:low 1:high) - */ -void -hal_gpio_write(int pin, int val) -{ - if (val) { - NRF_GPIO->OUTSET = HAL_GPIO_MASK(pin); - } else { - NRF_GPIO->OUTCLR = HAL_GPIO_MASK(pin); - } -} - -/** - * gpio read - * - * Reads the specified pin. - * - * @param pin Pin number to read - * - * @return int 0: low, 1: high - */ -int -hal_gpio_read(int pin) -{ - return ((NRF_GPIO->IN & HAL_GPIO_MASK(pin)) != 0); -} - -/** - * gpio toggle - * - * Toggles the specified pin - * - * @param pin Pin number to toggle - * - * @return current pin state int 0: low, 1: high - */ -int -hal_gpio_toggle(int pin) -{ - int pin_state = (hal_gpio_read(pin) == 0); - hal_gpio_write(pin, pin_state); - return pin_state; -} - -/* - * GPIO irq handler - * - * Handles the gpio interrupt attached to a gpio pin. - * - * @param index - */ -static void -hal_gpio_irq_handler(void) -{ - int i; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (NRF_GPIOTE->EVENTS_IN[i] && (NRF_GPIOTE->INTENSET & (1 << i))) { - NRF_GPIOTE->EVENTS_IN[i] = 0; - if (hal_gpio_irqs[i].func) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } - } - } -} - -/* - * Register IRQ handler for GPIOTE, and enable it. - */ -static void -hal_gpio_irq_setup(void) -{ - NVIC_SetVector(GPIOTE_IRQn, (uint32_t)hal_gpio_irq_handler); - NVIC_EnableIRQ(GPIOTE_IRQn); -} - -/* - * Find out whether we have an GPIOTE pin event to use. - */ -static int -hal_gpio_find_empty_slot(void) -{ - int i; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func == NULL) { - return i; - } - } - return -1; -} - -/* - * Find the GPIOTE event which handles this pin. - */ -static int -hal_gpio_find_pin(int pin) -{ - int i; - - pin = pin << GPIOTE_CONFIG_PSEL_Pos; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && - (NRF_GPIOTE->CONFIG[i] & GPIOTE_CONFIG_PSEL_Msk) == pin) { - return i; - } - } - return -1; -} - -/** - * gpio irq init - * - * Initialize an external interrupt on a gpio pin - * - * @param pin Pin number to enable gpio. - * @param handler Interrupt handler - * @param arg Argument to pass to interrupt handler - * @param trig Trigger mode of interrupt - * @param pull Push/pull mode of input. - * - * @return int - */ -int -hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, - hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) -{ - uint32_t conf; - int i; - - hal_gpio_irq_setup(); - i = hal_gpio_find_empty_slot(); - if (i < 0) { - return -1; - } - hal_gpio_init_in(pin, pull); - - switch (trig) { - case HAL_GPIO_TRIG_RISING: - conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_FALLING: - conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_BOTH: - conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos; - break; - default: - return -1; - } - conf |= pin << GPIOTE_CONFIG_PSEL_Pos; - conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos; - - NRF_GPIOTE->CONFIG[i] = conf; - - hal_gpio_irqs[i].func = handler; - hal_gpio_irqs[i].arg = arg; - - return 0; -} - -/** - * gpio irq release - * - * No longer interrupt when something occurs on the pin. NOTE: this function - * does not change the GPIO push/pull setting. - * It also does not disable the NVIC interrupt enable setting for the irq. - * - * @param pin - */ -void -hal_gpio_irq_release(int pin) -{ - int i; - - i = hal_gpio_find_pin(pin); - if (i < 0) { - return; - } - hal_gpio_irq_disable(pin); - - NRF_GPIOTE->CONFIG[i] = 0; - NRF_GPIOTE->EVENTS_IN[i] = 0; - - hal_gpio_irqs[i].arg = NULL; - hal_gpio_irqs[i].func = NULL; -} - -/** - * gpio irq enable - * - * Enable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_enable(int pin) -{ - int i; - - i = hal_gpio_find_pin(pin); - if (i < 0) { - return; - } - NRF_GPIOTE->EVENTS_IN[i] = 0; - NRF_GPIOTE->INTENSET = 1 << i; -} - -/** - * gpio irq disable - * - * - * @param pin - */ -void -hal_gpio_irq_disable(int pin) -{ - int i; - - i = hal_gpio_find_pin(pin); - if (i < 0) { - return; - } - NRF_GPIOTE->INTENCLR = 1 << i; -} diff --git a/hw/mcu/nordic/nrf52xxx/pkg.yml b/hw/mcu/nordic/nrf52xxx/pkg.yml index 5d6f95f1ab..cbe050d81f 100644 --- a/hw/mcu/nordic/nrf52xxx/pkg.yml +++ b/hw/mcu/nordic/nrf52xxx/pkg.yml @@ -27,8 +27,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - - "@apache-mynewt-core/hw/cmsis-core" - - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" pkg.ign_files.'!MCU_COMMON_STARTUP || SPLIT_LOADER': - gcc_startup_cm4.s diff --git a/hw/mcu/nordic/nrf5340/pkg.yml b/hw/mcu/nordic/nrf5340/pkg.yml index a725de27fd..ddc93e25a7 100644 --- a/hw/mcu/nordic/nrf5340/pkg.yml +++ b/hw/mcu/nordic/nrf5340/pkg.yml @@ -27,8 +27,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - - "@apache-mynewt-core/hw/cmsis-core" - - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" - "@apache-mynewt-core/hw/mcu/nordic/nrf5340/tfm" pkg.deps.BUS_DRIVER_PRESENT: diff --git a/hw/mcu/nordic/nrf5340/src/hal_gpio.c b/hw/mcu/nordic/nrf5340/src/hal_gpio.c deleted file mode 100644 index 8d3a4db78c..0000000000 --- a/hw/mcu/nordic/nrf5340/src/hal_gpio.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 -#include -#include -#include -#include -#include -#include - -/* XXX: - * 1) The code probably does not handle "re-purposing" gpio very well. - * "Re-purposing" means changing a gpio from input to output, or calling - * gpio_init_in and expecting previously enabled interrupts to be stopped. - * - */ - -/* GPIO interrupts */ -#define HAL_GPIO_MAX_IRQ 8 - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) -#define HAL_GPIO_SENSE_TRIG_NONE 0x00 /* just 0 */ -#define HAL_GPIO_SENSE_TRIG_BOTH 0x01 /* something else than both below */ -#define HAL_GPIO_SENSE_TRIG_HIGH 0x02 /* GPIO_PIN_CNF_SENSE_High */ -#define HAL_GPIO_SENSE_TRIG_LOW 0x03 /* GPIO_PIN_CNF_SENSE_Low */ -#endif - -/* Storage for GPIO callbacks. */ -struct hal_gpio_irq { - hal_gpio_irq_handler_t func; - void *arg; -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - int pin; - uint8_t sense_trig; -#endif -}; - -static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; - -/** - * Initializes the specified pin as an input - * - * @param pin Pin number to set as input - * @param pull pull type - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_in(int pin, hal_gpio_pull_t pull) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - switch (pull) { - case HAL_GPIO_PULL_UP: - conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_DOWN: - conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_NONE: - default: - conf = 0; - break; - } - - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - port->DIRCLR = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * Initialize the specified pin as an output, setting the pin to the specified - * value. - * - * @param pin Pin number to set as output - * @param val Value to set pin - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_out(int pin, int val) -{ - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } - port->PIN_CNF[pin_index] = GPIO_PIN_CNF_DIR_Output | - (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); - port->DIRSET = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * Deinitialize the specified pin to revert to default configuration - * - * @param pin Pin number to unset - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_deinit(int pin) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - conf = GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos; - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - - return 0; -} - -/** - * Write a value (either high or low) to the specified pin. - * - * @param pin Pin to set - * @param val Value to set pin (0:low 1:high) - */ -void -hal_gpio_write(int pin, int val) -{ - NRF_GPIO_Type *port; - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } -} - -/** - * Reads the specified pin. - * - * @param pin Pin number to read - * - * @return int 0: low, 1: high - */ -int -hal_gpio_read(int pin) -{ - NRF_GPIO_Type *port; - port = HAL_GPIO_PORT(pin); - - return (port->DIR & HAL_GPIO_MASK(pin)) ? - (port->OUT >> HAL_GPIO_INDEX(pin)) & 1UL : - (port->IN >> HAL_GPIO_INDEX(pin)) & 1UL; -} - -/** - * Toggles the specified pin - * - * @param pin Pin number to toggle - * - * @return current pin state int 0: low, 1: high - */ -int -hal_gpio_toggle(int pin) -{ - int pin_state = (hal_gpio_read(pin) == 0); - - hal_gpio_write(pin, pin_state); - - return pin_state; -} - -/** - * Handles the gpio interrupt attached to a gpio pin. - */ -static void -hal_gpio_irq_handler(void) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - int pin_state; - uint8_t sense_trig; - uint64_t gpio_state; -#endif - int i; - - os_trace_isr_enter(); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE0_S->EVENTS_PORT = 0; - - gpio_state = NRF_P0_S->IN; - gpio_state |= (uint64_t)NRF_P1_S->IN << 32; -#endif - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - if ((!hal_gpio_irqs[i].func) || - (hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_NONE)) { - continue; - } - - nrf_gpio = HAL_GPIO_PORT(hal_gpio_irqs[i].pin); - pin_index = HAL_GPIO_INDEX(hal_gpio_irqs[i].pin); - - /* Store current SENSE setting */ - sense_trig = (nrf_gpio->PIN_CNF[pin_index] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos; - - if (!sense_trig) { - continue; - } - - /* - * SENSE values are 0x02 for high and 0x03 for low, so bit #0 is the - * opposite of state which triggers interrupt (thus its value should be - * different than pin state). - */ - pin_state = (gpio_state >> hal_gpio_irqs[i].pin) & 0x01; - if (pin_state == (sense_trig & 0x01)) { - continue; - } - - /* - * Toggle sense to clear interrupt or allow detection of opposite edge - * when trigger on both edges is requested. - */ - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - if (sense_trig == HAL_GPIO_SENSE_TRIG_HIGH) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - /* - * Call handler in case SENSE configuration matches requested one or - * trigger on both edges is requested. - */ - if ((hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_BOTH) || - (hal_gpio_irqs[i].sense_trig == sense_trig)) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } -#else - if (NRF_GPIOTE0_S->EVENTS_IN[i] && (NRF_GPIOTE0_S->INTENSET & (1 << i))) { - NRF_GPIOTE0_S->EVENTS_IN[i] = 0; - if (hal_gpio_irqs[i].func) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } - } -#endif - } - - os_trace_isr_exit(); -} - -/* - * Register IRQ handler for GPIOTE, and enable it. - * Only executed once, during first registration. - */ -static void -hal_gpio_irq_setup(void) -{ - static uint8_t irq_setup = 0; - - if (!irq_setup) { - NVIC_SetVector(GPIOTE0_IRQn, (uint32_t)hal_gpio_irq_handler); - NVIC_EnableIRQ(GPIOTE0_IRQn); - irq_setup = 1; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE0_S->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - NRF_GPIOTE0_S->EVENTS_PORT = 0; -#endif - } -} - -/* - * Find out whether we have an GPIOTE pin event to use. - */ -static int -hal_gpio_find_empty_slot(void) -{ - int i; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func == NULL) { - return i; - } - } - return -1; -} - -/* - * Find the GPIOTE event which handles this pin. - */ -static int -hal_gpio_find_pin(int pin) -{ - int i; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && hal_gpio_irqs[i].pin == pin) { - return i; - } - } -#else - pin = pin << GPIOTE_CONFIG_PSEL_Pos; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && - (NRF_GPIOTE0_S->CONFIG[i] & HAL_GPIOTE_PIN_MASK) == pin) { - return i; - } - } -#endif - - return -1; -} - -/** - * Initialize an external interrupt on a gpio pin - * - * @param pin Pin number to enable gpio. - * @param handler Interrupt handler - * @param arg Argument to pass to interrupt handler - * @param trig Trigger mode of interrupt - * @param pull Push/pull mode of input. - * - * @return int - */ -int -hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, - hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) -{ - uint32_t conf; - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - hal_gpio_irq_setup(); - i = hal_gpio_find_empty_slot(); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - hal_gpio_init_in(pin, pull); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - (void)conf; - hal_gpio_irqs[i].pin = pin; - - switch (trig) { - case HAL_GPIO_TRIG_RISING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_HIGH; - break; - case HAL_GPIO_TRIG_FALLING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_LOW; - break; - case HAL_GPIO_TRIG_BOTH: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_BOTH; - break; - default: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } -#else - switch (trig) { - case HAL_GPIO_TRIG_RISING: - conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_FALLING: - conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_BOTH: - conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos; - break; - default: - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - - conf |= pin << GPIOTE_CONFIG_PSEL_Pos; - conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos; - - NRF_GPIOTE0_S->CONFIG[i] = conf; -#endif - - hal_gpio_irqs[i].func = handler; - hal_gpio_irqs[i].arg = arg; - - __HAL_ENABLE_INTERRUPTS(sr); - - return 0; -} - -/** - * No longer interrupt when something occurs on the pin. NOTE: this function - * does not change the GPIO push/pull setting. - * It also does not disable the NVIC interrupt enable setting for the irq. - * - * @param pin - */ -void -hal_gpio_irq_release(int pin) -{ - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - hal_gpio_irq_disable(pin); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; -#else - NRF_GPIOTE0_S->CONFIG[i] = 0; - NRF_GPIOTE0_S->EVENTS_IN[i] = 0; -#endif - - hal_gpio_irqs[i].arg = NULL; - hal_gpio_irqs[i].func = NULL; - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * Enable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_enable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - /* - * Always set initial SENSE to opposite of current pin state to avoid - * triggering immediately - */ - if (nrf_gpio->IN & (1 << pin_index)) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - NRF_GPIOTE0_S->INTENSET = GPIOTE_INTENSET_PORT_Msk; -#else - NRF_GPIOTE0_S->EVENTS_IN[i] = 0; - NRF_GPIOTE0_S->INTENSET = 1 << i; -#endif - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * Disable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_disable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - bool sense_enabled = false; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].sense_trig != HAL_GPIO_SENSE_TRIG_NONE) { - sense_enabled = true; - break; - } - } - - if (!sense_enabled) { - NRF_GPIOTE0_S->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - } -#else - NRF_GPIOTE0_S->INTENCLR = 1 << i; -#endif - __HAL_ENABLE_INTERRUPTS(sr); -} diff --git a/hw/mcu/nordic/nrf5340_net/pkg.yml b/hw/mcu/nordic/nrf5340_net/pkg.yml index d954597dd3..83146c6566 100644 --- a/hw/mcu/nordic/nrf5340_net/pkg.yml +++ b/hw/mcu/nordic/nrf5340_net/pkg.yml @@ -27,8 +27,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - - "@apache-mynewt-core/hw/cmsis-core" - - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" - "@apache-mynewt-core/hw/drivers/ipc_nrf5340" pkg.cflags.NFC_PINS_AS_GPIO: diff --git a/hw/mcu/nordic/nrf5340_net/src/hal_gpio.c b/hw/mcu/nordic/nrf5340_net/src/hal_gpio.c deleted file mode 100644 index 5a230b5bad..0000000000 --- a/hw/mcu/nordic/nrf5340_net/src/hal_gpio.c +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 -#include -#include -#include -#include -#include -#include - -/* XXX: - * 1) The code probably does not handle "re-purposing" gpio very well. - * "Re-purposing" means changing a gpio from input to output, or calling - * gpio_init_in and expecting previously enabled interrupts to be stopped. - * - */ - -/* GPIO interrupts */ -#define HAL_GPIO_MAX_IRQ 8 - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) -#define HAL_GPIO_SENSE_TRIG_NONE 0x00 /* just 0 */ -#define HAL_GPIO_SENSE_TRIG_BOTH 0x01 /* something else than both below */ -#define HAL_GPIO_SENSE_TRIG_HIGH 0x02 /* GPIO_PIN_CNF_SENSE_High */ -#define HAL_GPIO_SENSE_TRIG_LOW 0x03 /* GPIO_PIN_CNF_SENSE_Low */ -#endif - -/* Storage for GPIO callbacks. */ -struct hal_gpio_irq { - hal_gpio_irq_handler_t func; - void *arg; -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - int pin; - uint8_t sense_trig; -#endif -}; - -static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; - -/** - * Initializes the specified pin as an input - * - * @param pin Pin number to set as input - * @param pull pull type - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_in(int pin, hal_gpio_pull_t pull) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - switch (pull) { - case HAL_GPIO_PULL_UP: - conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_DOWN: - conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_NONE: - default: - conf = 0; - break; - } - - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - port->DIRCLR = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * Initialize the specified pin as an output, setting the pin to the specified - * value. - * - * @param pin Pin number to set as output - * @param val Value to set pin - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_out(int pin, int val) -{ - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } - port->PIN_CNF[pin_index] = GPIO_PIN_CNF_DIR_Output | - (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); - port->DIRSET = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * Deinitialize the specified pin to revert to default configuration - * - * @param pin Pin number to unset - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_deinit(int pin) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - conf = GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos; - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - - return 0; -} - -/** - * Write a value (either high or low) to the specified pin. - * - * @param pin Pin to set - * @param val Value to set pin (0:low 1:high) - */ -void -hal_gpio_write(int pin, int val) -{ - NRF_GPIO_Type *port; - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } -} - -/** - * Reads the specified pin. - * - * @param pin Pin number to read - * - * @return int 0: low, 1: high - */ -int -hal_gpio_read(int pin) -{ - NRF_GPIO_Type *port; - port = HAL_GPIO_PORT(pin); - - return (port->DIR & HAL_GPIO_MASK(pin)) ? - (port->OUT >> HAL_GPIO_INDEX(pin)) & 1UL : - (port->IN >> HAL_GPIO_INDEX(pin)) & 1UL; -} - -/** - * Toggles the specified pin - * - * @param pin Pin number to toggle - * - * @return current pin state int 0: low, 1: high - */ -int -hal_gpio_toggle(int pin) -{ - int pin_state = (hal_gpio_read(pin) == 0); - - hal_gpio_write(pin, pin_state); - - return pin_state; -} - -/** - * Handles the gpio interrupt attached to a gpio pin. - */ -static void -hal_gpio_irq_handler(void) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - int pin_state; - uint8_t sense_trig; - uint64_t gpio_state; -#endif - int i; - - os_trace_isr_enter(); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE_NS->EVENTS_PORT = 0; - - gpio_state = NRF_P0_NS->IN; - gpio_state |= (uint64_t)NRF_P1_NS->IN << 32; -#endif - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - if ((!hal_gpio_irqs[i].func) || - (hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_NONE)) { - continue; - } - - nrf_gpio = HAL_GPIO_PORT(hal_gpio_irqs[i].pin); - pin_index = HAL_GPIO_INDEX(hal_gpio_irqs[i].pin); - - /* Store current SENSE setting */ - sense_trig = (nrf_gpio->PIN_CNF[pin_index] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos; - - if (!sense_trig) { - continue; - } - - /* - * SENSE values are 0x02 for high and 0x03 for low, so bit #0 is the - * opposite of state which triggers interrupt (thus its value should be - * different than pin state). - */ - pin_state = (gpio_state >> hal_gpio_irqs[i].pin) & 0x01; - if (pin_state == (sense_trig & 0x01)) { - continue; - } - - /* - * Toggle sense to clear interrupt or allow detection of opposite edge - * when trigger on both edges is requested. - */ - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - if (sense_trig == HAL_GPIO_SENSE_TRIG_HIGH) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - /* - * Call handler in case SENSE configuration matches requested one or - * trigger on both edges is requested. - */ - if ((hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_BOTH) || - (hal_gpio_irqs[i].sense_trig == sense_trig)) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } -#else - if (NRF_GPIOTE_NS->EVENTS_IN[i] && (NRF_GPIOTE_NS->INTENSET & (1 << i))) { - NRF_GPIOTE_NS->EVENTS_IN[i] = 0; - if (hal_gpio_irqs[i].func) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } - } -#endif - } - - os_trace_isr_exit(); -} - -/* - * Register IRQ handler for GPIOTE, and enable it. - * Only executed once, during first registration. - */ -static void -hal_gpio_irq_setup(void) -{ - static uint8_t irq_setup = 0; - - if (!irq_setup) { - NVIC_SetVector(GPIOTE_IRQn, (uint32_t)hal_gpio_irq_handler); - NVIC_EnableIRQ(GPIOTE_IRQn); - irq_setup = 1; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE_NS->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - NRF_GPIOTE_NS->EVENTS_PORT = 0; -#endif - } -} - -/* - * Find out whether we have an GPIOTE pin event to use. - */ -static int -hal_gpio_find_empty_slot(void) -{ - int i; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func == NULL) { - return i; - } - } - return -1; -} - -/* - * Find the GPIOTE event which handles this pin. - */ -static int -hal_gpio_find_pin(int pin) -{ - int i; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && hal_gpio_irqs[i].pin == pin) { - return i; - } - } -#else - pin = pin << GPIOTE_CONFIG_PSEL_Pos; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && - (NRF_GPIOTE_NS->CONFIG[i] & HAL_GPIOTE_PIN_MASK) == pin) { - return i; - } - } -#endif - - return -1; -} - -/** - * Initialize an external interrupt on a gpio pin - * - * @param pin Pin number to enable gpio. - * @param handler Interrupt handler - * @param arg Argument to pass to interrupt handler - * @param trig Trigger mode of interrupt - * @param pull Push/pull mode of input. - * - * @return int - */ -int -hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, - hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) -{ - uint32_t conf; - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - hal_gpio_irq_setup(); - i = hal_gpio_find_empty_slot(); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - hal_gpio_init_in(pin, pull); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - (void)conf; - hal_gpio_irqs[i].pin = pin; - - switch (trig) { - case HAL_GPIO_TRIG_RISING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_HIGH; - break; - case HAL_GPIO_TRIG_FALLING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_LOW; - break; - case HAL_GPIO_TRIG_BOTH: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_BOTH; - break; - default: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } -#else - switch (trig) { - case HAL_GPIO_TRIG_RISING: - conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_FALLING: - conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_BOTH: - conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos; - break; - default: - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - - conf |= pin << GPIOTE_CONFIG_PSEL_Pos; - conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos; - - NRF_GPIOTE_NS->CONFIG[i] = conf; -#endif - - hal_gpio_irqs[i].func = handler; - hal_gpio_irqs[i].arg = arg; - - __HAL_ENABLE_INTERRUPTS(sr); - - return 0; -} - -/** - * No longer interrupt when something occurs on the pin. NOTE: this function - * does not change the GPIO push/pull setting. - * It also does not disable the NVIC interrupt enable setting for the irq. - * - * @param pin - */ -void -hal_gpio_irq_release(int pin) -{ - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - hal_gpio_irq_disable(pin); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; -#else - NRF_GPIOTE_NS->CONFIG[i] = 0; - NRF_GPIOTE_NS->EVENTS_IN[i] = 0; -#endif - - hal_gpio_irqs[i].arg = NULL; - hal_gpio_irqs[i].func = NULL; - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * Enable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_enable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - /* - * Always set initial SENSE to opposite of current pin state to avoid - * triggering immediately - */ - if (nrf_gpio->IN & (1 << pin_index)) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - NRF_GPIOTE_NS->INTENSET = GPIOTE_INTENSET_PORT_Msk; -#else - NRF_GPIOTE_NS->EVENTS_IN[i] = 0; - NRF_GPIOTE_NS->INTENSET = 1 << i; -#endif - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * Disable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_disable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - bool sense_enabled = false; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].sense_trig != HAL_GPIO_SENSE_TRIG_NONE) { - sense_enabled = true; - break; - } - } - - if (!sense_enabled) { - NRF_GPIOTE_NS->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - } -#else - NRF_GPIOTE_NS->INTENCLR = 1 << i; -#endif - __HAL_ENABLE_INTERRUPTS(sr); -} diff --git a/hw/mcu/nordic/nrf91xx/pkg.yml b/hw/mcu/nordic/nrf91xx/pkg.yml index 4acea0ec33..dedc5251e6 100644 --- a/hw/mcu/nordic/nrf91xx/pkg.yml +++ b/hw/mcu/nordic/nrf91xx/pkg.yml @@ -27,8 +27,7 @@ pkg.keywords: pkg.deps: - "@apache-mynewt-core/hw/mcu/nordic" - - "@apache-mynewt-core/hw/cmsis-core" - - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/mcu/nordic/nrf_common" pkg.deps.BUS_DRIVER_PRESENT: - "@apache-mynewt-core/hw/bus/drivers/i2c_hal" diff --git a/hw/mcu/nordic/nrf91xx/src/hal_gpio.c b/hw/mcu/nordic/nrf91xx/src/hal_gpio.c deleted file mode 100644 index e1e1674abc..0000000000 --- a/hw/mcu/nordic/nrf91xx/src/hal_gpio.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 -#include -#include "os/mynewt.h" -#include "hal/hal_gpio.h" -#include "mcu/cmsis_nvic.h" -#include "nrf.h" -#include "mcu/nrf91_hal.h" -#include "nrfx_config.h" - -/* XXX: - * 1) The code probably does not handle "re-purposing" gpio very well. - * "Re-purposing" means changing a gpio from input to output, or calling - * gpio_init_in and expecting previously enabled interrupts to be stopped. - * - */ - -/* GPIO interrupts */ -#define HAL_GPIO_MAX_IRQ 8 - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) -#define HAL_GPIO_SENSE_TRIG_NONE 0x00 /* just 0 */ -#define HAL_GPIO_SENSE_TRIG_BOTH 0x01 /* something else than both below */ -#define HAL_GPIO_SENSE_TRIG_HIGH 0x02 /* GPIO_PIN_CNF_SENSE_High */ -#define HAL_GPIO_SENSE_TRIG_LOW 0x03 /* GPIO_PIN_CNF_SENSE_Low */ -#endif - -/* Storage for GPIO callbacks. */ -struct hal_gpio_irq { - hal_gpio_irq_handler_t func; - void *arg; -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - int pin; - uint8_t sense_trig; -#endif -}; - -static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; - -/** - * gpio init in - * - * Initializes the specified pin as an input - * - * @param pin Pin number to set as input - * @param pull pull type - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_in(int pin, hal_gpio_pull_t pull) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - switch (pull) { - case HAL_GPIO_PULL_UP: - conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_DOWN: - conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; - break; - case HAL_GPIO_PULL_NONE: - default: - conf = 0; - break; - } - - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - port->DIRCLR = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * gpio init out - * - * Initialize the specified pin as an output, setting the pin to the specified - * value. - * - * @param pin Pin number to set as output - * @param val Value to set pin - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_init_out(int pin, int val) -{ - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } - port->PIN_CNF[pin_index] = GPIO_PIN_CNF_DIR_Output | - (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); - port->DIRSET = HAL_GPIO_MASK(pin); - - return 0; -} - -/** - * Deinitialize the specified pin to revert to default configuration - * - * @param pin Pin number to unset - * - * @return int 0: no error; -1 otherwise. - */ -int -hal_gpio_deinit(int pin) -{ - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - conf = GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos; - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - - return 0; -} - -/** - * gpio write - * - * Write a value (either high or low) to the specified pin. - * - * @param pin Pin to set - * @param val Value to set pin (0:low 1:high) - */ -void -hal_gpio_write(int pin, int val) -{ - NRF_GPIO_Type *port; - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } -} - -/** - * gpio read - * - * Reads the specified pin. - * - * @param pin Pin number to read - * - * @return int 0: low, 1: high - */ -int -hal_gpio_read(int pin) -{ - NRF_GPIO_Type *port; - port = HAL_GPIO_PORT(pin); - - return (port->DIR & HAL_GPIO_MASK(pin)) ? - (port->OUT >> HAL_GPIO_INDEX(pin)) & 1UL : - (port->IN >> HAL_GPIO_INDEX(pin)) & 1UL; -} - -/** - * gpio toggle - * - * Toggles the specified pin - * - * @param pin Pin number to toggle - * - * @return current pin state int 0: low, 1: high - */ -int -hal_gpio_toggle(int pin) -{ - int pin_state = (hal_gpio_read(pin) == 0); - hal_gpio_write(pin, pin_state); - return pin_state; -} - -/* - * GPIO irq handler - * - * Handles the gpio interrupt attached to a gpio pin. - * - * @param index - */ -static void -hal_gpio_irq_handler(void) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - int pin_state; - uint8_t sense_trig; - uint32_t gpio_state; -#endif - int i; - - os_trace_isr_enter(); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE0->EVENTS_PORT = 0; - gpio_state = NRF_P0->IN; -#endif - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - if ((!hal_gpio_irqs[i].func) || - (hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_NONE)) { - continue; - } - - nrf_gpio = HAL_GPIO_PORT(hal_gpio_irqs[i].pin); - pin_index = HAL_GPIO_INDEX(hal_gpio_irqs[i].pin); - - /* Store current SENSE setting */ - sense_trig = (nrf_gpio->PIN_CNF[pin_index] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos; - - if (!sense_trig) { - continue; - } - - /* - * SENSE values are 0x02 for high and 0x03 for low, so bit #0 is the - * opposite of state which triggers interrupt (thus its value should be - * different than pin state). - */ - pin_state = (gpio_state >> hal_gpio_irqs[i].pin) & 0x01; - if (pin_state == (sense_trig & 0x01)) { - continue; - } - - /* - * Toggle sense to clear interrupt or allow detection of opposite edge - * when trigger on both edges is requested. - */ - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - if (sense_trig == HAL_GPIO_SENSE_TRIG_HIGH) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - /* - * Call handler in case SENSE configuration matches requested one or - * trigger on both edges is requested. - */ - if ((hal_gpio_irqs[i].sense_trig == HAL_GPIO_SENSE_TRIG_BOTH) || - (hal_gpio_irqs[i].sense_trig == sense_trig)) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } -#else - if (NRF_GPIOTE0->EVENTS_IN[i] && (NRF_GPIOTE0->INTENSET & (1 << i))) { - NRF_GPIOTE0->EVENTS_IN[i] = 0; - if (hal_gpio_irqs[i].func) { - hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); - } - } -#endif - } - - os_trace_isr_exit(); -} - -/* - * Register IRQ handler for GPIOTE, and enable it. - * Only executed once, during first registration. - */ -static void -hal_gpio_irq_setup(void) -{ - static uint8_t irq_setup = 0; - - if (!irq_setup) { - NVIC_SetVector(GPIOTE1_IRQn, (uint32_t)hal_gpio_irq_handler); - NVIC_EnableIRQ(GPIOTE1_IRQn); - irq_setup = 1; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE0->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - NRF_GPIOTE0->EVENTS_PORT = 0; -#endif - } -} - -/* - * Find out whether we have an GPIOTE pin event to use. - */ -static int -hal_gpio_find_empty_slot(void) -{ - int i; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func == NULL) { - return i; - } - } - return -1; -} - -/* - * Find the GPIOTE event which handles this pin. - */ -static int -hal_gpio_find_pin(int pin) -{ - int i; - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && hal_gpio_irqs[i].pin == pin) { - return i; - } - } -#else - pin = pin << GPIOTE_CONFIG_PSEL_Pos; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].func && - (NRF_GPIOTE0->CONFIG[i] & HAL_GPIOTE_PIN_MASK) == pin) { - return i; - } - } -#endif - - return -1; -} - -/** - * gpio irq init - * - * Initialize an external interrupt on a gpio pin - * - * @param pin Pin number to enable gpio. - * @param handler Interrupt handler - * @param arg Argument to pass to interrupt handler - * @param trig Trigger mode of interrupt - * @param pull Push/pull mode of input. - * - * @return int - */ -int -hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, - hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) -{ - uint32_t conf; - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - hal_gpio_irq_setup(); - i = hal_gpio_find_empty_slot(); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - hal_gpio_init_in(pin, pull); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - (void)conf; - hal_gpio_irqs[i].pin = pin; - - switch (trig) { - case HAL_GPIO_TRIG_RISING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_HIGH; - break; - case HAL_GPIO_TRIG_FALLING: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_LOW; - break; - case HAL_GPIO_TRIG_BOTH: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_BOTH; - break; - default: - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } -#else - switch (trig) { - case HAL_GPIO_TRIG_RISING: - conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_FALLING: - conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; - break; - case HAL_GPIO_TRIG_BOTH: - conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos; - break; - default: - __HAL_ENABLE_INTERRUPTS(sr); - return -1; - } - - conf |= pin << GPIOTE_CONFIG_PSEL_Pos; - conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos; - - NRF_GPIOTE0->CONFIG[i] = conf; -#endif - - hal_gpio_irqs[i].func = handler; - hal_gpio_irqs[i].arg = arg; - - __HAL_ENABLE_INTERRUPTS(sr); - - return 0; -} - -/** - * gpio irq release - * - * No longer interrupt when something occurs on the pin. NOTE: this function - * does not change the GPIO push/pull setting. - * It also does not disable the NVIC interrupt enable setting for the irq. - * - * @param pin - */ -void -hal_gpio_irq_release(int pin) -{ - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - hal_gpio_irq_disable(pin); - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; -#else - NRF_GPIOTE0->CONFIG[i] = 0; - NRF_GPIOTE0->EVENTS_IN[i] = 0; -#endif - - hal_gpio_irqs[i].arg = NULL; - hal_gpio_irqs[i].func = NULL; - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * gpio irq enable - * - * Enable the irq on the specified pin - * - * @param pin - */ -void -hal_gpio_irq_enable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - /* - * Always set initial SENSE to opposite of current pin state to avoid - * triggering immediately - */ - if (nrf_gpio->IN & (1 << pin_index)) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; - } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; - } - - NRF_GPIOTE0->INTENSET = GPIOTE_INTENSET_PORT_Msk; -#else - NRF_GPIOTE0->EVENTS_IN[i] = 0; - NRF_GPIOTE0->INTENSET = 1 << i; -#endif - - __HAL_ENABLE_INTERRUPTS(sr); -} - -/** - * gpio irq disable - * - * - * @param pin - */ -void -hal_gpio_irq_disable(int pin) -{ -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - bool sense_enabled = false; -#endif - int i, sr; - - __HAL_DISABLE_INTERRUPTS(sr); - - i = hal_gpio_find_pin(pin); - if (i < 0) { - __HAL_ENABLE_INTERRUPTS(sr); - return; - } - -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { - if (hal_gpio_irqs[i].sense_trig != HAL_GPIO_SENSE_TRIG_NONE) { - sense_enabled = true; - break; - } - } - - if (!sense_enabled) { - NRF_GPIOTE0->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - } -#else - NRF_GPIOTE0->INTENCLR = 1 << i; -#endif - __HAL_ENABLE_INTERRUPTS(sr); -} diff --git a/hw/mcu/nordic/nrf_common/include/nrf_hal.h b/hw/mcu/nordic/nrf_common/include/nrf_hal.h new file mode 100644 index 0000000000..f69816efec --- /dev/null +++ b/hw/mcu/nordic/nrf_common/include/nrf_hal.h @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +#ifndef H_NRF52_HAL_ +#define H_NRF52_HAL_ + +#ifdef __cplusplus + extern "C" { +#endif + +/* Helper functions to enable/disable interrupts. */ +#define __HAL_DISABLE_INTERRUPTS(x) \ + do { \ + x = __get_PRIMASK(); \ + __disable_irq(); \ + } while(0); + +#define __HAL_ENABLE_INTERRUPTS(x) \ + do { \ + if (!x) { \ + __enable_irq(); \ + } \ + } while(0); + +#ifdef __cplusplus +} +#endif + +#endif /* H_NRF52_HAL_ */ + diff --git a/hw/mcu/nordic/nrf_common/pkg.yml b/hw/mcu/nordic/nrf_common/pkg.yml new file mode 100644 index 0000000000..54511733d9 --- /dev/null +++ b/hw/mcu/nordic/nrf_common/pkg.yml @@ -0,0 +1,33 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you 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. +# + +pkg.name: hw/mcu/nordic/nrf_common +pkg.description: NRF5x and NRF91 series chips shared drivers +pkg.author: "Apache Mynewt " +pkg.homepage: "http://mynewt.apache.org/" +pkg.keywords: + - nrf53 + - nrf52 + - nrf51 + - nrf91 + - hal + +pkg.deps: + - "@apache-mynewt-core/hw/hal" + - "@apache-mynewt-core/hw/cmsis-core" diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c b/hw/mcu/nordic/nrf_common/src/hal_gpio.c similarity index 66% rename from hw/mcu/nordic/nrf52xxx/src/hal_gpio.c rename to hw/mcu/nordic/nrf_common/src/hal_gpio.c index 244866fa66..6edd378f70 100644 --- a/hw/mcu/nordic/nrf52xxx/src/hal_gpio.c +++ b/hw/mcu/nordic/nrf_common/src/hal_gpio.c @@ -18,22 +18,15 @@ */ #include -#include #include "os/mynewt.h" #include "hal/hal_gpio.h" -#include "mcu/cmsis_nvic.h" #include "nrf.h" -#include "mcu/nrf52_hal.h" - -/* XXX: - * 1) The code probably does not handle "re-purposing" gpio very well. - * "Re-purposing" means changing a gpio from input to output, or calling - * gpio_init_in and expecting previously enabled interrupts to be stopped. - * - */ +#include "nrf_hal.h" +#include "nrfx_config.h" +#include "nrfx_gpiote.h" /* GPIO interrupts */ -#define HAL_GPIO_MAX_IRQ 8 +#define HAL_GPIO_MAX_IRQ GPIOTE_CH_NUM #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) #define HAL_GPIO_SENSE_TRIG_NONE 0x00 /* just 0 */ @@ -42,6 +35,10 @@ #define HAL_GPIO_SENSE_TRIG_LOW 0x03 /* GPIO_PIN_CNF_SENSE_Low */ #endif +#if defined(NRF5340_XXAA_APPLICATION) || defined(NRF9160_XXAA) +#define GPIOTE_IRQn GPIOTE0_IRQn +#endif + /* Storage for GPIO callbacks. */ struct hal_gpio_irq { hal_gpio_irq_handler_t func; @@ -67,27 +64,19 @@ static struct hal_gpio_irq hal_gpio_irqs[HAL_GPIO_MAX_IRQ]; int hal_gpio_init_in(int pin, hal_gpio_pull_t pull) { - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - switch (pull) { case HAL_GPIO_PULL_UP: - conf = GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos; + nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLUP); break; case HAL_GPIO_PULL_DOWN: - conf = GPIO_PIN_CNF_PULL_Pulldown << GPIO_PIN_CNF_PULL_Pos; + nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_PULLDOWN); break; case HAL_GPIO_PULL_NONE: default: - conf = 0; + nrf_gpio_cfg_input(pin, NRF_GPIO_PIN_NOPULL); break; } - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; - port->DIRCLR = HAL_GPIO_MASK(pin); - return 0; } @@ -105,18 +94,8 @@ hal_gpio_init_in(int pin, hal_gpio_pull_t pull) int hal_gpio_init_out(int pin, int val) { - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } - port->PIN_CNF[pin_index] = GPIO_PIN_CNF_DIR_Output | - (GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos); - port->DIRSET = HAL_GPIO_MASK(pin); + nrf_gpio_cfg_output(pin); + nrf_gpio_pin_write(pin, val); return 0; } @@ -131,13 +110,7 @@ hal_gpio_init_out(int pin, int val) int hal_gpio_deinit(int pin) { - uint32_t conf; - NRF_GPIO_Type *port; - int pin_index = HAL_GPIO_INDEX(pin); - - conf = GPIO_PIN_CNF_INPUT_Disconnect << GPIO_PIN_CNF_INPUT_Pos; - port = HAL_GPIO_PORT(pin); - port->PIN_CNF[pin_index] = conf; + nrf_gpio_cfg_default(pin); return 0; } @@ -153,14 +126,7 @@ hal_gpio_deinit(int pin) void hal_gpio_write(int pin, int val) { - NRF_GPIO_Type *port; - - port = HAL_GPIO_PORT(pin); - if (val) { - port->OUTSET = HAL_GPIO_MASK(pin); - } else { - port->OUTCLR = HAL_GPIO_MASK(pin); - } + nrf_gpio_pin_write(pin, val); } /** @@ -175,12 +141,7 @@ hal_gpio_write(int pin, int val) int hal_gpio_read(int pin) { - NRF_GPIO_Type *port; - port = HAL_GPIO_PORT(pin); - - return (port->DIR & HAL_GPIO_MASK(pin)) ? - (port->OUT >> HAL_GPIO_INDEX(pin)) & 1UL : - (port->IN >> HAL_GPIO_INDEX(pin)) & 1UL; + return nrf_gpio_pin_read(pin); } /** @@ -195,9 +156,8 @@ hal_gpio_read(int pin) int hal_gpio_toggle(int pin) { - int pin_state = (hal_gpio_read(pin) == 0); - hal_gpio_write(pin, pin_state); - return pin_state; + nrf_gpio_pin_toggle(pin); + return nrf_gpio_pin_read(pin); } /* @@ -211,27 +171,13 @@ static void hal_gpio_irq_handler(void) { #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; - int pin_state; uint8_t sense_trig; -#if NRF52840_XXAA - uint64_t gpio_state; -#else - uint32_t gpio_state; -#endif #endif int i; - os_trace_isr_enter(); #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE->EVENTS_PORT = 0; - - gpio_state = NRF_P0->IN; -#if NRF52840_XXAA - gpio_state |= (uint64_t)NRF_P1->IN << 32; -#endif + nrf_gpiote_event_clear(NRF_GPIOTE0, NRF_GPIOTE_EVENT_PORT); #endif for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { @@ -241,13 +187,10 @@ hal_gpio_irq_handler(void) continue; } - nrf_gpio = HAL_GPIO_PORT(hal_gpio_irqs[i].pin); - pin_index = HAL_GPIO_INDEX(hal_gpio_irqs[i].pin); - /* Store current SENSE setting */ - sense_trig = (nrf_gpio->PIN_CNF[pin_index] & GPIO_PIN_CNF_SENSE_Msk) >> GPIO_PIN_CNF_SENSE_Pos; + sense_trig = nrf_gpio_pin_sense_get(hal_gpio_irqs[i].pin); - if (!sense_trig) { + if (sense_trig == HAL_GPIO_SENSE_TRIG_NONE) { continue; } @@ -256,8 +199,7 @@ hal_gpio_irq_handler(void) * opposite of state which triggers interrupt (thus its value should be * different than pin state). */ - pin_state = (gpio_state >> hal_gpio_irqs[i].pin) & 0x01; - if (pin_state == (sense_trig & 0x01)) { + if (nrf_gpio_pin_read(hal_gpio_irqs[i].pin) == (sense_trig & 0x01)) { continue; } @@ -265,11 +207,10 @@ hal_gpio_irq_handler(void) * Toggle sense to clear interrupt or allow detection of opposite edge * when trigger on both edges is requested. */ - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; if (sense_trig == HAL_GPIO_SENSE_TRIG_HIGH) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; + nrf_gpio_cfg_sense_set(hal_gpio_irqs[i].pin, HAL_GPIO_SENSE_TRIG_LOW); } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; + nrf_gpio_cfg_sense_set(hal_gpio_irqs[i].pin, HAL_GPIO_SENSE_TRIG_HIGH); } /* @@ -281,8 +222,9 @@ hal_gpio_irq_handler(void) hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); } #else - if (NRF_GPIOTE->EVENTS_IN[i] && (NRF_GPIOTE->INTENSET & (1 << i))) { - NRF_GPIOTE->EVENTS_IN[i] = 0; + if (nrf_gpiote_event_check(NRF_GPIOTE0, nrf_gpiote_in_event_get(i)) && + nrf_gpiote_int_enable_check(NRF_GPIOTE0, 1 << i)) { + nrf_gpiote_event_clear(NRF_GPIOTE0, nrf_gpiote_in_event_get(i)); if (hal_gpio_irqs[i].func) { hal_gpio_irqs[i].func(hal_gpio_irqs[i].arg); } @@ -308,8 +250,8 @@ hal_gpio_irq_setup(void) irq_setup = 1; #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIOTE->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; - NRF_GPIOTE->EVENTS_PORT = 0; + nrf_gpiote_int_disable(NRF_GPIOTE0, GPIOTE_INTENCLR_PORT_Msk); + nrf_gpiote_event_clear(NRF_GPIOTE0, NRF_GPIOTE_EVENT_PORT); #endif } } @@ -334,7 +276,7 @@ hal_gpio_find_empty_slot(void) * Find the GPIOTE event which handles this pin. */ static int -hal_gpio_find_pin(int pin) +hal_gpio_get_gpiote_num(int pin) { int i; @@ -345,11 +287,9 @@ hal_gpio_find_pin(int pin) } } #else - pin = pin << GPIOTE_CONFIG_PSEL_Pos; - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { if (hal_gpio_irqs[i].func && - (NRF_GPIOTE->CONFIG[i] & HAL_GPIOTE_PIN_MASK) == pin) { + (nrf_gpiote_event_pin_get(NRF_GPIOTE0, i) == pin)) { return i; } } @@ -375,7 +315,6 @@ int hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull) { - uint32_t conf; int i, sr; __HAL_DISABLE_INTERRUPTS(sr); @@ -389,7 +328,6 @@ hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, hal_gpio_init_in(pin, pull); #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - (void)conf; hal_gpio_irqs[i].pin = pin; switch (trig) { @@ -410,23 +348,20 @@ hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg, #else switch (trig) { case HAL_GPIO_TRIG_RISING: - conf = GPIOTE_CONFIG_POLARITY_LoToHi << GPIOTE_CONFIG_POLARITY_Pos; + nrf_gpiote_event_configure(NRF_GPIOTE0, i, pin, GPIOTE_CONFIG_POLARITY_LoToHi); break; case HAL_GPIO_TRIG_FALLING: - conf = GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos; + nrf_gpiote_event_configure(NRF_GPIOTE0, i, pin, GPIOTE_CONFIG_POLARITY_HiToLo); break; case HAL_GPIO_TRIG_BOTH: - conf = GPIOTE_CONFIG_POLARITY_Toggle << GPIOTE_CONFIG_POLARITY_Pos; + nrf_gpiote_event_configure(NRF_GPIOTE0, i, pin, GPIOTE_CONFIG_POLARITY_Toggle); break; default: __HAL_ENABLE_INTERRUPTS(sr); return -1; } - conf |= pin << GPIOTE_CONFIG_PSEL_Pos; - conf |= GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos; - - NRF_GPIOTE->CONFIG[i] = conf; + nrf_gpiote_event_enable(NRF_GPIOTE0, i); #endif hal_gpio_irqs[i].func = handler; @@ -453,7 +388,7 @@ hal_gpio_irq_release(int pin) __HAL_DISABLE_INTERRUPTS(sr); - i = hal_gpio_find_pin(pin); + i = hal_gpio_get_gpiote_num(pin); if (i < 0) { __HAL_ENABLE_INTERRUPTS(sr); return; @@ -461,10 +396,10 @@ hal_gpio_irq_release(int pin) hal_gpio_irq_disable(pin); #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - hal_gpio_irqs[i].sense_trig = HAL_GPIO_SENSE_TRIG_NONE; + hal_gpio_irqs[i].sense_trig = NRF_GPIO_PIN_NOSENSE; #else - NRF_GPIOTE->CONFIG[i] = 0; - NRF_GPIOTE->EVENTS_IN[i] = 0; + nrf_gpiote_te_default(NRF_GPIOTE0, i); + nrf_gpiote_event_clear(NRF_GPIOTE0, nrf_gpiote_in_event_get(i)); #endif hal_gpio_irqs[i].arg = NULL; @@ -483,40 +418,31 @@ hal_gpio_irq_release(int pin) void hal_gpio_irq_enable(int pin) { -#if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; -#endif int i, sr; __HAL_DISABLE_INTERRUPTS(sr); - i = hal_gpio_find_pin(pin); + i = hal_gpio_get_gpiote_num(pin); if (i < 0) { __HAL_ENABLE_INTERRUPTS(sr); return; } #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - /* * Always set initial SENSE to opposite of current pin state to avoid * triggering immediately */ - if (nrf_gpio->IN & (1 << pin_index)) { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_Low << GPIO_PIN_CNF_SENSE_Pos; + if (nrf_gpio_pin_read(pin)) { + nrf_gpio_cfg_sense_set(pin, GPIO_PIN_CNF_SENSE_Low); } else { - nrf_gpio->PIN_CNF[pin_index] |= GPIO_PIN_CNF_SENSE_High << GPIO_PIN_CNF_SENSE_Pos; + nrf_gpio_cfg_sense_set(pin, GPIO_PIN_CNF_SENSE_High); } - NRF_GPIOTE->INTENSET = GPIOTE_INTENSET_PORT_Msk; + nrf_gpiote_int_enable(NRF_GPIOTE0, GPIOTE_INTENSET_PORT_Msk); #else - NRF_GPIOTE->EVENTS_IN[i] = 0; - NRF_GPIOTE->INTENSET = 1 << i; + nrf_gpiote_event_clear(NRF_GPIOTE0, nrf_gpiote_in_event_get(i)); + nrf_gpiote_int_enable(NRF_GPIOTE0, 1 << i); #endif __HAL_ENABLE_INTERRUPTS(sr); @@ -532,26 +458,19 @@ void hal_gpio_irq_disable(int pin) { #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - NRF_GPIO_Type *nrf_gpio; - int pin_index; bool sense_enabled = false; #endif int i, sr; __HAL_DISABLE_INTERRUPTS(sr); - i = hal_gpio_find_pin(pin); + i = hal_gpio_get_gpiote_num(pin); if (i < 0) { __HAL_ENABLE_INTERRUPTS(sr); return; } #if MYNEWT_VAL(MCU_GPIO_USE_PORT_EVENT) - nrf_gpio = HAL_GPIO_PORT(pin); - pin_index = HAL_GPIO_INDEX(pin); - - nrf_gpio->PIN_CNF[pin_index] &= ~GPIO_PIN_CNF_SENSE_Msk; - for (i = 0; i < HAL_GPIO_MAX_IRQ; i++) { if (hal_gpio_irqs[i].sense_trig != HAL_GPIO_SENSE_TRIG_NONE) { sense_enabled = true; @@ -560,10 +479,10 @@ hal_gpio_irq_disable(int pin) } if (!sense_enabled) { - NRF_GPIOTE->INTENCLR = GPIOTE_INTENCLR_PORT_Msk; + nrf_gpiote_int_disable(NRF_GPIOTE0, GPIOTE_INTENSET_PORT_Msk); } #else - NRF_GPIOTE->INTENCLR = 1 << i; + nrf_gpiote_int_disable(NRF_GPIOTE0, 1 << i); #endif __HAL_ENABLE_INTERRUPTS(sr); }