]> granicus.if.org Git - esp-idf/commitdiff
add NACK for the last byte to read
authorkooho <2229179028@qq.com>
Tue, 21 Nov 2017 13:10:17 +0000 (21:10 +0800)
committerkooho <2229179028@qq.com>
Tue, 26 Dec 2017 13:50:18 +0000 (21:50 +0800)
components/driver/i2c.c
components/driver/include/driver/i2c.h

index 57ae7547d25e58192611cd202443f78d108a0094..e0778be7016c76ad9e1facce4c95c9c5264fcb6b 100644 (file)
@@ -65,6 +65,8 @@ static DRAM_ATTR i2c_dev_t* const I2C[I2C_NUM_MAX] = { &I2C0, &I2C1 };
 #define I2C_SCL_IO_ERR_STR             "scl gpio number error"\r
 #define I2C_CMD_LINK_INIT_ERR_STR      "i2c command link error"\r
 #define I2C_GPIO_PULLUP_ERR_STR        "this i2c pin does not support internal pull-up"\r
+#define I2C_ACK_TYPE_ERR_STR           "i2c ack type error"\r
+#define I2C_DATA_LEN_ERR_STR           "i2c data read length error"\r
 #define I2C_FIFO_FULL_THRESH_VAL       (28)\r
 #define I2C_FIFO_EMPTY_THRESH_VAL      (5)\r
 #define I2C_IO_INIT_LEVEL              (1)\r
@@ -958,11 +960,8 @@ esp_err_t i2c_master_write_byte(i2c_cmd_handle_t cmd_handle, uint8_t data, bool
     return i2c_cmd_link_append(cmd_handle, &cmd);\r
 }\r
 \r
-esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, int ack)\r
+static esp_err_t i2c_master_read_static(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)\r
 {\r
-    I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);\r
-    I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);\r
-\r
     int len_tmp;\r
     int data_offset = 0;\r
     esp_err_t ret;\r
@@ -985,20 +984,44 @@ esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t dat
     return ESP_OK;\r
 }\r
 \r
-esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, int ack)\r
+esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, i2c_ack_type_t ack)\r
 {\r
     I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);\r
     I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);\r
+    I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);\r
+\r
     i2c_cmd_t cmd;\r
     cmd.ack_en = 0;\r
     cmd.ack_exp = 0;\r
-    cmd.ack_val = ack & 0x1;\r
+    cmd.ack_val = ((ack == I2C_MASTER_LAST_NACK) ? I2C_MASTER_NACK : (ack & 0x1));\r
     cmd.byte_num = 1;\r
     cmd.op_code = I2C_CMD_READ;\r
     cmd.data = data;\r
     return i2c_cmd_link_append(cmd_handle, &cmd);\r
 }\r
 \r
+esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack)\r
+{\r
+    I2C_CHECK((data != NULL), I2C_ADDR_ERROR_STR, ESP_ERR_INVALID_ARG);\r
+    I2C_CHECK(cmd_handle != NULL, I2C_CMD_LINK_INIT_ERR_STR, ESP_ERR_INVALID_ARG);\r
+    I2C_CHECK(ack < I2C_MASTER_ACK_MAX, I2C_ACK_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);\r
+    I2C_CHECK(data_len < 1, I2C_DATA_LEN_ERR_STR, ESP_ERR_INVALID_ARG);\r
+\r
+    if(ack != I2C_MASTER_LAST_NACK) {\r
+        return i2c_master_read_static(cmd_handle, data, data_len, ack);\r
+    } else {\r
+        if(data_len == 1) {\r
+            return i2c_master_read_byte(cmd_handle, data, I2C_MASTER_NACK);    \r
+        } else {\r
+            esp_err_t ret;\r
+            if((ret =  i2c_master_read_static(cmd_handle, data, data_len - 1, I2C_MASTER_ACK)) != ESP_OK) {\r
+                return ret;\r
+            }\r
+            return i2c_master_read_byte(cmd_handle, data + data_len - 1, I2C_MASTER_NACK);\r
+        }\r
+    }   \r
+}\r
+\r
 static void IRAM_ATTR i2c_master_cmd_begin_static(i2c_port_t i2c_num)\r
 {\r
     i2c_obj_t* p_i2c = p_i2c_obj[i2c_num];\r
index 765eab01cf9e3eb8e7ff9da30d01ebcfabafff13..b7aceb7b131771c25b92023ab484d63422e59c6b 100644 (file)
@@ -69,6 +69,13 @@ typedef enum {
     I2C_ADDR_BIT_MAX,\r
 } i2c_addr_mode_t;\r
 \r
+typedef enum {\r
+    I2C_MASTER_ACK = 0x0,        /*!< I2C ack for each byte read */\r
+    I2C_MASTER_NACK = 0x1,       /*!< I2C nack for each byte read */\r
+    I2C_MASTER_LAST_NACK = 0x2,   /*!< I2C nack for the last byte*/\r
+    I2C_MASTER_ACK_MAX,\r
+} i2c_ack_type_t;\r
+\r
 /**\r
  * @brief I2C initialization parameters\r
  */\r
@@ -288,7 +295,7 @@ esp_err_t i2c_master_write(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t da
  *     - ESP_OK Success\r
  *     - ESP_ERR_INVALID_ARG Parameter error\r
  */\r
-esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, int ack);\r
+esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, i2c_ack_type_t ack);\r
 \r
 /**\r
  * @brief Queue command for I2C master to read data from I2C bus\r
@@ -305,7 +312,7 @@ esp_err_t i2c_master_read_byte(i2c_cmd_handle_t cmd_handle, uint8_t* data, int a
  *     - ESP_OK Success\r
  *     - ESP_ERR_INVALID_ARG Parameter error\r
  */\r
-esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, int ack);\r
+esp_err_t i2c_master_read(i2c_cmd_handle_t cmd_handle, uint8_t* data, size_t data_len, i2c_ack_type_t ack);\r
 \r
 /**\r
  * @brief Queue command for I2C master to generate a stop signal\r