[answered] I2C issue, CLK is off
Posted: 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:
and ledc code with different divider values to get different frequencies from 250kHz down (its igrr code):
This is 100kHz i2c CLK and 24MHz sample rate:
and 400kHz i2c CLK with 24MHz sample rate:
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);
}
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);
}