сделаны базовые хедеры: - mylibs_config - mylibs_defs - mylibs_include - trace - trackers - bit_access также сделан модуль general_gpio.c/.h Но надо проверить переструктуризированные модули Остальные модули __general_XXX в целом готовы и как-то работают (на МЗКТЭ) но не структуризированы
293 lines
9.8 KiB
C
293 lines
9.8 KiB
C
/**
|
||
**************************************************************************
|
||
* @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;
|
||
}
|