First pass of debugging APDS9930 with a real chip.

Wed, 05 Apr 2023 20:00:26 +0200

author
Michiel Broek <mbroek@mbse.eu>
date
Wed, 05 Apr 2023 20:00:26 +0200
changeset 16
b3e96bbe4ce4
parent 15
64028e178ff1
child 17
1599e696d947

First pass of debugging APDS9930 with a real chip.

esp-idf-lib/components/apds9930/apds9930.c file | annotate | diff | comparison | revisions
esp-idf-lib/components/apds9930/apds9930.h file | annotate | diff | comparison | revisions
main/iotbalkon.c file | annotate | diff | comparison | revisions
main/task_apds9930.c file | annotate | diff | comparison | revisions
--- a/esp-idf-lib/components/apds9930/apds9930.c	Tue Apr 04 20:57:49 2023 +0200
+++ b/esp-idf-lib/components/apds9930/apds9930.c	Wed Apr 05 20:00:26 2023 +0200
@@ -19,7 +19,7 @@
 #include <esp_log.h>
 #include <esp_idf_lib_helpers.h>
 
-#define I2C_FREQ_HZ 1000000 // Max 1MHz for esp-idf
+#define I2C_FREQ_HZ 100000 // Max 400 KHz
 
 static const char *TAG = "apds9930";
 
@@ -72,23 +72,6 @@
 #define APDS9930_OFF			0
 #define APDS9930_ON			1
 
-/* Default values */
-#define APDS9930_DEFAULT_ATIME		0xED
-#define APDS9930_DEFAULT_WTIME		0xFF
-#define APDS9930_DEFAULT_PTIME		0xFF
-#define APDS9930_DEFAULT_PPULSE		0x08
-#define APDS9930_DEFAULT_POFFSET	0       // 0 offset
-#define APDS9930_DEFAULT_CONFIG		0
-#define APDS9930_DEFAULT_PDRIVE		APDS9930_LED_DRIVE_100MA
-#define APDS9930_DEFAULT_PDIODE		2
-#define APDS9930_DEFAULT_PGAIN		APDS9930_PGAIN_8X
-#define APDS9930_DEFAULT_AGAIN		APDS9930_AGAIN_1X
-#define APDS9930_DEFAULT_PILT		0       // Low proximity threshold
-#define APDS9930_DEFAULT_PIHT		50      // High proximity threshold
-#define APDS9930_DEFAULT_AILT		0xFFFF  // Force interrupt for calibration
-#define APDS9930_DEFAULT_AIHT		0
-#define APDS9930_DEFAULT_PERS		0x22    // 2 consecutive prox or ALS for int.
-
 /* Acceptable parameters for setMode */
 #define APDS9930_MODE_POWER		0
 #define APDS9930_MODE_AMBIENT_LIGHT	1
@@ -124,6 +107,29 @@
     } while (0)
 
 
+
+static inline esp_err_t read_reg_8_nolock(apds9930_t *dev, uint8_t reg, uint8_t *data)
+{
+    return i2c_dev_read_reg(&dev->i2c_dev, reg, data, 1);
+}
+
+static inline esp_err_t write_reg_8_nolock(apds9930_t *dev, uint8_t reg, uint8_t data)
+{
+    return i2c_dev_write_reg(&dev->i2c_dev, reg, &data, 1);
+}
+
+static esp_err_t read_reg_8(apds9930_t *dev, uint8_t reg, uint8_t *data)
+{
+    I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
+    I2C_DEV_CHECK(&dev->i2c_dev, read_reg_8_nolock(dev, reg, data));
+    I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
+
+    return ESP_OK;
+}
+
+
+
+
 inline static esp_err_t write_register8(i2c_dev_t *dev, uint8_t addr, uint8_t value)
 {
     return i2c_dev_write_reg(dev, addr, &value, 1);
@@ -167,25 +173,28 @@
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
 
     CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, APDS9930_ID, &dev->id, 1), "Sensor not found");
-
     if (dev->id != APDS9930_ID_1 && dev->id != APDS9930_ID_2 && dev->id != APDS9930_ID_3) {
 	CHECK_LOGE(dev, ESP_ERR_INVALID_VERSION,
 			"Invalid chip ID: expected: 0x%x or 0x%x or 0x%x got: 0x%x",
 			APDS9930_ID_1, APDS9930_ID_2, APDS9930_ID_3, dev->id);
     }
+    I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
     /* Set ENABLE register to 0 (disable all features) */
-    if ( !apds9930_setMode(dev, APDS9930_MODE_ALL, APDS9930_OFF) ) {
-        ESP_LOGE(TAG, "Regs off");
+    if (apds9930_setMode(dev, APDS9930_MODE_ALL, APDS9930_OFF) != ESP_OK) {
+        ESP_LOGE(TAG, "apds9930_init() error 'Regs off'");
 	err = ESP_ERR_INVALID_ARG;
     }
 
     /* Set default values for ambient light and proximity registers */
+    I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
     CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_ATIME, APDS9930_DEFAULT_ATIME), "Default atime");
     CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_WTIME, APDS9930_DEFAULT_WTIME), "Default wtime");
     CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_PPULSE, APDS9930_DEFAULT_PPULSE), "Default ppulse");
     CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_POFFSET, APDS9930_DEFAULT_POFFSET), "Default poffset");
     CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_CONFIG, APDS9930_DEFAULT_CONFIG), "Default config");
+    I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
+
     CHECK_LOGE(dev, apds9930_setLEDDrive(dev, APDS9930_DEFAULT_PDRIVE), "Default pdrive");
     CHECK_LOGE(dev, apds9930_setProximityGain(dev, APDS9930_DEFAULT_PGAIN), "Default pgain");
     CHECK_LOGE(dev, apds9930_setAmbientLightGain(dev, APDS9930_DEFAULT_AGAIN), "Default again");
@@ -194,9 +203,11 @@
     CHECK_LOGE(dev, apds9930_setProximityIntHighThreshold(dev, APDS9930_DEFAULT_PIHT), "Default PIHT");
     CHECK_LOGE(dev, apds9930_setLightIntLowThreshold(dev, APDS9930_DEFAULT_AILT), "Default ailt");
     CHECK_LOGE(dev, apds9930_setLightIntHighThreshold(dev, APDS9930_DEFAULT_AIHT), "Default aiht");
-    CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_PERS, APDS9930_DEFAULT_PERS), "Default pers");
 
+    I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
+    CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_PERS, APDS9930_DEFAULT_PERS), "Default pers");
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
+
     return err;
 }
 
@@ -208,9 +219,9 @@
 {
     uint8_t enable_value;
 
+    /* Read current ENABLE register */
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
-    /* Read current ENABLE register */
-    if (i2c_dev_read_reg(&dev->i2c_dev, APDS9930_ENABLE, &enable_value, 1) != ESP_OK) {
+    if (read_reg_8_nolock(dev, APDS9930_ENABLE, &enable_value) != ESP_OK) {
 	I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
         return APDS9930_ERROR;
     }
@@ -224,12 +235,13 @@
 {
     uint8_t reg_val;
 
-    CHECK_ARG(dev);
+//    CHECK_ARG(dev);
     /* Read current ENABLE register */
-    reg_val = apds9930_getMode(dev);
-    if( reg_val == APDS9930_ERROR ) {
-        return ESP_ERR_INVALID_RESPONSE;
-    }
+    I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
+    I2C_DEV_CHECK(&dev->i2c_dev, read_reg_8_nolock(dev, APDS9930_ENABLE, &reg_val));
+//    i2c_dev_read_reg(&dev->i2c_dev, (uint8_t)APDS9930_ENABLE, &reg_val, 1);
+    I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
+    ESP_LOGI(TAG, "apds9930_setMode(%d, %d) get=%02x", mode, enable, reg_val);
 
     /* Change bit(s) in ENABLE register */
     enable = enable & 0x01;
@@ -247,11 +259,15 @@
         }
     }
 
+    ESP_LOGI(TAG, "apds9930_setMode write %02x", reg_val);
     /* Write value back to ENABLE register */
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
-    CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_ENABLE, reg_val), "Enable register");
+    I2C_DEV_CHECK(&dev->i2c_dev, write_reg_8_nolock(dev, APDS9930_ENABLE, reg_val));
+//    CHECK_LOGE(dev, write_register8(&dev->i2c_dev, APDS9930_ENABLE, reg_val), "Enable register");
+//    CHECK_LOGE(dev, i2c_dev_write_reg(&dev->i2c_dev, (uint8_t)APDS9930_ENABLE, &reg_val, 1), "Enable register");
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
+//vTaskDelay(12 / portTICK_PERIOD_MS);
     return ESP_OK;
 }
 
@@ -395,17 +411,24 @@
 esp_err_t apds9930_readCh0Light(apds9930_t *dev, uint16_t *val)
 {
     uint8_t val_byte;
+    uint16_t val_word;
     *val = 0;
 
     CHECK_ARG(dev);
 
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
     /* Read value from channel 0 */
-    CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, APDS9930_Ch0DATAL, &val_byte, 1), "Read ch0 low");
+    CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, (uint8_t)APDS9930_Ch0DATAL, &val_byte, 1), "Read ch0 low");
+    ESP_LOGI(TAG, "l %02x", val_byte);
     *val = val_byte;
-    CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, APDS9930_Ch0DATAH, &val_byte, 1), "Read ch0 high");
+    CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, (uint8_t)APDS9930_Ch0DATAH, &val_byte, 1), "Read ch0 high");
+    ESP_LOGI(TAG, "h %02x", val_byte);
     *val += ((uint16_t)val_byte << 8);
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
+    ESP_LOGI(TAG, "val %04x", *val);
+
+    CHECK_LOGE(dev, i2c_dev_read_reg(&dev->i2c_dev, (uint8_t)APDS9930_Ch0DATAL, &val_word, 2), "Read ch0 16");
+    ESP_LOGI(TAG, "16 %04x", val_word);
 
     return ESP_OK;
 }
@@ -684,7 +707,7 @@
     CHECK_LOGE(dev, i2c_dev_write_reg(&dev->i2c_dev, APDS9930_CONTROL, &val, 1), "Write control");
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
-    return true;
+    return ESP_OK;
 }
 
 
@@ -894,14 +917,9 @@
     uint8_t	val = APDS9930_CLEAR_ALS_INT;
 
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
-    /* This should write to the chip without register address */
-    CHECK_LOGE(dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1), "Clear ALS_INT");
+    I2C_DEV_CHECK(&dev->i2c_dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1));
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
-//    if( !wireWriteByte(CLEAR_ALS_INT) ) {
-//      return false;
-    //}
-
     return ESP_OK;
 }
 
@@ -911,7 +929,7 @@
     uint8_t	val = APDS9930_CLEAR_PROX_INT;
 
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
-    CHECK_LOGE(dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1), "Clear PROX_INT");
+    I2C_DEV_CHECK(&dev->i2c_dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1));
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
     return ESP_OK;
@@ -923,7 +941,7 @@
     uint8_t	val = APDS9930_CLEAR_ALL_INTS;
 
     I2C_DEV_TAKE_MUTEX(&dev->i2c_dev);
-    CHECK_LOGE(dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1), "Clear ALL_INTS");
+    I2C_DEV_CHECK(&dev->i2c_dev, i2c_dev_write(&dev->i2c_dev, NULL, 0, &val, 1));
     I2C_DEV_GIVE_MUTEX(&dev->i2c_dev);
 
     return ESP_OK;
--- a/esp-idf-lib/components/apds9930/apds9930.h	Tue Apr 04 20:57:49 2023 +0200
+++ b/esp-idf-lib/components/apds9930/apds9930.h	Wed Apr 05 20:00:26 2023 +0200
@@ -47,6 +47,24 @@
 #define APDS9930_AGAIN_16X		2
 #define APDS9930_AGAIN_120X		3
 
+/* Default values */
+#define APDS9930_DEFAULT_ATIME          0xED
+#define APDS9930_DEFAULT_WTIME          0xFF
+#define APDS9930_DEFAULT_PTIME          0xFF
+#define APDS9930_DEFAULT_PPULSE         0x08
+#define APDS9930_DEFAULT_POFFSET        0       // 0 offset
+#define APDS9930_DEFAULT_CONFIG         0
+#define APDS9930_DEFAULT_PDRIVE         APDS9930_LED_DRIVE_100MA
+#define APDS9930_DEFAULT_PDIODE         2
+#define APDS9930_DEFAULT_PGAIN          APDS9930_PGAIN_8X
+#define APDS9930_DEFAULT_AGAIN          APDS9930_AGAIN_1X
+#define APDS9930_DEFAULT_PILT           0       // Low proximity threshold
+#define APDS9930_DEFAULT_PIHT           50      // High proximity threshold
+#define APDS9930_DEFAULT_AILT           0xFFFF  // Force interrupt for calibration
+#define APDS9930_DEFAULT_AIHT           0
+#define APDS9930_DEFAULT_PERS           0x22    // 2 consecutive prox or ALS for int.
+
+
 /**
  * Device descriptor
  */
--- a/main/iotbalkon.c	Tue Apr 04 20:57:49 2023 +0200
+++ b/main/iotbalkon.c	Wed Apr 05 20:00:26 2023 +0200
@@ -365,16 +365,15 @@
     memset(&bmp280_dev, 0, sizeof(bmp280_t));
     memset(&ina219_b_dev, 0, sizeof(ina219_t));
     memset(&ina219_s_dev, 0, sizeof(ina219_t));
-    memset(&apds9930_dev, 0, sizeof(i2c_dev_t));
+    memset(&apds9930_dev, 0, sizeof(apds9930_t));
 
     i2c_dev_t dev = { 0 };
     dev.cfg.sda_io_num = CONFIG_I2C_MASTER_SDA;
     dev.cfg.scl_io_num = CONFIG_I2C_MASTER_SCL;
-    dev.cfg.master.clk_speed = 1000000;
+    dev.cfg.master.clk_speed = 400000;
 
     dev.addr = 0x39;
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
-        ESP_LOGI(TAG, "Found ADPS-9930");
 	ESP_ERROR_CHECK(apds9930_init_desc(&apds9930_dev, 0x39, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
 	ESP_ERROR_CHECK(apds9930_init(&apds9930_dev));
 	ESP_LOGI(TAG, "Found APDS-9930 id: 0x%02x", apds9930_dev.id);
@@ -383,13 +382,13 @@
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
 	ESP_ERROR_CHECK(ina219_init_desc(&ina219_b_dev, 0x40, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
 	ESP_ERROR_CHECK(ina219_init(&ina219_b_dev));
-	ESP_LOGI(TAG, "Found INA219 Battery");
+	ESP_LOGI(TAG, "Found INA219 @0x40 Battery");
     }
     dev.addr = 0x41;
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
 	ESP_ERROR_CHECK(ina219_init_desc(&ina219_s_dev, 0x41, 0, CONFIG_I2C_MASTER_SDA, CONFIG_I2C_MASTER_SCL));
 	ESP_ERROR_CHECK(ina219_init(&ina219_s_dev));
-        ESP_LOGI(TAG, "Found INA219 Solar");
+        ESP_LOGI(TAG, "Found INA219 @0x41 Solar");
     }
     dev.addr = 0x76;
     if (i2c_dev_probe(&dev, I2C_DEV_WRITE) == 0) {
@@ -430,6 +429,13 @@
     int State = State_Init;
     int OldState = State_Init + 1;
 
+
+    while (1) {
+//	request_ina219();
+	request_apds9930();
+	vTaskDelay(5000 / portTICK_PERIOD_MS);
+    }
+
     while (1) {
 	if (OldState != State) {
 	    ESP_LOGI(TAG, "Switch to state %d", State);
--- a/main/task_apds9930.c	Tue Apr 04 20:57:49 2023 +0200
+++ b/main/task_apds9930.c	Wed Apr 05 20:00:26 2023 +0200
@@ -61,6 +61,10 @@
     apds9930_state->address = apds9930_dev.i2c_dev.addr;
     apds9930_state->error = APDS9930_ERR_NONE;
 
+    // Calculate these for auto gain scaling.
+    ALS_maxcount = (256 - APDS9930_DEFAULT_ATIME) * 1024;
+    ALS_mincount = ALS_maxcount / 64;
+
     /* event handler and event group for this task */
     xEventGroupAPDS9930 = xEventGroupCreate();
     EventBits_t uxBits;
@@ -77,23 +81,25 @@
 
 	    if (! apds9930_state->fake) {
 		/* Real sensor is present */
-		apds9930_enablePower(&apds9930_dev);
-		apds9930_enableLightSensor(&apds9930_dev, false);
-		apds9930_disableProximitySensor(&apds9930_dev);
 		if (xSemaphoreTake(xSemaphoreAPDS9930, 25) == pdTRUE) {
-		    l_gain = apds9930_state->gain;
-		    l_aglbit = apds9930_state->aglbit;
-		    xSemaphoreGive(xSemaphoreAPDS9930);
-		}
-		if (l_gain > 3)
-		    l_gain = 0;
-		apds9930_setAmbientLightGain(&apds9930_dev, l_gain);
-		apds9930_setAmbientGainLevel(&apds9930_dev, l_aglbit);
+                    l_gain = apds9930_state->gain;
+                    l_aglbit = apds9930_state->aglbit;
+                    xSemaphoreGive(xSemaphoreAPDS9930);
+                }
+                if (l_gain > 3)
+                    l_gain = 0;
+		ESP_LOGI(TAG, "1");
+		// ESP_ERROR_CHECK(apds9930_enablePower(&apds9930_dev));
+		ESP_ERROR_CHECK(apds9930_enableLightSensor(&apds9930_dev, false));	// Does apds9930_enablePower() too.
+		ESP_ERROR_CHECK(apds9930_disableProximitySensor(&apds9930_dev));
+		ESP_ERROR_CHECK(apds9930_setAmbientLightGain(&apds9930_dev, l_gain));
+		ESP_ERROR_CHECK(apds9930_setAmbientGainLevel(&apds9930_dev, l_aglbit));
 		vTaskDelay(200 / portTICK_PERIOD_MS);
 		tries = 6;
 		err = ESP_OK;
 
 		while (tries) {
+		    ESP_LOGI(TAG, "2 tries %d", tries);
 		    err = apds9930_readAmbientLightLux(&apds9930_dev, &ambient_light);
 		    if (err == ESP_OK) {
 			err = apds9930_readCh0Light(&apds9930_dev, &ch0);
@@ -105,6 +111,7 @@
 			ESP_LOGE(TAG, "read APDS-9930 values error '%s'", esp_err_to_name(err));
 			break;
 		    }
+		    ESP_LOGI(TAG, "2a ALS_maxcount=%d ALS_mincount=%d", ALS_maxcount, ALS_mincount);
 
 		    /*
 		     * Check ranges

mercurial