From b89c65bd8d6fa479b2e0a01e873fef2220ce563e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 1 Jan 2012 13:16:19 +0000 Subject: Added MEMS support to the STM32F4-Discovery demo. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3702 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F407-DISCOVERY/Makefile | 4 +- demos/ARMCM4-STM32F407-DISCOVERY/main.c | 42 ++++++++++-- demos/ARMCM4-STM32F407-DISCOVERY/mcuconf.h | 2 +- os/various/lis302dl.c | 103 +++++++++++++++++++++++++++++ os/various/lis302dl.h | 73 ++++++++++++++++++++ readme.txt | 1 + 6 files changed, 217 insertions(+), 8 deletions(-) create mode 100644 os/various/lis302dl.c create mode 100644 os/various/lis302dl.h diff --git a/demos/ARMCM4-STM32F407-DISCOVERY/Makefile b/demos/ARMCM4-STM32F407-DISCOVERY/Makefile index fbd0c2245..975e5f999 100644 --- a/demos/ARMCM4-STM32F407-DISCOVERY/Makefile +++ b/demos/ARMCM4-STM32F407-DISCOVERY/Makefile @@ -78,8 +78,8 @@ CSRC = $(PORTSRC) \ $(HALSRC) \ $(PLATFORMSRC) \ $(BOARDSRC) \ - $(CHIBIOS)/os/various/evtimer.c \ - $(CHIBIOS)/os/various/syscalls.c \ + $(CHIBIOS)/os/various/lis302dl.c \ + $(CHIBIOS)/os/various/chprintf.c \ main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global diff --git a/demos/ARMCM4-STM32F407-DISCOVERY/main.c b/demos/ARMCM4-STM32F407-DISCOVERY/main.c index 161bc63b5..d8b72e3f7 100644 --- a/demos/ARMCM4-STM32F407-DISCOVERY/main.c +++ b/demos/ARMCM4-STM32F407-DISCOVERY/main.c @@ -21,6 +21,8 @@ #include "ch.h" #include "hal.h" #include "test.h" +#include "lis302dl.h" +#include "chprintf.h" static void pwmpcb(PWMDriver *pwmp); static void adccb(ADCDriver *adcp, adcsample_t *buffer, size_t n); @@ -78,11 +80,24 @@ static PWMConfig pwmcfg = { }; /* - * SPI configuration structure. - * Maximum speed (12MHz), CPHA=0, CPOL=0, 16bits frames, MSb transmitted first. - * The slave select line is the pin GPIOA_SPI1NSS on the port GPIOA. + * SPI1 configuration structure. + * Speed 5.25MHz, CPHA=1, CPOL=1, 8bits frames, MSb transmitted first. + * The slave select line is the pin GPIOE_CS_SPI on the port GPIOE. */ -static const SPIConfig spicfg = { +static const SPIConfig spi1cfg = { + NULL, + /* HW dependent part.*/ + GPIOE, + GPIOE_CS_SPI, + SPI_CR1_BR_0 | SPI_CR1_BR_1 | SPI_CR1_CPOL | SPI_CR1_CPHA +}; + +/* + * SPI2 configuration structure. + * Speed 21MHz, CPHA=0, CPOL=0, 16bits frames, MSb transmitted first. + * The slave select line is the pin 12 on the port GPIOA. + */ +static const SPIConfig spi2cfg = { spicb, /* HW dependent part.*/ GPIOB, @@ -204,7 +219,7 @@ int main(void) { * PB14 - MISO. * PB15 - MOSI. */ - spiStart(&SPID2, &spicfg); + spiStart(&SPID2, &spi2cfg); palSetPad(GPIOB, 12); palSetPadMode(GPIOB, 12, PAL_MODE_OUTPUT_PUSHPULL | PAL_STM32_OSPEED_HIGHEST); /* NSS. */ @@ -234,6 +249,16 @@ int main(void) { */ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); + /* + * Initializes the SPI driver 1 in order to access the MEMS. The signals + * are initialized in the board file. + * Several LIS302DL registers are then initialized. + */ + spiStart(&SPID1, &spi1cfg); + lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG1, 0x43); + lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG2, 0x00); + lis302dlWriteRegister(&SPID1, LIS302DL_CTRL_REG3, 0x00); + /* * Normal main() thread activity, in this demo it does nothing except * sleeping in a loop and check the button state, when the button is @@ -241,8 +266,15 @@ int main(void) { * driver 2. */ while (TRUE) { + uint8_t x, y, z; + if (palReadPad(GPIOA, GPIOA_BUTTON)) TestThread(&SD2); + + x = lis302dlReadRegister(&SPID1, LIS302DL_OUTX); + y = lis302dlReadRegister(&SPID1, LIS302DL_OUTY); + z = lis302dlReadRegister(&SPID1, LIS302DL_OUTZ); + chprintf((BaseChannel *)&SD2, "%d, %d, %d\r\n", x, y, z); chThdSleepMilliseconds(500); } } diff --git a/demos/ARMCM4-STM32F407-DISCOVERY/mcuconf.h b/demos/ARMCM4-STM32F407-DISCOVERY/mcuconf.h index ba8c322fd..73999ec6b 100644 --- a/demos/ARMCM4-STM32F407-DISCOVERY/mcuconf.h +++ b/demos/ARMCM4-STM32F407-DISCOVERY/mcuconf.h @@ -173,7 +173,7 @@ /* * SPI driver system settings. */ -#define STM32_SPI_USE_SPI1 FALSE +#define STM32_SPI_USE_SPI1 TRUE #define STM32_SPI_USE_SPI2 TRUE #define STM32_SPI_USE_SPI3 FALSE #define STM32_SPI_SPI1_RX_DMA_STREAM STM32_DMA_STREAM_ID(2, 0) diff --git a/os/various/lis302dl.c b/os/various/lis302dl.c new file mode 100644 index 000000000..48e8ce200 --- /dev/null +++ b/os/various/lis302dl.c @@ -0,0 +1,103 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 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 . +*/ + +/** + * @file lis302dl.c + * @brief LIS302DL MEMS interface module through SPI code. + * + * @addtogroup lis302dl + * @{ + */ + +#include "ch.h" +#include "hal.h" +#include "lis302dl.h" + +static uint8_t txbuf[2]; +static uint8_t rxbuf[2]; + +/** + * @brief Reads a register value. + * @pre The SPI interface must be initialized and the driver started. + * + * @param[in] spip pointer to the SPI initerface + * @param[in] reg register number + * @return The register value. + */ +uint8_t lis302dlReadRegister(SPIDriver *spip, uint8_t reg) { + + spiSelect(spip); + txbuf[0] = 0x80 | reg; + txbuf[1] = 0xff; + spiExchange(spip, 2, txbuf, rxbuf); + spiUnselect(spip); + return rxbuf[1]; +} + +/** + * @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 initerface + * @param[in] reg register number + * @param[in] value the value to be written + */ +void lis302dlWriteRegister(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, "lis302dlWriteRegister(), #1", "reserved register"); + case LIS302DL_WHO_AM_I: + case LIS302DL_HP_FILTER_RESET: + case LIS302DL_STATUS_REG: + case LIS302DL_OUTX: + case LIS302DL_OUTY: + case LIS302DL_OUTZ: + case LIS302DL_FF_WU_SRC1: + case LIS302DL_FF_WU_SRC2: + case LIS302DL_CLICK_SRC: + /* Read only registers cannot be written, the command is ignored.*/ + return; + case LIS302DL_CTRL_REG1: + case LIS302DL_CTRL_REG2: + case LIS302DL_CTRL_REG3: + case LIS302DL_FF_WU_CFG1: + case LIS302DL_FF_WU_THS1: + case LIS302DL_FF_WU_DURATION1: + case LIS302DL_FF_WU_CFG2: + case LIS302DL_FF_WU_THS2: + case LIS302DL_FF_WU_DURATION2: + case LIS302DL_CLICK_CFG: + case LIS302DL_CLICK_THSY_X: + case LIS302DL_CLICK_THSZ: + case LIS302DL_CLICK_TIMELIMIT: + case LIS302DL_CLICK_LATENCY: + case LIS302DL_CLICK_WINDOW: + spiSelect(spip); + txbuf[0] = reg; + txbuf[1] = value; + spiSend(spip, 2, txbuf); + spiUnselect(spip); + } +} + +/** @} */ diff --git a/os/various/lis302dl.h b/os/various/lis302dl.h new file mode 100644 index 000000000..4e6fefaaa --- /dev/null +++ b/os/various/lis302dl.h @@ -0,0 +1,73 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 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 . +*/ + +/** + * @file lis302dl.h + * @brief LIS302DL MEMS interface module through SPI header. + * + * @addtogroup lis302dl + * @{ + */ + +#ifndef _LIS302DL_H_ +#define _LIS302DL_H_ + +/** + * @name LIS302DL register names + * @{ + */ +#define LIS302DL_WHO_AM_I 0x0F +#define LIS302DL_CTRL_REG1 0x20 +#define LIS302DL_CTRL_REG2 0x21 +#define LIS302DL_CTRL_REG3 0x22 +#define LIS302DL_HP_FILTER_RESET 0x23 +#define LIS302DL_STATUS_REG 0x27 +#define LIS302DL_OUTX 0x29 +#define LIS302DL_OUTY 0x2B +#define LIS302DL_OUTZ 0x2D +#define LIS302DL_FF_WU_CFG1 0x30 +#define LIS302DL_FF_WU_SRC1 0x31 +#define LIS302DL_FF_WU_THS1 0x32 +#define LIS302DL_FF_WU_DURATION1 0x33 +#define LIS302DL_FF_WU_CFG2 0x34 +#define LIS302DL_FF_WU_SRC2 0x35 +#define LIS302DL_FF_WU_THS2 0x36 +#define LIS302DL_FF_WU_DURATION2 0x37 +#define LIS302DL_CLICK_CFG 0x38 +#define LIS302DL_CLICK_SRC 0x39 +#define LIS302DL_CLICK_THSY_X 0x3B +#define LIS302DL_CLICK_THSZ 0x3C +#define LIS302DL_CLICK_TIMELIMIT 0x3D +#define LIS302DL_CLICK_LATENCY 0x3E +#define LIS302DL_CLICK_WINDOW 0x3F +/** @} */ + +#ifdef __cplusplus +extern "C" { +#endif + uint8_t lis302dlReadRegister(SPIDriver *spip, uint8_t reg); + void lis302dlWriteRegister(SPIDriver *spip, uint8_t reg, uint8_t value); +#ifdef __cplusplus +} +#endif + +#endif /* _LIS302DL_H_ */ + +/** @} */ diff --git a/readme.txt b/readme.txt index c5ff58d69..44c4b7454 100644 --- a/readme.txt +++ b/readme.txt @@ -78,6 +78,7 @@ - FIX: Fixed SYSCFG clock not started in STM32L1/F4 HALs (bug 3449139). - FIX: Fixed wrong definitions in STM32L-Discovery board file (bug 3449076). - OPT: Improved the exception exit code in the GCC Cortex-Mx ports. +- NEW: Added an utility module to access LIS302DL MEMS using a SPI. - NEW: Updated STM32F2xx support by inheriting the work done on the STM32F4xx, the whole thing is untested because lack of hardware. - NEW: Files nvic.c and nvic.h moved under ./os/ports/common/ARMCMx, removed -- cgit v1.2.3