mbed

Fork of mbed-dev by mbed official

Revision:
165:e614a9f1c9e2
Parent:
150:02e0a0aed4ec
Child:
176:af195413fb11
--- a/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c	Wed May 10 12:06:41 2017 +0100
+++ b/targets/TARGET_NORDIC/TARGET_NRF5/gpio_api.c	Fri May 26 12:39:01 2017 +0100
@@ -22,8 +22,12 @@
 
 #if defined(TARGET_MCU_NRF51822)
     #define GPIO_PIN_COUNT 31
+#elif defined(TARGET_MCU_NRF52832)
+    #define GPIO_PIN_COUNT 32
+#elif defined(TARGET_MCU_NRF52840)
+    #define GPIO_PIN_COUNT 48
 #else
-    #define GPIO_PIN_COUNT 32
+    #error not recognized gpio count for mcu
 #endif
 
 typedef struct {
@@ -36,8 +40,14 @@
     bool         irq_rise     : 1;
 } gpio_cfg_t;
 
-uint32_t m_gpio_initialized;
-gpio_cfg_t m_gpio_cfg[GPIO_PIN_COUNT];
+#if GPIO_PIN_COUNT > 32
+    typedef uint64_t gpio_mask_t;
+#else
+    typedef uint32_t gpio_mask_t;
+#endif
+
+static gpio_mask_t m_gpio_initialized;
+static gpio_cfg_t  m_gpio_cfg[GPIO_PIN_COUNT];
 
 
 /***********
@@ -46,7 +56,7 @@
 
 static gpio_irq_handler m_irq_handler;
 static uint32_t m_channel_ids[GPIO_PIN_COUNT] = {0};
-uint32_t m_gpio_irq_enabled;
+static gpio_mask_t m_gpio_irq_enabled;
 
 
 static void gpiote_irq_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
@@ -54,7 +64,7 @@
     nrf_gpio_pin_sense_t sense =  nrf_gpio_pin_sense_get(pin);
     gpio_irq_event event = (sense == NRF_GPIO_PIN_SENSE_LOW) ? IRQ_RISE : IRQ_FALL;
     
-    if (m_gpio_irq_enabled & (1UL << pin)) {
+    if (m_gpio_irq_enabled & ((gpio_mask_t)1 << pin)) {
         if (((event == IRQ_RISE) && m_gpio_cfg[pin].irq_rise)
             || ((event == IRQ_FALL) && m_gpio_cfg[pin].irq_fall)) {
                 m_irq_handler(m_channel_ids[pin], event);
@@ -79,12 +89,19 @@
     m_gpio_cfg[obj->pin].used_as_gpio = true;
 }
 
+#ifdef TARGET_SDK11
+// implement polyfill of gpio hal for the nRF5 SDK v11
+__STATIC_INLINE uint32_t nrf_gpio_pin_out_read(uint32_t pin)
+{
+    return (NRF_GPIO->OUTSET & (1UL << (pin)));
+}
+#endif
 
 int gpio_read(gpio_t *obj)
 {
     MBED_ASSERT(obj->pin != (PinName)NC);
     if (m_gpio_cfg[obj->pin].direction == PIN_OUTPUT) {
-        return ((NRF_GPIO->OUTSET & (1UL << obj->pin)) ? 1 : 0);
+        return (nrf_gpio_pin_out_read(obj->pin) ? 1 : 0);
     } else {
         return nrf_gpio_pin_read(obj->pin);
     }
@@ -92,7 +109,7 @@
 
 static void gpiote_pin_uninit(uint8_t pin)
 {
-    if (m_gpio_initialized & (1UL << pin)) {
+    if (m_gpio_initialized & ((gpio_mask_t)1UL << pin)) {
         if ((m_gpio_cfg[pin].direction == PIN_OUTPUT) && (!m_gpio_cfg[pin].used_as_irq)) {
             nrf_drv_gpiote_out_uninit(pin);
         }
@@ -116,7 +133,7 @@
             if (m_gpio_cfg[pin].used_as_irq) {
                 cfg.pull = NRF_GPIO_PIN_PULLUP;
                 nrf_drv_gpiote_in_init(pin, &cfg, gpiote_irq_handler);
-                if ((m_gpio_irq_enabled & (1 << pin))
+                if ((m_gpio_irq_enabled & ((gpio_mask_t)1 << pin))
                     && (m_gpio_cfg[pin].irq_rise || m_gpio_cfg[pin].irq_fall))
                 {
                     nrf_drv_gpiote_in_event_enable(pin, true);
@@ -142,17 +159,17 @@
             nrf_drv_gpiote_out_config_t cfg = GPIOTE_CONFIG_OUT_SIMPLE(m_gpio_cfg[pin].init_high);
             nrf_drv_gpiote_out_init(pin, &cfg);
         }
-        m_gpio_initialized |= (1UL << pin);
+        m_gpio_initialized |= ((gpio_mask_t)1UL << pin);
     }
     else {
-        m_gpio_initialized &= ~(1UL << pin);
+        m_gpio_initialized &= ~((gpio_mask_t)1UL << pin);
     }
 }
 
 
 void gpio_mode(gpio_t *obj, PinMode mode)
 {
-    MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
+    MBED_ASSERT(obj->pin != (PinName)NC);
     
     gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
     
@@ -163,7 +180,7 @@
 
 void gpio_dir(gpio_t *obj, PinDirection direction)
 {
-    MBED_ASSERT(obj->pin <= GPIO_PIN_COUNT);
+    MBED_ASSERT(obj->pin != (PinName)NC);
     
     gpiote_pin_uninit(obj->pin); // try to uninitialize gpio before a change.
     
@@ -211,7 +228,7 @@
 {
     gpio_cfg_t* cfg = &m_gpio_cfg[obj->ch];
     bool irq_enabled_before =
-        (m_gpio_irq_enabled & (1 << obj->ch)) &&
+        (m_gpio_irq_enabled & ((gpio_mask_t)1 << obj->ch)) &&
         (cfg->irq_rise || cfg->irq_fall);
 
     if (event == IRQ_RISE) {
@@ -235,7 +252,7 @@
 
 void gpio_irq_enable(gpio_irq_t *obj)
 {
-    m_gpio_irq_enabled |= (1 << obj->ch);
+    m_gpio_irq_enabled |= ((gpio_mask_t)1 << obj->ch);
     if (m_gpio_cfg[obj->ch].irq_rise || m_gpio_cfg[obj->ch].irq_fall) {
         nrf_drv_gpiote_in_event_enable(obj->ch, true);
     }
@@ -244,6 +261,6 @@
 
 void gpio_irq_disable(gpio_irq_t *obj)
 {
-    m_gpio_irq_enabled &= ~(1 << obj->ch);
+    m_gpio_irq_enabled &= ~((gpio_mask_t)1 << obj->ch);
     nrf_drv_gpiote_in_event_disable(obj->ch);
 }