STM32_ExtendedLibs/MyLibsGeneral/Src/__general_spi.c
Razvalyaev f61aa1ff0f init commit
сделаны базовые хедеры:
- mylibs_config
- mylibs_defs
- mylibs_include
- trace
- trackers
- bit_access

также сделан модуль general_gpio.c/.h

Но надо проверить переструктуризированные модули

Остальные модули  __general_XXX в целом готовы и как-то работают (на МЗКТЭ) но не структуризированы
2025-10-18 18:27:37 +03:00

293 lines
9.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
**************************************************************************
* @file general_spi.c
* @brief Модуль для инициализации SPI.
**************************************************************************
* //-------------------Функции-------------------//
* @verbatim
* Functions: users
* - SPI_Base_Init Инициализация SPI
*
* Functions: spi initialize
* - SPI_GPIO_Init Инициализация GPIO для SPI
* - SPI_DMA_Init Инициализация DMA для SPI
* - SPI_MspInit Аналог HAL_MspInit для SPI
* - SPI_MspDeInit Аналог HAL_MspDeInit для SPI
* @endverbatim
*************************************************************************/
#include "general_spi.h"
#include "general_gpio.h"
//-------------------------------------------------------------------
//------------------------SPI INIT FUNCTIONS------------------------
/**
* @brief Initialize SPI with SPI_SettingsTypeDef structure.
* @param sspi - указатель на структуру с настройками SPI.
* @return HAL status.
* @note SPI_SettingsTypeDef структура содержит хендл SPI и настройки перефирии (GPIO)
*/
HAL_StatusTypeDef SPI_Base_Init(SPI_SettingsTypeDef *sspi)
{ // function takes setting structure for init
// check is settings are valid
if(Check_SPI_Init_Struct(sspi) != HAL_OK)
return HAL_ERROR;
SPI_MspInit(&sspi->hspi);
if (HAL_SPI_Init(&sspi->hspi) != HAL_OK)
{
MyLibs_Error_Handler();
return HAL_ERROR;
}
// init gpio from SPISettings structure
SPI_GPIO_Init(sspi);
// // init dma from SPISettings structure if need
// if (sspi->DMAChannel != 0)
// SPI_DMA_Init(&sspi->hspi, sspi->hspi.hdmarx, sspi->DMAChannel, sspi->DMA_CHANNEL_X);
return HAL_OK;
}
/**
* @brief Initialize GPIO for SPI.
* @param GPIOx - порт для настройки.
* @param GPIO_PIN_RX - пин для настройки на прием.
* @param GPIO_PIN_TX - пин для настройки на передачу.
*/
void SPI_GPIO_Init(SPI_SettingsTypeDef *sspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
// GPIO INIT
GPIO_Clock_Enable(sspi->CLK_GPIOx);
GPIO_Clock_Enable(sspi->MISO_GPIOx);
GPIO_Clock_Enable(sspi->MOSI_GPIOx);
// CLK PIN INIT
GPIO_InitStruct.Pin = sspi->CLK_PIN;
GPIO_InitStruct.Alternate = sspi->CLK_GPIO_AlternageFunc;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(sspi->CLK_GPIOx, &GPIO_InitStruct);
// MISO PIN INIT
GPIO_InitStruct.Pin = sspi->MISO_PIN;
GPIO_InitStruct.Alternate = sspi->MISO_GPIO_AlternageFunc;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(sspi->MISO_GPIOx, &GPIO_InitStruct);
// MOSI PIN INIT
GPIO_InitStruct.Pin = sspi->MOSI_PIN;
GPIO_InitStruct.Alternate = sspi->MOSI_GPIO_AlternageFunc;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(sspi->MOSI_GPIOx, &GPIO_InitStruct);
}
/**
* @brief Initialize DMA for SPI.
* @param hspi - указатель на хендл SPI для настройки DMA.
* @param hdma_rx - указатель на хендл DMA для линии приема SPI.
* @param DMAChannel - указатель на канал DMA/поток DMA в STM32F407.
* @param DMA_CHANNEL_X - канал DMA.
*/
void SPI_DMA_Init(SPI_HandleTypeDef *hspi, DMA_HandleTypeDef *hdma_rx, DMA_Stream_TypeDef *DMAChannel, uint32_t DMA_CHANNEL_X)
{ // function takes spi and dma handlers and dmachannel for spi
// // for now only dma rx is supported, tx maybe later if needed
// // calc defines on boot_project_setup.h
// /* SPI3 DMA Init */
// /* SPI3_RX Init */
//
// hdma_rx->Instance = DMAChannel;
//#if defined(STM32F407xx) // dma channel choose for 407
// hdma_rx->Init.Channel = DMA_CHANNEL_X;
//#endif
// hdma_rx->Init.Direction = DMA_PERIPH_TO_MEMORY;
// hdma_rx->Init.PeriphInc = DMA_PINC_DISABLE;
// hdma_rx->Init.MemInc = DMA_MINC_ENABLE;
// hdma_rx->Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
// hdma_rx->Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
// hdma_rx->Init.Mode = DMA_CIRCULAR;
// hdma_rx->Init.Priority = DMA_PRIORITY_LOW;
// if (HAL_DMA_Init(hdma_rx) != HAL_OK)
// {
// MyLibs_Error_Handler();
// }
// __USER_LINKDMA(hspi,hdmarx,hdma_rx);
//
// // __USER_LINKDMA is need because __HAL_LINKDMA is written for global defined hdma_rx
// // so you get error because hal uses . insted of ->
}
/**
* @brief Initialize SPI & DMA clock and interrupt.
* @param hspi - указатель на хендл SPI для инициализации.
* @note Чтобы не генерировать функцию с иницилизацией неиспользуемых SPI,
дефайнами в general_spi.h определяются используемые SPI.
*/
void SPI_MspInit(SPI_HandleTypeDef *hspi) // analog for hal function
{
// rcc, dma and interrupt init for SPIs
// GPIO init was moved to own functions SPI_GPIO_Init
if(0);
#ifdef USE_SPI1
else if(hspi->Instance==SPI1)
{
// /* DMA2 clock enable */
// __HAL_RCC_DMA2_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
/* SPI1 interrupt Init */
HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI1_IRQn);
}
#endif // USE_SPI1
#ifdef USE_SPI2
else if(hspi->Instance==SPI2)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* SPI2 clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
/* SPI2 interrupt Init */
HAL_NVIC_SetPriority(SPI2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI2_IRQn);
}
#endif // USE_SPI2
#ifdef USE_SPI3
else if(hspi->Instance==SPI3)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/* SPI3 clock enable */
__HAL_RCC_SPI3_CLK_ENABLE();
/* SPI3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
}
#endif // USE_SPI3
}
/**
* @brief Deinitialize SPI & DMA clock and interrupt.
* @param hspi - указатель на хендл SPI для деинициализации.
* @note Чтобы не генерировать функцию с деиницилизацией неиспользуемых SPI,
дефайнами определяются используемые SPI.
*/
void SPI_MspDeInit(SPI_HandleTypeDef *hspi) // analog for hal function
{
// rcc, dma and interrupt init for SPIs
// GPIO init was moved to own functions SPI_GPIO_Init
if(0);
#ifdef USE_SPI1
else if(hspi->Instance==SPI1)
{
// /* DMA2 clock enable */
// __HAL_RCC_DMA2_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA2_Stream2_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA2_Stream2_IRQn);
/* SPI1 clock reset */
__HAL_RCC_SPI1_FORCE_RESET();
__HAL_RCC_SPI1_RELEASE_RESET();
}
#endif // USE_SPI1
#ifdef USE_SPI2
else if(hspi->Instance==SPI2)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* SPI2 clock reset */
__HAL_RCC_SPI2_FORCE_RESET();
__HAL_RCC_SPI2_RELEASE_RESET();
}
#endif // USE_SPI2
#ifdef USE_SPI3
else if(hspi->Instance==SPI3)
{
// /* DMA1 clock enable */
// __HAL_RCC_DMA1_CLK_ENABLE();
// /* DMA interrupt init */
// HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 0, 0);
// HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
/* SPI3 clock reset */
__HAL_RCC_SPI3_FORCE_RESET();
__HAL_RCC_SPI3_RELEASE_RESET();
}
#endif // USE_SPI3
}
/**
* @brief Check that spi init structure have correct values.
* @param sspi - указатель на структуру с настройками SPI.
* @return HAL status.
*/
HAL_StatusTypeDef Check_SPI_Init_Struct(SPI_SettingsTypeDef *sspi)
{
// check is settings are valid
if (!IS_SPI_ALL_INSTANCE(sspi->hspi.Instance))
return HAL_ERROR;
// check init settings
if (!IS_SPI_MODE(sspi->hspi.Init.Mode))
return HAL_ERROR;
if (!IS_SPI_DIRECTION(sspi->hspi.Init.Direction))
return HAL_ERROR;
if (!IS_SPI_DATASIZE(sspi->hspi.Init.DataSize))
return HAL_ERROR;
if (!IS_SPI_BAUDRATE_PRESCALER(sspi->hspi.Init.BaudRatePrescaler))
return HAL_ERROR;
if (!IS_SPI_CPOL(sspi->hspi.Init.CLKPolarity))
return HAL_ERROR;
if (!IS_SPI_CPHA(sspi->hspi.Init.CLKPhase))
return HAL_ERROR;
if (!IS_SPI_NSS(sspi->hspi.Init.NSS))
return HAL_ERROR;
if (!IS_SPI_FIRST_BIT(sspi->hspi.Init.FirstBit))
return HAL_ERROR;
if (!IS_SPI_CRC_CALCULATION(sspi->hspi.Init.CRCCalculation))
return HAL_ERROR;
if (!IS_SPI_CRC_POLYNOMIAL(sspi->hspi.Init.NSS) &&
(sspi->hspi.Init.CRCCalculation != SPI_CRCCALCULATION_DISABLE))
return HAL_ERROR;
if (!IS_SPI_TIMODE(sspi->hspi.Init.TIMode))
return HAL_ERROR;
// check gpio
if (!IS_GPIO_ALL_INSTANCE(sspi->CLK_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MISO_GPIOx) || !IS_GPIO_ALL_INSTANCE(sspi->MOSI_GPIOx))
return HAL_ERROR;
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
return HAL_ERROR;
return HAL_OK;
}