cancel
Showing results for 
Search instead for 
Did you mean: 

Problem to read correct Accelerometer Data from BMA530 Accelerometer Sensor

Michael10
Associate II

Hello,

at the moment i try to read correct accelerometer data with a STM32L010C6 Microcontroller from a accelerometer sensor BMA530. The connection is via I^2C (SDA and SCL) and i programm the Microcontroller with a ST-LINK V2. I took a code from gitHub Platform boschsensortec/BMA530_SensorAPI and changed it because in the common.c data i can´t use the coines commands because the STM32L010C6 needs STM32 HAL-Functions because Bosch use other Hardware as STMicroelectronics. 

The dev_addr2 = (0x18 << 1) see at https://sourcevu.sysprogs.com/stm32/HAL/symbols/HAL_I2C_Mem_Read#:~:text=SourceVu%20STM32%20Libraries%20and%20Samples,information%20for%20the%20specified%20I2C

and i got it from the BMA530 Datasheet - The default 7 bits I^2C address is 0x18.

The Mem_addr = 0x18, i got it from the BMA530 Datasheet. 0x18->ACC_DATA_0 -> Read-only acc_x_7_0.

 In the BMA530 Datasheet at the Connection Diagram there are two resistors which i don´t have at my board. Could the resistors be the troublemaker? 

I´m thankful for any help!

Best regards 

/**
 * Copyright (c) 2024 Bosch Sensortec GmbH. All rights reserved.
 *
 * BSD-3-Clause
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include "bma5.h"
#include "common.h"
#include "stm32l0xx_hal.h"
#include "main.h"
//#include "coines.h" nicht inkludiert weil die Hardware anders beim STM32 Mikroprozessor ist!

/* Kontext Variablendeklaration, uint16_t ist Datentyp, dev_addr ist die Variable, wegen HAL muss die DevAddress um 1 nach links verschoben werden */
uint16_t dev_addr2 = (0x18 << 1);
uint16_t Mem_addr = 0x18;
// I2C_handle_Structure_definition
extern I2C_HandleTypeDef hi2c1;
extern SPI_HandleTypeDef hspi1;

//I2C LeseFunktion für die STM32 Platform
BMA5_INTF_RET_TYPE bma5_i2c_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
	// Hol den Wert aus der Adresse 0x18 << 1 -> dev_addr = 0x30
    uint16_t dev_addr2 = *(uint16_t*)intf_ptr;
    if (HAL_I2C_Mem_Read(&hi2c1, dev_addr2, Mem_addr, I2C_MEMADD_SIZE_8BIT, reg_data, len, HAL_MAX_DELAY) != HAL_OK){
    	return BMA5_E_COM_FAIL;
    }
    return BMA5_OK;
}

BMA5_INTF_RET_TYPE bma5_i2c_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    uint16_t dev_addr2 = *(uint16_t*)intf_ptr;
    if (HAL_I2C_Mem_Write(&hi2c1, dev_addr2, Mem_addr, I2C_MEMADD_SIZE_8BIT, reg_data, len, HAL_MAX_DELAY) != HAL_OK){
    	return BMA5_E_COM_FAIL;
    }
    return BMA5_OK;
}
BMA5_INTF_RET_TYPE bma5_spi_read(uint8_t reg_addr, uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
	HAL_StatusTypeDef status;
	    uint8_t addr = reg_addr | 0x80; // Read-Bit setzen

	    HAL_GPIO_WritePin(FRAM_CS_GPIO_Port, FRAM_CS_Pin, GPIO_PIN_RESET); // CS Aktiv

	    // 1. Adresse senden
	    status = HAL_SPI_Transmit(&hspi1, &addr, 1, 100);

	    // 2. Nur empfangen, wenn Senden OK war
	    if (status == HAL_OK) {
	        status = HAL_SPI_Receive(&hspi1, reg_data, len, 100);
	    }

	    HAL_GPIO_WritePin(FRAM_CS_GPIO_Port, FRAM_CS_Pin, GPIO_PIN_SET); // CS Deaktiv

	    return (status == HAL_OK) ? 0 : -1; // 0 für Erfolg (BMA5_OK)

	//uint8_t dev_addr = *(uint8_t*)intf_ptr;
    //return HAL_SPI_Receive(&hspi1, reg_data, len, HAL_MAX_DELAY);
    // Abschnitt den ich ändern muss -> [return coines_read_spi(COINES_SPI_BUS_0, dev_addr, reg_addr, reg_data, (uint16_t)len);]
}

BMA5_INTF_RET_TYPE bma5_spi_write(uint8_t reg_addr, const uint8_t *reg_data, uint32_t len, void *intf_ptr)
{
    //uint8_t dev_addr = *(uint8_t*)intf_ptr;
    return HAL_SPI_Transmit(&hspi1, reg_data, len, HAL_MAX_DELAY);
    // Abschnitt den ich ändern muss -> [return coines_write_spi(COINES_SPI_BUS_0, dev_addr, reg_addr, (uint8_t *)reg_data, (uint16_t)len);]
}

void bma5_delay_us(uint32_t period, void *intf_ptr)
{
	if (period < 1000)
		HAL_Delay(1);
	else
	HAL_Delay(period / 1000);
}

void bma5_check_rslt(const char api_name[], int8_t rslt)
{
    switch (rslt)
    {
        case BMA5_OK:
            /* Do nothing */
            break;
        case BMA5_E_NULL_PTR:
            printf("API name %s\t", api_name);
            printf("Error  [%d] : Null pointer\r\n", rslt);
            break;
        case BMA5_E_COM_FAIL:
            printf("API name %s\t", api_name);
            printf("Error  [%d] : Communication failure\r\n", rslt);
            break;
        case BMA5_E_DEV_NOT_FOUND:
            printf("API name %s\t", api_name);
            printf("Error  [%d] : Device not found\r\n", rslt);
            break;
        default:
            printf("API name %s\t", api_name);
            printf("Error  [%d] : Unknown error code\r\n", rslt);
            break;
    }
}

int8_t bma5_interface_init(struct bma5_dev *bma5, uint8_t intf, enum bma5_context context)
{
    int8_t rslt = BMA5_OK;

    if (bma5 == NULL)
    {
    	return BMA5_E_NULL_PTR;
    }
    	/* Bus configuration : I2C */
        if (intf == BMA5_I2C_INTF)
        {
            bma5->bus_read = bma5_i2c_read;
            bma5->bus_write = bma5_i2c_write;
            bma5->intf = BMA5_I2C_INTF;
            bma5->intf_ptr = &dev_addr2;
        }
        /* Bus configuration : SPI */
        else if (intf == BMA5_SPI_INTF)
        {
            bma5->bus_read = bma5_spi_read;
            bma5->bus_write = bma5_spi_write;
            bma5->intf = BMA5_SPI_INTF;
            bma5->intf_ptr = NULL;
        }
        else
        {
        	return BMA5_E_COM_FAIL;
        }
        /* Configure delay in microseconds */
        bma5->delay_us = bma5_delay_us;
        /* Assign context parameter */
        bma5->context = context;
    return BMA5_OK;
}

Michael Wilkens

Connection_Diagramm_BMA530.pngScreenshot_Debugger_STM_Cube_IDE.png

10 REPLIES 10

@Michael10 wrote:

It worked out and i can see the correct accelerometer data.


Great!

Now please mark the solution on the post which provided the answer (not this one!)

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.