Giter Club home page Giter Club logo

stmems_standard_c_drivers's Introduction

latest tag

1 - Introduction

This repository contains examples of low-level platform-independent drivers for STMicroelectronics sensors. Sensor drivers and examples are written in C programming language.

If you are using STM32Cube packages, evaluate also the hardware abstractions STM32Cube-compatible drivers.

The STMicroelectronics naming convention for driver repositories is:

  • PARTNUMBER (e.g. hts221) for low-level platform-independent drivers
  • stm32-PARTNUMBER (e.g. stm32-hts221) for hardware-abstracted STM32Cube-compatible drivers

1.a - Repository structure

This repository contains two types of folders, identifiable using the following naming convention:

  • folder that contains the sensor drivers, named xxxxxxx_STdC where xxxxxxx identifies the sensor part number
  • folder that contains the demo project, named _prj_XXXXXXX where XXXXXXX is the name of the ST evaluation board

Another folder, named _resources, cannot be identified with the two types described above and contains other useful resources such as libraries and predefined device configurations used in some examples. In order to clone the complete content of this folder, use the command:

git clone --recursive https://github.com/STMicroelectronics/STMems_Standard_C_drivers

1.b - Sensor driver folder structure

Every sensor driver folder contains:

  • xxxxxxx_STdC\driver : this folder points to another repository which contains only the sensor driver files (.h and .c) to be included, or linked directly as a git submodule, in your project. Driver documentation can be generated using the Doxygen tool.
  • xxxxxxx_STdC\examples: examples showing how to integrate the C driver in a project. They are written for STM32 Microcontrollers using the STM32CubeMX tool, but they can be used as a guideline for every platform.
  • README: additional info about the specific driver.

1.c - Demo project folder structure

Every demo project folder contains a single configuration file for the STM32CubeMX tool named _prj_XXXXXXX\XXXXXX.ioc where XXXXXXX is the name of the ST evaluation board.

Using the STM32CubeMX tool (configured with the related MCU package) and the .ioc file, it is possible to create a project in which you can easily run the examples available in each sensor driver folder.


2 - Integration details

The driver is platform-independent, you only need to define the two functions for read and write transactions from the sensor hardware bus (ie. SPI or I2C/I3C) and a platform dependent delay function, which is sometimes required by the underlying driver.

Note: A few devices integrate an extra bit in the communication protocol in order to enable multi read/write access, this bit must be managed in read and write functions defined by the user. Please refer to the read and write implementation in the reference examples.

2.a Source code integration

  • Include in your project the driver files of the sensor (.h and .c) located in the xxxxxxx_STdC\driver folder of the corresponding product.

  • Define in your code the read and write as well as the delay functions that use the I2C, I3C or SPI platform driver like the following:

/** Please note that it is MANDATORY: return 0 -> no Error.**/
int32_t platform_write(void *handle, uint8_t Reg, const uint8_t *Bufp, uint16_t len);
int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len);
void platform_delay(uint32_t ms);
  • Declare and initialize the structure of the device interface:
xxxxxxx_ctx_t dev_ctx; /** xxxxxxx is the used part number **/
dev_ctx.write_reg = platform_write;
dev_ctx.read_reg = platform_read;
dev_ctx.mdelay = platform_delay;
  • If needed by the platform read and write functions, initialize the handle parameter:
dev_ctx.handle = &platform_handle;
  • Any additional initialization work has to be done in platform_init routine:
void platform_init(void);

2.b Required properties

  • A standard C language compiler for the target MCU
  • A C library for the target MCU and the desired interface (i.e. SPI, I2C, I3C)

3 - Running examples

Examples are written for STM32 Microcontrollers using the STM32CubeMX tool, but they can be used as a guideline for every platform.

3.a Using STMicroelectronics evaluation boards

When using the supported STMicroelectronics evaluation boards, the example file(.c) can be run without applying any modifications (as is).

In order to run that file, please follow these steps:

  1. Download and install the STM32CubeMX tool and the related MCU package (i.e. STM32CubeF4 for NucleoF401 and STEVAL_MKI109V3).
  2. Open the .ioc configuration file associated to the selected evaluation board with the STM32CubeMX tool. The .ioc configuration files for the supported evaluation boards can be found in the related ST evaluation board demo project folder.
  3. Generate the project using the STM32CubeMX tool and select your preferred IDE / toolchain.
  4. Add to your project the STMicroelectronics sensor driver. Driver files are located in the sensor drivers folder atxxxxxxx_STdC\driver\xxxxxxx_reg.c(.h) where xxxxxxx identifies the sensor part number.
  5. Add to your project the example source file (.c) that you are interested in. Example files are located in the sensor drivers folder at xxxxxxx_STdC\example where xxxxxxx identifies the sensor part number.
  6. Uncomment the selected board definition in section /* STMicroelectronics evaluation boards definition */ in the selected example file (.c).
  7. Add the call to the example function inside the while(1) loop in the main() function of the main.c file automatically generated by the STM32CubeMX tool.
  8. Enjoy :-)

More info is available in each specific provided example platform:

If you are using STM32Cube packages, evaluate also the hardware-abstracted STM32Cube-compatible drivers specifically designed to be compatible with the STM32Cube. The complete list is provided here.

3.b Running examples using different hardware

If a different MCU is used, please follow these steps:

  1. Add the STMicroelectronics sensor driver to your project. Driver files are located in the sensor drivers folder atxxxxxxx_STdC\driver\xxxxxxx_reg.c(.h) where xxxxxxx identifies a sensor part number.

  2. Add the example source file (.c) that interests you to your project. Example files are located in the sensor drivers folder at xxxxxxx_STdC\example where xxxxxxx identifies the sensor part number.

  3. Comment all the definitions of the boards in section `/* STMicroelectronics evaluation boards definition */ in the selected example file(.c).

  4. Add the call to the example function inside the while(1) loop in yourmain() function.

  5. Modify in the selected example file (.c) the hardware-related functions:

    • platform_write(void *handle, uint8_t Reg, const uint8_t *Bufp,uint16_t len)
    • platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len)
    • void platform_delay(uint32_t ms)
    • if needed, add/replace the hardware-related functions reported in the example file.
  6. Enjoy :-)


More information: http://www.st.com

Copyright (C) 2018-2024 STMicroelectronics

stmems_standard_c_drivers's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stmems_standard_c_drivers's Issues

lsm6dsl_pin_int1/2_route_set overrides global interrupts_enable flag

Take this example :

    // Set INT1 to wake up
    lsm6dsl_int1_route_t int1 = {
        .int1_wu = 1,
    };
    lsm6dsl_pin_int1_route_set(&dev_ctx, int1);
    
    // Disable INT2
    lsm6dsl_int2_route_t int2 = {0};
    lsm6dsl_pin_int2_route_set(&dev_ctx, int2);

The call to lsm6dsl_pin_int2_route_set sets TAP_CFG.INTERRUPTS_ENABLE to 0, which globally disables all interrupts, including the INT1 one

Possible fixes :

  • Merge lsm6dsl_pin_int1_route_set and lsm6dsl_pin_int2_route_set into a single function
  • Set TAP_CFG.INTERRUPTS_ENABLE if one interrupt is enabled, but never clear it

This bug seems to apply to the following drivers :

  • iis2dlpc
  • ism330dlc
  • lis2dw12
  • lsm6dsl
  • lsm6dsm
  • lsm6dso

Incorrect Tap axis assignment in lsm6dsox_all_sources_get

Within the function lsm6dsox_all_sources_get there is incorrect axis assigned from the Tap sources

val->tap_x = tap_src.z_tap;
val->tap_y = tap_src.y_tap;
val->tap_z = tap_src.x_tap;

should be

val->tap_x = tap_src.x_tap;
val->tap_y = tap_src.y_tap;
val->tap_z = tap_src.z_tap;

LSM9DS1 false default values

Hey There,
In the libary are some defines, that doesn't fit each other.
Setting up the filters of the accelerometer with:
typedef enum {
LSM9DS1_LP_DISABLE = 0x00,
LSM9DS1_LP_ODR_DIV_50 = 0x10,
LSM9DS1_LP_ODR_DIV_100 = 0x11,
LSM9DS1_LP_ODR_DIV_9 = 0x12,
LSM9DS1_LP_ODR_DIV_400 = 0x13,
} lsm9ds1_xl_lp_bw_t;

doesn't match the lines
ctrl_reg7_xl.dcf = ((uint8_t)val & 0x10U) >> 4;
ctrl_reg7_xl.hr = ((uint8_t)val & 0x03U);

in:
int32_t lsm9ds1_xl_filter_lp_bandwidth_set(lsm9ds1_ctx_t *ctx,
lsm9ds1_xl_lp_bw_t val)
{
lsm9ds1_ctrl_reg7_xl_t ctrl_reg7_xl;
int32_t ret;

ret = lsm9ds1_read_reg(ctx, LSM9DS1_CTRL_REG7_XL,
(uint8_t*)&ctrl_reg7_xl, 1);
if(ret == 0){
ctrl_reg7_xl.dcf = ((uint8_t)val & 0x10U) >> 4;
ctrl_reg7_xl.hr = ((uint8_t)val & 0x03U);
ret = lsm9ds1_write_reg(ctx, LSM9DS1_CTRL_REG7_XL,
(uint8_t*)&ctrl_reg7_xl, 1);
}
return ret;
}

because dcf has two bits, see:

#define LSM9DS1_CTRL_REG7_XL 0x21U
typedef struct {
uint8_t hpis1 : 1;
uint8_t not_used_01 : 1;
uint8_t fds : 1;
uint8_t not_used_02 : 2;
uint8_t dcf : 2;
uint8_t hr : 1;
} lsm9ds1_ctrl_reg7_xl_t;

So the right code must be

ctrl_reg7_xl.hr = ((uint8_t)val & 0x10U) >> 4;
ctrl_reg7_xl.dcf = ((uint8_t)val & 0x03U);

Plans to add driver for LSM9DS1

Hi,
I am interested in using the LSM9DS1 as a component in a multi-sensor IMU run on an STM32. Are there any plans to add a C driver for this component, or would you be willing to take a pull request if I were to write one myself?
Thanks

lis2dtw12 wrong Sensitivity

Hi.
in lis2dtw12_reg.c file you are using very different Sensitivity. for example in lis2dtw12_from_fs8_lp1_to_mg function you are using 0.244 Sensitivity. according to the datasheet, it should be 0.976 or 1.952 according to the power mode.

thank you

Right-Shifting of negative signed numbers is implementation-specific

File lsm303agr_STdC/driver/lsm303agr_reg.h contains some macros for converting the raw acceleration values depending on the mode and scale such as the following:
#define LSM303AGR_FROM_FS_2g_HR_TO_mg(lsb) (float)((int16_t)lsb>>4)* 1.0f
The drivers are supposed to be platform agnostic, however the shifting of signed numbers is implementation specific, as shown in the C99 standard, 6.5.7 Bitwise shift operators:

The result of E1 >> E2 is E1 right-shifted E2 bit positions. If E1 has an unsigned type
or if E1 has a signed type and a nonnegative value, the value of the result is the integral
part of the quotient of E1 / 2E2. If E1 has a signed type and a negative value, the
resulting value is implementation-defined.

(The same applies for C89 and C11). Sure, in most platforms the right shifting of negative signed numbers will act with sign extension, but I think it is better to be safe by substituting the bitwise operation with arithmetic. I made a pull request fixing this, please see #5

Add check to ensure little endian

/* Guard to ensure microcontroller is Little Endian, which is required by lsm6dsm.h */
    #define LITTLE_ENDIAN 0x41424344UL 
    #define ENDIAN_ORDER  ('ABCD') 

    #if ENDIAN_ORDER!=LITTLE_ENDIAN
        #error "machine is not little endian"
    #endif

LPS22HB lps22hb_from_lsb_to_hpa should take int32_t or uint32_t

According to the register address map in the documentation of the LPS22HB there are 3 x 8 bit registers for the measured pressure output value: -

PRESS_OUT_XL (0x28) (Pressure value bits 7 to 0)
PRESS_OUT_L (0x29) (Pressure value bits 15 to 8)
PRESS_OUT_H . (0x2A) (Pressure value bits 23 to 16)

The lps22hb_pressure_raw_get() function correctly reads the 3 consecutive addresses to retrieve the full data, however a subsequent call to lps22hb_from_lsb_to_hpa() (as per the example) only accepts a int16_t so the MSBs are lost in truncation.

The correct function should take a uint32_t or int32_t (and probably mask off the top 8 bits)

IIS3DHHC I2C support

Hi,

The datasheet for IIS3DHHC doesn't mention any support for I2C. However, there are some references to I2C in example code.

From what I can see, most drivers that support I2C have a *_I2C_ADD_* address define in the corresponding header file, IIS3DHHC does not.

Is I2C supported with IIS3DHHC?

lis2dh12 function for calculating mG wrong implementation

Function
float lis2dh12_from_fs2_hr_to_mg(int16_t lsb)
{
return ( (float)lsb / 16.0f ) * 1.0f;
}
is not implented right. According to datasheet page 16 where modes are described, the conversation for high res fs2 mode is 1 mg/digit, so the function doesnt have to do anything at all :) Check the other conversation functions as well, because I thing they are foo to :)

float lis2dh12_from_fs2_hr_to_mg(int16_t lsb)

lsm6dsl_den_enable_set

Hi

I've found an error in the LSM6DSL api. I tried to extend the DEN functionallity to the accelerometer with a call of lsm6dsl_den_enable_set function.

The following code snippet is from your api function, whereas val = 2 (LSM6DSL_STAMP_IN_GY_XL_DATA).
reg.ctrl4_c.den_xl_en = (uint8_t)val & 0x02U;

The problem is that "val & 0x02" will return 0x02 instead of 0x01 --> the bit won't get set. The code should be fixed with "val && 0x02U".

Kind regards

Finite State Machine submodule points to commit which is not on any branch

Hello,

The _resources/STMems_Finite_State_Machine @ 1c74d4e
is not on any branch of the FSM project. Maybe something has been force-pushed over commits

1c74d4e lsm6dsr: modified licence format
fb969ba lsm6dsox: modified licence format
2f2aba9 lsm6dso: modified licence format

maybe something else, but in any case it would be nice to point the submodule to some commit of the FSM master

Why I am stuck in I2C_ISR_TXIS flag set?

I have MPU6050 accerlometer, i need to interface with stm32f0 (via I2C).

Firstly i am check if the sensor is responding by reading the

"WHO_AM_I (0x75)" Register.

If the sensor responds with 0x68, this means itโ€™s available and good to go.

but the code is stuck in while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET){} ,

why this happens?

__inline static void stm32_I2cSetup(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
	I2C_InitTypeDef  I2C_InitStructure;
  
#if	_I2C1_ENABLE__
  /* Configure the I2C clock source. The clock is derived from the HSI */
  RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
    
  /* I2C_SCL_GPIO_CLK and I2C_SDA_GPIO_CLK Periph clock enable */
  RCC_AHBPeriphClockCmd(I2C1_SCL_GPIO_CLK | I2C1_SDA_GPIO_CLK, ENABLE);
  
  /* I2C Periph clock enable */
  RCC_APB1PeriphClockCmd(I2C1_CLK, ENABLE);
  
  /* Connect PXx to I2C_SCL*/
  GPIO_PinAFConfig(I2C1_SCL_GPIO_PORT, I2C1_SCL_SOURCE, I2C1_SCL_AF);
  
  /* Connect PXx to I2C_SDA*/
  GPIO_PinAFConfig(I2C1_SDA_GPIO_PORT, I2C1_SDA_SOURCE, I2C1_SDA_AF);
  
  /* GPIO configuration */  
  /* Configure I2C pins: SCL */
  GPIO_InitStructure.GPIO_Pin = I2C1_SCL_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
  GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);
  
  /* Configure I2C pins: SDA */
  GPIO_InitStructure.GPIO_Pin = I2C1_SDA_PIN;
  GPIO_Init(I2C1_SDA_GPIO_PORT, &GPIO_InitStructure);	
	
  /* I2C configuration */
  /* sEE_I2C configuration */
  I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
  I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
  I2C_InitStructure.I2C_DigitalFilter = 0x00;
  I2C_InitStructure.I2C_OwnAddress1 = 0x00;
  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  I2C_InitStructure.I2C_Timing = I2C1_TIMING;
  
  /* Apply sEE_I2C configuration after enabling it */
  I2C_Init(I2C1, &I2C_InitStructure);
   
  /* sEE_I2C Peripheral Enable */
  I2C_Cmd(I2C1, ENABLE);
  
//  /* Select the EEPROM address */
// SlaveAddr = 0x60;  
	Current_I2C	 = I2C1; 
#endif

#if _I2C2_ENABLE__

#endif
}

void reg_read(void)
{
uint32_t Data = 0;


 while(I2C_GetFlagStatus(I2C1, I2C_ISR_BUSY) != RESET){;;}

 I2C_TransferHandling(I2C1,0x68, 1, I2C_Reload_Mode,       I2C_Generate_Start_Write);  //I2C_SoftEnd_Mode


 while(I2C_GetFlagStatus(I2C1, I2C_ISR_TXIS) == RESET){}

 I2C_SendData(I2C1,0x75);
while(I2C_GetFlagStatus(I2C1, I2C_ISR_TC) == RESET){} 

 I2C_TransferHandling(I2C1, 0x68, 1,          I2C_AutoEnd_Mode,I2C_Generate_Start_Read);

 while(I2C_GetFlagStatus(I2C1, I2C_ISR_RXNE) == RESET) { }

Data= I2C_ReceiveData(I2C1);

while(I2C_GetFlagStatus(I2C1, I2C_ISR_STOPF) == RESET) {}

I2C_ClearFlag(I2C1, I2C_ICR_STOPCF);

 memset(ucGBuff1,0,sizeof(ucGBuff1));
 sprintf((char *)ucGBuff1,"C:  %d",Data);

printk((char *)ucGBuff1);

  }

LSM6DSOX self test "xl" vs "gy" typos

I believe that there are a couple typos in lsm6dsox_STdC/example/lsm6dsox_self_test.c, specifically during the gyro section of the self-test there are a couple of accelerometer functions called.

on line 281 lsm6dsox_xl_flag_data_ready_get(&dev_ctx, &drdy);
on line 306 lsm6dsox_xl_flag_data_ready_get(&dev_ctx, &drdy);
on line 335 lsm6dsox_xl_data_rate_set(&dev_ctx, LSM6DSOX_GY_ODR_OFF);

I had to change all of the "lsm6dsox_xl_..." to "lsm6dsox_gy_..." to get the test to complete successfully. Without these changes, the test loops forever waiting for a accelerometer data ready flag.

LIS2DW12: conversion functions

Hi,

Why are the conversion factors used in functions lis2dw12_from_*_to_mg not the same as the ones in the LIS2DW12 datasheet (page 6, sensitivity values) ?

Thank you,
Greg

LIS2DW12 Software Trigger Question

Hey There,
ive got a question related to sowtware Triggering the LIS2DW12 Sensor.

for (int i=0; i<0x3FF; i++);
lis2dw12_data_rate_set(&dev_ctx, LIS2DW12_XL_SET_SW_TRIG);

what purpose has the loop there? i dont get it ..
the code is taken from the lis2dw12_read_data_single example

LSM9DS1 I2C Address 8bit Format - Change Request

I was reading through the datasheet page 30, table 20; I believe there is a fix needed for
https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/lsm9ds1_STdC/driver/lsm9ds1_reg.h

on Line 127
/** I2C Device Address 8 bit format if SA0=0 -> 0x3D if SA0=1 -> 0x39 **/
#define LSM9DS1_MAG_I2C_ADD_L 0x3DU
#define LSM9DS1_MAG_I2C_ADD_H 0x39U

should be:
#define LSM9DS1_MAG_I2C_ADD_L 0x39U
#define LSM9DS1_MAG_I2C_ADD_H 0x3DU

Addresses are inverted

LIS2DW12: Single data conversion mode in CTRL3

Hi,

The lis2dw12 driver sets the following enum values:

LIS2DW12_XL_SET_SW_TRIG        = 0x32,  /* Use this only in SINGLE mode */
LIS2DW12_XL_SET_PIN_TRIG       = 0x22,  /* Use this only in SINGLE mode */

Then in the C file, the CTRL3 register is written like this:

ctrl3.slp_mode = ( (uint8_t) val & 0x30U ) >> 4;
ret = lis2dw12_write_reg(ctx, LIS2DW12_CTRL3,(uint8_t*) &ctrl3, 1);

This will set the SLP_MODE_SEL bit1 of CTRL3 in both cases (SW and PIN trig). But the datasheet says it shall be 0 when enabled with external trigger on INT2.

This is a bug or did I miss something?

Also the driver will assign 0x02 for the ODR (CTRL1). Why?

Thank you,
Greg

About Unico

I use your sensors in my board.
I want to use Unico to capture, process, display sensor data.
I may need to implement the communication protocol via serial port.
Do you have some document about how to do it?

By the way, I just need Unico to receive and handle data from MCU, I don't need it send command to MCU, do you have a more light weight solution?

iis328dq spi read data problem

What is the procedure to read data from iis328dq sensor
By datasheet format isn't responding
Simply sending to read WHO_I_AM register
0x8F is it ok or want to send another other form or want to add any other previous steps

MISRA C compliance

Are the drivers on this repository MISRA C compliant?

I see there are some references to MISRA C compliance within some header files, but there is no statement related to that on the documents/resources.
How do the drivers relate to MISRA C on a general level?

I think this should be better specified somewhere.

LSM6DS3 in Sensor hub mode : code issues

Hi, I was looking at the code of for LSM6DS used as a sensor hub.

There must be a mistake in the example code line 195 or in the structure declaration lsm6ds3_sh_read_t : there is no .byte member in that structure.

I believe there is another mistake in the driver L5563 : the second read to registers should be LSM6DS3_SENSORHUB13_REG , I believe.

Best Regards

Alexandre Barsacq

an error in comment

lsm6dsox_reg.c

About FSM operation
Line 7839, 7865, 7964:

FSM --> Finite State Machine

Error variable is overwritten.

mm_error is overwritten by second operation. Needs an if statement.

`int32_t lsm6dsm_spi_mode_set(lsm6dsm_ctx_t *ctx, lsm6dsm_sim_t val)
{
lsm6dsm_reg_t reg;
int32_t mm_error;

mm_error = lsm6dsm_read_reg(ctx, LSM6DSM_CTRL3_C, &reg.byte, 1);
reg.ctrl3_c.sim = val;
mm_error = lsm6dsm_write_reg(ctx, LSM6DSM_CTRL3_C, &reg.byte, 1);

return mm_error;
}
`

LIS2DH12 STdC driver read: Read, auto increment bits - are not set

Description

When integrating LIS2DH12 driver to my project, I have to define platform read function as

int32_t spi_stm_platform_read(void* dev_id, uint8_t reg_addr, uint8_t *data,
                              uint16_t len)
{
  uint8_t ss = *(uint8_t*)dev_id;
  // bit 0: READ bit. The value is 1.
  // bit 1: MS bit. When 0, does not increment the address; when 1, increments the address in
  // multiple reads.
  uint8_t read_cmd = reg_addr | 0x80;
  if(len > 1) { read_cmd |= 0x40; }
  return spi_platform_read(ss, read_cmd, data, len);
}

because the driver does not set appropriate bit flags when reading registers.

Proposed fix:

Implement int32_t lis2dh12_read_reg as

int32_t lis2dh12_read_reg(lis2dh12_ctx_t* ctx, uint8_t reg, uint8_t* data,
                          uint16_t len)
{
  uint8_t read_cmd = reg | 0x80;
  if(len > 1) { read_cmd |= 0x40; }
  return ctx->read_reg(ctx->handle, read_cmd, data, len);
}

Action

Would you accept pull request for the change if I opened one?
I'm fine with assigning copyrights of contribution to you under any MIT-compatible license in case your legal department asks :)

Buff not being incremented

In the function "int32_t h3lis100dl_acceleration_raw_get(stmdev_ctx_t *ctx, uint8_t *buff)",
the buff pointer should be incremented after each read, otherwise all of the data is loaded into the first buffer location.

Question

Do the app using on LSM6DSO can be used on LSM6DSOX without any change?

About Unico

To communicate with Unico, I try to implement commands on my own board as your ducument.
I met a strange thing, which may not be mentioned in the doucument.
Once I click conncet on Unico, Unico send "0x00 0x80" continously.
image

How should I respond to this?
I thought it should send "*setdbXXXVY" at first.
Do I miss anything?

LIS2DW12: Wakeup example generates a pulse on INT1 after enabling the feature

Hello,

I'm trying the wake-up example of the LIS2DW12. It's working except that the accelerometer generates a pulse on the INT1 pin ~1ms after the setup (i.e. after enabling the wake-up in CTRL4).
It's systematic, even if the accelerometer is motionless. The pulse duration is 5ms.
If I add some delay, few milliseconds, before configuring CTRL4, then the pulse disappear. But it's something I'd like to avoid, I would prefer to understand why the chip generates the pulse after enabling the wake-up feature. This pulse is a wrong information coming from the LIS2DW12.

Capture:
2020-03-06 10_36_29-Saleae Logic Software

Thank you.

Buffer overflow in ais2dw12

Hello,
I have performed a simple formal verification using TrustInSoft CI on the ais2dw12 driver.
The results are available at https://ci.trust-in-soft.com/projects/monate/STMems_Standard_C_drivers/6?page=1&test=3
The analysis is performed on a fork of this repository that contains one additional commit to configure TrustInSoft CI.
The analyzer identifies a buffer overflow that comes from this type definition:

typedef struct{
ais2dw12_status_dup_t status_dup;
ais2dw12_wake_up_src_t wake_up_src;
ais2dw12_sixd_src_t sixd_src;
ais2dw12_all_int_src_t all_int_src;
} ais2dw12_all_sources_t;

According to the datasheet, the 4 registers status_dup, wake_up_src, sixd_src and all_int_src are not consecutive because of a reserved register.
They are read with a 5 bytes read by the function at
int32_t ais2dw12_all_sources_get(stmdev_ctx_t *ctx,
ais2dw12_all_sources_t *val)
{
int32_t ret;
ret = ais2dw12_read_reg(ctx, AIS2DW12_STATUS_DUP, (uint8_t*) val, 5);
return ret;
}

This function indeed asks for 5 bytes but the destination buffer only contains 4 bytes.
With the following fix monate@cb733cf the buffer overflow disappears and TrustInSoft CI shows that for all the existing tests, whatever the registers of the hardware contain, there is no undefined behavior in the driver.
See https://ci.trust-in-soft.com/projects/monate/STMems_Standard_C_drivers/7?page=1 for the final result.

Feel free to retrieve the commits in my fork and/or to get in touch with me if you are interested in deploying TrustInSoft CI on your repository for this or other drivers.

LIS3DH - Error in C-Driver-MEMS

See: https://community.st.com/s/question/0D50X0000B6QVmzSQG/lis3dh-error-in-cdrivermems

The LIS3DH Temperature Sensor is connected to ADC3

But lis3dh_temperature_raw_get() reads ADC1:

 /**
  * @brief  Temperature output value.[get]
  *
  * @param  ctx      read / write interface definitions
  * @param  buff     buffer that stores data read
  * @retval          interface status (MANDATORY: return 0 -> no Error)
  *
  */
int32_t lis3dh_temperature_raw_get(lis3dh_ctx_t *ctx, uint8_t *buff)
{
  int32_t ret;
  ret = lis3dh_read_reg(ctx, LIS3DH_OUT_ADC1_H, buff, 1);   // <<<<< HERE !!
  return ret;
} 

And why is it only reading the High byte?

IIS3DWB Question

When will there be published example code for the iis3dwb? I'm a developer working on that accelerometer, but i'm having trouble configuring the wake-up interrupt.

ISM330DLC with Arduino

Hello, I am having some issues connecting an Arduino to a ISM330DLC(connected through a STEVAL-MKI182V2) using these drivers. When running the driver the device id is always 255. This is my current code:

static int32_t platform_write(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len) { 
  SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE3));
  digitalWrite(SSpin, LOW);
  SPI.transfer(Reg);
  SPI.transfer(Bufp);
  digitalWrite(SSpin, HIGH);
  SPI.endTransaction();
  return 0;
}
static int32_t platform_read(void *handle, uint8_t Reg, uint8_t *Bufp, uint16_t len) {
  Reg |= 0x80; //Set bit 0 (MSB) in order to read
  SPI.beginTransaction(SPISettings(14000000, MSBFIRST, SPI_MODE3));
  digitalWrite(SSpin, LOW);
  SPI.transfer(Reg);
  *Bufp = SPI.transfer(0x00); //Dummy send to get value from module
  digitalWrite(SSpin, HIGH);
  SPI.endTransaction();
  return 0;
}
void setup() {
  delay(100);
  Serial.begin(9600);
  pinMode(SSpin, OUTPUT);
  digitalWrite(SSpin, HIGH);

  /* Initialize SPI */
  SPI.begin();
  ....
  ....

Does anyone know what might be wrong?

LSM6DSOX data get

Hello,

I tried to use lsm6dsox_data_get() function in lsm6dsox_reg.c


I noticed that aux_ctx is used instead of ctx to read data in register

/* read data */
if( ctx != NULL ) {
ret = lsm6dsox_read_reg(aux_ctx, LSM6DSOX_OUT_TEMP_L, buff, 14);
}


Then later in code, register is read in a sense : temperature, accelerometer and gyroscope [Link].
However, in the datasheet, the order of register is temperature, gyroscope and accelerometer [Link].

Inverting angular conversion with acceleration conversion seems to solve this problem.


I don't use ois chain, I suspect similar issue for it:

Conversion of accelerometer comes before gyroscope [Link]. It is inversed in datasheet [Link].

Then, the read of register should starts with gyroscope instead of accelerometer here:

/* read data from ois chain */
if (aux_ctx != NULL) {
if (ret == 0) {
ret = lsm6dsox_read_reg(aux_ctx, LSM6DSOX_SPI2_OUTX_L_A_OIS, buff, 12);
}
}
else {
if ((ctx != NULL) && (md->ois.ctrl_md == LSM6DSOX_OIS_ONLY_UI)) {
ret = lsm6dsox_read_reg(ctx, LSM6DSOX_UI_OUTX_L_A_OIS, buff, 12);
}
}

(LSM6DSOX_SPI2_OUTX_L_G_OIS should replace LSM6DSOX_SPI2_OUTX_L_A_OIS)

driver for LSM9DS1 for the STM32F4 series

Hi,
I'm working on a project which requires LSM9DS1 to be integrated. I saw in one of the older closed issues indicating there will be a driver releasing soon (august 16th). The issue was closed although I could not find a driver in your repo. Could you please redirect me to any Beta version for now? or may be let me know when it would be made available?

Best Regards,
Sathya

LSM9DS1 Self-test Correction

It appears that there is a correction needed for the LSM9DS1 selftest example at Line 129
https://github.com/STMicroelectronics/STMems_Standard_C_drivers/blob/master/lsm9ds1_STdC/example/lsm9ds1_self_test.c

Current:
static sensbus_t imu_bus = {&SENSOR_BUS, LSM9DS1_MAG_I2C_ADD_L, 0, 0};
static sensbus_t mag_bus = {&SENSOR_BUS, LSM9DS1_IMU_I2C_ADD_H 0, 0};

I believe should be:
static sensbus_t imu_bus = {&SENSOR_BUS, LSM9DS1_IMU_I2C_ADD_H, 0, 0};
static sensbus_t mag_bus = {&SENSOR_BUS, LSM9DS1_MAG_I2C_ADD_L, 0, 0};

MAG_I2C_ADD and IMU_I2C_ADD are inverted

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.