-
Notifications
You must be signed in to change notification settings - Fork 0
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
Comments
Hello @erian747, Why are you using 2 pins for the INT ?
In your BSP you shall implement 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. |
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. |
Hi 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 |
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
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.
Yes, that makes sense. We can focus on the issues you're having.
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.
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. |
Hi @erian747, any luck on your side? Were you able to figure out the issue with the RTC cal? |
Hi, thanks for your advices and clarifications! |
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 Sorry for wasting your time and thanks for the support! |
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. |
Hi, I am working on same sensor ch101 interface to nRF5340. 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.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: [00:00:00.455,078] ch_driver: [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,374] ch_driver: Test I2C read: FF17 [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,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,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.421,020] ch101_sensor: ch_group_start failed:1 Please analyze the log and provide what is going wrong? Thanks in advance Regards, |
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 |
Hi @mhkline , [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: [00:00:00.404,937] ch_driver: [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,078] ch_driver: Device [0] found on bus [00:00:00.412,078] ch_driver: Loading RAM init data... [00:00:00.412,292] ch_driver: Programming sensor... [00:00:00.412,506] ch_driver: Error programming device [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. Regards, |
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, |
Hi @mhkline Br, |
Hi @erian747 , |
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:
Best, |
HI @mhkline ,
This is the circuit used for level shifting, the level shifter part number used for INT is 74AVCH4T245PW-Q10J Thanks&Regards, |
Hi @mhkline , |
Hi @mhkline , |
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.
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. |
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. |
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);
}
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);
}
void chbsp_print_str(char *s)
{
LOG_INF("chbsp: %s", s);
}
int chbsp_i2c_init(void)
{
i2c_dev = device_get_binding("i2c@58001c00");
}
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;
}
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;
}
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;
}
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;
}
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;
}
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);
}
The text was updated successfully, but these errors were encountered: