[answered] I2C issue, CLK is off

chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

[answered] I2C issue, CLK is off

Postby chegewara » Wed Feb 13, 2019 9:08 am

I must be dumb and doing something wrong because it seems only i have this issue.
Ive been trying to connect MAX30100 with arduino library and didnt work, so i connected logic analyzer. What i found that CLK with 100kHz setup is not exactly what i would have expected. Logic analyzer with 1MHz sampling rate shows 90.9091kHz. For CLK 400kHz is even worse.
I thought maybe its something with arduino i2c driver, and i switched to esp-idf. But the result is the same.
Ive been trying to eliminate hardware as the reason, so ive been trying with different esp32. Result still the same. Next i thought, maybe its my logic analyzer is odd. I decided to test it with simple ledc example, but here logic analyzer shows exactly what esp32 is generating.

Here are sample codes i am using for test. Simple i2c scanner:

Code: Select all

#include <driver/i2c.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdio.h>
#include "sdkconfig.h"

#define SDA_PIN 21
#define SCL_PIN 22

static char tag[] = "i2cscanner";

extern void task_i2cscanner(void *ignore) {
	ESP_LOGD(tag, ">> i2cScanner");
	i2c_config_t conf;
	conf.mode = I2C_MODE_MASTER;
	conf.sda_io_num = SDA_PIN;
	conf.scl_io_num = SCL_PIN;
	conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
	conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
	conf.master.clk_speed = 400000;
	i2c_param_config(I2C_NUM_1, &conf);

	i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);

	int i;
	esp_err_t espRc;
	printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
	printf("00:         ");
	for (i=3; i< 0x78; i++) {
		i2c_cmd_handle_t cmd = i2c_cmd_link_create();
		i2c_master_start(cmd);
		i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
		i2c_master_stop(cmd);

		espRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 10/portTICK_PERIOD_MS);
		if (i%16 == 0) {
			printf("\n%.2x:", i);
		}
		if (espRc == 0) {
			printf(" %.2x", i);
		} else {
			printf(" --");
		}
		//ESP_LOGD(tag, "i=%d, rc=%d (0x%x)", i, espRc, espRc);
		i2c_cmd_link_delete(cmd);
		vTaskDelay(25);
	}
	printf("\n");
	vTaskDelete(NULL);
}
and ledc code with different divider values to get different frequencies from 250kHz down (its igrr code):

Code: Select all

#include <stdio.h>
#include "esp_err.h"
#include "driver/ledc.h"
#include "driver/periph_ctrl.h"


void app_main()
{
    periph_module_enable(PERIPH_LEDC_MODULE);

    int bit_width = 2; // 1 - 20 bits
    int divider = 0x100;  // Q10.8 fixed point number, 0x100 — 0x3FFFF
    int duty_cycle = 1 << (bit_width-1);

    float freq_hz = ((uint64_t) LEDC_REF_CLK_HZ << 8) / (float) divider / (1 << bit_width);
    printf("frequency: %f Hz\n", freq_hz);

    ledc_timer_set(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0, divider, bit_width, LEDC_REF_TICK);
    ledc_timer_rst(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0);
    ledc_timer_resume(LEDC_HIGH_SPEED_MODE, LEDC_TIMER_0);
    ledc_channel_config_t channel_config = {
        .channel    = LEDC_CHANNEL_0,
        .duty       = duty_cycle,
        .gpio_num   = GPIO_NUM_22,
        .speed_mode = LEDC_HIGH_SPEED_MODE,
        .timer_sel  = LEDC_TIMER_0
    };

    ledc_channel_config(&channel_config);
}
This is 100kHz i2c CLK and 24MHz sample rate:
i2c_off.PNG
i2c_off.PNG (9.51 KiB) Viewed 4185 times
and 400kHz i2c CLK with 24MHz sample rate:
i2c_off400khz.PNG
i2c_off400khz.PNG (9.08 KiB) Viewed 4185 times
Last edited by chegewara on Fri Feb 15, 2019 4:52 am, edited 1 time in total.

mikemoy
Posts: 599
Joined: Fri Jan 12, 2018 9:10 pm

Re: I2C issue, CLK is off

Postby mikemoy » Wed Feb 13, 2019 1:17 pm

I cannot say for sure if this is it, but try moving your i2c_cmd_link_delete(cmd); right after
espRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 10/portTICK_PERIOD_MS);

Code: Select all

#include <driver/i2c.h>
#include <esp_log.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <stdio.h>
#include "sdkconfig.h"

#define SDA_PIN 21
#define SCL_PIN 22

static char tag[] = "i2cscanner";

extern void task_i2cscanner(void *ignore) {
	ESP_LOGD(tag, ">> i2cScanner");
	i2c_config_t conf;
	conf.mode = I2C_MODE_MASTER;
	conf.sda_io_num = SDA_PIN;
	conf.scl_io_num = SCL_PIN;
	conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
	conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
	conf.master.clk_speed = 400000;
	i2c_param_config(I2C_NUM_1, &conf);

	i2c_driver_install(I2C_NUM_1, I2C_MODE_MASTER, 0, 0, 0);

	int i;
	esp_err_t espRc;
	printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
	printf("00:         ");
	for (i=3; i< 0x78; i++) {
		i2c_cmd_handle_t cmd = i2c_cmd_link_create();
		i2c_master_start(cmd);
		i2c_master_write_byte(cmd, (i << 1) | I2C_MASTER_WRITE, 1 /* expect ack */);
		i2c_master_stop(cmd);

		espRc = i2c_master_cmd_begin(I2C_NUM_1, cmd, 10/portTICK_PERIOD_MS);
		i2c_cmd_link_delete(cmd);
		
		if (i%16 == 0) {
			printf("\n%.2x:", i);
		}
		if (espRc == 0) {
			printf(" %.2x", i);
		} else {
			printf(" --");
		}
		//ESP_LOGD(tag, "i=%d, rc=%d (0x%x)", i, espRc, espRc);

		vTaskDelay(25);
	}
	printf("\n");
	vTaskDelete(NULL);
}

ESP_igrr
Posts: 2067
Joined: Tue Dec 01, 2015 8:37 am

Re: I2C issue, CLK is off

Postby ESP_igrr » Thu Feb 14, 2019 2:08 pm


chegewara
Posts: 2207
Joined: Wed Jun 14, 2017 9:00 pm

Re: I2C issue, CLK is off

Postby chegewara » Fri Feb 15, 2019 4:51 am

Thanks. My problems are caused by 2 factors: 1. ignorance or lack of knowledge, 2. max30100.

Ive been told that i2c clock is not constant and depend on many factors like wiring, pull-up etc. My test was performed with max30100 and with floating i2c pins without pull-ups. Other i2c "sensors" i have are working.

Now when i know more i can perform better tests and find root cause with max30100.

Who is online

Users browsing this forum: ESP_Sprite and 99 guests