Hi guys,
So, I've been working on a project for measuring liquid using the TDC1000 IC from TI which was running fine on STM32.
My experience with nordic connect sdk is not great and I may be doing something wrong here.
I want to run a single thread application that will first enable external power for the driver, then activate the PWM signal for the CLKIN of the TDC1000 and then perform a reading by driving the trigger pin.
I've this implemented and it seems to work since I receive some debug messages on the interrupt callback. However, after wrapping the code by doing something like:
static const struct gpio_dt_spec *required_gpios_ins[2] = {&tdc1000_start, &tdc1000_stop};
for (uint8_t i = 0; i < sizeof(required_gpios_ins) / sizeof(struct gpio_dt_spec *); i++)
{
if (!gpio_is_ready_dt(required_gpios_ins[i]))
{
LOG_ERR("One of the required GPIO's port is not ready.\n");
return EXIT_FAILURE;
}
err = gpio_pin_configure_dt(required_gpios_ins[i], GPIO_INPUT);
if (err != 0)
{
LOG_ERR("Error %d: failed to configure %s pin %d",
err, required_gpios_ins[i]->port->name, required_gpios_ins[i]->pin);
return EXIT_FAILURE;
}
err = gpio_pin_interrupt_configure_dt(required_gpios_ins[i], GPIO_INT_EDGE_TO_ACTIVE);
if (err != 0)
{
LOG_ERR("Error %d: failed to configure interrupt on %s pin %d",
err, required_gpios_ins[i]->port->name, required_gpios_ins[i]->pin);
return EXIT_FAILURE;
}
gpio_init_callback(gpio_cb_data[i], gpio_interrupt_handler, BIT(required_gpios_ins[i]->pin));
gpio_add_callback(required_gpios_ins[i]->port, gpio_cb_data[i]);
}
static void gpio_interrupt_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
static gpio_int_context_t int_context = {0};
int_context.cycle_count = k_cycle_get_32();
if (cb == &tdc1000_start_cb_data)
{
int_context.pin = TDC1000_START_PIN;
LOG_INF("Interrupt from START pin at %" PRIu32 "\n", k_cyc_to_us_floor32(k_cycle_get_32()));
}
else if (cb == &tdc1000_stop_cb_data)
{
int_context.pin = TDC1000_STOP_PIN;
LOG_INF("Interrupt from STOP pin at %" PRIu32 "\n", k_cyc_to_us_floor32(k_cycle_get_32()));
}
else if (cb == &tdc1000_errb_cb_data)
{
int_context.pin = TDC1000_ERRB_PIN;
LOG_INF("Interrupt from ERRB pin at %" PRIu32 "\n", k_cyc_to_us_floor32(k_cycle_get_32()));
}
else
{
// Nothing to do
return;
}
// add to the queue
k_msgq_put(&gpio_interrupt_q, &int_context, K_NO_WAIT);
}When I try to get the interrupt events from the queue "gpio_interrupt_q" in my main() loop application:
// wait for trigger start
if ((k_msgq_get(&gpio_interrupt_q, &interrupt_context, K_MSEC(10)) == 0) && (interrupt_context.pin == TDC1000_START_PIN))
{
uint32_t start_time = (uint32_t)k_uptime_get();
uint32_t elapsed = 0;
LOG_INF("Measure started at: %u!", start_time);
uint32_t stop_cycle_count[INT_QUEUE_SIZE] = {0};
stop_cycle_count[0] = interrupt_context.cycle_count; // start cycle
uint8_t stop_cycles_detected = 1;
// wait for reply
int msg = -1;
while ((timeout > elapsed) || ((msg = k_msgq_get(&gpio_interrupt_q, &interrupt_context, K_NO_WAIT)) == 0))
{
elapsed = (uint32_t)k_uptime_get() - start_time;
k_sleep(K_USEC(100));
if (msg == 0)
{
LOG_INF("Millis2: %u Elapsed: %u", (uint32_t)k_uptime_get(), elapsed);
...aNothing is received or debugged via the RTT logger until the timeout expires. If I set the timeout to 1 sec the log messages "Interrupt from STOP pin at" are received after 1 second. If I set the timeout to 10 seconds the log messages are received after 10 seconds. It seems that g_msgq_get is blocking the ISR? I've attempted different settings, like doing K_MSEC() instead of K_NOWAIT, or using just k_sleep and waiting to see the log messages and nothing works. K_sleep has the same beahviour as g_msgq_get. Only after elapsing the time the log messages are sent. The cycle time that is printed makes sense with the moment that it's printed. So, it really seems that the ISR is being delayed.
My prj.conf:
CONFIG_SENSOR=y CONFIG_LIS2DH=y CONFIG_I2C=y CONFIG_GPIO=y CONFIG_LOG=y CONFIG_USE_SEGGER_RTT=y CONFIG_CONSOLE=y CONFIG_RTT_CONSOLE=y CONFIG_UART_CONSOLE=n CONFIG_SERIAL=y CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_ADC=y CONFIG_MCP970X=y CONFIG_BT=y CONFIG_PWM=y CONFIG_CLOCK_CONTROL=y CONFIG_SPI=y CONFIG_WDT_LOG_LEVEL_INF=n CONFIG_WATCHDOG=n CONFIG_WDT_DISABLE_AT_BOOT=n CONFIG_REQUIRES_FLOAT_PRINTF=y CONFIG_BT_DEVICE_NAME="Beacon" CONFIG_MAIN_THREAD_PRIORITY=10 CONFIG_LIS2DH_TRIGGER_OWN_THREAD=n CONFIG_LIS2DH_ACCEL_RANGE_2G=y CONFIG_LIS2DH_OPER_MODE_LOW_POWER=y CONFIG_LIS2DH_ODR_1=y
Thank you for the ongoing support.
Best regards,
Fernando Fontes