You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by we...@apache.org on 2016/10/14 00:00:47 UTC

incubator-mynewt-core git commit: MYNEWT-402: Add i2c hal to nrf51

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop 9e52a7c1e -> 0d5cc344f


MYNEWT-402: Add i2c hal to nrf51


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/0d5cc344
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/0d5cc344
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/0d5cc344

Branch: refs/heads/develop
Commit: 0d5cc344f7f70c6de6329603c1e38b8e0c24e090
Parents: 9e52a7c
Author: William San Filippo <wi...@runtime.io>
Authored: Thu Oct 13 16:55:41 2016 -0700
Committer: William San Filippo <wi...@runtime.io>
Committed: Thu Oct 13 17:00:40 2016 -0700

----------------------------------------------------------------------
 hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h |   8 +-
 hw/mcu/nordic/nrf51xxx/src/hal_i2c.c           | 199 ++++++++++++++++++++
 2 files changed, 206 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0d5cc344/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h
index 44eedc1..a6dee13 100755
--- a/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h
+++ b/hw/mcu/nordic/nrf51xxx/include/mcu/nrf51_hal.h
@@ -6,7 +6,7 @@
  * 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,
@@ -46,6 +46,12 @@ struct nrf51_uart_cfg {
 };
 const struct nrf51_uart_cfg *bsp_uart_config(void);
 
+struct nrf51_hal_i2c_cfg {
+    int scl_pin;
+    int sda_pin;
+    uint32_t i2c_frequency;
+};
+
 struct hal_flash;
 extern const struct hal_flash nrf51_flash_dev;
 

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/0d5cc344/hw/mcu/nordic/nrf51xxx/src/hal_i2c.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf51xxx/src/hal_i2c.c b/hw/mcu/nordic/nrf51xxx/src/hal_i2c.c
new file mode 100644
index 0000000..583b498
--- /dev/null
+++ b/hw/mcu/nordic/nrf51xxx/src/hal_i2c.c
@@ -0,0 +1,199 @@
+/**
+ * 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_i2c.h>
+
+#include <string.h>
+#include <errno.h>
+
+#include <nrf.h>
+#include <nrf_drv_twi.h>
+
+#include <mcu/nrf51_hal.h>
+
+#include <assert.h>
+
+struct nrf51_hal_i2c {
+    nrf_drv_twi_t nhi_nrf_master;
+};
+
+#define NRF51_HAL_I2C_MAX (2)
+
+#if TWI0_ENABLED
+struct nrf51_hal_i2c hal_twi_i2c0 = {NRF_DRV_TWI_INSTANCE(0)};
+#endif
+#if TWI1_ENABLED
+struct nrf51_hal_i2c hal_twi_i2c1 = {NRF_DRV_TWI_INSTANCE(1)};
+#endif
+
+static const struct nrf51_hal_i2c *nrf51_hal_i2cs[NRF51_HAL_I2C_MAX] = {
+#if TWI0_ENABLED
+        &hal_twi_i2c0,
+#else
+        NULL,
+#endif
+#if TWI1_ENABLED
+        &hal_twi_i2c1
+#else
+        NULL
+#endif
+};
+
+#define NRF51_HAL_I2C_RESOLVE(__n, __v)                      \
+    if ((__n) >= NRF51_HAL_I2C_MAX) {                        \
+        rc = EINVAL;                                         \
+        goto err;                                            \
+    }                                                        \
+    (__v) = (struct nrf51_hal_i2c *) nrf51_hal_i2cs[(__n)];  \
+    if ((__v) == NULL) {                                     \
+        rc = EINVAL;                                         \
+        goto err;                                            \
+    }
+
+int
+hal_i2c_init(uint8_t i2c_num, void *usercfg)
+{
+    struct nrf51_hal_i2c *i2c;
+    struct nrf51_hal_i2c_cfg *i2c_cfg;
+    nrf_drv_twi_config_t cfg;
+    int rc;
+
+    assert(usercfg != NULL);
+
+    NRF51_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    i2c_cfg = (struct nrf51_hal_i2c_cfg *) usercfg;
+
+    cfg.scl = i2c_cfg->scl_pin;
+    cfg.sda = i2c_cfg->sda_pin;
+    switch (i2c_cfg->i2c_frequency) {
+        case 100:
+            cfg.frequency = NRF_TWI_FREQ_100K;
+            break;
+        case 250:
+            cfg.frequency = NRF_TWI_FREQ_250K;
+            break;
+        case 400:
+            cfg.frequency = NRF_TWI_FREQ_400K;
+            break;
+        default:
+            rc = EINVAL;
+            goto err;
+    }
+
+    rc = nrf_drv_twi_init(&i2c->nhi_nrf_master, &cfg, NULL, NULL);
+    if (rc != 0) {
+        goto err;
+    }
+
+    nrf_drv_twi_enable(&i2c->nhi_nrf_master);
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
+  uint32_t timo)
+{
+    struct nrf51_hal_i2c *i2c;
+    int rc;
+
+    NRF51_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    rc = nrf_drv_twi_tx(&i2c->nhi_nrf_master, pdata->address, pdata->buffer,
+            pdata->len, true);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata,
+  uint32_t timo)
+{
+    struct nrf51_hal_i2c *i2c;
+    int rc;
+
+    NRF51_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    rc = nrf_drv_twi_rx(&i2c->nhi_nrf_master, pdata->address, pdata->buffer,
+            pdata->len);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+hal_i2c_master_begin(uint8_t i2c_num)
+{
+    return (0);
+}
+
+int
+hal_i2c_master_end(uint8_t i2c_num)
+{
+    struct nrf51_hal_i2c *i2c;
+    int rc;
+
+    NRF51_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    /**
+     * XXX: Nordic doesn't provide a function for generating the stop
+     * character, and I don't trust issue'ing nrf_drv_twi_tx() with NULL
+     * data, and 0 length, so directly use the stop task in HAL driver.
+     * This is subject to break as NRF SDK is updated, as reg.p_twi is
+     * private, however, seems like it will be reasonably easy to spot.
+     * Famous last words.
+     */
+    nrf_twi_task_trigger(i2c->nhi_nrf_master.reg.p_twi, NRF_TWI_TASK_RESUME);
+    nrf_twi_task_trigger(i2c->nhi_nrf_master.reg.p_twi, NRF_TWI_TASK_STOP);
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+hal_i2c_master_probe(uint8_t i2c_num, uint8_t address, uint32_t timo)
+{
+    struct nrf51_hal_i2c *i2c;
+    uint8_t buf;
+    int rc;
+
+    NRF51_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    rc = nrf_drv_twi_rx(&i2c->nhi_nrf_master, address, &buf, 1);
+    if (rc != 0) {
+        goto err;
+    }
+
+    return (0);
+err:
+    return (rc);
+}