You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ju...@apache.org on 2017/05/08 09:29:28 UTC

[1/2] incubator-mynewt-core git commit: hw: mcu: pic32mz2048efg100: Implement hal_gpio driver

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/master 5ae5f3df5 -> debf64f45


hw: mcu: pic32mz2048efg100: Implement hal_gpio driver

Signed-off-by: Francois Berder <fb...@outlook.fr>


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/32427b41
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/32427b41
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/32427b41

Branch: refs/heads/master
Commit: 32427b4128abf57836b98a73800a14c48ea22793
Parents: 5ae5f3d
Author: Francois Berder <fb...@outlook.fr>
Authored: Sun May 7 19:08:53 2017 +0200
Committer: Francois Berder <fb...@outlook.fr>
Committed: Sun May 7 20:07:28 2017 +0200

----------------------------------------------------------------------
 .../pic32mz2048efg100/include/mcu/mcu.h         |  16 +
 .../microchip/pic32mz2048efg100/src/hal_gpio.c  | 485 +++++++++++++++++++
 2 files changed, 501 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/32427b41/hw/mcu/microchip/pic32mz2048efg100/include/mcu/mcu.h
----------------------------------------------------------------------
diff --git a/hw/mcu/microchip/pic32mz2048efg100/include/mcu/mcu.h b/hw/mcu/microchip/pic32mz2048efg100/include/mcu/mcu.h
index 2be36a9..186bfee 100644
--- a/hw/mcu/microchip/pic32mz2048efg100/include/mcu/mcu.h
+++ b/hw/mcu/microchip/pic32mz2048efg100/include/mcu/mcu.h
@@ -22,4 +22,20 @@
 
 #include "p32mz2048efg100.h"
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MCU_GPIO_PORTA(pin)	((0 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTB(pin)	((1 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTC(pin)	((2 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTD(pin)	((3 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTE(pin)	((4 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTF(pin)	((5 * 16) + (pin & 0xF))
+#define MCU_GPIO_PORTG(pin)	((6 * 16) + (pin & 0xF))
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __MCU_MCU_H_ */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/32427b41/hw/mcu/microchip/pic32mz2048efg100/src/hal_gpio.c
----------------------------------------------------------------------
diff --git a/hw/mcu/microchip/pic32mz2048efg100/src/hal_gpio.c b/hw/mcu/microchip/pic32mz2048efg100/src/hal_gpio.c
new file mode 100644
index 0000000..1c98a7a
--- /dev/null
+++ b/hw/mcu/microchip/pic32mz2048efg100/src/hal_gpio.c
@@ -0,0 +1,485 @@
+/**
+ * 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 <os/os.h>
+#include <hal/hal_gpio.h>
+#include <mcu/mips_hal.h>
+#include <mcu/p32mz2048efg100.h>
+
+#define GPIO_INDEX(pin)     ((pin) & 0x0F)
+#define GPIO_PORT(pin)      (((pin) >> 4) & 0x0F)
+#define GPIO_MASK(pin)      (1 << GPIO_INDEX(pin))
+
+#define LATxCLR(P)      (base_address[P].gpio[0x14 / 0x4])
+#define LATxSET(P)      (base_address[P].gpio[0x18 / 0x4])
+#define LATxINV(P)      (base_address[P].gpio[0x1C / 0x4])
+#define PORTx(P)        (base_address[P].gpio[0x0])
+#define CNPUxCLR(P)     (base_address[P].gpio[0x34 / 0x4])
+#define CNPUxSET(P)     (base_address[P].gpio[0x38 / 0x4])
+#define CNPDxCLR(P)     (base_address[P].gpio[0x44 / 0x4])
+#define CNPDxSET(P)     (base_address[P].gpio[0x48 / 0x4])
+#define ODCxCLR(P)      (base_address[P].gpio[0x24 / 0x4])
+#define CNCONxSET(P)    (base_address[P].gpio[0x58 / 0x4])
+#define CNENxCLR(P)     (base_address[P].gpio[0x64 / 0x4])
+#define CNENxSET(P)     (base_address[P].gpio[0x68 / 0x4])
+#define CNNExCLR(P)     (base_address[P].gpio[0x84 / 0x4])
+#define CNNExSET(P)     (base_address[P].gpio[0x88 / 0x4])
+#define CNFx(P)         (base_address[P].gpio[0x90 / 0x4])
+#define CNFxCLR(P)      (base_address[P].gpio[0x94 / 0x4])
+#define ANSELxCLR(P)    (base_address[P].ansel[0x04 / 0x4])
+#define TRISxCLR(P)     (base_address[P].tris[0x04 / 0x4])
+#define TRISxSET(P)     (base_address[P].tris[0x08 / 0x4])
+
+struct hal_gpio_irq_t {
+    int                    pin;
+    hal_gpio_irq_trig_t    trig;
+    hal_gpio_irq_handler_t handler;
+    void                   *arg;
+};
+
+#define HAL_GPIO_MAX_IRQ    (8)
+static struct hal_gpio_irq_t hal_gpio_irqs[HAL_GPIO_MAX_IRQ];
+
+struct pic32_gpio_t {
+    volatile uint32_t * gpio;
+    volatile uint32_t * ansel;
+    volatile uint32_t * tris;
+};
+
+static struct pic32_gpio_t base_address[] = {
+    {
+        .gpio  = (volatile uint32_t *)_PORTA_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELA,
+        .tris  = (volatile uint32_t *)&TRISA
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTB_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELB,
+        .tris  = (volatile uint32_t *)&TRISB
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTC_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELC,
+        .tris  = (volatile uint32_t *)&TRISC
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTD_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELD,
+        .tris  = (volatile uint32_t *)&TRISD
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTE_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELE,
+        .tris  = (volatile uint32_t *)&TRISE
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTF_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELF,
+        .tris  = (volatile uint32_t *)&TRISF
+    },
+    {
+        .gpio  = (volatile uint32_t *)_PORTG_BASE_ADDRESS,
+        .ansel = (volatile uint32_t *)&ANSELG,
+        .tris  = (volatile uint32_t *)&TRISG
+    }
+};
+
+static uint8_t
+hal_gpio_find_pin(int pin)
+{
+    uint8_t index = 0;
+
+    while (index < HAL_GPIO_MAX_IRQ) {
+        if (hal_gpio_irqs[index].pin == pin) {
+            break;
+        }
+
+        ++index;
+    }
+
+    return index;
+}
+
+static uint8_t
+hal_gpio_find_empty_slot(void)
+{
+    uint8_t index = 0;
+
+    while (index < HAL_GPIO_MAX_IRQ) {
+        if (hal_gpio_irqs[index].handler == NULL) {
+            break;
+        }
+
+        ++index;
+    }
+
+    return index;
+}
+
+static void
+hal_gpio_handle_isr(uint32_t port)
+{
+    uint8_t index = 0;
+    static unsigned int i = 0;
+    for (index = 0; index < HAL_GPIO_MAX_IRQ; ++index) {
+        uint32_t mask, val;
+
+        if (hal_gpio_irqs[index].handler == NULL) {
+            continue;
+        }
+        if (GPIO_PORT(hal_gpio_irqs[index].pin) != port) {
+            continue;
+        }
+
+        mask = GPIO_MASK(hal_gpio_irqs[index].pin);
+        if (CNFx(port) & mask != mask) {
+            continue;
+        }
+
+        val = PORTx(port) & mask;
+        if ((val && (hal_gpio_irqs[index].trig & HAL_GPIO_TRIG_RISING)) ||
+            (!val && (hal_gpio_irqs[index].trig & HAL_GPIO_TRIG_FALLING))) {
+            hal_gpio_irqs[index].handler(hal_gpio_irqs[index].arg);
+        }
+        CNFxCLR(port) = mask;
+    }
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_A_VECTOR)))
+hal_gpio_porta_isr(void)
+{
+    hal_gpio_handle_isr(0);
+    IFS3CLR = _IFS3_CNAIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_B_VECTOR)))
+hal_gpio_portb_isr(void)
+{
+    hal_gpio_handle_isr(1);
+    IFS3CLR = _IFS3_CNBIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_C_VECTOR)))
+hal_gpio_portc_isr(void)
+{
+    hal_gpio_handle_isr(2);
+    IFS3CLR = _IFS3_CNCIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_D_VECTOR)))
+hal_gpio_portd_isr(void)
+{
+    hal_gpio_handle_isr(3);
+    IFS3CLR = _IFS3_CNDIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_E_VECTOR)))
+hal_gpio_porte_isr(void)
+{
+    hal_gpio_handle_isr(4);
+    IFS3CLR = _IFS3_CNEIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_F_VECTOR)))
+hal_gpio_portf_isr(void)
+{
+    hal_gpio_handle_isr(5);
+    IFS3CLR = _IFS3_CNFIF_MASK;
+}
+
+void
+__attribute__((interrupt(IPL1AUTO), vector(_CHANGE_NOTICE_G_VECTOR)))
+hal_gpio_portg_isr(void)
+{
+    hal_gpio_handle_isr(6);
+    IFS3CLR = _IFS3_CNGIF_MASK;
+}
+
+int
+hal_gpio_init_in(int pin, hal_gpio_pull_t pull)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    /* Configure pin as digital */
+    ANSELxCLR(port) = mask;
+
+    ODCxCLR(port) = mask;
+
+    switch (pull) {
+        case HAL_GPIO_PULL_NONE:
+            CNPUxCLR(port) = mask;
+            CNPDxCLR(port) = mask;
+            break;
+
+        case HAL_GPIO_PULL_DOWN:
+            CNPUxCLR(port) = mask;
+            CNPDxSET(port) = mask;
+            break;
+
+        case HAL_GPIO_PULL_UP:
+            CNPUxSET(port) = mask;
+            CNPDxCLR(port) = mask;
+            break;
+
+        default:
+            return -1;
+    }
+
+    /* Configure pin direction as input */
+    TRISxSET(port) = mask;
+
+    return 0;
+}
+
+int
+hal_gpio_init_out(int pin, int val)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    /* Configure pin as digital */
+    ANSELxCLR(port) = mask;
+
+    /* Disable pull-up, pull-down and open drain */
+    CNPUxCLR(port) = mask;
+    CNPDxCLR(port) = mask;
+    ODCxCLR(port) = mask;
+
+    if (val) {
+        LATxSET(port) = mask;
+    } else {
+        LATxCLR(port) = mask;
+    }
+
+    /* Configure pin direction as output */
+    TRISxCLR(port) = mask;
+
+    return 0;
+}
+
+void
+hal_gpio_write(int pin, int val)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    if (val) {
+        LATxSET(port) = mask;
+    } else {
+        LATxCLR(port) = mask;
+    }
+}
+
+int
+hal_gpio_read(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    return !!(PORTx(port) & mask);
+}
+
+int
+hal_gpio_toggle(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    LATxINV(port) = mask;
+
+    /*
+     * One instruction cycle is required between a write and a read
+     * operation on the same port.
+     */
+    asm volatile ("nop");
+
+    return !!(PORTx(port) & mask);
+}
+
+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 port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+    uint32_t ctx;
+    int ret;
+    uint8_t index;
+
+    /* HAL_GPIO_TRIG_LOW and HAL_GPIO_TRIG_HIGH are not supported */
+    if (trig == HAL_GPIO_TRIG_LOW ||
+        trig == HAL_GPIO_TRIG_HIGH ||
+        trig == HAL_GPIO_TRIG_NONE) {
+        return -1;
+    }
+
+    /* Remove any existing irq handler attached to the pin */
+    hal_gpio_irq_release(pin);
+    hal_gpio_irq_disable(pin);
+
+    index = hal_gpio_find_empty_slot();
+    if (index == HAL_GPIO_MAX_IRQ) {
+        return -1;
+    }
+
+    ret = hal_gpio_init_in(pin, pull);
+    if (ret < 0) {
+        return ret;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+    hal_gpio_irqs[index].arg = arg;
+    hal_gpio_irqs[index].pin = pin;
+    hal_gpio_irqs[index].trig = trig;
+    hal_gpio_irqs[index].handler = handler;
+    __HAL_ENABLE_INTERRUPTS(ctx);
+
+    return 0;
+}
+
+void
+hal_gpio_irq_release(int pin)
+{
+    uint32_t ctx;
+    uint8_t index = hal_gpio_find_pin(pin);
+    if (index == HAL_GPIO_MAX_IRQ) {
+        return;
+    }
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+    hal_gpio_irqs[index].handler = NULL;
+    __HAL_ENABLE_INTERRUPTS(ctx);
+}
+
+void
+hal_gpio_irq_enable(int pin)
+{
+    volatile uint32_t dummy;
+    uint32_t port, mask, ctx;
+
+    uint8_t index = hal_gpio_find_pin(pin);
+    if (index == HAL_GPIO_MAX_IRQ)
+        return;
+
+    port = GPIO_PORT(pin);
+    mask = GPIO_MASK(pin);
+
+    __HAL_DISABLE_INTERRUPTS(ctx);
+
+    /* Enable Change Notice module for the port */
+    CNCONxSET(port) = _CNCONA_ON_MASK | _CNCONA_EDGEDETECT_MASK;
+
+    switch (hal_gpio_irqs[index].trig) {
+        case HAL_GPIO_TRIG_RISING:
+            CNENxSET(port) = mask;
+            break;
+        case HAL_GPIO_TRIG_FALLING:
+            CNNExSET(port) = mask;
+            break;
+        case HAL_GPIO_TRIG_BOTH:
+            CNENxSET(port) = mask;
+            CNNExSET(port) = mask;
+            break;
+        default:
+            break;
+    }
+
+    /* Set interrupt priority */
+    switch (port) {
+        case 0:
+            IPC29CLR = (_IPC29_CNAIP_MASK | _IPC29_CNAIS_MASK);
+            IPC29 |= 1 << _IPC29_CNAIP_POSITION;
+            break;
+        case 1:
+            IPC29CLR = (_IPC29_CNBIP_MASK | _IPC29_CNBIS_MASK);
+            IPC29 |= 1 << _IPC29_CNBIP_POSITION;
+            break;
+        case 2:
+            IPC30CLR = (_IPC30_CNCIP_MASK | _IPC30_CNCIS_MASK);
+            IPC30 |= 1 << _IPC30_CNCIP_POSITION;
+            break;
+        case 3:
+            IPC30CLR = (_IPC30_CNDIP_MASK | _IPC30_CNDIS_MASK);
+            IPC30 |= 1 << _IPC30_CNDIP_POSITION;
+            break;
+        case 4:
+            IPC30CLR = (_IPC30_CNEIP_MASK | _IPC30_CNEIS_MASK);
+            IPC30 |= 1 << _IPC30_CNEIP_POSITION;
+            break;
+        case 5:
+            IPC30CLR = (_IPC30_CNFIP_MASK | _IPC30_CNFIS_MASK);
+            IPC30 |= 1 << _IPC30_CNFIP_POSITION;
+            break;
+        case 6:
+            IPC31CLR = (_IPC31_CNGIP_MASK | _IPC31_CNGIS_MASK);
+            IPC31 |= 1 << _IPC31_CNGIP_POSITION;
+            break;
+    }
+
+    /* Clear interrupt flag and enable Change Notice interrupt */
+    switch (port) {
+        case 0:
+            IFS3CLR = _IFS3_CNAIF_MASK;
+            IEC3SET = _IEC3_CNAIE_MASK;
+            break;
+        case 1:
+            IFS3CLR = _IFS3_CNBIF_MASK;
+            IEC3SET = _IEC3_CNBIE_MASK;
+            break;
+        case 2:
+            IFS3CLR = _IFS3_CNCIF_MASK;
+            IEC3SET = _IEC3_CNCIE_MASK;
+            break;
+        case 3:
+            IFS3CLR = _IFS3_CNDIF_MASK;
+            IEC3SET = _IEC3_CNDIE_MASK;
+            break;
+        case 4:
+            IFS3CLR = _IFS3_CNEIF_MASK;
+            IEC3SET = _IEC3_CNEIE_MASK;
+            break;
+        case 5:
+            IFS3CLR = _IFS3_CNFIF_MASK;
+            IEC3SET = _IEC3_CNFIE_MASK;
+            break;
+        case 6:
+            IFS3CLR = _IFS3_CNGIF_MASK;
+            IEC3SET = _IEC3_CNGIE_MASK;
+            break;
+    }
+
+    __HAL_ENABLE_INTERRUPTS(ctx);
+}
+
+void
+hal_gpio_irq_disable(int pin)
+{
+    uint32_t port = GPIO_PORT(pin);
+    uint32_t mask = GPIO_MASK(pin);
+
+    CNENxCLR(port) = mask;
+    CNNExCLR(port) = mask;
+}
\ No newline at end of file


[2/2] incubator-mynewt-core git commit: This closes pull request #259

Posted by ju...@apache.org.
This closes pull request #259


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/debf64f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/debf64f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/debf64f4

Branch: refs/heads/master
Commit: debf64f45157a0f8690d1274129229e2cc96705e
Parents: 5ae5f3d 32427b4
Author: julian <ju...@imgtec.com>
Authored: Mon May 8 10:27:30 2017 +0100
Committer: julian <ju...@imgtec.com>
Committed: Mon May 8 10:27:30 2017 +0100

----------------------------------------------------------------------
 .../pic32mz2048efg100/include/mcu/mcu.h         |  16 +
 .../microchip/pic32mz2048efg100/src/hal_gpio.c  | 485 +++++++++++++++++++
 2 files changed, 501 insertions(+)
----------------------------------------------------------------------