STM32F3 and Gyroscope Topic is solved

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

unicondor
Posts: 9
Joined: Tue May 14, 2013 1:00 pm

STM32F3 and Gyroscope

Post by unicondor »

Hi to all,

Anyone can send me some example program (or documents) on how to use gyroscope with ChibiOS?

Thanks so muck

Flavio
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F3 and Gyroscope

Post by Giovanni »

Hi,

The document would be the gyroscope data sheet and you would interface it using the ChibiOS SPI driver, I don't have a demo for it right now. Maybe somebody else already did something with the Gyro, if so please post here.

Giovanni
unicondor
Posts: 9
Joined: Tue May 14, 2013 1:00 pm

Re: STM32F3 and Gyroscope

Post by unicondor »

If i find some example for F1 or F4 and ChibiOS, can i use it for F3?
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: STM32F3 and Gyroscope

Post by Giovanni »

Yes, almost unmodified as long the gyro is the same device.

Giovanni
MartinP
Posts: 35
Joined: Mon Apr 02, 2012 11:54 am

Re: STM32F3 and Gyroscope

Post by MartinP »

For the Stm32F3 Discovery You could take the attachment (download/file.php?id=354) in this post (viewtopic.php?f=3&t=1021&p=9621#p9621)as an example

regards

Martin
unicondor
Posts: 9
Joined: Tue May 14, 2013 1:00 pm

Re: STM32F3 and Gyroscope

Post by unicondor »

MartinP wrote:For the Stm32F3 Discovery You could take the attachment (download/file.php?id=354) in this post (viewtopic.php?f=3&t=1021&p=9621#p9621)as an example



Thanks a lot... I'm trying the code ;)
User avatar
RoccoMarco
Posts: 655
Joined: Wed Apr 24, 2013 4:11 pm
Has thanked: 83 times
Been thanked: 67 times

Re: STM32F3 and Gyroscope

Post by RoccoMarco »

Hi Unicondor,
this is main.h of my first application with gyroscope.

Code: Select all

/*
    ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
*/

#include "ch.h"
#include "hal.h"

#include "l3gd20.h"

static msg_t message=0;


/*
 * SPI RX and TX buffers.
 */
static uint8_t rxbuf[2];
static uint8_t txbuf[2];


/*
 *Configuration @ max frequency according to MEMS
 *Configuration (9 MHz, CPHA=1, CPOL=1, MSb first, 8bit word).
 */
static const SPIConfig std_spicfg = {
  NULL,
  GPIOE,                                                        /*port of CS  */
  GPIOE_SPI1_CS,                                                /*pin of CS   */
  SPI_CR1_BR_0|SPI_CR1_CPOL|SPI_CR1_CPHA,                       /*CR1 register*/
  SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0                    /*CR2 register*/
};


/*
 * This Thread reads the value of WHO_AM_I register of L3GD20
 */
static msg_t SPID1_Thread(void *arg) {
  (void)arg;
  chRegSetThreadName("SPI Drive 1 thread");
  while (TRUE){
    spiAcquireBus(&SPID1);
    spiStart(&SPID1, &std_spicfg);
    spiSelect(&SPID1);
    spiExchange (&SPID1, 2, txbuf, rxbuf);
    spiUnselect(&SPID1);
    spiReleaseBus(&SPID1);
    chThdSleepMilliseconds(10);
  }
  return message;
}


/*
 * This is a periodic thread that does absolutely nothing except flashing
 * a LED.
 */
static msg_t Blinker_Thread(void *arg) {
  (void)arg;
  chRegSetThreadName("Blinker");
  while (TRUE) {
    palSetPad(GPIOE, GPIOE_LED3_RED);
    chThdSleepMilliseconds(500);
    palClearPad(GPIOE, GPIOE_LED3_RED);
    chThdSleepMilliseconds(500);
  }
  return message;
}


/*
 * Declaration of the working areas of threads
 */
static WORKING_AREA(waSPID1_Thread, 256);
static WORKING_AREA(waBlinker_Thread, 128);


/*
 * Application entry point.
 */
int main(void) {

  /*
   * System initializations.
   * - HAL initialization, this also initializes the configured device drivers
   *   and performs the board-specific initializations.
   * - Kernel initialization, the main() function becomes a thread and the
   *   RTOS is active.
   */
  halInit();
  chSysInit();


  /*
   * SPI2 I/O pins setup.(It bypasses board.h configurations)
   */
  palSetPadMode(GPIOA, GPIOA_SPI1_SCK ,
                PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST);   /* New SCK */
  palSetPadMode(GPIOA, GPIOA_SPI1_MISO ,
                PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST);   /* New MISO*/
  palSetPadMode(GPIOA, GPIOA_SPI1_MOSI ,
                PAL_MODE_ALTERNATE(5)|PAL_STM32_OSPEED_HIGHEST);   /* New MOSI*/
  palSetPadMode(GPIOE, GPIOE_SPI1_CS ,
                PAL_MODE_OUTPUT_PUSHPULL|PAL_STM32_OSPEED_HIGHEST);/* New CS  */


  /*
   *  Transmission buffer setup.
   */

  txbuf[0]=L3GD20_SPI_RW|L3GD20_SPI_AD_3|L3GD20_SPI_AD_2|L3GD20_SPI_AD_1|
      L3GD20_SPI_AD_0;
  txbuf[1]=0x00FF;


  /*
   * Starting the transmitter\receiver and the blinker threads.
   */
  chThdCreateStatic(waBlinker_Thread, sizeof(waBlinker_Thread),
                    NORMALPRIO-1, Blinker_Thread, NULL);
  chThdCreateStatic(waSPID1_Thread, sizeof(waSPID1_Thread),
                    NORMALPRIO+1, SPID1_Thread, NULL);


  /*
   * Normal main() thread activity, in this demo it does nothing.
   */
  while (TRUE) {
    chThdSleepMilliseconds(500);
  }
  return 0;
}


In order to use this code you have to include these files

l3gd20.h

Code: Select all

/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
                 2011,2012,2013 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file    l3gd20.h
 * @brief   L3GD20 MEMS interface module through SPI header.
 *
 * @addtogroup l3gd20
 * @{
 */

#ifndef _L3GD20_H_
#define _L3GD20_H_

/*===========================================================================*/
/* Driver constants.                                                         */
/*===========================================================================*/

/**
 * @name    L3GD20 register names
 * @{
 */
/******************************************************************************/
/*                                                                            */
/*                        L3GD20 on board MEMS                                */
/*                                                                            */
/******************************************************************************/
/*******************  Bit definition for SPI communication  *******************/
#define  L3GD20_SPI_DI                        ((uint8_t)0xFF)            /*!< AD[7:0] Data input */
#define  L3GD20_SPI_DI_0                      ((uint8_t)0x01)            /*!< bit 0 */
#define  L3GD20_SPI_DI_1                      ((uint8_t)0x02)            /*!< bit 1 */
#define  L3GD20_SPI_DI_2                      ((uint8_t)0x04)            /*!< bit 2 */
#define  L3GD20_SPI_DI_3                      ((uint8_t)0x08)            /*!< bit 3 */
#define  L3GD20_SPI_DI_4                      ((uint8_t)0x10)            /*!< bit 4 */
#define  L3GD20_SPI_DI_5                      ((uint8_t)0x20)            /*!< bit 5 */
#define  L3GD20_SPI_DI_6                      ((uint8_t)0x40)            /*!< bit 6 */
#define  L3GD20_SPI_DI_7                      ((uint8_t)0x80)            /*!< bit 7 */

#define  L3GD20_SPI_AD                        ((uint8_t)0x3F)            /*!< AD[5:0] Address Data */
#define  L3GD20_SPI_AD_0                      ((uint8_t)0x01)            /*!< bit 0 */
#define  L3GD20_SPI_AD_1                      ((uint8_t)0x02)            /*!< bit 1 */
#define  L3GD20_SPI_AD_2                      ((uint8_t)0x04)            /*!< bit 2 */
#define  L3GD20_SPI_AD_3                      ((uint8_t)0x08)            /*!< bit 3 */
#define  L3GD20_SPI_AD_4                      ((uint8_t)0x10)            /*!< bit 4 */
#define  L3GD20_SPI_AD_5                      ((uint8_t)0x20)            /*!< bit 5 */

#define  L3GD20_SPI_MS                        ((uint8_t)0x40)            /*!< Multiple read write */
#define  L3GD20_SPI_RW                        ((uint8_t)0x80)            /*!< Read Write */

/*******************  Bit definition for Registers Addresses*******************/
#define  L3GD20_SPI_AD_WHO_AM_I               ((uint8_t)0x0F)            /*!< WHO I AM */
#define  L3GD20_SPI_AD_CTRL_REG1              ((uint8_t)0x20)            /*!< CONTROL REGISTER 1 */
#define  L3GD20_SPI_AD_CTRL_REG2              ((uint8_t)0x21)            /*!< CONTROL REGISTER 2 */
#define  L3GD20_SPI_AD_CTRL_REG3              ((uint8_t)0x22)            /*!< CONTROL REGISTER 3 */
#define  L3GD20_SPI_AD_CTRL_REG4              ((uint8_t)0x23)            /*!< CONTROL REGISTER 4 */
#define  L3GD20_SPI_AD_CTRL_REG5              ((uint8_t)0x24)            /*!< CONTROL REGISTER 5 */
#define  L3GD20_SPI_AD_REFERENCE              ((uint8_t)0x25)            /*!< REFERENCE/DATACAPTURE */
#define  L3GD20_SPI_AD_OUT_TEMP               ((uint8_t)0x26)            /*!< MEMS ONBOARD TEMP SENSOR */
#define  L3GD20_SPI_AD_STATUS_REG             ((uint8_t)0x27)            /*!< STATUS REGISTER */
#define  L3GD20_SPI_AD_OUT_X_L                ((uint8_t)0x28)            /*!< OUTPUT X-AXIS LOW */
#define  L3GD20_SPI_AD_OUT_X_H                ((uint8_t)0x29)            /*!< OUTPUT X-AXIS HIGH */
#define  L3GD20_SPI_AD_OUT_Y_L                ((uint8_t)0x2A)            /*!< OUTPUT Y-AXIS LOW */
#define  L3GD20_SPI_AD_OUT_Y_H                ((uint8_t)0x2B)            /*!< OUTPUT Y-AXIS HIGH */
#define  L3GD20_SPI_AD_OUT_Z_L                ((uint8_t)0x2C)            /*!< OUTPUT Z-AXIS LOW */
#define  L3GD20_SPI_AD_OUT_Z_H                ((uint8_t)0x2D)            /*!< OUTPUT Z-AXIS HIGH */
#define  L3GD20_SPI_AD_FIFO_CTRL_REG          ((uint8_t)0x2E)            /*!< FIFO CONTROL REGISTER */
#define  L3GD20_SPI_AD_FIFO_SRC_REG           ((uint8_t)0x2F)            /*!< FIFO SRC REGISTER */
#define  L3GD20_SPI_AD_INT1_CFG               ((uint8_t)0x30)            /*!< INTERRUPT1 CONFIG REGISTER */
#define  L3GD20_SPI_AD_INT1_SRC               ((uint8_t)0x31)            /*!< INTERRUPT1 SRC REGISTER */
#define  L3GD20_SPI_AD_INT1_TSH_XH            ((uint8_t)0x32)            /*!< INTERRUPT1 THRESHOLD X-AXIS HIGH */
#define  L3GD20_SPI_AD_INT1_TSH_XL            ((uint8_t)0x33)            /*!< INTERRUPT1 THRESHOLD X-AXIS LOW */
#define  L3GD20_SPI_AD_INT1_TSH_YH            ((uint8_t)0x34)            /*!< INTERRUPT1 THRESHOLD Y-AXIS HIGH */
#define  L3GD20_SPI_AD_INT1_TSH_YL            ((uint8_t)0x35)            /*!< INTERRUPT1 THRESHOLD Y-AXIS LOW */
#define  L3GD20_SPI_AD_INT1_TSH_ZH            ((uint8_t)0x36)            /*!< INTERRUPT1 THRESHOLD Z-AXIS HIGH */
#define  L3GD20_SPI_AD_INT1_TSH_ZL            ((uint8_t)0x37)            /*!< INTERRUPT1 THRESHOLD Z-AXIS LOW */
#define  L3GD20_SPI_AD_INT1_DURATION          ((uint8_t)0x38)            /*!< INTERRUPT1 DURATION */
/** @} */

/*===========================================================================*/
/* Driver pre-compile time settings.                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Derived constants and error checks.                                       */
/*===========================================================================*/

/*===========================================================================*/
/* Driver data structures and types.                                         */
/*===========================================================================*/

/*===========================================================================*/
/* Driver macros.                                                            */
/*===========================================================================*/

/*===========================================================================*/
/* External declarations.                                                    */
/*===========================================================================*/

#ifdef __cplusplus
extern "C" {
#endif
  uint8_t l3gd20ReadRegister(SPIDriver *spip, uint8_t reg);
  int16_t l3gd20ReadAxis (SPIDriver *spip, uint8_t reg);
  void l3gd20WriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value);
#ifdef __cplusplus
}
#endif

#endif /* _L3GD20_H_ */

/** @} */


l3gd20.c

Code: Select all

/*
    ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
                 2011,2012,2013 Giovanni Di Sirio.

    This file is part of ChibiOS/RT.

    ChibiOS/RT is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ChibiOS/RT is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/**
 * @file    l3gd20.c
 * @brief   L3GD20 MEMS interface module through SPI code.
 *
 * @addtogroup l3gd20
 * @{
 */

#include "ch.h"
#include "hal.h"
#include "l3gd20.h"

/*===========================================================================*/
/* Driver local definitions.                                                 */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported variables.                                                */
/*===========================================================================*/

/*===========================================================================*/
/* Driver local variables and types.                                         */
/*===========================================================================*/

static uint8_t txbuf [2];
static uint8_t rxbuf [2];
static uint8_t axis_txbuf[2];
static uint8_t axis_rxbuf[3];
static int16_t axis_value=0;

/*===========================================================================*/
/* Driver local functions.                                                   */
/*===========================================================================*/

/*===========================================================================*/
/* Driver exported functions.                                                */
/*===========================================================================*/

/**
 * @brief   Reads a generic register value.
 * @pre     The SPI interface must be initialized and the driver started.
 *
 * @param[in] spip      pointer to the SPI interface
 * @param[in] reg       register number
 * @return              register value.
 */
uint8_t l3gd20ReadRegister(SPIDriver *spip, uint8_t reg) {
  txbuf[0] = L3GD20_SPI_RW | reg;
  txbuf[1] = 0xFF;
  spiSelect(spip);
  spiExchange(spip, 2, txbuf, rxbuf);
  spiUnselect(spip);
  return rxbuf[1];
}


/**
 * @brief   Reads an axis register value.
 * @pre     The SPI interface must be initialized and the driver started.
 *
 * @param[in] spip      pointer to the SPI interface
 * @param[in] reg       low value of an axis register number
 * @return              combined value of low and high axis register.
 */
int16_t l3gd20ReadAxis (SPIDriver *spip, uint8_t reg){
  spiSelect(spip);
  axis_txbuf[0] = L3GD20_SPI_RW | L3GD20_SPI_MS | reg;
  axis_txbuf[1] = 0xFF;
  spiExchange(spip,3, axis_txbuf, axis_rxbuf);
  spiUnselect(spip);
  axis_value=axis_rxbuf[2];
  axis_value=(axis_value << 8) | axis_rxbuf[1];
  return axis_value;
}

/**
 * @brief   Writes a value into a register.
 * @pre     The SPI interface must be initialized and the driver started.
 *
 * @param[in] spip      pointer to the SPI interface
 * @param[in] reg       register number
 * @param[in] value     the value to be written
 */
void l3gd20WriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value) {

  switch (reg) {
    default:
      /* Reserved register must not be written, according to the datasheet
       * this could permanently damage the device.
       */
      chDbgAssert(FALSE, "lg3d20WriteRegister(), #1", "reserved register");
    case L3GD20_SPI_AD_WHO_AM_I:
    case L3GD20_SPI_AD_OUT_TEMP :
    case L3GD20_SPI_AD_STATUS_REG:
    case L3GD20_SPI_AD_OUT_X_L:
    case L3GD20_SPI_AD_OUT_X_H:
    case L3GD20_SPI_AD_OUT_Y_L:
    case L3GD20_SPI_AD_OUT_Y_H:
    case L3GD20_SPI_AD_OUT_Z_L:
    case L3GD20_SPI_AD_OUT_Z_H:
    case L3GD20_SPI_AD_FIFO_SRC_REG:
    case L3GD20_SPI_AD_INT1_SRC:
    /* Read only registers cannot be written, the command is ignored.*/
      return;
    case L3GD20_SPI_AD_CTRL_REG1:
    case L3GD20_SPI_AD_CTRL_REG2:
    case L3GD20_SPI_AD_CTRL_REG3:
    case L3GD20_SPI_AD_CTRL_REG4:
    case L3GD20_SPI_AD_CTRL_REG5:
    case L3GD20_SPI_AD_REFERENCE:
    case L3GD20_SPI_AD_FIFO_CTRL_REG:
    case L3GD20_SPI_AD_INT1_CFG:
    case L3GD20_SPI_AD_INT1_TSH_XH:
    case L3GD20_SPI_AD_INT1_TSH_XL:
    case L3GD20_SPI_AD_INT1_TSH_YH:
    case L3GD20_SPI_AD_INT1_TSH_YL:
    case L3GD20_SPI_AD_INT1_TSH_ZH:
    case L3GD20_SPI_AD_INT1_TSH_ZL:
    case L3GD20_SPI_AD_INT1_DURATION:
      spiSelect(spip);
      txbuf[0] = reg;
      txbuf[1] = value;
      spiSend(spip, 2, txbuf);
      spiUnselect(spip);
  }
}

/** @} */


I hope this is usefull to you,
best regards
unicondor
Posts: 9
Joined: Tue May 14, 2013 1:00 pm

Re: STM32F3 and Gyroscope

Post by unicondor »

Thanks so muck Rocco,

You gave me a nice toy to try :D

I will send you a feedback...

Flavio
User avatar
RoccoMarco
Posts: 655
Joined: Wed Apr 24, 2013 4:11 pm
Has thanked: 83 times
Been thanked: 67 times

Re: STM32F3 and Gyroscope

Post by RoccoMarco »

I have a few toys, a little more complicated, that also involves the Serial over USB Driver. But i'm just a newbie: a lot of bug to do the simplest things. I'll follow this topic. Keep me informed. :mrgreen:
unicondor
Posts: 9
Joined: Tue May 14, 2013 1:00 pm

Re: STM32F3 and Gyroscope

Post by unicondor »

I have some error when i try to compile your source code

Description Resource Path Location Type
unknown type name 'SPIConfig' main.c /ARMCM4-STM32F303-DISCOVERY line 36 C/C++ Problem
unknown type name 'SPIDriver' l3gd20.h /ARMCM4-STM32F303-DISCOVERY line 120 C/C++ Problem
unknown type name 'SPIDriver' l3gd20.h /ARMCM4-STM32F303-DISCOVERY line 121 C/C++ Problem
unknown type name 'SPIDriver' l3gd20.h /ARMCM4-STM32F303-DISCOVERY line 119 C/C++ Problem


Where i can find this driver??

Thanks
Flavio
Post Reply