You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/04/18 21:32:45 UTC

[GitHub] vrahane closed pull request #940: nrf52xxx_i2c: Fix to allow hal_i2c_clear_bus to read from input-buffer

vrahane closed pull request #940: nrf52xxx_i2c: Fix to allow hal_i2c_clear_bus to read from input-buffer 
URL: https://github.com/apache/mynewt-core/pull/940
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
index bc98afff6..1ec75ee15 100644
--- a/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
+++ b/hw/mcu/nordic/nrf52xxx/src/hal_i2c.c
@@ -39,6 +39,14 @@
       (GPIO_PIN_CNF_DIR_Input     << GPIO_PIN_CNF_DIR_Pos))
 #define NRF52_SDA_PIN_CONF NRF52_SCL_PIN_CONF
 
+#define NRF52_SCL_PIN_CONF_CLR                                  \
+     ((GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) | \
+      (GPIO_PIN_CNF_DRIVE_S0D1     << GPIO_PIN_CNF_DRIVE_Pos) | \
+      (GPIO_PIN_CNF_PULL_Pullup    << GPIO_PIN_CNF_PULL_Pos)  | \
+      (GPIO_PIN_CNF_INPUT_Connect  << GPIO_PIN_CNF_INPUT_Pos) | \
+      (GPIO_PIN_CNF_DIR_Output     << GPIO_PIN_CNF_DIR_Pos))
+#define NRF52_SDA_PIN_CONF_CLR    NRF52_SCL_PIN_CONF_CLR
+
 #define NRF52_HAL_I2C_RESOLVE(__n, __v)                      \
     if ((__n) >= NRF52_HAL_I2C_MAX) {                        \
         rc = EINVAL;                                         \
@@ -155,6 +163,19 @@ __ASM volatile (
     : "+r" (delay));
 }
 
+/**
+ * Reads the input buffer of the specified pin regardless
+ * of if it is set as output or input
+ */
+static int
+read_gpio_inbuffer(int pin)
+{
+    NRF_GPIO_Type *port;
+    port = HAL_GPIO_PORT(pin);
+
+    return (port->IN >> HAL_GPIO_INDEX(pin)) & 1UL;
+}
+
 /*
  * Clear the bus after reset by clocking 9 bits manually.
  * This should reset state from (most of) the devices on the other end.
@@ -163,26 +184,30 @@ static void
 hal_i2c_clear_bus(const struct nrf52_hal_i2c_cfg *cfg)
 {
     int i;
+    NRF_GPIO_Type *scl_port, *sda_port;
+    /* Resolve which GPIO port these pins belong to */
+    scl_port = HAL_GPIO_PORT(cfg->scl_pin);
+    sda_port = HAL_GPIO_PORT(cfg->sda_pin);
 
     /* Input connected, standard-low disconnected-high, pull-ups */
-    NRF_GPIO->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF;
-    NRF_GPIO->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF;
+    scl_port->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF;
+    sda_port->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF;
 
     hal_gpio_write(cfg->scl_pin, 1);
     hal_gpio_write(cfg->sda_pin, 1);
 
-    /* Still with input buffer connected, the direction is output */
-    NRF_GPIO->DIRSET = ((1<<cfg->scl_pin)|(1<<cfg->sda_pin));
+    scl_port->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF_CLR;
+    sda_port->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF_CLR;
 
     hal_i2c_delay_us(4);
 
     for (i = 0; i < 9; i++) {
-        if (hal_gpio_read(cfg->sda_pin)) {
+        if (read_gpio_inbuffer(cfg->sda_pin)) {
             if (i == 0) {
                 /*
                  * Nothing to do here.
                  */
-                return;
+                goto ret;
             } else {
                 break;
             }
@@ -199,6 +224,11 @@ hal_i2c_clear_bus(const struct nrf52_hal_i2c_cfg *cfg)
     hal_gpio_write(cfg->sda_pin, 0);
     hal_i2c_delay_us(4);
     hal_gpio_write(cfg->sda_pin, 1);
+
+ret:
+    /* Restore GPIO config */
+    scl_port->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF;
+    sda_port->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF;
 }
 
 int
@@ -209,6 +239,7 @@ hal_i2c_init(uint8_t i2c_num, void *usercfg)
     struct nrf52_hal_i2c_cfg *cfg;
     uint32_t freq;
     int rc;
+    NRF_GPIO_Type *scl_port, *sda_port;
 
     assert(usercfg != NULL);
 
@@ -234,8 +265,12 @@ hal_i2c_init(uint8_t i2c_num, void *usercfg)
 
     hal_i2c_clear_bus(cfg);
 
-    NRF_GPIO->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF;
-    NRF_GPIO->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF;
+    /* Resolve which GPIO port these pins belong to */
+    scl_port = HAL_GPIO_PORT(cfg->scl_pin);
+    sda_port = HAL_GPIO_PORT(cfg->sda_pin);
+
+    scl_port->PIN_CNF[cfg->scl_pin] = NRF52_SCL_PIN_CONF;
+    sda_port->PIN_CNF[cfg->sda_pin] = NRF52_SDA_PIN_CONF;
 
     regs->PSELSCL = cfg->scl_pin;
     regs->PSELSDA = cfg->sda_pin;


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services