# HG changeset patch # User Michiel Broek # Date 1680717626 -7200 # Node ID b3e96bbe4ce4dab30e0e3464483b6aae343b6581 # Parent 64028e178ff1f23c187535c51c67d0d5d625234d First pass of debugging APDS9930 with a real chip. diff -r 64028e178ff1 -r b3e96bbe4ce4 esp-idf-lib/components/apds9930/apds9930.c --- 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 #include -#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, ®_val)); +// i2c_dev_read_reg(&dev->i2c_dev, (uint8_t)APDS9930_ENABLE, ®_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, ®_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; diff -r 64028e178ff1 -r b3e96bbe4ce4 esp-idf-lib/components/apds9930/apds9930.h --- 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 */ diff -r 64028e178ff1 -r b3e96bbe4ce4 main/iotbalkon.c --- 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); diff -r 64028e178ff1 -r b3e96bbe4ce4 main/task_apds9930.c --- 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