I am a beginner in riot os and trying to implement a i2c compatible sensor for a project, however, i am not getting past the situation of using generic driver provided by the sensirion to riot compatible. Any help regarding obvious issues and directions are much appreciated.
firstly i have downloaded the embedded codes provided by sensirion from https://github.com/Sensirion/embedded-i2c-sts4x
to this folder /home/RIOT/sys/sensirion
In this folder i have :
- makefile
MODULE = sensirion
include $(RIOTBASE)/Makefile.base
- sensirion_common.h and c
- sensirion_config.h
- sensirion_i2c_hal.h and .c
- sensirion_i2c.h and .c
- sts4x_i2c.h and .c
Then i have written the implementation code for sensirion_i2c_hal.h in sensirion_i2c_hal.c file. [Note: other files e.g., header file and .C file i didn’t modify as it didn’t require it ]
#include "periph/i2c.h"
#include "xtimer.h"
#include "sensirion_i2c_hal.h"
#include "sensirion_common.h"
#include "sensirion_config.h"
/* int16_t sensirion_i2c_hal_select_bus(uint8_t bus_idx) {
// No need to implement for single I2C bus
return 0;
}*/
void sensirion_i2c_hal_init(void) {
// Initialize the I2C device (bus 0 for nRF52840 Dongle)
i2c_acquire(I2C_DEV(0));
}
void sensirion_i2c_hal_free(void) {
// Release the I2C device (bus 0)
i2c_release(I2C_DEV(0));
}
int8_t sensirion_i2c_hal_read(uint8_t address, uint8_t* data, uint16_t count) {
int res;
// Acquire the I2C device
i2c_acquire(I2C_DEV(0));
// Perform the I2C read operation
res = i2c_read_bytes(I2C_DEV(1), address, data, count, 0);
// Release the I2C device
i2c_release(I2C_DEV(0));
return (res == count) ? 0 : -1;
}
int8_t sensirion_i2c_hal_write(uint8_t address, const uint8_t* data, uint16_t count) {
int res;
// Acquire the I2C device
i2c_acquire(I2C_DEV(0));
// Perform the I2C write operation
res = i2c_write_bytes(I2C_DEV(1), address, data, count, 0);
// Release the I2C device
i2c_release(I2C_DEV(0));
return (res == count) ? 0 : -1;
}
void sensirion_i2c_hal_sleep_usec(uint32_t useconds) {
// Sleep
xtimer_usleep(useconds);
}
Then, I have changed/Modified #include “periph_conf.h” file which always redirects to nrf52840dk folder but i am using nrf52840 dongle, so i modified both with desired pin:
/**
* @name I2C configuration
* @{
*/
static const i2c_conf_t i2c_config[] = {
{
.dev = NRF_TWIM0,
.scl = GPIO_PIN(0, 20),
.sda = GPIO_PIN(0, 22),
.speed = I2C_SPEED_NORMAL
}
};
#define I2C_NUMOF ARRAY_SIZE(i2c_config)
/** @} */
finally the main.c file implementation
#include <stdio.h>
#include <string.h>
#include "xtimer.h"
#include "periph_conf.h"
#include "periph/i2c.h"
#include "periph/gpio.h"
#include "sensirion_common.h"
#include "sensirion_config.h"
#include "sensirion_i2c_hal.h"
#include "sensirion_i2c.h"
#include "sts4x_i2c.h"
int main(void) {
puts("STS40 check");
// Initialize the I2C HAL
sensirion_i2c_hal_init();
printf("STS40 check1");
// Initialize the STS4x driver
init_driver(ADDR_STS4X);
printf("STS40 check2");
// Read the serial number
uint32_t serial_number;
int16_t error = sts4x_serial_number(&serial_number);
if (error) {
printf("Error reading serial number: %d\n", error);
} else {
printf("Sensor serial number: %lu\n", serial_number);
}
printf("STS40 check3");
// Start measurement
while (1) {
int32_t temperature;
error = sts4x_measure_high_precision(&temperature);
if (error) {
printf("Error reading temperature: %d\n", error);
} else {
printf("Temperature: %.1f °C\n", temperature / 1000.0f);
}
// Sleep for 1 second between measurements
xtimer_sleep(1);
}
return 0;
}
and makefile
Name of your application
APPLICATION = i2c_test
# If no BOARD is found in the environment, use this default:
BOARD = nrf52840dongle
# This has to be the absolute path to the RIOT base directory
RIOTBASE ?= $(CURDIR)/../..
# Include the header files directory
INCLUDES += -I/home/my_home/RIOT/sys/sensirion
# Use I2C module from RIOT
USEMODULE += xtimer
USEMODULE += periph_i2c
USEMODULE += periph_gpio
USEMODULE += sensirion
FEATURES_REQUIRED += periph_i2c
CFLAGS += -DLOG_LEVEL=LOG_DEBUG
DEVELHELP ?= 1
# Change this to 0 to show compiler invocation lines by default:
QUIET ?= 1
# Include the main RIOT build system
include $(RIOTBASE)/Makefile.include
After all these i was expecting it would somehow work but it the code compiled all okay and outputs only until the sensirion_i2c_hal_init();
, that i am assuming my i2c initialization is wrong, and the whole code provided by sensirion somehow is not compatible the way i am implementing.
output:
2024-09-23 13:11:38,513 # main(): This is RIOT! (Version: 2024.10-devel-154-g821a7e)
2024-09-23 13:11:38,513 # STS40 check
I would appreciate any clue on this situation.