Paparazzi UAS  v4.2.2_stable-4-gcc32f65
Paparazzi is a free software Unmanned Aircraft System.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
imu_aspirin_arch.c
Go to the documentation of this file.
1 #include "subsystems/imu.h"
2 
3 #include <stm32/gpio.h>
4 #include <stm32/misc.h>
5 #include <stm32/rcc.h>
6 #include <stm32/exti.h>
7 #include <stm32/spi.h>
8 #include <stm32/dma.h>
9 
10 #include "mcu_periph/i2c.h"
11 
12 /* gyro int handler */
13 void exti15_10_irq_handler(void);
14 /* mag int handler */
15 void exti9_5_irq_handler(void);
16 /* accelerometer int handler */
17 void exti2_irq_handler(void);
18 /* accelerometer SPI selection */
19 #define Adxl345Unselect() GPIOB->BSRR = GPIO_Pin_12
20 #define Adxl345Select() GPIOB->BRR = GPIO_Pin_12
21 /* accelerometer dma end of rx handler */
22 void dma1_c4_irq_handler(void);
23 
25  NVIC_InitTypeDef NVIC_InitStructure;
26 
27 #ifdef ASPIRIN_USE_GYRO_INT
28  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
29  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
30  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
31  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
32  NVIC_Init(&NVIC_InitStructure);
33 #endif
34 
35  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
36  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
37  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
38  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
39  NVIC_Init(&NVIC_InitStructure);
40 
41  /* Enable DMA1 channel4 IRQ Channel ( SPI RX) */
42  NVIC_InitTypeDef NVIC_init_struct = {
43  .NVIC_IRQChannel = DMA1_Channel4_IRQn,
44  .NVIC_IRQChannelPreemptionPriority = 0,
45  .NVIC_IRQChannelSubPriority = 0,
46  .NVIC_IRQChannelCmd = ENABLE
47  };
48  NVIC_Init(&NVIC_init_struct);
49 
50 }
51 
53  NVIC_InitTypeDef NVIC_InitStructure;
54 
55 #ifdef ASPIRIN_USE_GYRO_INT
56  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
57  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
58  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
59  NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
60  NVIC_Init(&NVIC_InitStructure);
61 #endif
62 
63  NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
64  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
65  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
66  NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
67  NVIC_Init(&NVIC_InitStructure);
68 
69  /* Enable DMA1 channel4 IRQ Channel ( SPI RX) */
70  NVIC_InitTypeDef NVIC_init_struct = {
71  .NVIC_IRQChannel = DMA1_Channel4_IRQn,
72  .NVIC_IRQChannelPreemptionPriority = 0,
73  .NVIC_IRQChannelSubPriority = 0,
74  .NVIC_IRQChannelCmd = DISABLE
75  };
76  NVIC_Init(&NVIC_init_struct);
77 
78 }
79 
81 
82  GPIO_InitTypeDef GPIO_InitStructure;
83  EXTI_InitTypeDef EXTI_InitStructure;
84  SPI_InitTypeDef SPI_InitStructure;
85 
86  /* Set "mag ss" and "mag reset" as floating inputs ------------------------*/
87  /* "mag ss" (PC12) is shorted to I2C2 SDA */
88  /* "mag reset" (PC13) is shorted to I2C2 SCL */
89  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
90  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12|GPIO_Pin_13;
91  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
92  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
93  GPIO_Init(GPIOC, &GPIO_InitStructure);
94 
95  /* Gyro --------------------------------------------------------------------*/
96  /* set "eeprom ss" as floating input (on PC14) = gyro int ---------*/
97  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
98  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
99  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
100  GPIO_Init(GPIOC, &GPIO_InitStructure);
101  /* configure external interrupt exti15_10 on PC14( gyro int ) */
102  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
103  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
104  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
105  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
106  GPIO_Init(GPIOC, &GPIO_InitStructure);
107 
108 #ifdef ASPIRIN_USE_GYRO_INT
109  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource14);
110  EXTI_InitStructure.EXTI_Line = EXTI_Line14;
111  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
112  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
113  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
114  EXTI_Init(&EXTI_InitStructure);
115 #endif
116 
117  /* Accel */
118  /* set accel slave select as output and assert it ( on PB12) */
119  Adxl345Unselect();
120  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
121  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
122  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
123  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
124  GPIO_Init(GPIOB, &GPIO_InitStructure);
125 
126  /* configure external interrupt exti2 on PB2( accel int ) */
127  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
128  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
129  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
130  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
131  GPIO_Init(GPIOB, &GPIO_InitStructure);
132  GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource2);
133 
134  EXTI_InitStructure.EXTI_Line = EXTI_Line2;
135  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
136  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
137  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
138  EXTI_Init(&EXTI_InitStructure);
139 
140  /* Enable SPI2 Periph clock -------------------------------------------------*/
141  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
142 
143  /* Configure GPIOs: SCK, MISO and MOSI --------------------------------*/
144  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
145  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
146  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
147  GPIO_Init(GPIOB, &GPIO_InitStructure);
148 
149  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);
150  SPI_Cmd(SPI2, ENABLE);
151 
152  /* configure SPI */
153  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
154  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
155  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
156  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
157  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
158  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
159  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_32;
160  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
161  SPI_InitStructure.SPI_CRCPolynomial = 7;
162  SPI_Init(SPI2, &SPI_InitStructure);
163 
164 
165  /* Enable SPI_2 DMA clock ---------------------------------------------------*/
166  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
167 
168 
169 }
170 
171 
173 
174  Adxl345Select();
175  SPI_I2S_SendData(SPI2, addr);
176  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
177  SPI_I2S_SendData(SPI2, val);
178  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
179  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
180  Adxl345Unselect();
181 
182 }
183 
185  uint8_t __attribute__ ((unused)) ret = SPI_I2S_ReceiveData(SPI2);
186 }
187 
189  Adxl345Select();
190 
192 
193  /* SPI2_Rx_DMA_Channel configuration ------------------------------------*/
194  DMA_DeInit(DMA1_Channel4);
195  DMA_InitTypeDef DMA_initStructure_4 = {
196  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
197  .DMA_MemoryBaseAddr = (uint32_t)imu_aspirin.accel_rx_buf,
198  .DMA_DIR = DMA_DIR_PeripheralSRC,
199  .DMA_BufferSize = 7,
200  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
201  .DMA_MemoryInc = DMA_MemoryInc_Enable,
202  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
203  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
204  .DMA_Mode = DMA_Mode_Normal,
205  .DMA_Priority = DMA_Priority_VeryHigh,
206  .DMA_M2M = DMA_M2M_Disable
207  };
208  DMA_Init(DMA1_Channel4, &DMA_initStructure_4);
209 
210  /* SPI2_Tx_DMA_Channel configuration ------------------------------------*/
211  DMA_DeInit(DMA1_Channel5);
212  DMA_InitTypeDef DMA_initStructure_5 = {
213  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
214  .DMA_MemoryBaseAddr = (uint32_t)imu_aspirin.accel_tx_buf,
215  .DMA_DIR = DMA_DIR_PeripheralDST,
216  .DMA_BufferSize = 7,
217  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
218  .DMA_MemoryInc = DMA_MemoryInc_Enable,
219  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
220  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
221  .DMA_Mode = DMA_Mode_Normal,
222  .DMA_Priority = DMA_Priority_Medium,
223  .DMA_M2M = DMA_M2M_Disable
224  };
225  DMA_Init(DMA1_Channel5, &DMA_initStructure_5);
226 
227  /* Enable SPI_2 Rx request */
228  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
229  /* Enable DMA1 Channel4 */
230  DMA_Cmd(DMA1_Channel4, ENABLE);
231 
232  /* Enable SPI_2 Tx request */
233  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
234  /* Enable DMA1 Channel5 */
235  DMA_Cmd(DMA1_Channel5, ENABLE);
236 
237  /* Enable DMA1 Channel4 Transfer Complete interrupt */
238  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
239 }
240 
241 /*
242  *
243  * Gyro data ready
244  *
245  */
247 
248  /* clear EXTI */
249  if(EXTI_GetITStatus(EXTI_Line14) != RESET)
250  EXTI_ClearITPendingBit(EXTI_Line14);
251 
252 #ifdef ASPIRIN_USE_GYRO_INT
253  imu_aspirin.gyro_eoc = TRUE;
255 #endif
256 
257 }
258 
259 /*
260  *
261  * Accel data ready
262  *
263  */
264 void exti2_irq_handler(void) {
265 
266  /* clear EXTI */
267  if(EXTI_GetITStatus(EXTI_Line2) != RESET)
268  EXTI_ClearITPendingBit(EXTI_Line2);
269 
271 
272 }
273 
274 /*
275  *
276  * Accel end of DMA transfert
277  *
278  */
280  Adxl345Unselect();
281  if (DMA_GetITStatus(DMA1_IT_TC4)) {
282  // clear int pending bit
283  DMA_ClearITPendingBit(DMA1_IT_GL4);
284 
285  // mark as available
287  }
288 
289  // disable DMA Channel
290  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, DISABLE);
291  /* Disable SPI_2 Rx and TX request */
292  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
293  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
294  /* Disable DMA1 Channel4 and 5 */
295  DMA_Cmd(DMA1_Channel4, DISABLE);
296  DMA_Cmd(DMA1_Channel5, DISABLE);
297 
298 }
struct ImuAspirin imu_aspirin
Definition: imu_aspirin.c:6
void imu_aspirin_arch_init(void)
volatile uint8_t accel_tx_buf[7]
Definition: imu_aspirin.h:139
void exti9_5_irq_handler(void)
Definition: hmc5843_arch.c:66
void dma1_c4_irq_handler(void)
void adxl345_clear_rx_buf(void)
void imu_aspirin_arch_int_disable(void)
uint16_t val[TCOUPLE_NB]
unsigned long uint32_t
Definition: types.h:18
void exti15_10_irq_handler(void)
Inertial Measurement Unit interface.
#define TRUE
Definition: imu_chimu.h:144
volatile uint8_t accel_rx_buf[7]
Definition: imu_aspirin.h:140
void exti2_irq_handler(void)
unsigned char uint8_t
Definition: types.h:14
#define ADXL345_REG_DATA_X0
Definition: adxl345.h:13
volatile uint8_t accel_available
Definition: imu_aspirin.h:138
#define Adxl345Unselect()
enum AspirinStatus status
Definition: imu_aspirin.h:135
void imu_aspirin_arch_int_enable(void)
void adxl345_write_to_reg(uint8_t addr, uint8_t val)
#define RESET
Definition: humid_sht.h:40
__attribute__((always_inline))
Definition: i2c_arch.c:35
void adxl345_start_reading_data(void)
#define Adxl345Select()