Paparazzi UAS  v4.0.4_stable-3-gf39211a
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
lisa_test_adxl345_dma.c
Go to the documentation of this file.
1 /*
2  * $Id$
3  *
4  * Copyright (C) 2009 Antoine Drouin <poinix@gmail.com>
5  *
6  * This file is part of paparazzi.
7  *
8  * paparazzi is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * paparazzi is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with paparazzi; see the file COPYING. If not, write to
20  * the Free Software Foundation, 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
24 #include <stm32/gpio.h>
25 #include <stm32/flash.h>
26 #include <stm32/misc.h>
27 #include <stm32/exti.h>
28 #include <stm32/spi.h>
29 #include <stm32/dma.h>
30 
31 #include BOARD_CONFIG
32 #include "mcu.h"
33 #include "mcu_periph/sys_time.h"
34 #include "mcu_periph/uart.h"
36 
37 #include "peripherals/adxl345.h"
38 #include "my_debug_servo.h"
39 #include "led.h"
40 
41 static inline void main_init( void );
42 static inline void main_periodic_task( void );
43 static inline void main_event_task( void );
44 
45 static inline void main_init_hw(void);
46 
47 void exti2_irq_handler(void);
48 void dma1_c4_irq_handler(void);
49 
50 int main(void) {
51  main_init();
52 
53  while(1) {
57  }
58 
59  return 0;
60 }
61 
62 static inline void main_init( void ) {
63  mcu_init();
65  main_init_hw();
66 
67 }
68 
69 static void write_to_reg(uint8_t addr, uint8_t val);
70 static uint8_t read_fom_reg(uint8_t addr);
71 #define CONFIGURED 6
73 static volatile uint8_t acc_data_available = FALSE;
74 
75 static uint8_t dma_tx_buf[7];
76 static uint8_t dma_rx_buf[7];
77 
78 #define AccUnselect() GPIOB->BSRR = GPIO_Pin_12
79 #define AccSelect() GPIOB->BRR = GPIO_Pin_12
80 #define AccToggleSelect() GPIOB->ODR ^= GPIO_Pin_12
81 
82 static void write_to_reg(uint8_t addr, uint8_t val) {
83 
84  AccSelect();
85  SPI_I2S_SendData(SPI2, addr);
86  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
87  SPI_I2S_SendData(SPI2, val);
88  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
89  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
90  AccUnselect();
91 
92 }
93 
95  AccSelect();
96  SPI_I2S_SendData(SPI2, (1<<7|addr));
97  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
98  SPI_I2S_SendData(SPI2, 0x00);
99  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
100  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
101  uint8_t ret = SPI_I2S_ReceiveData(SPI2);
102  AccUnselect();
103  return ret;
104 }
105 
106 static void read_data(void) {
107  AccSelect();
108 
109  dma_tx_buf[0] = (1<<7|1<<6|ADXL345_REG_DATA_X0);
110 
111  /* SPI2_Rx_DMA_Channel configuration ------------------------------------*/
112  DMA_DeInit(DMA1_Channel4);
113  DMA_InitTypeDef DMA_initStructure_4 = {
114  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
115  .DMA_MemoryBaseAddr = (uint32_t)dma_rx_buf,
116  .DMA_DIR = DMA_DIR_PeripheralSRC,
117  .DMA_BufferSize = 7,
118  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
119  .DMA_MemoryInc = DMA_MemoryInc_Enable,
120  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
121  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
122  .DMA_Mode = DMA_Mode_Normal,
123  .DMA_Priority = DMA_Priority_VeryHigh,
124  .DMA_M2M = DMA_M2M_Disable
125  };
126  DMA_Init(DMA1_Channel4, &DMA_initStructure_4);
127 
128  /* SPI2_Tx_DMA_Channel configuration ------------------------------------*/
129  DMA_DeInit(DMA1_Channel5);
130  DMA_InitTypeDef DMA_initStructure_5 = {
131  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
132  .DMA_MemoryBaseAddr = (uint32_t)dma_tx_buf,
133  .DMA_DIR = DMA_DIR_PeripheralDST,
134  .DMA_BufferSize = 7,
135  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
136  .DMA_MemoryInc = DMA_MemoryInc_Enable,
137  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
138  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
139  .DMA_Mode = DMA_Mode_Normal,
140  .DMA_Priority = DMA_Priority_Medium,
141  .DMA_M2M = DMA_M2M_Disable
142  };
143  DMA_Init(DMA1_Channel5, &DMA_initStructure_5);
144 
145  /* Enable SPI_2 Rx request */
146  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
147  /* Enable DMA1 Channel4 */
148  DMA_Cmd(DMA1_Channel4, ENABLE);
149 
150  /* Enable SPI_2 Tx request */
151  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
152  /* Enable DMA1 Channel5 */
153  DMA_Cmd(DMA1_Channel5, ENABLE);
154 
155  /* Enable DMA1 Channel4 Transfer Complete interrupt */
156  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
157 
158 }
159 
160 
161 static inline void main_periodic_task( void ) {
162 
163 
164  RunOnceEvery(10,
165  {
166  DOWNLINK_SEND_ALIVE(DefaultChannel, DefaultDevice, 16, MD5SUM);
167  LED_PERIODIC();
168  });
169 
170  if (acc_status != CONFIGURED) {
171  {
172  /* read data rate */
173  // uint8_t bar = read_fom_reg(ADXL345_REG_BW_RATE);
174  }
175  /* set data rate to 800Hz */
177  /* switch to measurememnt mode */
179  /* enable data ready interrupt */
181  /* Enable full res and interrupt active low */
183  /* reads data once to bring interrupt line up */
184  uint8_t ret = SPI_I2S_ReceiveData(SPI2);
185  read_data();
187  }
188 
189 }
190 
191 
192 static inline void main_event_task( void ) {
193 
196  int16_t ax = dma_rx_buf[1] | (dma_rx_buf[2]<<8);
197  int16_t ay = dma_rx_buf[3] | (dma_rx_buf[4]<<8);
198  int16_t az = dma_rx_buf[5] | (dma_rx_buf[6]<<8);
199  int32_t iax = ax;
200  int32_t iay = ay;
201  int32_t iaz = az;
202  RunOnceEvery(10, {DOWNLINK_SEND_IMU_ACCEL_RAW(DefaultChannel, DefaultDevice, &iax, &iay, &iaz);});
203  }
204 
205 }
206 
207 static inline void main_init_hw( void ) {
208 
209  /* configure acc slave select */
210  /* set acc slave select as output and assert it ( on PB12) */
211  AccUnselect();
212  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
213  GPIO_InitTypeDef GPIO_InitStructure;
214  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
215  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
216  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
217  GPIO_Init(GPIOB, &GPIO_InitStructure);
218 
219  /* configure external interrupt exti2 on PD2( accel int ) */
220  RCC_APB2PeriphClockCmd(IMU_ACC_DRDY_RCC_GPIO | RCC_APB2Periph_AFIO, ENABLE);
221  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
222  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
223  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
224  GPIO_Init(IMU_ACC_DRDY_GPIO, &GPIO_InitStructure);
225  EXTI_InitTypeDef EXTI_InitStructure;
226  GPIO_EXTILineConfig(IMU_ACC_DRDY_GPIO_PORTSOURCE, GPIO_PinSource2);
227  EXTI_InitStructure.EXTI_Line = EXTI_Line2;
228  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
229  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
230  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
231  EXTI_Init(&EXTI_InitStructure);
232  NVIC_InitTypeDef NVIC_InitStructure;
233  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
234  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
235  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
236  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
237  NVIC_Init(&NVIC_InitStructure);
238 
239 
240  /* Enable SPI2 Periph clock -------------------------------------------------*/
241  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
242 
243  /* Configure GPIOs: SCK, MISO and MOSI --------------------------------*/
244  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
245  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
246  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
247  GPIO_Init(GPIOB, &GPIO_InitStructure);
248 
249  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);
250  SPI_Cmd(SPI2, ENABLE);
251 
252  /* configure SPI */
253  SPI_InitTypeDef SPI_InitStructure;
254  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
255  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
256  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
257  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
258  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
259  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
260  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
261  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
262  SPI_InitStructure.SPI_CRCPolynomial = 7;
263  SPI_Init(SPI2, &SPI_InitStructure);
264 
265  /* Enable DMA1 channel4 IRQ Channel ( SPI RX) */
266  NVIC_InitTypeDef NVIC_init_struct = {
267  .NVIC_IRQChannel = DMA1_Channel4_IRQn,
268  .NVIC_IRQChannelPreemptionPriority = 0,
269  .NVIC_IRQChannelSubPriority = 0,
270  .NVIC_IRQChannelCmd = ENABLE
271  };
272  NVIC_Init(&NVIC_init_struct);
273 
274  /* Enable SPI_2 DMA clock ---------------------------------------------------*/
275  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
276 
278 
279 }
280 
281 
282 void exti2_irq_handler(void) {
283 
284  /* clear EXTI */
285  if(EXTI_GetITStatus(EXTI_Line2) != RESET)
286  EXTI_ClearITPendingBit(EXTI_Line2);
287 
288  DEBUG_S4_TOGGLE();
289 
290  read_data();
291 
292 }
293 
295  AccUnselect();
296  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, DISABLE);
297  /* Disable SPI_2 Rx and TX request */
298  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
299  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
300  /* Disable DMA1 Channel4 and 5 */
301  DMA_Cmd(DMA1_Channel4, DISABLE);
302  DMA_Cmd(DMA1_Channel5, DISABLE);
303 
305 }
arch independent UART (Universal Asynchronous Receiver/Transmitter) API
#define ADXL345_REG_DATA_FORMAT
Definition: adxl345.h:12
#define AccSelect()
int main(void)
void dma1_c4_irq_handler(void)
static uint8_t dma_tx_buf[7]
static uint8_t read_fom_reg(uint8_t addr)
#define ADXL345_REG_POWER_CTL
Definition: adxl345.h:10
static uint8_t dma_rx_buf[7]
#define PERIODIC_FREQUENCY
Definition: imu_aspirin2.c:54
#define FALSE
Definition: imu_chimu.h:141
static void main_init_hw(void)
static void main_periodic_task(void)
#define IMU_ACC_DRDY_GPIO
Definition: lisa_l_1.0.h:24
static void main_init(void)
Architecture independent timing functions.
static volatile uint8_t acc_data_available
uint16_t val[TCOUPLE_NB]
unsigned long uint32_t
Definition: types.h:18
signed short int16_t
Definition: types.h:17
#define IMU_ACC_DRDY_RCC_GPIO
Definition: lisa_l_1.0.h:23
#define CONFIGURED
#define DEBUG_S4_TOGGLE()
#define DEBUG_SERVO2_INIT()
#define ADXL345_REG_BW_RATE
Definition: adxl345.h:9
int sys_time_register_timer(float duration, sys_time_cb cb)
Register a new system timer.
Definition: sys_time.c:35
static bool_t sys_time_check_and_ack_timer(tid_t id)
Definition: sys_time.h:90
signed long int32_t
Definition: types.h:19
#define TRUE
Definition: imu_chimu.h:144
#define LED_PERIODIC()
Definition: led_hw.h:8
arch independent mcu ( Micro Controller Unit ) utilities
unsigned char uint8_t
Definition: types.h:14
#define ADXL345_REG_DATA_X0
Definition: adxl345.h:13
void exti2_irq_handler(void)
static void read_data(void)
arch independent LED (Light Emitting Diodes) API
#define IMU_ACC_DRDY_GPIO_PORTSOURCE
Definition: lisa_l_1.0.h:25
#define ADXL345_REG_INT_ENABLE
Definition: adxl345.h:11
static void write_to_reg(uint8_t addr, uint8_t val)
static void main_event_task(void)
#define AccUnselect()
#define RESET
Definition: humid_sht.h:40
static uint8_t acc_status
void mcu_init(void)
Definition: mcu.c:57