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);
+}