Example for Bluetooth low energy interface

Dependencies:   mbed HC_SR04_Ultrasonic_Library

Sensor_Shield/x_nucleo_iks01a1.c

Committer:
julientiron
Date:
2015-05-19
Revision:
1:bdbf36f8408d

File content as of revision 1:bdbf36f8408d:

/**
 ******************************************************************************
 * @file    x_nucleo_iks01a1.c
 * @author  MEMS Application Team
 * @version V1.0.0
 * @date    30-July-2014
 * @brief   This file provides X_NUCLEO_IKS01A1 MEMS shield board specific functions
 ******************************************************************************
 * @attention
 *
 * <h2><center>&copy; COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
 *
 * 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 STMicroelectronics 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.
 *
 ******************************************************************************
 */
/* Includes ------------------------------------------------------------------*/
#include "x_nucleo_iks01a1.h"

/** @addtogroup BSP
 * @{
 */

/** @addtogroup X_NUCLEO_IKS01A1
 * @{
 */

/** @defgroup X_NUCLEO_IKS01A1_Private_Types_Definitions
 * @{
 */

/**
 * @}
 */


/** @defgroup X_NUCLEO_IKS01A1_Private_Defines
 * @{
 */
#ifndef NULL
  #define NULL      (void *) 0
#endif
/**
 * @}
 */

/** @defgroup X_NUCLEO_IKS01A1_Private_Macros
 * @{
 */

/**
 * @}
 */

/** @defgroup X_NUCLEO_IKS01A1_Private_Variables
 * @{
 */

uint32_t I2C_SHIELDS_Timeout = NUCLEO_I2C_SHIELDS_TIMEOUT_MAX;    /*<! Value of Timeout when I2C communication fails */

static I2C_HandleTypeDef    I2C_SHIELDS_Handle;


#ifdef USE_FREE_RTOS
  osMutexId I2C1_Mutex_id = 0;
#endif

/**
 * @}
 */

/** @defgroup X_NUCLEO_IKS01A1_Private_Function_Prototypes
 * @{
 */

/* Link function for 6 Axes IMU peripheral */
void            IMU_6AXES_IO_Init(void);
void            IMU_6AXES_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t WriteAddr, uint16_t NumByteToWrite);
void            IMU_6AXES_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t ReadAddr, uint16_t NumByteToRead);

/* Link function for MAGNETO peripheral */
void            MAGNETO_IO_Init(void);
void            MAGNETO_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t WriteAddr, uint16_t NumByteToWrite);
void            MAGNETO_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t ReadAddr, uint16_t NumByteToRead);

/* Link function for PRESSURE peripheral */
void            PRESSURE_IO_Init(void);
void            PRESSURE_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t WriteAddr, uint16_t NumByteToWrite);
void            PRESSURE_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead);

/* Link function for HUM_TEMP peripheral */
void            HUM_TEMP_IO_Init(void);
void            HUM_TEMP_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t WriteAddr, uint16_t NumByteToWrite);
void            HUM_TEMP_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead);


static void I2C_SHIELDS_MspInit(void);
static void I2C_SHIELDS_Error(uint8_t Addr);
static void I2C_SHIELDS_ReadData(uint8_t* pBuffer, uint8_t Addr, uint8_t Reg, uint16_t Size);
static void I2C_SHIELDS_WriteData(uint8_t* pBuffer, uint8_t Addr, uint8_t Reg, uint16_t Size);
static void I2C_SHIELDS_Init(void);

/**
 * @}
 */

/** @defgroup X_NUCLEO_IKS01A1_Private_Functions
 * @{
 */



/********************************* LINK IMU 6 AXES *****************************/
/**
 * @brief  Configures Imu 6 axes I2C interface.
 * @param  None
 * @retval None
 */
void IMU_6AXES_IO_Init(void)
{
    I2C_SHIELDS_Init();
}


/**
 * @brief  Writes a buffer to the IMU 6 axes sensor.
 * @param  pBuffer: pointer to data to be written.
 * @param  DeviceAddr: specifies the slave address to be programmed.
 * @param  RegisterAddr: specifies the IMU 6 axes register to be written.
 * @param  NumByteToWrite: number of bytes to be written.
 * @retval None.
 */
void IMU_6AXES_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif

    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_WriteData(pBuffer, DeviceAddr, RegisterAddr, NumByteToWrite);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}

/**
 * @brief  Reads a buffer from the IMU 6 axes sensor.
 * @param  pBuffer: pointer to data to be read.
 * @param  DeviceAddr: specifies the address of the device.
 * @param  RegisterAddr: specifies the IMU 6 axes internal address register to read from.
 * @param  NumByteToRead: number of bytes to be read.
 * @retval None.
 */
void IMU_6AXES_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif

    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_ReadData(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}



/********************************* LINK MAGNETO *****************************/
/**
 * @brief  Configures MAGNETO I2C interface.
 * @param  None
 * @retval None
 */
void MAGNETO_IO_Init(void)
{
    I2C_SHIELDS_Init();
}


/**
 * @brief  Writes a buffer to the MAGNETO sensor.
 * @param  pBuffer: pointer to data to be written.
 * @param  DeviceAddr: specifies the slave address to be programmed.
 * @param  RegisterAddr: specifies the MAGNETO register to be written.
 * @param  NumByteToWrite: number of bytes to be written.
 * @retval None.
 */
void MAGNETO_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif

    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_WriteData(pBuffer, DeviceAddr, RegisterAddr, NumByteToWrite);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}

/**
 * @brief  Reads a buffer from the MAGNETO sensor.
 * @param  pBuffer: pointer to data to be read.
 * @param  DeviceAddr: specifies the address of the device.
 * @param  RegisterAddr: specifies the MAGNETO internal address register to read from.
 * @param  NumByteToRead: number of bytes to be read.
 * @retval None.
 */
void MAGNETO_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif

    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_ReadData(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}



/********************************* LINK PRESSURE *****************************/
/**
 * @brief  Configures Pressure I2C interface.
 * @param  None
 * @retval None
 */
void PRESSURE_IO_Init(void)
{
    I2C_SHIELDS_Init();
}


/**
 * @brief  Writes a buffer to the Pressure sensor.
 * @param  pBuffer: pointer to data to be written.
 * @param  DeviceAddr: specifies the slave address to be programmed.
 * @param  RegisterAddr: specifies the Pressure register to be written.
 * @param  NumByteToWrite: number of bytes to be written.
 * @retval None.
 */
void PRESSURE_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif
    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_WriteData(pBuffer, DeviceAddr, RegisterAddr, NumByteToWrite);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}

/**
 * @brief  Reads a buffer from the Pressure sensor.
 * @param  pBuffer: pointer to data to be read.
 * @param  DeviceAddr: specifies the address of the device.
 * @param  RegisterAddr: specifies the Pressure internal address register to read from.
 * @param  NumByteToRead: number of bytes to be read.
 * @retval None.
 */
void PRESSURE_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif
    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_ReadData(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead);

  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}


/********************************* LINK HUM_TEMP *****************************/
/**
 * @brief  Configures Humidity and Temperature I2C interface.
 * @param  None
 * @retval None
 */
void HUM_TEMP_IO_Init(void)
{
    I2C_SHIELDS_Init();
}


/**
 * @brief  Writes a buffer to the HUM_TEMP sensor.
 * @param  pBuffer: pointer to data to be written.
 * @param  DeviceAddr: specifies the slave address to be programmed.
 * @param  RegisterAddr: specifies the Pressure register to be written.
 * @param  NumByteToWrite: number of bytes to be written.
 * @retval None.
 */
void HUM_TEMP_IO_Write(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToWrite)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif
    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_WriteData(pBuffer, DeviceAddr, RegisterAddr, NumByteToWrite);
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}

/**
 * @brief  Reads a buffer from the Uvi sensor.
 * @param  pBuffer: pointer to data to be read.
 * @param  DeviceAddr: specifies the address of the device.
 * @param  RegisterAddr: specifies the Pressure internal address register to read from.
 * @param  NumByteToRead: number of bytes to be read.
 * @retval None.
 */
void HUM_TEMP_IO_Read(uint8_t* pBuffer, uint8_t DeviceAddr, uint8_t RegisterAddr, uint16_t NumByteToRead)
{
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_TAKE();
  #endif
    /* call I2C_SHIELDS Read data bus function */
    I2C_SHIELDS_ReadData(pBuffer, DeviceAddr, RegisterAddr, NumByteToRead);
  #ifdef USE_FREE_RTOS
    NUCLEO_I2C_SHIELDS_MUTEX_RELEASE();
  #endif
}



/******************************* I2C Routines**********************************/
/**
 * @brief  Configures I2C interface.
 * @param  None
 * @retval None
 */
static void I2C_SHIELDS_Init(void)
{
    if(HAL_I2C_GetState(&I2C_SHIELDS_Handle) == HAL_I2C_STATE_RESET)
    {
        /* I2C_SHIELDS peripheral configuration */
      //  I2C_SHIELDS_Handle.Init.ClockSpeed = NUCLEO_I2C_SHIELDS_SPEED;
      //  I2C_SHIELDS_Handle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#ifdef STM32F401xE      
        I2C_SHIELDS_Handle.Init.ClockSpeed = NUCLEO_I2C_SHIELDS_SPEED;
        I2C_SHIELDS_Handle.Init.DutyCycle = I2C_DUTYCYCLE_2;
#endif
#ifdef STM32L053xx
        I2C_SHIELDS_Handle.Init.Timing = 0x0070D8FF;                            /*Refer AN4235-Application note Document*/
#endif        
        I2C_SHIELDS_Handle.Init.OwnAddress1 = 0x33;
        I2C_SHIELDS_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
        I2C_SHIELDS_Handle.Instance = NUCLEO_I2C_SHIELDS;

        /* Init the I2C */
        I2C_SHIELDS_MspInit();
        HAL_I2C_Init(&I2C_SHIELDS_Handle);
    }
}

/**
 * @brief  Write a value in a register of the device through BUS.
 * @param  Addr: Device address on BUS Bus.
 * @param  Reg: The target register address to write
 * @param  Value: The target register value to be written
 * @retval HAL status
 */

static void I2C_SHIELDS_WriteData(uint8_t* pBuffer, uint8_t Addr, uint8_t Reg, uint16_t Size)
{
    HAL_StatusTypeDef status = HAL_OK;

    status = HAL_I2C_Mem_Write(&I2C_SHIELDS_Handle, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, pBuffer, Size, I2C_SHIELDS_Timeout);

    /* Check the communication status */
    if(status != HAL_OK)
    {
        /* Execute user timeout callback */
        I2C_SHIELDS_Error(Addr);
    }
}


/**
 * @brief  Read a register of the device through BUS
 * @param  Addr: Device address on BUS .
 * @param  Reg: The target register address to read
 * @retval HAL status
 */
static void I2C_SHIELDS_ReadData(uint8_t* pBuffer, uint8_t Addr, uint8_t Reg, uint16_t Size)
{
    HAL_StatusTypeDef status = HAL_OK;

    status = HAL_I2C_Mem_Read(&I2C_SHIELDS_Handle, Addr, (uint16_t)Reg, I2C_MEMADD_SIZE_8BIT, pBuffer, Size, I2C_SHIELDS_Timeout);

    /* Check the communication status */
    if(status != HAL_OK)
    {
        /* Execute user timeout callback */
        I2C_SHIELDS_Error(Addr);
    }

}

/**
 * @brief  Manages error callback by re-initializing I2C.
 * @param  Addr: I2C Address
 * @retval None
 */
static void I2C_SHIELDS_Error(uint8_t Addr)
{
    /* De-initialize the I2C comunication bus */
    HAL_I2C_DeInit(&I2C_SHIELDS_Handle);

    /* Re-Initiaize the I2C comunication bus */
    I2C_SHIELDS_Init();
}

/**
 * @brief I2C MSP Initialization
 * @param None
 * @retval None
 */

static void I2C_SHIELDS_MspInit(void)
{
    GPIO_InitTypeDef  GPIO_InitStruct;

#ifdef USE_FREE_RTOS
    if(!NUCLEO_I2C_SHIELDS_MUTEX) {
        NUCLEO_I2C_SHIELDS_MUTEX = osMutexCreate(0);
    }
#endif

    /* Enable I2C GPIO clocks */
    NUCLEO_I2C_SHIELDS_SCL_SDA_GPIO_CLK_ENABLE();

    /* I2C_SHIELDS SCL and SDA pins configuration -------------------------------------*/
    GPIO_InitStruct.Pin = NUCLEO_I2C_SHIELDS_SCL_PIN | NUCLEO_I2C_SHIELDS_SDA_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
    GPIO_InitStruct.Pull  = GPIO_NOPULL;
    GPIO_InitStruct.Alternate  = NUCLEO_I2C_SHIELDS_SCL_SDA_AF;
    HAL_GPIO_Init(NUCLEO_I2C_SHIELDS_SCL_SDA_GPIO_PORT, &GPIO_InitStruct);

    /* Enable the I2C_SHIELDS peripheral clock */
    NUCLEO_I2C_SHIELDS_CLK_ENABLE();

    /* Force the I2C peripheral clock reset */
    NUCLEO_I2C_SHIELDS_FORCE_RESET();

    /* Release the I2C peripheral clock reset */
    NUCLEO_I2C_SHIELDS_RELEASE_RESET();

    /* Enable and set I2C_SHIELDS Interrupt to the highest priority */
    HAL_NVIC_SetPriority(NUCLEO_I2C_SHIELDS_EV_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(NUCLEO_I2C_SHIELDS_EV_IRQn);
    
#ifdef STM32F401xE
    /* Enable and set I2C_SHIELDS Interrupt to the highest priority */
    HAL_NVIC_SetPriority(NUCLEO_I2C_SHIELDS_ER_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(NUCLEO_I2C_SHIELDS_ER_IRQn);
#endif
}


/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/