Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CH101 does not start measure in free run mode #8

Open
erian747 opened this issue Jun 2, 2024 · 21 comments
Open

CH101 does not start measure in free run mode #8

erian747 opened this issue Jun 2, 2024 · 21 comments
Assignees

Comments

@erian747
Copy link

erian747 commented Jun 2, 2024

Hi, im trying to get a CH101 sensor working with a STM32H747I Discovery kit
I think loading of the sensor is ok, but it doesn't seem to start any measurements (INT pin stays low)
See attached below UART log, BSP file and initilization in main.c
Im a bit stuck on how to proceed, do you have any advice of what i can test or do to get further?

Startup log
[00:00:00.456,000] chbsp_chirp: chbsp: prog enabled
[00:00:00.457,000] chbsp_chirp: chbsp: reset released
[00:00:00.460,000] chbsp_chirp: chbsp: prog disabled
[00:00:00.460,000] chbsp_chirp: chbsp: prog enabled
[00:00:00.461,000] chbsp_chirp: chbsp: Test I2C read: 020A

[00:00:00.462,000] chbsp_chirp: chbsp: PROG_STAT: 0x05

[00:00:00.462,000] chbsp_chirp: chbsp: chdrv_init_ram

[00:00:00.462,000] chbsp_chirp: chbsp: Loading RAM init data...

[00:00:00.464,000] chbsp_chirp: chbsp: Wrote 13 bytes in 2 ms.

[00:00:00.464,000] chbsp_chirp: chbsp: chdrv_write_firmware

[00:00:00.464,000] chbsp_chirp: chbsp: Programming sensor...

[00:00:00.627,000] chbsp_chirp: chbsp: Wrote 2048 bytes in 164 ms.

[00:00:00.628,000] chbsp_chirp: chbsp: Changing I2C address to 45

[00:00:00.642,000] chbsp_chirp: chbsp: prog disabled
[00:00:00.642,000] chbsp_chirp: chbsp: Sensor count: 1, 185 ms.
Chirp sensor initialized on I2C addr 0:45

[00:00:00.677,000] chbsp_chirp: chbsp: Frequency locked, 220 ms

[00:00:00.678,000] chbsp_chirp: chbsp INT in-active
[00:00:00.678,000] chbsp_chirp: chbsp INT in-active
[00:00:00.688,000] chbsp_chirp: chbsp INT active
[00:00:00.789,000] chbsp_chirp: chbsp INT in-active
[00:00:00.789,000] chbsp_chirp: chbsp: RTC calibrated, 333 ms
0 : Cal result = 256

uart:~$ Set samples: ret_val: 0 dev_ptr->num_rx_samples: 2
[00:00:00.892,000] chbsp_chirp: chbsp: num_samples=2

[00:00:00.897,000] chbsp_chirp: chbsp: Set period=4, tick_interval=128

[00:00:00.899,000] chbsp_chirp: chbsp: Set period=4, tick_interval=128

[00:00:00.901,000] chbsp_chirp: chbsp INT interrupt enable


chbsp.c
#include <stdint.h>
#include <stdbool.h>

#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/i2c.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(chbsp_chirp, CONFIG_LOG_DEFAULT_LEVEL);

// Chirp SonicLib API definitions
#include <invn/soniclib/chirp_bsp.h>
#include <invn/soniclib/soniclib.h>

#define CHX01_INT_DIR_OUT (1)
#define CHX01_INT_DIR_IN (0)

#define CHBSP_RTC_CAL_PULSE_MS (100)

/*
D09 - PJ6 - Orange - INT pull to 1.8V (Push-pull, pull low to activate 1.8V wih P-MOS)
D10 - PK1 - Blue - RST
D11 - PJ10 - Orange INT input
D12 - PJ11 - White - PROG (Inverted)

D13 - PK0 - Orange - INT (unused, set to folating input)
*/

static const struct device *i2c_dev = NULL;
static const uint8_t chx01_i2c_addrs[] = {0x2D, 0x2C, 0x2B, 0x2A};

static ch_group_t *sensor_group_ptr = NULL;
static struct gpio_callback int_cb;

#if !DT_NODE_HAS_STATUS(DT_NODELABEL(gpioj), okay)
#error GPIOA not configured
#endif
#if !DT_NODE_HAS_STATUS(DT_NODELABEL(gpiok), okay)
#error GPIOK not configured
#endif

typedef struct {
const struct device *dev;
uint32_t pin;
} ch_gpio_t;

static const ch_gpio_t rst_pin = {DEVICE_DT_GET(DT_NODELABEL(gpiok)), 1};
static const ch_gpio_t prog_pin = {DEVICE_DT_GET(DT_NODELABEL(gpioj)), 11};
static const ch_gpio_t int_pin_in = {DEVICE_DT_GET(DT_NODELABEL(gpioj)), 10};
static const ch_gpio_t int_pin_out = {DEVICE_DT_GET(DT_NODELABEL(gpioj)), 6};

static int chpin_configure(const ch_gpio_t *gpio, uint32_t mode)
{
int res;
if (!device_is_ready(gpio->dev)) {
LOG_ERR("gpio device driver not ready.");
return -ENODEV;
}
res = gpio_pin_configure(gpio->dev, gpio->pin, mode);

return res;

}

static int sensors_pin_init(ch_dev_t dev_ptr)
{
int res = 0;
/
Configure INT I/O pins */
res |= chpin_configure(&int_pin_in, GPIO_INPUT | GPIO_PULL_UP);
res |= chpin_configure(&int_pin_out, GPIO_OUTPUT | GPIO_OUTPUT_INIT_HIGH);

/* Configure RST pin as output */
res |= chpin_configure(&rst_pin, GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW);

/* Configure PROG pin as output */
res |= chpin_configure(&prog_pin, GPIO_OUTPUT | GPIO_OUTPUT_INIT_LOW);
return res;

}

void chbsp_print_str(char *s)
{
LOG_INF("chbsp: %s", s);
}

int chbsp_i2c_init(void)
{
i2c_dev = device_get_binding("i2c@58001c00");

if (!i2c_dev) {
	LOG_ERR("I2C: Device driver not found.");
	return -ENODEV;
}
return 0;

}

void chbsp_i2c_reset(ch_dev_t *dev_ptr)
{
(void)dev_ptr;
}

static void int_cb_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
if(sensor_group_ptr != NULL)
{
ch_interrupt(sensor_group_ptr, 0);
// Data ready handler disables interrupt, make it ready to fire again !
chbsp_int1_interrupt_enable(ch_get_dev_ptr(sensor_group_ptr, 0));
}
}

void chbsp_board_init(ch_group_t grp_ptr)
{
int ret;
/
Make local copy of group pointer */
sensor_group_ptr = grp_ptr;

/* Initialize group descriptor */
grp_ptr->num_ports = 1;
grp_ptr->num_buses = 1;
grp_ptr->rtc_cal_pulse_ms = CHBSP_RTC_CAL_PULSE_MS;
grp_ptr->disco_hook = NULL;

ret = chbsp_i2c_init();
if (ret) {
	return;
}
ret = sensors_pin_init(grp_ptr->device[0]);
if (ret) {
	return;
}
gpio_init_callback(&int_cb, int_cb_handler, BIT(int_pin_in.pin));
ret = gpio_add_callback(int_pin_in.dev, &int_cb);
if (ret) {
	LOG_ERR("Error adding irq callback");
}

}

void chbsp_set_int1_dir_out(ch_dev_t *dev_ptr)
{
//chpin_configure(&int_pin, GPIO_OUTPUT);
}

void chbsp_set_int1_dir_in(ch_dev_t *dev_ptr)
{
//chpin_configure(&int_pin, GPIO_INPUT | GPIO_PULL_UP);
}

void chbsp_int1_clear(ch_dev_t *dev_ptr)
{
LOG_INF("chbsp INT in-active");
// Turn off P-MOS
gpio_pin_set(int_pin_out.dev, int_pin_out.pin, 1);
}

void chbsp_int1_set(ch_dev_t *dev_ptr)
{
LOG_INF("chbsp INT active");
// Turn on P-MOS to connect 1.8V
gpio_pin_set(int_pin_out.dev, int_pin_out.pin, 0);
}

void chbsp_int1_interrupt_enable(ch_dev_t *dev_ptr)
{
LOG_INF("chbsp INT interrupt enable");
chbsp_set_int1_dir_in(dev_ptr);
gpio_pin_interrupt_configure(int_pin_in.dev, int_pin_in.pin, GPIO_INT_EDGE_TO_INACTIVE);
}

void chbsp_int1_interrupt_disable(ch_dev_t *dev_ptr)
{
LOG_INF("chbsp INT interrupt disable");
gpio_pin_interrupt_configure(int_pin_in.dev, int_pin_in.pin, GPIO_INT_DISABLE);
}

uint8_t chbsp_i2c_get_info(ch_group_t attribute((unused)) * grp_ptr, uint8_t io_index, ch_i2c_info_t info_ptr)
{
info_ptr->address = chx01_i2c_addrs[io_index];
/
All sensors on same bus /
info_ptr->bus_num = 0;
info_ptr->drv_flags = 0; /
no special I2C handling by SonicLib driver is needed */
return 0;
}

int chbsp_i2c_write(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes)
{
int ret;
struct i2c_msg msgs[1];
msgs[0].buf = data;
msgs[0].len = num_bytes;
msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

ret = i2c_transfer(i2c_dev, &msgs[0], 1, ch_get_i2c_address(dev_ptr));
if (ret != 0) {
	LOG_ERR("chbsp_i2c_write: I2C write failed: %d", ret);
}
return ret;

}

int chbsp_i2c_read(ch_dev_t *dev_ptr, uint8_t *data, uint16_t num_bytes)
{
int ret;
struct i2c_msg msgs[1];
msgs[0].buf = data;
msgs[0].len = num_bytes;
msgs[0].flags = I2C_MSG_READ | I2C_MSG_STOP;

ret = i2c_transfer(i2c_dev, &msgs[0], 1, ch_get_i2c_address(dev_ptr));
if (ret != 0) {
	LOG_ERR("chbsp_i2c_read: I2C read failed: %d", ret);
}
return ret;

}

int chbsp_i2c_mem_write(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes)
{
int ret;
struct i2c_msg msgs[2];
uint8_t reg = mem_addr;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[0].flags = I2C_MSG_WRITE;
msgs[1].buf = data;
msgs[1].len = num_bytes;
msgs[1].flags = I2C_MSG_WRITE | I2C_MSG_STOP;

ret = i2c_transfer(i2c_dev, msgs, 2, ch_get_i2c_address(dev_ptr));
if (ret != 0) {
	LOG_ERR("chbsp_i2c_mem_write: I2C mem write failed: %d", ret);
}

return ret;

}

int chbsp_i2c_mem_read(ch_dev_t *dev_ptr, uint16_t mem_addr, uint8_t *data, uint16_t num_bytes)
{
int ret;
struct i2c_msg msgs[2];
uint8_t reg = mem_addr;
msgs[0].buf = ®
msgs[0].len = 1;
msgs[0].flags = I2C_MSG_WRITE;
msgs[1].buf = data;
msgs[1].len = num_bytes;
msgs[1].flags = I2C_MSG_RESTART | I2C_MSG_READ | I2C_MSG_STOP;

ret = i2c_transfer(i2c_dev, msgs, 2, ch_get_i2c_address(dev_ptr));
if (ret != 0) {
	LOG_ERR("chbsp_i2c_mem_read: I2C mem read failed: %d", ret);
}
return ret;

}

void chbsp_reset_assert(void)
{
gpio_pin_set(rst_pin.dev, rst_pin.pin, 0);
LOG_INF("chbsp: reset asserted");
}

void chbsp_reset_release(void)
{
gpio_pin_set(rst_pin.dev, rst_pin.pin, 1);
LOG_INF("chbsp: reset released");
}

void chbsp_program_enable(ch_dev_t *dev_ptr)
{
// Inverted on adapter board
gpio_pin_set(prog_pin.dev, prog_pin.pin, 0);
LOG_INF("chbsp: prog enabled");
}

void chbsp_program_disable(ch_dev_t *dev_ptr)
{
gpio_pin_set(prog_pin.dev, prog_pin.pin, 1);
LOG_INF("chbsp: prog disabled");
}

void chbsp_delay_us(uint32_t us)
{
k_usleep(us);
}

void chbsp_delay_ms(uint32_t ms)
{
k_msleep(ms);
}

void chbsp_group_set_int1_dir_out(ch_group_t *grp_ptr)
{
chbsp_set_int1_dir_out(ch_get_dev_ptr(grp_ptr, 0));
}

void chbsp_group_set_int1_dir_in(ch_group_t *grp_ptr)
{
chbsp_set_int1_dir_in(ch_get_dev_ptr(grp_ptr, 0));
}

void chbsp_group_int1_clear(ch_group_t *grp_ptr)
{
chbsp_int1_clear(ch_get_dev_ptr(grp_ptr, 0));
}

void chbsp_group_int1_set(ch_group_t *grp_ptr)
{
chbsp_int1_set(ch_get_dev_ptr(grp_ptr, 0));
}
void chbsp_group_int1_interrupt_enable(ch_group_t *grp_ptr)
{
chbsp_int1_interrupt_enable(ch_get_dev_ptr(grp_ptr, 0));
}
void chbsp_group_int1_interrupt_disable(ch_group_t *grp_ptr)
{
chbsp_int1_interrupt_disable(ch_get_dev_ptr(grp_ptr, 0));
}

uint32_t chbsp_timestamp_ms(void)
{
return k_ticks_to_ms_near32(k_uptime_ticks());
}


// Main.c

extern void chbsp_board_init(ch_group_t *grp_ptr);
static ch_group_t chirp_group;
static ch_dev_t chirp_device;

static bool is_measure_ready = false;

static void sensor_int_callback(ch_group_t *grp_ptr, uint8_t dev_num, ch_interrupt_type_t int_type)
{
if (int_type == CH_INTERRUPT_TYPE_DATA_RDY) {
is_measure_ready = true;
}
}

/* Initialize hardware and ICU sensor */
static int ch_101_init(void)
{
int rc = 0;
chbsp_board_init(&chirp_group);
rc = ch_init(&chirp_device, &chirp_group, 0, ch101_gpr_init);

if (rc == 0) {
	rc = ch_group_start(&chirp_group);
}
if (rc == 0) {
	/* Register callback function to be called when Chirp sensor interrupts */
	ch_io_int_callback_set(&chirp_group, sensor_int_callback);
}
if (rc == 0) {
	rc = ch101_free_run(&chirp_device, 800, 100);
}
return rc;

}

@gferard-invn
Copy link

Hello @erian747,

Why are you using 2 pins for the INT ?
The interrupt pin of sensor is bidirectional.
The int pin shall :

  • have a pull down.
  • be configured to trigger an interrupt on rising edge (interrupt disabled at init)

In your BSP you shall implement chbsp_set_int1_dir_out() and chbsp_set_int1_dir_in()

In the trace below you will see during the initialization a pulse which lasts 100 ms. It's important that this pulse is effectively 100 ms because it's used to calibrate the internal RTC which is used for freerun mode.

You'll find attached a logic analyzer trace of what it should look like.
ch101_gpr_init_2_measures_freerun.zip

@erian747
Copy link
Author

erian747 commented Jun 3, 2024

Hi, thanks for your response!

Im using 2 pins for interfacing with a custom level shifter as seen below
Screenshot from 2024-06-03 22-05-13

I have verified that the level-shifter works as expected in both directions, Made a quick capture of pin during calibration pulse:
Screenshot from 2024-06-03 22-17-54

By the design of the level-shifter, i think chbsp_set_int1_dir_out() can be left unimplemented, but you are right in that chbsp_set_int1_dir_in should be implemented (needed in case "int_pin_out" is not deasserted before int_pin_in on STM32 should reflect CH101 pin state). Fixed now in code, but didnt solve my issue unfortunately

I also tested calling ch_common_check_program() function, and it reported FW was written correctly

I forced a read by setting "is_measure_ready" to true by debugger which triggers this code:

ch_iq_sample_t raw_data[256];
memset(raw_data, 0, sizeof(raw_data));
uint16_t nb_samples = ch_get_num_samples(&chirp_device);
int rc = ch_get_iq_data(&chirp_device,raw_data, 0, nb_samples, CH_IO_MODE_BLOCK);
for(int i = 0; i < 10; i++) {
  LOG_INF("iq_data: %d:%d", raw_data[i].i, raw_data[i].q);

but the result below stays fixed every forced read with data below, so no measurements seems to be performed
[00:00:23.248,000] app: iq_data: -3:1
[00:00:23.248,000] app: iq_data: -21:133
[00:00:23.248,000] app: iq_data: -77:486
[00:00:23.248,000] app: iq_data: -159:672
[00:00:23.248,000] app: iq_data: -199:362
[00:00:23.248,000] app: iq_data: -190:-83
[00:00:23.248,000] app: iq_data: -183:-254
[00:00:23.248,000] app: iq_data: 0:0
[00:00:23.248,000] app: iq_data: 0:0

I have stepped trough most of the initialization code, and everything looks ok with no errors occurring
What i am missing is how to read back the state of CH101 when it is in free running mode,
are there any I2C registers i can read to check the reason why measurements is not started?

@mhkline
Copy link
Contributor

mhkline commented Jun 4, 2024

Hi @erian747,

You do not observe that the CH101 generates any interrupts after you set it into freerunning mode? That is the easiest way to check that it is performing measurements.

Do you have a SmartSonic EVK board that you could use with our example as a reference? I think this would be the most helpful thing for you. We can share the schematic for that board if it's helpful.

@erian747
Copy link
Author

erian747 commented Jun 4, 2024

Hi
Yes that is correct, INT is not pulled high by CH101 after entering free run mode
I don't have any SmartSonic EVK to test on, could possibly buy one if that would help, but isn't that used together with the "SmartSonic_HelloChirp_v1.31.0" software package? which includes the older"sonclib v2"?

That is one thing that confuses me, seems like different ports: Arduino, Raspberry Pi Pico and SmartSonic uses its own unique versions of CHx01 drivers (one would expect this library to be used by all HW ports)

Hope you understand me, but i have already spent quite some time to get everything up and running with this library so i would really prefer not having to start over again with an outdated library version, especially when everything seems to be working except starting a measurement

I like the library in this repo because it was really easy to integrate with CMake and Zephyr
Maybe you have a working example of a port that is using the library in this repo?
If not, do you think it's worth trying the version of the library used in the Arduino port? (it seems to be newer)

@mhkline
Copy link
Contributor

mhkline commented Jun 5, 2024

I don't have any SmartSonic EVK to test on, could possibly buy one if that would help, but isn't that used together with the "SmartSonic_HelloChirp_v1.31.0" software package? which includes the older"sonclib v2"?

First, I apologize for the confusion here. The smartsonic example for CH101 on our developer corner appears to be very out of date. I'm attaching our latest internally validated example here, which uses soniclib 3.24.0. It should not be an issue to update this to 3.32.6 (latest 3.x.x tag). We have also taken an action to get the developer corner updated. Hopefully we can get the examples moved over to our public github, but it will be a bit of a process for us.

invn.chirpmicro.smartsonic.chx01-hellochirp-example.2.31.0.zip

That is one thing that confuses me, seems like different ports: Arduino, Raspberry Pi Pico and SmartSonic uses its own unique versions of CHx01 drivers (one would expect this library to be used by all HW ports)

Yes, good point. I am not as familiar with the Raspberry Pi side, but I can speak to why this is the case for the Arduino and SmartSonic. The 3.x.x version of soniclib was not compatible (or easy) to use an Arduino projects, which is the main motivation for soniclib v4. We have just pushed soniclib v4 to this repo, and we are in the process of trying to unify this. You can still use soniclib v3.x.x by checking out the old tags, so you can continue to use that until we get your issues figured out.

Hope you understand me, but i have already spent quite some time to get everything up and running with this library so i would really prefer not having to start over again with an outdated library version, especially when everything seems to be working except starting a measurement

Yes, that makes sense. We can focus on the issues you're having.

I like the library in this repo because it was really easy to integrate with CMake and Zephyr
Maybe you have a working example of a port that is using the library in this repo?

Yes, we tried to make this project easy to integrate, and I'm glad you were able to get that to work. Can you check the attached 2.31.0 example and see if that clears anything up?


Regarding your specific issue, there is one thing that really jumps out at me.

[00:00:00.789,000] chbsp_chirp: chbsp: RTC calibrated, 333 ms
0 : Cal result = 256

This result is way off of what it should be. The normal range for this is something like 2700-3000. It's the number of counts of the ASIC's internal RTC over that 100ms pulse that you're providing, and the RTC has a frequency in the 27kHz-30kHz range.

So, there is something going wrong with the RTC cal process. I'm attaching the soniclib programmer's guide because it explains what this does pretty well, and it also gives some options for skipping the cal entirely, which you can try to see if this resolves the issue. Please refer to section 8.5 on page 53 of the attached pdf.

AN-000175_SonicLib_Programmers_Guide_v2.0.pdf

If skipping the cal resolves the issue, then we can focus on what's going wrong with the cal process. Maybe something in the provided example will jump out at you. If not, please let me know, and we can work together to resolve.

EDIT:

I meant to also comment on why the RTC cal could cause an issue like this. If the host MCU thinks the RTC is this slow (only 256 clock cycles in 100 ms = 2560 Hz), then the host will be attempting to set some extremely small value as the free running measurement period. For example, if you wanted a period of 100ms, it would set the period to 256. In reality, the RTC is approximately 10x faster than this, so the ASIC would be trying to take a measurement every 10ms, which may be much too fast given the maximum range setting.

@mhkline mhkline self-assigned this Jun 6, 2024
@mhkline
Copy link
Contributor

mhkline commented Jun 7, 2024

Hi @erian747, any luck on your side? Were you able to figure out the issue with the RTC cal?

@erian747
Copy link
Author

erian747 commented Jun 7, 2024

Hi, thanks for your advices and clarifications!
I am on vacation until monday, but i will come back with some results in early next week

@erian747
Copy link
Author

Hi

I finally found the problem by hooking up a logic analyzer on I2C, there was a bug in the STM32 I2C driver, causing the chbsp_i2c_mem_write() to issue an I2C restart condition between register addr and length/data
That in turn caused RTC calibration to be skipped
After fixing that, now everything is working as expected, freerun mode pulls INT pin high and measurement results are updated

Sorry for wasting your time and thanks for the support!

@mhkline
Copy link
Contributor

mhkline commented Jun 10, 2024

Hi @erian747. I'm glad you were able to resolve your issue. No need to apologize. :D I'm sure you won't be the only one to come across this bug, and maybe this issue will help someone in the future.

@mhkline mhkline closed this as completed Jun 10, 2024
@NaveenKoyyada
Copy link

Hi,

I am working on same sensor ch101 interface to nRF5340.
The library version is
ch101_gpr_version = "gpr_gpr-101_v47";
SonicLib API/Driver version = 4.2.1

Are above versions works with this part number <EV_MOD_CH101-01-02>?

Currently, I am facing I2C error when prog pin is enabling during reset. In normal I2C call, the write and read calls are ok. I think the sensor is not getting into programming mode.

Below is the log:
[00:00:00.454,681] main_init: GPIO Initialization

[00:00:00.455,047] chbsp_chirp: i2c_ch101 is ready!

[00:00:00.455,078] ch101_sensor: ch_init successful

[00:00:00.455,078] ch_driver:
chdrv_group_prepare:0

[00:00:00.455,078] ch_driver:
chbsp_i2c_init:0

[00:00:00.455,108] ch_driver: INCLUDE_WHITNEY_SUPPORT called

[00:00:00.455,108] ch_driver: set_all_devices_idle called

[00:00:00.455,108] chbsp_chirp: chbsp_reset_assert called

[00:00:00.455,139] chbsp_chirp: chbsp_program_enable called

[00:00:00.456,207] chbsp_chirp: chbsp_reset_release called

[00:00:00.456,237] ch_driver: chdrv_prog_write called2

[00:00:00.456,237] chbsp_chirp: chbsp_i2c_write called 3 nbytes

[00:00:00.456,573] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.456,573] ch_driver: chdrv_prog_write called4

[00:00:00.456,573] ch_driver: chdrv_prog_mem_write exit: 251

[00:00:00.456,604] chbsp_chirp: chbsp_program_disable called

[00:00:00.456,604] ch_driver: scanning num_ports:0

[00:00:00.456,604] chbsp_chirp: chbsp_program_enable called

[00:00:00.456,634] chbsp_chirp: chbsp_i2c_write called 2 nbytes

[00:00:00.457,031] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.457,031] chbsp_chirp: chbsp_i2c_write called 2 nbytes

[00:00:00.457,427] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.457,458] ch_driver: reset_and_halt: 00FB

[00:00:00.457,458] chbsp_chirp: chbsp_i2c_write called 1 nbytes

[00:00:00.457,763] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.457,763] chbsp_chirp: chbsp_i2c_read called

[00:00:00.458,312] chbsp_chirp: data[0]:0x17
[00:00:00.458,343] chbsp_chirp: data[1]:0xff
[00:00:00.458,343] chbsp_chirp: data[2]:0xff
[00:00:00.458,343] chbsp_chirp: data[3]:0xff
[00:00:00.458,374] chbsp_chirp: chbsp_i2c_read success from addr:0x45

[00:00:00.458,374] ch_driver: Test I2C read: FF17
[00:00:00.458,374] ch_driver: Ping failed, device 0 not found
[00:00:00.458,404] chbsp_chirp: chbsp_program_disable called

[00:00:00.458,404] ch_driver: exit whitney_detect_and_program ch_err:0

[00:00:00.458,404] ch_driver: ch101 sensor not yet ready:0 ch_err:0
[00:00:00.458,404] ch_driver: No Chirp sensor devices are responding
[00:00:00.458,435] ch_common:
-------CH_GROUP_STAT_INIT_FAILED

[00:00:00.458,435] ch101_sensor: ch_group_start failed:1

success from addr:0x45

[00:00:00.420,959] ch_driver: Test I2C read: FF17
[00:00:00.420,959] ch_driver: Ping failed, device 0 not found
[00:00:00.420,959] chbsp_chirp: chbsp_program_disable called

[00:00:00.420,989] ch_driver: exit whitney_detect_and_program ch_err:0

[00:00:00.420,989] ch_driver: ch101 sensor not yet ready:0 ch_err:0
[00:00:00.420,989] ch_driver: No Chirp sensor devices are responding
[00:00:00.421,020] ch_common:
-------CH_GROUP_STAT_INIT_FAILED

[00:00:00.421,020] ch101_sensor: ch_group_start failed:1

Please analyze the log and provide what is going wrong?

Thanks in advance

Regards,
KNK

@mhkline
Copy link
Contributor

mhkline commented Jul 31, 2024

Hi @NaveenKoyyada,

Thanks for your detailed message.

I looked at the log and unfortunately can't tell what's going wrong exactly. It looks like the first thing that fails is a write to the I2C programming address 0x45?

How can you tell that the "normal" I2C calls are working? IIRC, the driver should not interact with the part at all on the application address until after it has written the program using the programming address.

Do you have a logic analyzer you could use to capture the I2C, program, reset, and interrupt lines? This is our standard approach for debugging these types of issues. We have Saleae analyzers and can easily load up something if you send a Logic2 format file.

FYI @gferard-invn

@mhkline mhkline reopened this Jul 31, 2024
@NaveenKoyyada
Copy link

NaveenKoyyada commented Aug 1, 2024

Hi @mhkline ,
I have replaced level shifter circuit board, then I witness some positive result see log below
*** Booting nRF Connect SDK d96769faceca ***
[00:00:00.304,412] main_init: GPIO Initialization

[00:00:00.304,779] chbsp_chirp: i2c_ch101 is ready!

[00:00:00.304,809] ch101_sensor: ch_init successful

[00:00:00.304,809] ch101_sensor: ch_group_start with delay of 100mS

[00:00:00.404,937] ch_driver:
chdrv_group_prepare:0

[00:00:00.404,937] ch_driver:
chbsp_i2c_init:0

[00:00:00.404,968] ch_driver: set_all_devices_idle called

[00:00:00.404,968] chbsp_chirp: chbsp_reset_assert called

[00:00:00.404,968] chbsp_chirp: chbsp_program_enable called

[00:00:00.406,066] chbsp_chirp: chbsp_reset_release called

[00:00:00.406,585] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.407,104] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.407,501] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.408,111] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.408,508] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.408,935] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.409,423] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.409,942] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.410,339] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.410,339] chbsp_chirp: chbsp_program_disable called

[00:00:00.410,339] ch_driver: scanning num_ports:0

[00:00:00.410,369] chbsp_chirp: chbsp_program_enable called

[00:00:00.410,766] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.411,163] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.411,163] ch_driver: reset_and_halt: 0000

[00:00:00.411,468] chbsp_chirp: chbsp_i2c_write success to addr:0x45

[00:00:00.412,017] chbsp_chirp: data[0]:0xa
[00:00:00.412,017] chbsp_chirp: data[1]:0x2
[00:00:00.412,048] chbsp_chirp: data[2]:0xa
[00:00:00.412,048] chbsp_chirp: data[3]:0xff
[00:00:00.412,048] chbsp_chirp: chbsp_i2c_read success from addr:0x45

[00:00:00.412,078] ch_driver: Device [0] found on bus
[00:00:00.412,078] ch_driver: ram_address:512 ram_bytecount38

[00:00:00.412,078] ch_driver: Loading RAM init data...
[00:00:00.412,292] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.412,292] ch_driver: Programming sensor...
[00:00:00.412,506] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.412,506] ch_driver: Error programming device
[00:00:00.412,719] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.412,933] chbsp_chirp: chbsp_i2c_write failed addr:0x45 err:-5

[00:00:00.412,933] chbsp_chirp: chbsp_program_disable called

[00:00:00.412,933] chbsp_chirp: chbsp_i2c_reset called

[00:00:00.412,963] ch_driver: dev_ptr & current_fw is NULL

[00:00:00.412,963] ch_driver: ch101 sensor not yet ready:1 ch_err:251

program continues to retry

Loading RAM is getting failed.
The level shifter which I am using was given the issue, but this RAM is not loading.

Regards,
Naveen

@mhkline
Copy link
Contributor

mhkline commented Aug 1, 2024

Hi Naveen,

I wonder if maybe the normal write function is working but maybe the burst write is not? It's hard to say what's happening exactly without the logic analyzer.

Best,
Mitchell

@NaveenKoyyada
Copy link

NaveenKoyyada commented Aug 2, 2024

Hi @mhkline
Even it is a burts write, the corresponding function initial call is for 2bytes storing.
image

Br,
Naveen

@NaveenKoyyada
Copy link

Hi @erian747 ,
Did you face any challenges during init_ram()? Currently I am facing I2C failure at this function call.
Could you please have a look at my previous messages and let me know.
your response will appreciate.
Br,
@NaveenKoyyada

@mhkline
Copy link
Contributor

mhkline commented Aug 2, 2024

Hi @NaveenKoyyada,

I think you'll either need to share your BSP implementation or some logic analyzer traces for us to make some progress on this. I will say that one common pitfall with the CH*01 is the level shifter. I know you've already diagnosed some issue with that, but it's something we can review if you share a schematic. The CH*01 has a bidirecitonal interrupt line with a weak pull-down, so it's not so easy to level shift (though there are recommended circuits in the datasheet). The ICU-*0201 parts use open-drain style interrupts, so that's one of many improvements in the new line.

You can also try reaching out through the developer's corner support page to get in touch with an application engineer.

Some other info that would be good to know:

  1. Did you start from one of our hellochirp examples? Which version?
  2. What is the version of SonicLib (it's in the soniclib.h header)?
  3. Did you create your board support package from scratch or start with something existing?
  4. Did you make any modifications to soniclib (outside of the BSP layer)?

Best,
Mitchell

@NaveenKoyyada
Copy link

HI @mhkline ,
Answer to questions

  1. It's an arduino library(v1.0.4) downloaded from https://www.arduinolibraries.info/libraries/c-hx01
  2. ch101_gpr_version = "gpr_gpr-101_v47"; SonicLib API/Driver version = 4.2.1
  3. Yes, I created my own bsp as per nRF SDK.
  4. No, I didn't modify the library. Only I have put logs to track the flow.

This is the circuit used for level shifting, the level shifter part number used for INT is 74AVCH4T245PW-Q10J
LevelShifter_ch101
I will share the bsp implementation.
As I am stuck with the load ram issue, in parallel I want to check with hello chirp example 2.31.0 as mentioned before.

Thanks&Regards,
Naveen

@NaveenKoyyada
Copy link

Hi @mhkline ,
This is chbsp_chirp.c for nRF board specific,
chbsp_chirp_c.txt
Br,
Naveen

@NaveenKoyyada
Copy link

Hi @mhkline ,
I tried to capture the signals on scope
image
At least this would give some idea that what is happening on I2C clk.
Br,
Naveen

@mhkline
Copy link
Contributor

mhkline commented Aug 5, 2024

This is the circuit used for level shifting, the level shifter part number used for INT is 74AVCH4T245PW-Q10J

I'm a little confused by the schematic. It looks like you have the 74XX chip in addition to a single-transistor level shifter? I think this IC should work, as it seems very similar to the recommended SN74LVC2T45, but the single-transistor shifter needs to be disconnected/removed.

I tried to capture the signals on scope

It's a little hard to tell what's going on, but it almost looks like your clock signal is switching between 1.8 and 3.3 instead of between 0 and 1.8.

@NaveenKoyyada
Copy link

NaveenKoyyada commented Aug 5, 2024

Okay, I will replace single transistor shifter by 74xx.

and will observe the result.

Please confirm me that INT will not be in use until ch_group_start is succes, Can I ignore it? Once this is success, will make separate level shifter for INT.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants