MyLibs 1.0
Расширенные библиотеки для STM32
Loading...
Searching...
No Matches
__general_spi.c
1/**
2**************************************************************************
3* @file general_spi.c
4* @brief Модуль для инициализации SPI.
5**************************************************************************
6* @details
7*
8* Функции:
9* - SPI_Base_Init Инициализация SPI
10*
11* Functions: spi initialize
12* - SPI_GPIO_Init Инициализация GPIO для SPI
13* - SPI_DMA_Init Инициализация DMA для SPI
14* - SPI_MspInit Аналог HAL_MspInit для SPI
15* - SPI_MspDeInit Аналог HAL_MspDeInit для SPI
16*
17*************************************************************************/
18#include "general_spi.h"
19#include "general_gpio.h"
20
21//-------------------------------------------------------------------
22//------------------------SPI INIT FUNCTIONS------------------------
23/**
24 * @brief Initialize SPI with SPI_SettingsTypeDef structure.
25 * @param sspi - указатель на структуру с настройками SPI.
26 * @return HAL status.
27 * @note SPI_SettingsTypeDef структура содержит хендл SPI и настройки перефирии (GPIO)
28 */
29HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi)
30{ // function takes setting structure for init
31
32 // check is settings are valid
33 if(Check_SPI_Init_Struct(sspi) != HAL_OK)
34 return HAL_ERROR;
35
36 SPI_MspInit(&sspi->hspi);
37
38 if (HAL_SPI_Init(&sspi->hspi) != HAL_OK)
39 {
41 return HAL_ERROR;
42 }
43
44 // init gpio from SPISettings structure
45 SPI_GPIO_Init(sspi);
46
47// // init dma from SPISettings structure if need
48// if (sspi->DMAChannel != 0)
49// SPI_DMA_Init(&sspi->hspi, sspi->hspi.hdmarx, sspi->DMAChannel, sspi->DMA_CHANNEL_X);
50
51 return HAL_OK;
52}
53
54
55/**
56 * @brief Initialize GPIO for SPI.
57 * @param GPIOx - порт для настройки.
58 * @param GPIO_PIN_RX - пин для настройки на прием.
59 * @param GPIO_PIN_TX - пин для настройки на передачу.
60 */
61void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi)
62{
63 GPIO_InitTypeDef GPIO_InitStruct = {0};
64 // GPIO INIT
65 GPIO_Clock_Enable(sspi->CLK_GPIOx);
66 GPIO_Clock_Enable(sspi->MISO_GPIOx);
67 GPIO_Clock_Enable(sspi->MOSI_GPIOx);
68 // CLK PIN INIT
69 GPIO_InitStruct.Pin = sspi->CLK_PIN;
70 GPIO_InitStruct.Alternate = sspi->CLK_GPIO_AlternageFunc;
71 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
72 GPIO_InitStruct.Pull = GPIO_NOPULL;
73 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
74 HAL_GPIO_Init(sspi->CLK_GPIOx, &GPIO_InitStruct);
75 // MISO PIN INIT
76 GPIO_InitStruct.Pin = sspi->MISO_PIN;
77 GPIO_InitStruct.Alternate = sspi->MISO_GPIO_AlternageFunc;
78 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
79 GPIO_InitStruct.Pull = GPIO_NOPULL;
80 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
81 HAL_GPIO_Init(sspi->MISO_GPIOx, &GPIO_InitStruct);
82 // MOSI PIN INIT
83 GPIO_InitStruct.Pin = sspi->MOSI_PIN;
84 GPIO_InitStruct.Alternate = sspi->MOSI_GPIO_AlternageFunc;
85 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
86 GPIO_InitStruct.Pull = GPIO_NOPULL;
87 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
88 HAL_GPIO_Init(sspi->MOSI_GPIOx, &GPIO_InitStruct);
89}
90
91/**
92 * @brief Initialize DMA for SPI.
93 * @param hspi - указатель на хендл SPI для настройки DMA.
94 * @param hdma_rx - указатель на хендл DMA для линии приема SPI.
95 * @param DMAChannel - указатель на канал DMA/поток DMA в STM32F407.
96 * @param DMA_CHANNEL_X - канал DMA.
97 */
98void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
99{ // function takes spi and dma handlers and dmachannel for spi
100// // for now only dma rx is supported, tx maybe later if needed
101// // calc defines on boot_project_setup.h
102
103// /* SPI3 DMA Init */
104// /* SPI3_RX Init */
105//
106// hdma_rx->Instance = DMAChannel;
107//#if defined(STM32F407xx) // dma channel choose for 407
108// hdma_rx->Init.Channel = DMA_CHANNEL_X;
109//#endif
110// hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
111// hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
112// hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
113// hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
114// hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
115// hdma_rx->Init.Mode = DMA_CIRCULAR;
116// hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
117// if (HAL_DMA_Init(hdma_rx) != HAL_OK)
118// {
119// MyLibs_Error_Handler();
120// }
121
122// __USER_LINKDMA(hspi,hdmarx,hdma_rx);
123//
124
125// // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx
126// // so you get error because hal uses . insted of ->
127}
128
129/**
130 * @brief Initialize SPI & DMA clock and interrupt.
131 * @param hspi - указатель на хендл SPI для инициализации.
132 * @note Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI,
133 дефайнами в general_spi.h определяются используемые SPI.
134 */
135void SPI_MspInit(SPI_HandleTypeDef *hspi) // analog for hal function
136{
137 // rcc, dma and interrupt init for SPIs
138 // GPIO init was moved to own functions SPI_GPIO_Init
139 if(0);
140#ifdef USE_SPI1
141 else if(hspi->Instance==SPI1)
142 {
143
144// /* DMA2 clock enable */
145// __HAL_RCC_DMA2_CLK_ENABLE();
146// /* DMA interrupt init */
147// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
148// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
149
150 /* SPI1 clock enable */
151 __HAL_RCC_SPI1_CLK_ENABLE();
152
153 /* SPI1 interrupt Init */
154 HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
155 HAL_NVIC_EnableIRQ(SPI1_IRQn);
156 }
157#endif // USE_SPI1
158#ifdef USE_SPI2
159 else if(hspi->Instance==SPI2)
160 {
161// /* DMA1 clock enable */
162// __HAL_RCC_DMA1_CLK_ENABLE();
163// /* DMA interrupt init */
164// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
165// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
166
167 /* SPI2 clock enable */
168 __HAL_RCC_SPI2_CLK_ENABLE();
169
170 /* SPI2 interrupt Init */
171 HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
172 HAL_NVIC_EnableIRQ(SPI2_IRQn);
173 }
174#endif // USE_SPI2
175#ifdef USE_SPI3
176 else if(hspi->Instance==SPI3)
177 {
178// /* DMA1 clock enable */
179// __HAL_RCC_DMA1_CLK_ENABLE();
180// /* DMA interrupt init */
181// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
182// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
183
184 /* SPI3 clock enable */
185 __HAL_RCC_SPI3_CLK_ENABLE();
186 /* SPI3 interrupt Init */
187 HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
188 HAL_NVIC_EnableIRQ(SPI3_IRQn);
189 }
190#endif // USE_SPI3
191}
192
193/**
194 * @brief Deinitialize SPI & DMA clock and interrupt.
195 * @param hspi - указатель на хендл SPI для деинициализации.
196 * @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых SPI,
197 дефайнами определяются используемые SPI.
198 */
199void SPI_MspDeInit(SPI_HandleTypeDef *hspi) // analog for hal function
200{
201 // rcc, dma and interrupt init for SPIs
202 // GPIO init was moved to own functions SPI_GPIO_Init
203 if(0);
204#ifdef USE_SPI1
205 else if(hspi->Instance==SPI1)
206 {
207
208// /* DMA2 clock enable */
209// __HAL_RCC_DMA2_CLK_ENABLE();
210// /* DMA interrupt init */
211// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
212// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
213
214 /* SPI1 clock reset */
215 __HAL_RCC_SPI1_FORCE_RESET();
216 __HAL_RCC_SPI1_RELEASE_RESET();
217 }
218#endif // USE_SPI1
219#ifdef USE_SPI2
220 else if(hspi->Instance==SPI2)
221 {
222// /* DMA1 clock enable */
223// __HAL_RCC_DMA1_CLK_ENABLE();
224// /* DMA interrupt init */
225// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
226// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
227
228 /* SPI2 clock reset */
229 __HAL_RCC_SPI2_FORCE_RESET();
230 __HAL_RCC_SPI2_RELEASE_RESET();
231 }
232#endif // USE_SPI2
233#ifdef USE_SPI3
234 else if(hspi->Instance==SPI3)
235 {
236// /* DMA1 clock enable */
237// __HAL_RCC_DMA1_CLK_ENABLE();
238// /* DMA interrupt init */
239// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
240// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
241
242 /* SPI3 clock reset */
243 __HAL_RCC_SPI3_FORCE_RESET();
244 __HAL_RCC_SPI3_RELEASE_RESET();
245 }
246#endif // USE_SPI3
247}
248
249/**
250 * @brief Check that spi init structure have correct values.
251 * @param sspi - указатель на структуру с настройками SPI.
252 * @return HAL status.
253 */
254HAL_StatusTypeDef Check_SPI_Init_Struct(SPI_SettingsTypeDef *sspi)
255{
256 // check is settings are valid
257 if (!IS_SPI_ALL_INSTANCE(sspi->hspi.Instance))
258 return HAL_ERROR;
259
260 // check init settings
261 if (!IS_SPI_MODE(sspi->hspi.Init.Mode))
262 return HAL_ERROR;
263 if (!IS_SPI_DIRECTION(sspi->hspi.Init.Direction))
264 return HAL_ERROR;
265 if (!IS_SPI_DATASIZE(sspi->hspi.Init.DataSize))
266 return HAL_ERROR;
267 if (!IS_SPI_BAUDRATE_PRESCALER(sspi->hspi.Init.BaudRatePrescaler))
268 return HAL_ERROR;
269 if (!IS_SPI_CPOL(sspi->hspi.Init.CLKPolarity))
270 return HAL_ERROR;
271 if (!IS_SPI_CPHA(sspi->hspi.Init.CLKPhase))
272 return HAL_ERROR;
273 if (!IS_SPI_NSS(sspi->hspi.Init.NSS))
274 return HAL_ERROR;
275 if (!IS_SPI_FIRST_BIT(sspi->hspi.Init.FirstBit))
276 return HAL_ERROR;
277 if (!IS_SPI_CRC_CALCULATION(sspi->hspi.Init.CRCCalculation))
278 return HAL_ERROR;
279 if (!IS_SPI_CRC_POLYNOMIAL(sspi->hspi.Init.NSS) &&
280 (sspi->hspi.Init.CRCCalculation != SPI_CRCCALCULATION_DISABLE))
281 return HAL_ERROR;
282 if (!IS_SPI_TIMODE(sspi->hspi.Init.TIMode))
283 return HAL_ERROR;
284
285 // check gpio
286 if (!IS_GPIO_ALL_INSTANCE(sspi->CLK_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MISO_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MOSI_GPIOx))
287 return HAL_ERROR;
288 if (!IS_GPIO_PIN(sspi->CLK_PIN) && !IS_GPIO_PIN(sspi->MISO_PIN) && !IS_GPIO_PIN(sspi->MOSI_PIN)) // if both pins arent set up
289 return HAL_ERROR;
290
291 return HAL_OK;
292}
Заголовочный файл для модуля инициализации портов и работы с ними.
#define MyLibs_Error_Handler(params)
Error_Handler который будет вызыватся в библиотеке
Definition mylibs_defs.h:31
HAL_StatusTypeDef GPIO_Clock_Enable(GPIO_TypeDef *GPIOx)
Включить тактирование порта GPIO.