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
spi_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/spi.h"
11 
12 // SPI2 Slave Selection
13 #define Spi2Slave0Unselect() GPIOB->BSRR = GPIO_Pin_12
14 #define Spi2Slave0Select() GPIOB->BRR = GPIO_Pin_12
15 
16 
17 // spi dma end of rx handler
18 void dma1_c4_irq_handler(void);
19 
20 void spi_arch_int_enable(void) {
21  // Enable DMA1 channel4 IRQ Channel ( SPI RX)
22  NVIC_InitTypeDef NVIC_init_struct = {
23  .NVIC_IRQChannel = DMA1_Channel4_IRQn,
24  .NVIC_IRQChannelPreemptionPriority = 0,
25  .NVIC_IRQChannelSubPriority = 0,
26  .NVIC_IRQChannelCmd = ENABLE
27  };
28  NVIC_Init(&NVIC_init_struct);
29 
30 }
31 
33  // Enable DMA1 channel4 IRQ Channel ( SPI RX)
34  NVIC_InitTypeDef NVIC_init_struct = {
35  .NVIC_IRQChannel = DMA1_Channel4_IRQn,
36  .NVIC_IRQChannelPreemptionPriority = 0,
37  .NVIC_IRQChannelSubPriority = 0,
38  .NVIC_IRQChannelCmd = DISABLE
39  };
40  NVIC_Init(&NVIC_init_struct);
41 }
42 
43 void spi_init(void) {
44 
45  GPIO_InitTypeDef GPIO_InitStructure;
46  SPI_InitTypeDef SPI_InitStructure;
47 
48  // Enable SPI2 Periph clock -------------------------------------------------
49  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
50 
51  // Configure GPIOs: SCK, MISO and MOSI --------------------------------
52  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
53  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
54  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
55  GPIO_Init(GPIOB, &GPIO_InitStructure);
56 
57  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO , ENABLE);
58  SPI_Cmd(SPI2, ENABLE);
59 
60  // configure SPI
61  SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
62  SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
63  SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
64  SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
65  SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
66  SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
67  SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_64;
68  SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
69  SPI_InitStructure.SPI_CRCPolynomial = 7;
70  SPI_Init(SPI2, &SPI_InitStructure);
71 
72  // Enable SPI_2 DMA clock ---------------------------------------------------
73  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
74 
75  // SLAVE 0
76  // set accel slave select as output and assert it ( on PB12)
78  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
79  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
80  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
81  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
82  GPIO_Init(GPIOB, &GPIO_InitStructure);
83 
85 }
86 
87 /*
88 void adxl345_write_to_reg(uint8_t addr, uint8_t val) {
89 
90  Adxl345Select();
91  SPI_I2S_SendData(SPI2, addr);
92  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
93  SPI_I2S_SendData(SPI2, val);
94  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);
95  while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_BSY) == SET);
96  Adxl345Unselect();
97 }
98 
99 void spi_clear_rx_buf(void) {
100  uint8_t __attribute__ ((unused)) ret = SPI_I2S_ReceiveData(SPI2);
101 }
102 */
103 
104 struct spi_transaction* slave0;
105 
106 void spi_rw(struct spi_transaction * _trans)
107 {
108  // Store local copy to notify of the results
109  slave0 = _trans;
110  slave0->status = SPITransRunning;
111 
113 
114  // SPI2_Rx_DMA_Channel configuration ------------------------------------
115  DMA_DeInit(DMA1_Channel4);
116  DMA_InitTypeDef DMA_initStructure_4 = {
117  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
118  .DMA_MemoryBaseAddr = (uint32_t) slave0->miso_buf,
119  .DMA_DIR = DMA_DIR_PeripheralSRC,
120  .DMA_BufferSize = slave0->length,
121  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
122  .DMA_MemoryInc = DMA_MemoryInc_Enable,
123  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
124  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
125  .DMA_Mode = DMA_Mode_Normal,
126  .DMA_Priority = DMA_Priority_VeryHigh,
127  .DMA_M2M = DMA_M2M_Disable
128  };
129  DMA_Init(DMA1_Channel4, &DMA_initStructure_4);
130 
131  // SPI2_Tx_DMA_Channel configuration ------------------------------------
132  DMA_DeInit(DMA1_Channel5);
133  DMA_InitTypeDef DMA_initStructure_5 = {
134  .DMA_PeripheralBaseAddr = (uint32_t)(SPI2_BASE+0x0C),
135  .DMA_MemoryBaseAddr = (uint32_t) slave0->mosi_buf,
136  .DMA_DIR = DMA_DIR_PeripheralDST,
137  .DMA_BufferSize = slave0->length,
138  .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
139  .DMA_MemoryInc = DMA_MemoryInc_Enable,
140  .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
141  .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
142  .DMA_Mode = DMA_Mode_Normal,
143  .DMA_Priority = DMA_Priority_Medium,
144  .DMA_M2M = DMA_M2M_Disable
145  };
146  DMA_Init(DMA1_Channel5, &DMA_initStructure_5);
147 
148  // Enable SPI_2 Rx request
149  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
150  // Enable DMA1 Channel4
151  DMA_Cmd(DMA1_Channel4, ENABLE);
152 
153  // Enable SPI_2 Tx request
154  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
155  // Enable DMA1 Channel5
156  DMA_Cmd(DMA1_Channel5, ENABLE);
157 
158  // Enable DMA1 Channel4 Transfer Complete interrupt
159  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
160 }
161 
162 
163 
164 // Accel end of DMA transfert
166 {
168 
169  if (DMA_GetITStatus(DMA1_IT_TC4)) {
170  // clear int pending bit
171  DMA_ClearITPendingBit(DMA1_IT_GL4);
172 
173  // mark as available
175  }
176 
177  // disable DMA Channel
178  DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, DISABLE);
179  // Disable SPI_2 Rx and TX request
180  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, DISABLE);
181  SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, DISABLE);
182  // Disable DMA1 Channel4 and 5
183  DMA_Cmd(DMA1_Channel4, DISABLE);
184  DMA_Cmd(DMA1_Channel5, DISABLE);
185 
186  slave0->status = SPITransSuccess;
187  *(slave0->ready) = 1;
188 }
bool_t spi_message_received
Definition: sim_baro.c:8
void spi_arch_int_enable(void)
handling of stm32 SPI hardware
Definition: spi_arch.c:20
void spi_arch_int_disable(void)
Definition: spi_arch.c:32
void spi_rw(struct spi_transaction *_trans)
Definition: spi_arch.c:106
#define Spi2Slave0Unselect()
Definition: spi_arch.c:13
arch independent SPI (Serial Peripheral Interface) API
void spi_init(void)
Definition: spi_arch.c:3
unsigned long uint32_t
Definition: types.h:18
struct spi_transaction * slave0
Definition: spi_arch.c:104
Inertial Measurement Unit interface.
#define TRUE
Definition: imu_chimu.h:144
#define Spi2Slave0Select()
Definition: spi_arch.c:14
void dma1_c4_irq_handler(void)
Definition: spi_arch.c:165