You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/08/04 21:14:43 UTC

incubator-mynewt-core git commit: add I2C HAL. Update I2C HAL to remove vestigates of system_device_id, and convert docs to doxygen format.

Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/sterly_refactor 30da46584 -> e22285ca8


add I2C HAL.  Update I2C HAL to remove vestigates of system_device_id, and convert docs to doxygen format.


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

Branch: refs/heads/sterly_refactor
Commit: e22285ca8e12ec9c0a31689729f5c2b4d6f384a1
Parents: 30da465
Author: Sterling Hughes <st...@apache.org>
Authored: Thu Aug 4 14:14:32 2016 -0700
Committer: Sterling Hughes <st...@apache.org>
Committed: Thu Aug 4 14:14:32 2016 -0700

----------------------------------------------------------------------
 hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h |   2 +-
 hw/hal/include/hal/hal_i2c.h                |  92 +++++++----
 hw/hal/include/hal/hal_spi.h                |   6 +-
 hw/mcu/nordic/nrf52xxx/src/hal_i2c.c        | 188 +++++++++++++++++++++++
 4 files changed, 252 insertions(+), 36 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e22285ca/hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h
----------------------------------------------------------------------
diff --git a/hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h b/hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h
index 320dd87..d90fc99 100644
--- a/hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h
+++ b/hw/bsp/nrf52dk/include/bsp/nrf_drv_config.h
@@ -314,7 +314,7 @@
 #define TWI0_INSTANCE_INDEX      0
 #endif
 
-#define TWI1_ENABLED 0
+#define TWI1_ENABLED 1
 
 #if (TWI1_ENABLED == 1)
 #define TWI1_USE_EASY_DMA 0

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e22285ca/hw/hal/include/hal/hal_i2c.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_i2c.h b/hw/hal/include/hal/hal_i2c.h
index 876e287..e8c02db 100644
--- a/hw/hal/include/hal/hal_i2c.h
+++ b/hw/hal/include/hal/hal_i2c.h
@@ -27,7 +27,8 @@
 extern "C" {
 #endif
 
-/* This is the API for an i2c bus.  Currently, this is a master API
+/**
+ * This is the API for an i2c bus.  Currently, this is a master API
  * allowing the mynewt device to function as an I2C master.
  *
  * A slave API is pending for future release
@@ -47,9 +48,9 @@ extern "C" {
  *      hal_i2c_end();
  */
 
-struct hal_i2c;
-
-/* when sending a packet, use this structure to pass the arguments */
+/**
+ * when sending a packet, use this structure to pass the arguments.
+ */
 struct hal_i2c_master_data {
     uint8_t  address;   /* destination address */
             /* a I2C address has 7 bits. In the protocol these
@@ -64,53 +65,82 @@ struct hal_i2c_master_data {
     uint8_t *buffer;    /* buffer space to hold the transmit or receive */
 };
 
-/* Initialize a new i2c device with the I2C number.
- * Returns a pointer to the i2c device or NULL on error
+/**
+ * Initialize a new i2c device with the I2C number.
+ *
+ * @param i2c_num The number of the I2C device being initialized
+ * @param scl_pin The GPIO pin to use for clock
+ * @param sda_pin The GPIO pin to use for data
+ * @param i2c_frequency The I2C frequency to use, in KHz
+ *
+ * @return 0 on success, and non-zero error code on failure
  */
-struct hal_i2c *hal_i2c_init(uint8_t i2c_num);
+int hal_i2c_init(uint8_t i2c_num, int scl_pin, int sda_pin,
+        uint32_t i2c_frequency);
 
-/* Sends a start condition and writes <len> bytes of data on the i2c.
+/**
+ * Sends a start condition and writes <len> bytes of data on the i2c.
  * This API assumes that you have already called hal_i2c_master_begin
- *  It will fail if you have not. This API does NOT issue a stop condition.
+ * It will fail if you have not. This API does NOT issue a stop condition.
  * You must stop the bus after successful or unsuccessful write attempts.
  * This API is blocking until an error or NaK occurs. Timeout is platform
- * dependent
- * Returns 0 on success, negative on failure
+ * dependent.
+ *
+ * @param i2c_num The number of the I2C device being written to
+ * @param pdata The data to write to the I2C bus
+ *
+ * @return 0 on success, and non-zero error code on failure
  */
-int
-hal_i2c_master_write(struct hal_i2c *, struct hal_i2c_master_data *pdata);
+int hal_i2c_master_write(uint8_t i2c_num, struct hal_i2c_master_data *pdata);
 
-/* Sends a start condition and reads <len> bytes of data on the i2c.
+/**
+ * Sends a start condition and reads <len> bytes of data on the i2c.
  * This API assumes that you have already called hal_i2c_master_begin
- *  It will fail if you have not. This API does NOT issue a stop condition.
+ * It will fail if you have not. This API does NOT issue a stop condition.
  * You must stop the bus after successful or unsuccessful write attempts.
  * This API is blocking until an error or NaK occurs. Timeout is platform
- * dependent
- * Returns 0 on success, negative on failure
+ * dependent.
+ *
+ * @param i2c_num The number of the I2C device being written to
+ * @param pdata The location to place read data
+ *
+ * @return 0 on success, and non-zero error code on failure
  */
-int
-hal_i2c_master_read(struct hal_i2c *, struct hal_i2c_master_data *pdata);
+int hal_i2c_master_read(uint8_t i2c_num, struct hal_i2c_master_data *pdata);
 
-/*
+/**
  * Starts an I2C transaction with the driver. This API does not send
- * anything over the bus itself
+ * anything over the bus itself.
+ *
+ * @param i2c_num The number of the I2C to begin a transaction on
+ *
+ * @return 0 on success, non-zero error code on failure
  */
-int
-hal_i2c_master_begin(struct hal_i2c *);
+int hal_i2c_master_begin(uint8_t i2c_num);
 
-/* issues a stop condition on the bus and ends the I2C transaction.
+/**
+ * Issues a stop condition on the bus and ends the I2C transaction.
  * You must call i2c_master_end for every hal_i2c_master_begin
- * API call that succeeds  */
-int
-hal_i2c_master_end(struct hal_i2c *);
+ * API call that succeeds.
+ *
+ * @param i2c_num The number of the I2C to end a transaction on
+ *
+ * @return 0 on success, non-zero error code on failure
+ */
+int hal_i2c_master_end(uint8_t i2c_num);
 
-/* Probes the i2c bus for a device with this address.  THIS API
+/**
+ * Probes the i2c bus for a device with this address.  THIS API
  * issues a start condition, probes the address using a read
  * command and issues a stop condition.   There is no need to call
- * hal_i2c_master_begin/end with this method
+ * hal_i2c_master_begin/end with this method.
+ *
+ * @param i2c_num The number of the I2C to probe
+ * @param address The address to probe for
+ *
+ * @return 0 on success, non-zero error code on failure
  */
-int
-hal_i2c_master_probe(struct hal_i2c *, uint8_t address);
+int hal_i2c_master_probe(uint8_t i2c_num, uint8_t address);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e22285ca/hw/hal/include/hal/hal_spi.h
----------------------------------------------------------------------
diff --git a/hw/hal/include/hal/hal_spi.h b/hw/hal/include/hal/hal_spi.h
index 4ed5aa6..19219a4 100644
--- a/hw/hal/include/hal/hal_spi.h
+++ b/hw/hal/include/hal/hal_spi.h
@@ -65,8 +65,7 @@ struct hal_spi_settings {
 struct hal_spi *hal_spi_init(uint8_t spi_num);
 
 /* configure the spi., Reutrns 0 on success, negative on error */
-int
-hal_spi_config(struct hal_spi *pspi, struct hal_spi_settings *psettings);
+int hal_spi_config(struct hal_spi *pspi, struct hal_spi_settings *psettings);
 
 /* Do a blocking master spi transfer of one SPI data word.
  * The data to send is an 8 or 9-bit pattern (depending on configuration)
@@ -74,8 +73,7 @@ hal_spi_config(struct hal_spi *pspi, struct hal_spi_settings *psettings);
  * a 16-bit number to allow up to 9-bit SPI data words.
  * Returns the data received from the remote device or negative on error.
  */
-int
-hal_spi_master_transfer(struct hal_spi *psdi, uint16_t tx);
+int hal_spi_master_transfer(struct hal_spi *psdi, uint16_t tx);
 
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e22285ca/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
new file mode 100644
index 0000000..17b841d
--- /dev/null
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
@@ -0,0 +1,188 @@
+/**
+ * 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>
+
+struct nrf52_hal_i2c {
+    nrf_drv_twi_t nhi_nrf_master;
+};
+
+#define NRF52_HAL_I2C_MAX (2)
+
+#if TWI0_ENABLED
+struct nrf52_hal_i2c hal_twi_i2c0;
+#endif
+#if TWI1_ENABLED
+struct nrf52_hal_i2c hal_twi_i2c1;
+#endif
+
+struct nrf52_hal_i2c *nrf52_hal_i2cs[NRF52_HAL_I2C_MAX] = {
+#if TWI0_ENABLED
+        &hal_twi_i2c0,
+#else
+        NULL,
+#endif
+#if TWI1_ENABLED
+        &hal_twi_i2c1
+#else
+        NULL
+#endif
+};
+
+#define NRF52_HAL_I2C_RESOLVE(__n, __v) \
+    if ((__n) >= NRF52_HAL_I2C_MAX) {   \
+        rc = EINVAL;                    \
+        goto err;                       \
+    }                                   \
+    (__v) = nrf52_hal_i2cs[(__n)];     \
+    if ((__v) == NULL) {                \
+        rc = EINVAL;                    \
+        goto err;                       \
+    }
+
+int
+hal_i2c_init(uint8_t i2c_num, int scl_pin, int sda_pin,
+        uint32_t i2c_frequency)
+{
+    struct nrf52_hal_i2c *i2c;
+    nrf_drv_twi_config_t cfg;
+    int rc;
+
+    NRF52_HAL_I2C_RESOLVE(i2c_num, i2c);
+
+    cfg.scl = scl_pin;
+    cfg.sda = sda_pin;
+    switch (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)
+{
+    struct nrf52_hal_i2c *i2c;
+    int rc;
+
+    NRF52_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)
+{
+    struct nrf52_hal_i2c *i2c;
+    int rc;
+
+    NRF52_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 nrf52_hal_i2c *i2c;
+    int rc;
+
+    NRF52_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_STOP);
+
+    return (0);
+err:
+    return (rc);
+}
+
+int
+hal_i2c_master_probe(uint8_t i2c_num, uint8_t address)
+{
+    struct nrf52_hal_i2c *i2c;
+    uint8_t buf;
+    int rc;
+
+    NRF52_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);
+}