Touch pt. 1
This commit is contained in:
parent
22982db966
commit
46a5748e75
22 changed files with 3528 additions and 613 deletions
File diff suppressed because one or more lines are too long
|
@ -24,6 +24,31 @@ void MainLoop()
|
|||
m.Loop();
|
||||
}
|
||||
|
||||
#define CMD_X_READ 0b10010000
|
||||
#define CMD_Y_READ 0b11010000
|
||||
|
||||
|
||||
uint8_t SpiIo(SPI_TypeDef *spi, uint8_t data)
|
||||
{
|
||||
while(!LL_SPI_IsActiveFlag_TXE(spi));
|
||||
LL_SPI_TransmitData8(spi, data);
|
||||
while(!LL_SPI_IsActiveFlag_RXNE(spi));
|
||||
return LL_SPI_ReceiveData8(spi);
|
||||
}
|
||||
|
||||
uint16_t ReadTouch(SPI_TypeDef *spi, bool x)
|
||||
{
|
||||
uint16_t tmp;
|
||||
|
||||
LL_GPIO_ResetOutputPin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin);
|
||||
SpiIo(spi, x ? CMD_X_READ: CMD_Y_READ);
|
||||
tmp = (uint16_t)SpiIo(spi, 0) << 8;
|
||||
tmp |= SpiIo(spi, 0);
|
||||
LL_GPIO_SetOutputPin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin);
|
||||
|
||||
return tmp >> 3;
|
||||
}
|
||||
|
||||
Application::Application()
|
||||
: GlobalsInitializer(&m_console)
|
||||
, m_console(USART1, DMA2, LL_DMA_STREAM_2, LL_DMA_STREAM_7, this, nullptr)
|
||||
|
@ -32,18 +57,18 @@ Application::Application()
|
|||
|
||||
void Application::Loop()
|
||||
{
|
||||
char buffer[32];
|
||||
char buffer[128];
|
||||
|
||||
Ili9341Fsmc &lcd(Ili9341Fsmc::Init(nullptr, nullptr, DMA2, LL_DMA_STREAM_4, false));
|
||||
lcd.SetScrollMode(true);
|
||||
|
||||
lcd.FillRect(Ili9341Fsmc::ILI9341_BLACK, false);
|
||||
|
||||
for(uint32_t l = 0; l < 100; ++l) {
|
||||
uitodec(buffer, l);
|
||||
lcd.Print(buffer);
|
||||
lcd.Print("\r\n");
|
||||
}
|
||||
LL_SPI_Enable(SPI2);
|
||||
|
||||
for(int i = 0; i < 100; ++i) {
|
||||
m_console.SendLine("Lofasz a seggedbe!\r\n");
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
if(m_received && m_transmitted) {
|
||||
|
@ -55,6 +80,22 @@ void Application::Loop()
|
|||
m_received = false;
|
||||
m_rcvdBuffer->busy = false;
|
||||
}
|
||||
|
||||
if(LL_GPIO_IsInputPinSet(PENIRQ_GPIO_Port, PENIRQ_Pin))
|
||||
LL_GPIO_SetOutputPin(LED1_GPIO_Port, LED1_Pin);
|
||||
else {
|
||||
LL_GPIO_ResetOutputPin(LED1_GPIO_Port, LED1_Pin);
|
||||
|
||||
uint16_t x = ReadTouch(SPI2, true);
|
||||
uint16_t y = ReadTouch(SPI2, false);
|
||||
unsigned len = strcpy_ex(buffer, "X: ");
|
||||
len += uitodec(buffer+len, x);
|
||||
len += strcpy_ex(buffer + len, ", Y: ");
|
||||
len += uitodec(buffer + len, y);
|
||||
len += strcpy_ex(buffer + len, "\r\n");
|
||||
lcd.Print(buffer, len);
|
||||
m_console.SendLine(buffer, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,184 +0,0 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_crc.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CRC HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F4xx_HAL_CRC_H
|
||||
#define STM32F4xx_HAL_CRC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal_def.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/** @defgroup CRC_Exported_Types CRC Exported Types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief CRC HAL State Structure definition
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
HAL_CRC_STATE_RESET = 0x00U, /*!< CRC not yet initialized or disabled */
|
||||
HAL_CRC_STATE_READY = 0x01U, /*!< CRC initialized and ready for use */
|
||||
HAL_CRC_STATE_BUSY = 0x02U, /*!< CRC internal process is ongoing */
|
||||
HAL_CRC_STATE_TIMEOUT = 0x03U, /*!< CRC timeout state */
|
||||
HAL_CRC_STATE_ERROR = 0x04U /*!< CRC error state */
|
||||
} HAL_CRC_StateTypeDef;
|
||||
|
||||
|
||||
/**
|
||||
* @brief CRC Handle Structure definition
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
CRC_TypeDef *Instance; /*!< Register base address */
|
||||
|
||||
HAL_LockTypeDef Lock; /*!< CRC Locking object */
|
||||
|
||||
__IO HAL_CRC_StateTypeDef State; /*!< CRC communication state */
|
||||
|
||||
} CRC_HandleTypeDef;
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup CRC_Exported_Constants CRC Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macros -----------------------------------------------------------*/
|
||||
/** @defgroup CRC_Exported_Macros CRC Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @brief Reset CRC handle state.
|
||||
* @param __HANDLE__ CRC handle.
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CRC_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_CRC_STATE_RESET)
|
||||
|
||||
/**
|
||||
* @brief Reset CRC Data Register.
|
||||
* @param __HANDLE__ CRC handle
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CRC_DR_RESET(__HANDLE__) ((__HANDLE__)->Instance->CR |= CRC_CR_RESET)
|
||||
|
||||
/**
|
||||
* @brief Store data in the Independent Data (ID) register.
|
||||
* @param __HANDLE__ CRC handle
|
||||
* @param __VALUE__ Value to be stored in the ID register
|
||||
* @note Refer to the Reference Manual to get the authorized __VALUE__ length in bits
|
||||
* @retval None
|
||||
*/
|
||||
#define __HAL_CRC_SET_IDR(__HANDLE__, __VALUE__) (WRITE_REG((__HANDLE__)->Instance->IDR, (__VALUE__)))
|
||||
|
||||
/**
|
||||
* @brief Return the data stored in the Independent Data (ID) register.
|
||||
* @param __HANDLE__ CRC handle
|
||||
* @note Refer to the Reference Manual to get the authorized __VALUE__ length in bits
|
||||
* @retval Value of the ID register
|
||||
*/
|
||||
#define __HAL_CRC_GET_IDR(__HANDLE__) (((__HANDLE__)->Instance->IDR) & CRC_IDR_IDR)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Private macros --------------------------------------------------------*/
|
||||
/** @defgroup CRC_Private_Macros CRC Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup CRC_Exported_Functions CRC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Initialization and de-initialization functions ****************************/
|
||||
/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @{
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc);
|
||||
HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc);
|
||||
void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc);
|
||||
void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral Control functions ***********************************************/
|
||||
/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @{
|
||||
*/
|
||||
uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
|
||||
uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Peripheral State and Error functions ***************************************/
|
||||
/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
|
||||
* @{
|
||||
*/
|
||||
HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F4xx_HAL_CRC_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
204
Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_crc.h
Normal file
204
Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_crc.h
Normal file
|
@ -0,0 +1,204 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_ll_crc.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of CRC LL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef STM32F4xx_LL_CRC_H
|
||||
#define STM32F4xx_LL_CRC_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(CRC)
|
||||
|
||||
/** @defgroup CRC_LL CRC
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
|
||||
/* Exported types ------------------------------------------------------------*/
|
||||
/* Exported constants --------------------------------------------------------*/
|
||||
/** @defgroup CRC_LL_Exported_Constants CRC Exported Constants
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Exported macro ------------------------------------------------------------*/
|
||||
/** @defgroup CRC_LL_Exported_Macros CRC Exported Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_LL_EM_WRITE_READ Common Write and read registers Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Write a value in CRC register
|
||||
* @param __INSTANCE__ CRC Instance
|
||||
* @param __REG__ Register to be written
|
||||
* @param __VALUE__ Value to be written in the register
|
||||
* @retval None
|
||||
*/
|
||||
#define LL_CRC_WriteReg(__INSTANCE__, __REG__, __VALUE__) WRITE_REG(__INSTANCE__->__REG__, __VALUE__)
|
||||
|
||||
/**
|
||||
* @brief Read a value in CRC register
|
||||
* @param __INSTANCE__ CRC Instance
|
||||
* @param __REG__ Register to be read
|
||||
* @retval Register value
|
||||
*/
|
||||
#define LL_CRC_ReadReg(__INSTANCE__, __REG__) READ_REG(__INSTANCE__->__REG__)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @defgroup CRC_LL_Exported_Functions CRC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_LL_EF_Configuration CRC Configuration functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Reset the CRC calculation unit.
|
||||
* @note If Programmable Initial CRC value feature
|
||||
* is available, also set the Data Register to the value stored in the
|
||||
* CRC_INIT register, otherwise, reset Data Register to its default value.
|
||||
* @rmtoll CR RESET LL_CRC_ResetCRCCalculationUnit
|
||||
* @param CRCx CRC Instance
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_CRC_ResetCRCCalculationUnit(CRC_TypeDef *CRCx)
|
||||
{
|
||||
SET_BIT(CRCx->CR, CRC_CR_RESET);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_LL_EF_Data_Management Data_Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Write given 32-bit data to the CRC calculator
|
||||
* @rmtoll DR DR LL_CRC_FeedData32
|
||||
* @param CRCx CRC Instance
|
||||
* @param InData value to be provided to CRC calculator between between Min_Data=0 and Max_Data=0xFFFFFFFF
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_CRC_FeedData32(CRC_TypeDef *CRCx, uint32_t InData)
|
||||
{
|
||||
WRITE_REG(CRCx->DR, InData);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return current CRC calculation result. 32 bits value is returned.
|
||||
* @rmtoll DR DR LL_CRC_ReadData32
|
||||
* @param CRCx CRC Instance
|
||||
* @retval Current CRC calculation result as stored in CRC_DR register (32 bits).
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_CRC_ReadData32(CRC_TypeDef *CRCx)
|
||||
{
|
||||
return (uint32_t)(READ_REG(CRCx->DR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Return data stored in the Independent Data(IDR) register.
|
||||
* @note This register can be used as a temporary storage location for one byte.
|
||||
* @rmtoll IDR IDR LL_CRC_Read_IDR
|
||||
* @param CRCx CRC Instance
|
||||
* @retval Value stored in CRC_IDR register (General-purpose 8-bit data register).
|
||||
*/
|
||||
__STATIC_INLINE uint32_t LL_CRC_Read_IDR(CRC_TypeDef *CRCx)
|
||||
{
|
||||
return (uint32_t)(READ_REG(CRCx->IDR));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Store data in the Independent Data(IDR) register.
|
||||
* @note This register can be used as a temporary storage location for one byte.
|
||||
* @rmtoll IDR IDR LL_CRC_Write_IDR
|
||||
* @param CRCx CRC Instance
|
||||
* @param InData value to be stored in CRC_IDR register (8-bit) between Min_Data=0 and Max_Data=0xFF
|
||||
* @retval None
|
||||
*/
|
||||
__STATIC_INLINE void LL_CRC_Write_IDR(CRC_TypeDef *CRCx, uint32_t InData)
|
||||
{
|
||||
*((uint8_t __IO *)(&CRCx->IDR)) = (uint8_t) InData;
|
||||
}
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
/** @defgroup CRC_LL_EF_Init Initialization and de-initialization functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined(CRC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* STM32F4xx_LL_CRC_H */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
2029
Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h
Normal file
2029
Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_ll_spi.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,330 +0,0 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_hal_crc.c
|
||||
* @author MCD Application Team
|
||||
* @brief CRC HAL module driver.
|
||||
* This file provides firmware functions to manage the following
|
||||
* functionalities of the Cyclic Redundancy Check (CRC) peripheral:
|
||||
* + Initialization and de-initialization functions
|
||||
* + Peripheral Control functions
|
||||
* + Peripheral State functions
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### How to use this driver #####
|
||||
===============================================================================
|
||||
[..]
|
||||
(+) Enable CRC AHB clock using __HAL_RCC_CRC_CLK_ENABLE();
|
||||
(+) Initialize CRC calculator
|
||||
(++) specify generating polynomial (peripheral default or non-default one)
|
||||
(++) specify initialization value (peripheral default or non-default one)
|
||||
(++) specify input data format
|
||||
(++) specify input or output data inversion mode if any
|
||||
(+) Use HAL_CRC_Accumulate() function to compute the CRC value of the
|
||||
input data buffer starting with the previously computed CRC as
|
||||
initialization value
|
||||
(+) Use HAL_CRC_Calculate() function to compute the CRC value of the
|
||||
input data buffer starting with the defined initialization value
|
||||
(default or non-default) to initiate CRC calculation
|
||||
|
||||
@endverbatim
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
|
||||
/** @addtogroup STM32F4xx_HAL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC CRC
|
||||
* @brief CRC HAL module driver.
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef HAL_CRC_MODULE_ENABLED
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
/* Private define ------------------------------------------------------------*/
|
||||
/* Private macro -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions CRC Exported Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group1 Initialization and de-initialization functions
|
||||
* @brief Initialization and Configuration functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Initialization and de-initialization functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) Initialize the CRC according to the specified parameters
|
||||
in the CRC_InitTypeDef and create the associated handle
|
||||
(+) DeInitialize the CRC peripheral
|
||||
(+) Initialize the CRC MSP (MCU Specific Package)
|
||||
(+) DeInitialize the CRC MSP
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialize the CRC according to the specified
|
||||
* parameters in the CRC_InitTypeDef and create the associated handle.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_CRC_Init(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Check the CRC handle allocation */
|
||||
if (hcrc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
|
||||
|
||||
if (hcrc->State == HAL_CRC_STATE_RESET)
|
||||
{
|
||||
/* Allocate lock resource and initialize it */
|
||||
hcrc->Lock = HAL_UNLOCKED;
|
||||
/* Init the low level hardware */
|
||||
HAL_CRC_MspInit(hcrc);
|
||||
}
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the CRC peripheral.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL status
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_CRC_DeInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Check the CRC handle allocation */
|
||||
if (hcrc == NULL)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(hcrc->Instance));
|
||||
|
||||
/* Check the CRC peripheral state */
|
||||
if (hcrc->State == HAL_CRC_STATE_BUSY)
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Reset CRC calculation unit */
|
||||
__HAL_CRC_DR_RESET(hcrc);
|
||||
|
||||
/* Reset IDR register content */
|
||||
CLEAR_BIT(hcrc->Instance->IDR, CRC_IDR_IDR);
|
||||
|
||||
/* DeInit the low level hardware */
|
||||
HAL_CRC_MspDeInit(hcrc);
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_RESET;
|
||||
|
||||
/* Process unlocked */
|
||||
__HAL_UNLOCK(hcrc);
|
||||
|
||||
/* Return function status */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the CRC MSP.
|
||||
* @param hcrc CRC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_CRC_MspInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcrc);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_CRC_MspInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief DeInitialize the CRC MSP.
|
||||
* @param hcrc CRC handle
|
||||
* @retval None
|
||||
*/
|
||||
__weak void HAL_CRC_MspDeInit(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Prevent unused argument(s) compilation warning */
|
||||
UNUSED(hcrc);
|
||||
|
||||
/* NOTE : This function should not be modified, when the callback is needed,
|
||||
the HAL_CRC_MspDeInit can be implemented in the user file
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group2 Peripheral Control functions
|
||||
* @brief management functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral Control functions #####
|
||||
===============================================================================
|
||||
[..] This section provides functions allowing to:
|
||||
(+) compute the 32-bit CRC value of a 32-bit data buffer
|
||||
using combination of the previous CRC value and the new one.
|
||||
|
||||
[..] or
|
||||
|
||||
(+) compute the 32-bit CRC value of a 32-bit data buffer
|
||||
independently of the previous CRC value.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Compute the 32-bit CRC value of a 32-bit data buffer
|
||||
* starting with the previously computed CRC as initialization value.
|
||||
* @param hcrc CRC handle
|
||||
* @param pBuffer pointer to the input data buffer.
|
||||
* @param BufferLength input data buffer length (number of uint32_t words).
|
||||
* @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*/
|
||||
uint32_t HAL_CRC_Accumulate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
|
||||
{
|
||||
uint32_t index; /* CRC input data buffer index */
|
||||
uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Enter Data to the CRC calculator */
|
||||
for (index = 0U; index < BufferLength; index++)
|
||||
{
|
||||
hcrc->Instance->DR = pBuffer[index];
|
||||
}
|
||||
temp = hcrc->Instance->DR;
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return the CRC computed value */
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compute the 32-bit CRC value of a 32-bit data buffer
|
||||
* starting with hcrc->Instance->INIT as initialization value.
|
||||
* @param hcrc CRC handle
|
||||
* @param pBuffer pointer to the input data buffer.
|
||||
* @param BufferLength input data buffer length (number of uint32_t words).
|
||||
* @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)
|
||||
*/
|
||||
uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)
|
||||
{
|
||||
uint32_t index; /* CRC input data buffer index */
|
||||
uint32_t temp = 0U; /* CRC output (read from hcrc->Instance->DR register) */
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_BUSY;
|
||||
|
||||
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is
|
||||
* written in hcrc->Instance->DR) */
|
||||
__HAL_CRC_DR_RESET(hcrc);
|
||||
|
||||
/* Enter 32-bit input data to the CRC calculator */
|
||||
for (index = 0U; index < BufferLength; index++)
|
||||
{
|
||||
hcrc->Instance->DR = pBuffer[index];
|
||||
}
|
||||
temp = hcrc->Instance->DR;
|
||||
|
||||
/* Change CRC peripheral state */
|
||||
hcrc->State = HAL_CRC_STATE_READY;
|
||||
|
||||
/* Return the CRC computed value */
|
||||
return temp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @defgroup CRC_Exported_Functions_Group3 Peripheral State functions
|
||||
* @brief Peripheral State functions.
|
||||
*
|
||||
@verbatim
|
||||
===============================================================================
|
||||
##### Peripheral State functions #####
|
||||
===============================================================================
|
||||
[..]
|
||||
This subsection permits to get in run-time the status of the peripheral.
|
||||
|
||||
@endverbatim
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Return the CRC handle state.
|
||||
* @param hcrc CRC handle
|
||||
* @retval HAL state
|
||||
*/
|
||||
HAL_CRC_StateTypeDef HAL_CRC_GetState(CRC_HandleTypeDef *hcrc)
|
||||
{
|
||||
/* Return CRC handle state */
|
||||
return hcrc->State;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
#endif /* HAL_CRC_MODULE_ENABLED */
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
107
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_crc.c
Normal file
107
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_crc.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_ll_crc.c
|
||||
* @author MCD Application Team
|
||||
* @brief CRC LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_ll_crc.h"
|
||||
#include "stm32f4xx_ll_bus.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (CRC)
|
||||
|
||||
/** @addtogroup CRC_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup CRC_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup CRC_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize CRC registers (Registers restored to their default values).
|
||||
* @param CRCx CRC Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: CRC registers are de-initialized
|
||||
* - ERROR: CRC registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_CRC_DeInit(CRC_TypeDef *CRCx)
|
||||
{
|
||||
ErrorStatus status = SUCCESS;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_CRC_ALL_INSTANCE(CRCx));
|
||||
|
||||
if (CRCx == CRC)
|
||||
{
|
||||
/* Force CRC reset */
|
||||
LL_AHB1_GRP1_ForceReset(LL_AHB1_GRP1_PERIPH_CRC);
|
||||
|
||||
/* Release CRC reset */
|
||||
LL_AHB1_GRP1_ReleaseReset(LL_AHB1_GRP1_PERIPH_CRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = ERROR;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (CRC) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
626
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_spi.c
Normal file
626
Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_ll_spi.c
Normal file
|
@ -0,0 +1,626 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f4xx_ll_spi.c
|
||||
* @author MCD Application Team
|
||||
* @brief SPI LL module driver.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
#if defined(USE_FULL_LL_DRIVER)
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_ll_spi.h"
|
||||
#include "stm32f4xx_ll_bus.h"
|
||||
#include "stm32f4xx_ll_rcc.h"
|
||||
|
||||
#ifdef USE_FULL_ASSERT
|
||||
#include "stm32_assert.h"
|
||||
#else
|
||||
#define assert_param(expr) ((void)0U)
|
||||
#endif
|
||||
|
||||
/** @addtogroup STM32F4xx_LL_Driver
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined (SPI1) || defined (SPI2) || defined (SPI3) || defined (SPI4) || defined (SPI5) || defined(SPI6)
|
||||
|
||||
/** @addtogroup SPI_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Constants SPI Private Constants
|
||||
* @{
|
||||
*/
|
||||
/* SPI registers Masks */
|
||||
#define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
|
||||
SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
|
||||
SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_DFF | \
|
||||
SPI_CR1_CRCNEXT | SPI_CR1_CRCEN | SPI_CR1_BIDIOE | \
|
||||
SPI_CR1_BIDIMODE)
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup SPI_LL_Private_Macros SPI Private Macros
|
||||
* @{
|
||||
*/
|
||||
#define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
|
||||
|| ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
|
||||
|| ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
|
||||
|
||||
#define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
|
||||
|| ((__VALUE__) == LL_SPI_MODE_SLAVE))
|
||||
|
||||
#define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
|
||||
|| ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
|
||||
|
||||
#define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_SPI_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
|
||||
|| ((__VALUE__) == LL_SPI_PHASE_2EDGE))
|
||||
|
||||
#define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
|
||||
|| ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
|
||||
|
||||
#define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
|
||||
|| ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
|
||||
|
||||
#define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
|
||||
|| ((__VALUE__) == LL_SPI_MSB_FIRST))
|
||||
|
||||
#define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) \
|
||||
|| ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE))
|
||||
|
||||
#define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1U)
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup SPI_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup SPI_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the SPI registers to their default reset values.
|
||||
* @param SPIx SPI Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are de-initialized
|
||||
* - ERROR: SPI registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the parameters */
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
#if defined(SPI1)
|
||||
if (SPIx == SPI1)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI1 */
|
||||
#if defined(SPI2)
|
||||
if (SPIx == SPI2)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI2 */
|
||||
#if defined(SPI3)
|
||||
if (SPIx == SPI3)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI3 */
|
||||
#if defined(SPI4)
|
||||
if (SPIx == SPI4)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI4);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI4);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI4 */
|
||||
#if defined(SPI5)
|
||||
if (SPIx == SPI5)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI5);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI5);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI5 */
|
||||
#if defined(SPI6)
|
||||
if (SPIx == SPI6)
|
||||
{
|
||||
/* Force reset of SPI clock */
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI6);
|
||||
|
||||
/* Release reset of SPI clock */
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI6);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
#endif /* SPI6 */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
|
||||
* @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
||||
* SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param SPIx SPI Instance
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value. (Return always SUCCESS)
|
||||
*/
|
||||
ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the SPI Instance SPIx*/
|
||||
assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
||||
|
||||
/* Check the SPI parameters from SPI_InitStruct*/
|
||||
assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
|
||||
assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
|
||||
assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
|
||||
assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
|
||||
assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
|
||||
assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
|
||||
assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
|
||||
assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
|
||||
assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation));
|
||||
|
||||
if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx CR1 Configuration ------------------------
|
||||
* Configure SPIx CR1 with parameters:
|
||||
* - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
|
||||
* - Master/Slave Mode: SPI_CR1_MSTR bit
|
||||
* - DataWidth: SPI_CR1_DFF bit
|
||||
* - ClockPolarity: SPI_CR1_CPOL bit
|
||||
* - ClockPhase: SPI_CR1_CPHA bit
|
||||
* - NSS management: SPI_CR1_SSM bit
|
||||
* - BaudRate prescaler: SPI_CR1_BR[2:0] bits
|
||||
* - BitOrder: SPI_CR1_LSBFIRST bit
|
||||
* - CRCCalculation: SPI_CR1_CRCEN bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR1,
|
||||
SPI_CR1_CLEAR_MASK,
|
||||
SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode | SPI_InitStruct->DataWidth |
|
||||
SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
|
||||
SPI_InitStruct->NSS | SPI_InitStruct->BaudRate |
|
||||
SPI_InitStruct->BitOrder | SPI_InitStruct->CRCCalculation);
|
||||
|
||||
/*---------------------------- SPIx CR2 Configuration ------------------------
|
||||
* Configure SPIx CR2 with parameters:
|
||||
* - NSS management: SSOE bit
|
||||
*/
|
||||
MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, (SPI_InitStruct->NSS >> 16U));
|
||||
|
||||
/*---------------------------- SPIx CRCPR Configuration ----------------------
|
||||
* Configure SPIx CRCPR with parameters:
|
||||
* - CRCPoly: CRCPOLY[15:0] bits
|
||||
*/
|
||||
if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE)
|
||||
{
|
||||
assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
|
||||
LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly);
|
||||
}
|
||||
status = SUCCESS;
|
||||
}
|
||||
|
||||
/* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
|
||||
CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD);
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_SPI_InitTypeDef field to default value.
|
||||
* @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
|
||||
{
|
||||
/* Set SPI_InitStruct fields to default values */
|
||||
SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
|
||||
SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
|
||||
SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
|
||||
SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
|
||||
SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
|
||||
SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
|
||||
SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
|
||||
SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
|
||||
SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
|
||||
SPI_InitStruct->CRCPoly = 7U;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_LL
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* Private types -------------------------------------------------------------*/
|
||||
/* Private variables ---------------------------------------------------------*/
|
||||
/* Private constants ---------------------------------------------------------*/
|
||||
/** @defgroup I2S_LL_Private_Constants I2S Private Constants
|
||||
* @{
|
||||
*/
|
||||
/* I2S registers Masks */
|
||||
#define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
|
||||
SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
|
||||
SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD )
|
||||
|
||||
#define I2S_I2SPR_CLEAR_MASK 0x0002U
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
/* Private macros ------------------------------------------------------------*/
|
||||
/** @defgroup I2S_LL_Private_Macros I2S Private Macros
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_24B) \
|
||||
|| ((__VALUE__) == LL_I2S_DATAFORMAT_32B))
|
||||
|
||||
#define IS_LL_I2S_CPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) \
|
||||
|| ((__VALUE__) == LL_I2S_POLARITY_HIGH))
|
||||
|
||||
#define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_MSB) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_LSB) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) \
|
||||
|| ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG))
|
||||
|
||||
#define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_MASTER_TX) \
|
||||
|| ((__VALUE__) == LL_I2S_MODE_MASTER_RX))
|
||||
|
||||
#define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) \
|
||||
|| ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE))
|
||||
|
||||
#define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) \
|
||||
&& ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) \
|
||||
|| ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT))
|
||||
|
||||
#define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) >= 0x2U)
|
||||
|
||||
#define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) \
|
||||
|| ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD))
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* Private function prototypes -----------------------------------------------*/
|
||||
|
||||
/* Exported functions --------------------------------------------------------*/
|
||||
/** @addtogroup I2S_LL_Exported_Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** @addtogroup I2S_LL_EF_Init
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief De-initialize the SPI/I2S registers to their default reset values.
|
||||
* @param SPIx SPI Instance
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are de-initialized
|
||||
* - ERROR: SPI registers are not de-initialized
|
||||
*/
|
||||
ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx)
|
||||
{
|
||||
return LL_SPI_DeInit(SPIx);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct.
|
||||
* @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
||||
* SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
||||
* @param SPIx SPI Instance
|
||||
* @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: SPI registers are Initialized
|
||||
* - ERROR: SPI registers are not Initialized
|
||||
*/
|
||||
ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct)
|
||||
{
|
||||
uint32_t i2sdiv = 2U;
|
||||
uint32_t i2sodd = 0U;
|
||||
uint32_t packetlength = 1U;
|
||||
uint32_t tmp;
|
||||
uint32_t sourceclock;
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the I2S parameters */
|
||||
assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
||||
assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
|
||||
assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
|
||||
assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
|
||||
assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput));
|
||||
assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq));
|
||||
assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
|
||||
|
||||
if (LL_I2S_IsEnabled(SPIx) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx I2SCFGR Configuration --------------------
|
||||
* Configure SPIx I2SCFGR with parameters:
|
||||
* - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
|
||||
* - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
|
||||
* - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
|
||||
* - ClockPolarity: SPI_I2SCFGR_CKPOL bit
|
||||
*/
|
||||
|
||||
/* Write to SPIx I2SCFGR */
|
||||
MODIFY_REG(SPIx->I2SCFGR,
|
||||
I2S_I2SCFGR_CLEAR_MASK,
|
||||
I2S_InitStruct->Mode | I2S_InitStruct->Standard |
|
||||
I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
|
||||
SPI_I2SCFGR_I2SMOD);
|
||||
|
||||
/*---------------------------- SPIx I2SPR Configuration ----------------------
|
||||
* Configure SPIx I2SPR with parameters:
|
||||
* - MCLKOutput: SPI_I2SPR_MCKOE bit
|
||||
* - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits
|
||||
*/
|
||||
|
||||
/* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv)
|
||||
* else, default values are used: i2sodd = 0U, i2sdiv = 2U.
|
||||
*/
|
||||
if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT)
|
||||
{
|
||||
/* Check the frame length (For the Prescaler computing)
|
||||
* Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U).
|
||||
*/
|
||||
if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B)
|
||||
{
|
||||
/* Packet length is 32 bits */
|
||||
packetlength = 2U;
|
||||
}
|
||||
|
||||
/* If an external I2S clock has to be used, the specific define should be set
|
||||
in the project configuration or in the stm32f4xx_ll_rcc.h file */
|
||||
/* Get the I2S source clock value */
|
||||
sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S1_CLKSOURCE);
|
||||
|
||||
/* Compute the Real divider depending on the MCLK output state with a floating point */
|
||||
if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE)
|
||||
{
|
||||
/* MCLK output is enabled */
|
||||
tmp = (((((sourceclock / 256U) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* MCLK output is disabled */
|
||||
tmp = (((((sourceclock / (32U * packetlength)) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
||||
}
|
||||
|
||||
/* Remove the floating point */
|
||||
tmp = tmp / 10U;
|
||||
|
||||
/* Check the parity of the divider */
|
||||
i2sodd = (tmp & (uint16_t)0x0001U);
|
||||
|
||||
/* Compute the i2sdiv prescaler */
|
||||
i2sdiv = ((tmp - i2sodd) / 2U);
|
||||
|
||||
/* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
|
||||
i2sodd = (i2sodd << 8U);
|
||||
}
|
||||
|
||||
/* Test if the divider is 1 or 0 or greater than 0xFF */
|
||||
if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
|
||||
{
|
||||
/* Set the default values */
|
||||
i2sdiv = 2U;
|
||||
i2sodd = 0U;
|
||||
}
|
||||
|
||||
/* Write to SPIx I2SPR register the computed value */
|
||||
WRITE_REG(SPIx->I2SPR, i2sdiv | i2sodd | I2S_InitStruct->MCLKOutput);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set each @ref LL_I2S_InitTypeDef field to default value.
|
||||
* @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
||||
* whose fields will be set to default values.
|
||||
* @retval None
|
||||
*/
|
||||
void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct)
|
||||
{
|
||||
/*--------------- Reset I2S init structure parameters values -----------------*/
|
||||
I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX;
|
||||
I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS;
|
||||
I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B;
|
||||
I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE;
|
||||
I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT;
|
||||
I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set linear and parity prescaler.
|
||||
* @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n
|
||||
* Check Audio frequency table and formulas inside Reference Manual (SPI/I2S).
|
||||
* @param SPIx SPI Instance
|
||||
* @param PrescalerLinear value Min_Data=0x02 and Max_Data=0xFF.
|
||||
* @param PrescalerParity This parameter can be one of the following values:
|
||||
* @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
|
||||
* @arg @ref LL_I2S_PRESCALER_PARITY_ODD
|
||||
* @retval None
|
||||
*/
|
||||
void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity)
|
||||
{
|
||||
/* Check the I2S parameters */
|
||||
assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
||||
assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear));
|
||||
assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity));
|
||||
|
||||
/* Write to SPIx I2SPR */
|
||||
MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV | SPI_I2SPR_ODD, PrescalerLinear | (PrescalerParity << 8U));
|
||||
}
|
||||
|
||||
#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
|
||||
/**
|
||||
* @brief Configures the full duplex mode for the I2Sx peripheral using its extension
|
||||
* I2Sxext according to the specified parameters in the I2S_InitStruct.
|
||||
* @note The structure pointed by I2S_InitStruct parameter should be the same
|
||||
* used for the master I2S peripheral. In this case, if the master is
|
||||
* configured as transmitter, the slave will be receiver and vice versa.
|
||||
* Or you can force a different mode by modifying the field I2S_Mode to the
|
||||
* value I2S_SlaveRx or I2S_SlaveTx independently of the master configuration.
|
||||
* @param I2Sxext SPI Instance
|
||||
* @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
||||
* @retval An ErrorStatus enumeration value:
|
||||
* - SUCCESS: I2Sxext registers are Initialized
|
||||
* - ERROR: I2Sxext registers are not Initialized
|
||||
*/
|
||||
ErrorStatus LL_I2S_InitFullDuplex(SPI_TypeDef *I2Sxext, LL_I2S_InitTypeDef *I2S_InitStruct)
|
||||
{
|
||||
uint32_t mode = 0U;
|
||||
ErrorStatus status = ERROR;
|
||||
|
||||
/* Check the I2S parameters */
|
||||
assert_param(IS_I2S_EXT_ALL_INSTANCE(I2Sxext));
|
||||
assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
|
||||
assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
|
||||
assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
|
||||
assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
|
||||
|
||||
if (LL_I2S_IsEnabled(I2Sxext) == 0x00000000U)
|
||||
{
|
||||
/*---------------------------- SPIx I2SCFGR Configuration --------------------
|
||||
* Configure SPIx I2SCFGR with parameters:
|
||||
* - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
|
||||
* - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
|
||||
* - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
|
||||
* - ClockPolarity: SPI_I2SCFGR_CKPOL bit
|
||||
*/
|
||||
|
||||
/* Reset I2SPR registers */
|
||||
WRITE_REG(I2Sxext->I2SPR, I2S_I2SPR_CLEAR_MASK);
|
||||
|
||||
/* Get the mode to be configured for the extended I2S */
|
||||
if ((I2S_InitStruct->Mode == LL_I2S_MODE_MASTER_TX) || (I2S_InitStruct->Mode == LL_I2S_MODE_SLAVE_TX))
|
||||
{
|
||||
mode = LL_I2S_MODE_SLAVE_RX;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((I2S_InitStruct->Mode == LL_I2S_MODE_MASTER_RX) || (I2S_InitStruct->Mode == LL_I2S_MODE_SLAVE_RX))
|
||||
{
|
||||
mode = LL_I2S_MODE_SLAVE_TX;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write to SPIx I2SCFGR */
|
||||
MODIFY_REG(I2Sxext->I2SCFGR,
|
||||
I2S_I2SCFGR_CLEAR_MASK,
|
||||
I2S_InitStruct->Standard |
|
||||
I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
|
||||
SPI_I2SCFGR_I2SMOD | mode);
|
||||
|
||||
status = SUCCESS;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) || defined (SPI4) || defined (SPI5) || defined(SPI6) */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#endif /* USE_FULL_LL_DRIVER */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -48,47 +48,53 @@ Mcu.IP1=DMA
|
|||
Mcu.IP2=FSMC
|
||||
Mcu.IP3=NVIC
|
||||
Mcu.IP4=RCC
|
||||
Mcu.IP5=SYS
|
||||
Mcu.IP6=USART1
|
||||
Mcu.IPNb=7
|
||||
Mcu.IP5=SPI2
|
||||
Mcu.IP6=SYS
|
||||
Mcu.IP7=USART1
|
||||
Mcu.IPNb=8
|
||||
Mcu.Name=STM32F407V(E-G)Tx
|
||||
Mcu.Package=LQFP100
|
||||
Mcu.Pin0=PE3
|
||||
Mcu.Pin1=PE4
|
||||
Mcu.Pin10=PE11
|
||||
Mcu.Pin11=PE12
|
||||
Mcu.Pin12=PE13
|
||||
Mcu.Pin13=PE14
|
||||
Mcu.Pin14=PE15
|
||||
Mcu.Pin15=PD8
|
||||
Mcu.Pin16=PD9
|
||||
Mcu.Pin17=PD10
|
||||
Mcu.Pin18=PD13
|
||||
Mcu.Pin19=PD14
|
||||
Mcu.Pin10=PE10
|
||||
Mcu.Pin11=PE11
|
||||
Mcu.Pin12=PE12
|
||||
Mcu.Pin13=PE13
|
||||
Mcu.Pin14=PE14
|
||||
Mcu.Pin15=PE15
|
||||
Mcu.Pin16=PB12
|
||||
Mcu.Pin17=PB13
|
||||
Mcu.Pin18=PB14
|
||||
Mcu.Pin19=PB15
|
||||
Mcu.Pin2=PH0-OSC_IN
|
||||
Mcu.Pin20=PD15
|
||||
Mcu.Pin21=PA9
|
||||
Mcu.Pin22=PA10
|
||||
Mcu.Pin23=PA13
|
||||
Mcu.Pin24=PA14
|
||||
Mcu.Pin25=PA15
|
||||
Mcu.Pin26=PD0
|
||||
Mcu.Pin27=PD1
|
||||
Mcu.Pin28=PD4
|
||||
Mcu.Pin29=PD5
|
||||
Mcu.Pin20=PD8
|
||||
Mcu.Pin21=PD9
|
||||
Mcu.Pin22=PD10
|
||||
Mcu.Pin23=PD13
|
||||
Mcu.Pin24=PD14
|
||||
Mcu.Pin25=PD15
|
||||
Mcu.Pin26=PA9
|
||||
Mcu.Pin27=PA10
|
||||
Mcu.Pin28=PA13
|
||||
Mcu.Pin29=PA14
|
||||
Mcu.Pin3=PH1-OSC_OUT
|
||||
Mcu.Pin30=PD7
|
||||
Mcu.Pin31=PB3
|
||||
Mcu.Pin32=PB4
|
||||
Mcu.Pin33=VP_CRC_VS_CRC
|
||||
Mcu.Pin34=VP_SYS_VS_Systick
|
||||
Mcu.Pin30=PA15
|
||||
Mcu.Pin31=PD0
|
||||
Mcu.Pin32=PD1
|
||||
Mcu.Pin33=PD4
|
||||
Mcu.Pin34=PD5
|
||||
Mcu.Pin35=PD7
|
||||
Mcu.Pin36=PB3
|
||||
Mcu.Pin37=PB4
|
||||
Mcu.Pin38=VP_CRC_VS_CRC
|
||||
Mcu.Pin39=VP_SYS_VS_Systick
|
||||
Mcu.Pin4=PA6
|
||||
Mcu.Pin5=PA7
|
||||
Mcu.Pin6=PE7
|
||||
Mcu.Pin7=PE8
|
||||
Mcu.Pin8=PE9
|
||||
Mcu.Pin9=PE10
|
||||
Mcu.PinsNb=35
|
||||
Mcu.Pin6=PC5
|
||||
Mcu.Pin7=PE7
|
||||
Mcu.Pin8=PE8
|
||||
Mcu.Pin9=PE9
|
||||
Mcu.PinsNb=40
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F407VETx
|
||||
|
@ -128,10 +134,27 @@ PA7.PinState=GPIO_PIN_SET
|
|||
PA7.Signal=GPIO_Output
|
||||
PA9.Mode=Asynchronous
|
||||
PA9.Signal=USART1_TX
|
||||
PB12.GPIOParameters=GPIO_Label
|
||||
PB12.GPIO_Label=TOUCH_CS
|
||||
PB12.Locked=true
|
||||
PB12.Signal=GPIO_Output
|
||||
PB13.Locked=true
|
||||
PB13.Mode=Full_Duplex_Master
|
||||
PB13.Signal=SPI2_SCK
|
||||
PB14.Locked=true
|
||||
PB14.Mode=Full_Duplex_Master
|
||||
PB14.Signal=SPI2_MISO
|
||||
PB15.Locked=true
|
||||
PB15.Mode=Full_Duplex_Master
|
||||
PB15.Signal=SPI2_MOSI
|
||||
PB3.Mode=JTAG_5_pins
|
||||
PB3.Signal=SYS_JTDO-SWO
|
||||
PB4.Mode=JTAG_5_pins
|
||||
PB4.Signal=SYS_JTRST
|
||||
PC5.GPIOParameters=GPIO_Label
|
||||
PC5.GPIO_Label=PENIRQ
|
||||
PC5.Locked=true
|
||||
PC5.Signal=GPIO_Input
|
||||
PCC.Checker=false
|
||||
PCC.Line=STM32F407/417
|
||||
PCC.MCU=STM32F407V(E-G)Tx
|
||||
|
@ -219,7 +242,7 @@ ProjectManager.StackSize=0x400
|
|||
ProjectManager.TargetToolchain=STM32CubeIDE
|
||||
ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UnderRoot=true
|
||||
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-MX_DMA_Init-DMA-false-LL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_USART1_UART_Init-USART1-false-LL-true,5-MX_FSMC_Init-FSMC-false-HAL-true
|
||||
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-LL-true,2-MX_DMA_Init-DMA-false-LL-true,3-SystemClock_Config-RCC-false-HAL-false,4-MX_USART1_UART_Init-USART1-false-LL-true,5-MX_FSMC_Init-FSMC-false-HAL-true,6-MX_CRC_Init-CRC-false-LL-true,7-MX_SPI2_Init-SPI2-false-LL-true
|
||||
RCC.48MHZClocksFreq_Value=84000000
|
||||
RCC.AHBFreq_Value=168000000
|
||||
RCC.APB1CLKDivider=RCC_HCLK_DIV4
|
||||
|
@ -253,6 +276,12 @@ RCC.VCOI2SOutputFreq_Value=384000000
|
|||
RCC.VCOInputFreq_Value=2000000
|
||||
RCC.VCOOutputFreq_Value=336000000
|
||||
RCC.VcooutputI2S=192000000
|
||||
SPI2.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_64
|
||||
SPI2.CalculateBaudRate=656.25 KBits/s
|
||||
SPI2.Direction=SPI_DIRECTION_2LINES
|
||||
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate,BaudRatePrescaler
|
||||
SPI2.Mode=SPI_MODE_MASTER
|
||||
SPI2.VirtualType=VM_MASTER
|
||||
USART1.IPParameters=VirtualMode
|
||||
USART1.VirtualMode=VM_ASYNC
|
||||
VP_CRC_VS_CRC.Mode=CRC_Activate
|
||||
|
|
|
@ -30,8 +30,6 @@
|
|||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern CRC_HandleTypeDef hcrc;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
|
|
@ -29,8 +29,10 @@ extern "C" {
|
|||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "stm32f4xx_ll_crc.h"
|
||||
#include "stm32f4xx_ll_dma.h"
|
||||
#include "stm32f4xx_hal.h"
|
||||
#include "stm32f4xx_ll_spi.h"
|
||||
#include "stm32f4xx_ll_usart.h"
|
||||
#include "stm32f4xx_ll_rcc.h"
|
||||
#include "stm32f4xx.h"
|
||||
|
@ -78,6 +80,10 @@ void Error_Handler(void);
|
|||
#define LED1_GPIO_Port GPIOA
|
||||
#define LED2_Pin LL_GPIO_PIN_7
|
||||
#define LED2_GPIO_Port GPIOA
|
||||
#define PENIRQ_Pin LL_GPIO_PIN_5
|
||||
#define PENIRQ_GPIO_Port GPIOC
|
||||
#define TOUCH_CS_Pin LL_GPIO_PIN_12
|
||||
#define TOUCH_CS_GPIO_Port GPIOB
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
|
56
Inc/spi.h
Normal file
56
Inc/spi.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* File Name : SPI.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the SPI instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
||||
#ifndef __spi_H
|
||||
#define __spi_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "main.h"
|
||||
|
||||
/* USER CODE BEGIN Includes */
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_SPI2_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
/* USER CODE END Prototypes */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /*__ spi_H */
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -39,7 +39,7 @@
|
|||
/* #define HAL_ADC_MODULE_ENABLED */
|
||||
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||
/* #define HAL_CAN_MODULE_ENABLED */
|
||||
#define HAL_CRC_MODULE_ENABLED
|
||||
/* #define HAL_CRC_MODULE_ENABLED */
|
||||
/* #define HAL_CRYP_MODULE_ENABLED */
|
||||
/* #define HAL_DAC_MODULE_ENABLED */
|
||||
/* #define HAL_DCMI_MODULE_ENABLED */
|
||||
|
|
41
Src/crc.c
41
Src/crc.c
|
@ -24,52 +24,15 @@
|
|||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
CRC_HandleTypeDef hcrc;
|
||||
|
||||
/* CRC init function */
|
||||
void MX_CRC_Init(void)
|
||||
{
|
||||
|
||||
hcrc.Instance = CRC;
|
||||
if (HAL_CRC_Init(&hcrc) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* Peripheral clock enable */
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
|
||||
|
||||
}
|
||||
|
||||
void HAL_CRC_MspInit(CRC_HandleTypeDef* crcHandle)
|
||||
{
|
||||
|
||||
if(crcHandle->Instance==CRC)
|
||||
{
|
||||
/* USER CODE BEGIN CRC_MspInit 0 */
|
||||
|
||||
/* USER CODE END CRC_MspInit 0 */
|
||||
/* CRC clock enable */
|
||||
__HAL_RCC_CRC_CLK_ENABLE();
|
||||
/* USER CODE BEGIN CRC_MspInit 1 */
|
||||
|
||||
/* USER CODE END CRC_MspInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_CRC_MspDeInit(CRC_HandleTypeDef* crcHandle)
|
||||
{
|
||||
|
||||
if(crcHandle->Instance==CRC)
|
||||
{
|
||||
/* USER CODE BEGIN CRC_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END CRC_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_CRC_CLK_DISABLE();
|
||||
/* USER CODE BEGIN CRC_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END CRC_MspDeInit 1 */
|
||||
}
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
|
|
@ -51,9 +51,9 @@ void MX_FSMC_Init(void)
|
|||
hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;
|
||||
hsram1.Init.PageSize = FSMC_PAGE_SIZE_NONE;
|
||||
/* Timing */
|
||||
Timing.AddressSetupTime = 0;
|
||||
Timing.AddressSetupTime = 1;
|
||||
Timing.AddressHoldTime = 15;
|
||||
Timing.DataSetupTime = 1;
|
||||
Timing.DataSetupTime = 4;
|
||||
Timing.BusTurnAroundDuration = 0;
|
||||
Timing.CLKDivision = 16;
|
||||
Timing.DataLatency = 17;
|
||||
|
|
20
Src/gpio.c
20
Src/gpio.c
|
@ -46,12 +46,16 @@ void MX_GPIO_Init(void)
|
|||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOE);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOH);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOA);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOC);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOD);
|
||||
|
||||
/**/
|
||||
LL_GPIO_ResetOutputPin(LED1_GPIO_Port, LED1_Pin);
|
||||
|
||||
/**/
|
||||
LL_GPIO_ResetOutputPin(TOUCH_CS_GPIO_Port, TOUCH_CS_Pin);
|
||||
|
||||
/**/
|
||||
LL_GPIO_SetOutputPin(LED2_GPIO_Port, LED2_Pin);
|
||||
|
||||
|
@ -69,6 +73,20 @@ void MX_GPIO_Init(void)
|
|||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
/**/
|
||||
GPIO_InitStruct.Pin = PENIRQ_Pin;
|
||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_INPUT;
|
||||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(PENIRQ_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/**/
|
||||
GPIO_InitStruct.Pin = TOUCH_CS_Pin;
|
||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
|
||||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||||
LL_GPIO_Init(TOUCH_CS_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "main.h"
|
||||
#include "crc.h"
|
||||
#include "dma.h"
|
||||
#include "spi.h"
|
||||
#include "usart.h"
|
||||
#include "gpio.h"
|
||||
#include "fsmc.h"
|
||||
|
@ -97,6 +98,7 @@ int main(void)
|
|||
MX_USART1_UART_Init();
|
||||
MX_FSMC_Init();
|
||||
MX_CRC_Init();
|
||||
MX_SPI2_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
MainLoop();
|
||||
/* USER CODE END 2 */
|
||||
|
|
70
Src/spi.c
Normal file
70
Src/spi.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* File Name : SPI.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of the SPI instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "spi.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
/* SPI2 init function */
|
||||
void MX_SPI2_Init(void)
|
||||
{
|
||||
LL_SPI_InitTypeDef SPI_InitStruct = {0};
|
||||
|
||||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
|
||||
/* Peripheral clock enable */
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);
|
||||
/**SPI2 GPIO Configuration
|
||||
PB13 ------> SPI2_SCK
|
||||
PB14 ------> SPI2_MISO
|
||||
PB15 ------> SPI2_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = LL_GPIO_PIN_13|LL_GPIO_PIN_14|LL_GPIO_PIN_15;
|
||||
GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
|
||||
GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
|
||||
GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
|
||||
LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;
|
||||
SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;
|
||||
SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;
|
||||
SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_LOW;
|
||||
SPI_InitStruct.ClockPhase = LL_SPI_PHASE_1EDGE;
|
||||
SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
|
||||
SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV64;
|
||||
SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;
|
||||
SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
|
||||
SPI_InitStruct.CRCPoly = 10;
|
||||
LL_SPI_Init(SPI2, &SPI_InitStruct);
|
||||
LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
@ -14,7 +14,7 @@
|
|||
#define LCD_RAM (*((volatile unsigned short *) 0x60080000)) /* DC = 1 */
|
||||
|
||||
#define RGB2U16(R,G,B) ((R & 0xf8) << 8 | (G & 0xfc) << 3 | (B & 0xf8) >> 3)
|
||||
#define SPLIT(x) ((uint8_t)(x >> 8)), ((uint8_t)x)
|
||||
#define MSBSPLIT(x) ((uint8_t)(x >> 8)), ((uint8_t)x)
|
||||
|
||||
Ili9341Fsmc::Ili9341Fsmc(volatile uint16_t *reg, volatile uint16_t *ram,
|
||||
DMA_TypeDef *dma, uint32_t dmaStream,
|
||||
|
@ -58,7 +58,6 @@ Ili9341Fsmc::Ili9341Fsmc(volatile uint16_t *reg, volatile uint16_t *ram,
|
|||
WriteCmd(ILI9341_SLEEP_OUT);
|
||||
LL_mDelay(100);
|
||||
WriteCmd(ILI9341_DISPLAY_ON);
|
||||
WriteCmd(ILI9341_VERTICAL_SCROLLING_DEFINITION, {0x00, 0x00, SPLIT(m_height), 0x00, 0x00});
|
||||
}
|
||||
|
||||
void Ili9341Fsmc::WriteCmd(uint16_t cmd, std::initializer_list<const uint16_t> params)
|
||||
|
@ -80,6 +79,17 @@ void Ili9341Fsmc::WriteCmd_(uint16_t cmd, uint16_t cnt, ...)
|
|||
va_end(argp);
|
||||
}
|
||||
|
||||
void Ili9341Fsmc::SetScrollMode(bool on)
|
||||
{
|
||||
if(on != m_scrollMode) {
|
||||
if(on)
|
||||
WriteCmd(ILI9341_VERTICAL_SCROLLING_DEFINITION, {0x00, 0x00, MSBSPLIT(m_height), 0x00, 0x00});
|
||||
else
|
||||
WriteCmd(ILI9341_NORMAL_DISPLAY_MODE_ON);
|
||||
m_scrollMode = on;
|
||||
}
|
||||
}
|
||||
|
||||
void Ili9341Fsmc::WritePixels(void *src, uint32_t count, bool increment, bool async)
|
||||
{
|
||||
WriteCmd(ILI9341_GRAM);
|
||||
|
@ -130,7 +140,7 @@ void Ili9341Fsmc::ReadPixels(uint16_t *dst, uint32_t count)
|
|||
|
||||
void Ili9341Fsmc::SetScrollOffset()
|
||||
{
|
||||
uint16_t offsetData[2] = { SPLIT(m_scrollOffset) };
|
||||
uint16_t offsetData[2] = { MSBSPLIT(m_scrollOffset) };
|
||||
WriteCmd(ILI9341_VERTICAL_SCROLLING_START_ADDRESS);
|
||||
*m_ram = offsetData[0];
|
||||
*m_ram = offsetData[1];
|
||||
|
@ -151,8 +161,8 @@ void Ili9341Fsmc::SetRect(uint16_t x, uint16_t y, uint16_t width, uint16_t heigh
|
|||
uint16_t right = x + m_rectWidth - 1;
|
||||
uint16_t bottom = y + m_rectHeight - 1;
|
||||
|
||||
WriteCmd(ILI9341_COLUMN_ADDR, { SPLIT(x), SPLIT(right) });
|
||||
WriteCmd(ILI9341_PAGE_ADDR, { SPLIT(y), SPLIT(bottom) });
|
||||
WriteCmd(ILI9341_COLUMN_ADDR, { MSBSPLIT(x), MSBSPLIT(right) });
|
||||
WriteCmd(ILI9341_PAGE_ADDR, { MSBSPLIT(y), MSBSPLIT(bottom) });
|
||||
}
|
||||
|
||||
void Ili9341Fsmc::FillRect(uint16_t color, bool async)
|
||||
|
@ -237,7 +247,7 @@ void Ili9341Fsmc::PrintChar(char c, uint16_t x, uint16_t y, uint16_t fgColor, ui
|
|||
PrintChar(c);
|
||||
}
|
||||
|
||||
void Ili9341Fsmc::Print(char const *str, uint8_t len)
|
||||
void Ili9341Fsmc::Print(char const *str, uint8_t len, bool transparent)
|
||||
{
|
||||
if(!len)
|
||||
len = strlen(str);
|
||||
|
@ -253,11 +263,12 @@ void Ili9341Fsmc::Print(char const *str, uint8_t len)
|
|||
m_scrollOffset -= m_height;
|
||||
WaitDmaIdle();
|
||||
SetScrollOffset();
|
||||
FillRect(0, AdjustY(m_yPos), m_width, CHRHEIGHT, m_bgColor);
|
||||
if(!transparent)
|
||||
FillRect(0, AdjustY(m_yPos), m_width, CHRHEIGHT, m_bgColor);
|
||||
}
|
||||
}
|
||||
else
|
||||
PrintChar(*str, false);
|
||||
PrintChar(*str, transparent);
|
||||
++str;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ public:
|
|||
DMA_TypeDef *dma, uint32_t dmaStream,
|
||||
bool horizontal = true);
|
||||
|
||||
void SetScrollMode(bool on);
|
||||
void FillRect(uint16_t color, bool async = true);
|
||||
void FillRect(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t color, bool async = true);
|
||||
uint16_t Width() { return m_width; }
|
||||
|
@ -26,7 +27,7 @@ public:
|
|||
void SetCursor(uint16_t x, uint16_t y);
|
||||
void PrintChar(char c, uint16_t x, uint16_t y, uint16_t fgColor, uint16_t bgColor);
|
||||
void PrintChar(char c, bool transparent = false);
|
||||
void Print(char const *str, uint8_t len = 0);
|
||||
void Print(char const *str, uint8_t len = 0, bool transparent = false);
|
||||
|
||||
inline void WaitDmaIdle() { while(m_dmaEngineBusy); }
|
||||
|
||||
|
@ -65,6 +66,7 @@ private:
|
|||
uint16_t m_rectWidth;
|
||||
uint16_t m_rectHeight;
|
||||
|
||||
bool m_scrollMode = false;
|
||||
uint16_t m_scrollOffset = 0;
|
||||
|
||||
uint16_t m_xPos = 0;
|
||||
|
|
|
@ -40,6 +40,8 @@ public:
|
|||
void HandleUsartIrq();
|
||||
|
||||
private:
|
||||
void SetupTransmit(void *buffer, uint16_t length);
|
||||
|
||||
bool m_activeRxBuffer = false;
|
||||
Buffer m_rxBuffers[2];
|
||||
Buffer m_txBuffer;
|
||||
|
@ -59,6 +61,12 @@ template<unsigned int bufSize> SerialConsole<bufSize>::SerialConsole(
|
|||
SetupReceive(m_rxBuffers[m_activeRxBuffer].buffer, bufSize);
|
||||
}
|
||||
|
||||
template<unsigned int bufSize> void SerialConsole<bufSize>::SetupTransmit(void *buffer, uint16_t length)
|
||||
{
|
||||
m_txBuffer.busy = true;
|
||||
UartBase::SetupTransmit(buffer, length);
|
||||
}
|
||||
|
||||
template<unsigned int bufSize> void SerialConsole<bufSize>::HandleRxDmaIrq()
|
||||
{
|
||||
if(*m_rxDma.GetIsReg() & m_rxDma.GetTcMask()) {
|
||||
|
@ -150,7 +158,7 @@ template<unsigned int bufSize> void SerialConsole<bufSize>::SendLine(char const
|
|||
if(length) {
|
||||
while( m_txBuffer.busy );
|
||||
memcpy(m_txBuffer.buffer, buffer, length);
|
||||
if(m_txBuffer.buffer[length-1 != '\n']) {
|
||||
if(m_txBuffer.buffer[length-1] != '\n') {
|
||||
m_txBuffer.buffer[length++] = '\r';
|
||||
m_txBuffer.buffer[length++] = '\n';
|
||||
}
|
||||
|
|
259
platforms/test/Readme.md
Normal file
259
platforms/test/Readme.md
Normal file
|
@ -0,0 +1,259 @@
|
|||
<h1>Mocking (low level bare-metal embedded) C code</h1>
|
||||
|
||||
<h2>Preparations</h2>
|
||||
As Google test framework expect your test code to be written in c++, declaring your C functions as extern "C" is mandatory. Use
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
at the beginning of your headers and
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
at the end.
|
||||
|
||||
Keep in mind that STM32 is a 32 bit platform so unfortunately we cannot use amd64 for running our tests as pointer sizes would not match.
|
||||
|
||||
<h2>Creating stubs for external code</h2>
|
||||
|
||||
Unfortunately there is no way to make C functions dynamically mockable without source code modifications. We should use some macro magic to declare/define the functions need to be dynamically mockable.
|
||||
|
||||
<h3>Original code</h3>
|
||||
|
||||
foo.h:
|
||||
|
||||
...
|
||||
uint8_t* Pu_GetTxBuffer(struct usartstatus_t *status);
|
||||
...
|
||||
|
||||
foo.c:
|
||||
|
||||
...
|
||||
uint8_t* Pu_GetTxBuffer(struct usartstatus_t *status)
|
||||
{
|
||||
return status->txBuffer.packet.payload;
|
||||
}
|
||||
...
|
||||
|
||||
<h3>Prepared for dynamic mocking</h3>
|
||||
|
||||
foo.h:
|
||||
|
||||
...
|
||||
uint8_t* Pu_GetTxBuffer(struct usartstatus_t *status);
|
||||
...
|
||||
DECLARE_MOCK(Pu_GetTxBuffer);
|
||||
...
|
||||
|
||||
foo.c:
|
||||
|
||||
...
|
||||
uint8_t* MOCKABLE(Pu_GetTxBuffer)(struct usartstatus_t *status)
|
||||
{
|
||||
return status->txBuffer.packet.payload;
|
||||
}
|
||||
...
|
||||
|
||||
During normal build `DECLARE_MOCK(Pu_GetTxBuffer)` expands to nothing and `MOCKABLE(Pu_GetTxBuffer)` expands to `Pu_GetTxBuffer`, so using them have no effect on the compiled binary.
|
||||
|
||||
When compiling the code for unit tests `DECLARE_MOCK(Pu_GetTxBuffer)` will do two things:
|
||||
* Declares a function with the same signature as `Pu_GetTxBuffer` named `Pu_GetTxBuffer__`
|
||||
* Declares a function pointer named `test_GetTxBuffer`
|
||||
|
||||
`MOCKABLE` macro is the tricikiest part of the whole framework. It injects x86 assembly code into the intermediate assembly source generated from the C source to achieve the following:
|
||||
|
||||
Hijacks `Pu_GetTxBuffer` and injects a code which check s the value of `test_GetTextBuffer` pointer and calls the function it points to if the pointer is not NULL. Defines `Pu_GetTxBuffer__` (using the original implementation) which is called in case `test_GetTextBuffer` contains NULL.
|
||||
|
||||
As result we have an extra pointer for each prepared function to divert the execution when we need it and leave the original implementation in place when not.
|
||||
|
||||
|
||||
<h2>Mocking/stubing platform code</h2>
|
||||
|
||||
Platform (like CMSIS, STM32 HAL or LL) has plenty of declarations and definitions necessary your code might be using. Unfortunately unit tests will need them too to compile. In most of the cases they even should be mockable. As the platform code written for ARM (sometimes even containing ARM assembly inserts) it would be extremely hard to make it compile on x86. there is no other way to make your own code compilable but copying necessary declarations and provide trivial (stub) definition in your own "fake" platform code.
|
||||
|
||||
It is also a good idea to make (at least parts of) your stub implementation mockable using the macros described above (see headers and sources in platforms/test/platform for example)
|
||||
|
||||
<h2>Writing your unit tests</h2>
|
||||
|
||||
There are several macros provided to make writing unit test as convinient as possible.
|
||||
|
||||
<h3>Defining mocks</h3>
|
||||
|
||||
Defining mock functions with no (void) return value:
|
||||
|
||||
DEFINE_MOCK(<function_name>, <decoration>, [<parameter list>]) {
|
||||
<mock_function_implementation>
|
||||
LEAVE_MOCK;
|
||||
}
|
||||
|
||||
Example:
|
||||
|
||||
DEFINE_MOCK(LL_DMA_SetM2MDstAddress, mock, DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
|
||||
<implementation>
|
||||
LEAVE_MOCK;
|
||||
}
|
||||
|
||||
The above will generate the following C code:
|
||||
|
||||
static int LL_DMA_SetM2MDstAddress_mock_callcount;
|
||||
static void LL_DMA_SetM2MDstAddress_mock(DMA_TypeDef *dma, uint32_t stream, uint32_t address) {
|
||||
++LL_DMA_SetM2MDstAddress_mock_callcount;
|
||||
{
|
||||
<implementation>
|
||||
}
|
||||
}
|
||||
|
||||
Defining mock functions with return (non-void) value:
|
||||
|
||||
DEFINE_MOCK_RET(<return_type>, <function_name>, <decoration>, [<parameter list>]) {
|
||||
<mock_function_implementation>
|
||||
RETURN_MOCK_PREDEF(<function_name>, <decoration> | RETURN_MOCK(<function_name>, <decoration>, <return value>);
|
||||
}
|
||||
|
||||
Example:
|
||||
|
||||
DEFINE_MOCK_RET(uint32_t, LL_USART_IsActiveFlag_IDLE, mock, USART_TypeDef *usart) {
|
||||
<implementation>
|
||||
RETURN_MOCK_PREDEF(LL_USART_IsActiveFlag_IDLE, mock)
|
||||
}
|
||||
|
||||
The above will generate the following C code:
|
||||
|
||||
static int LL_USART_IsActiveFlag_IDLE_mock_callcount;
|
||||
static uint32_t LL_USART_IsActiveFlag_IDLE_mock_retval;
|
||||
static uint32_t LL_USART_IsActiveFlag_IDLE_mock(USART_TypeDef *usart) {
|
||||
++LL_USART_IsActiveFlag_IDLE_mock_callcount;
|
||||
{
|
||||
<implementation>
|
||||
}
|
||||
return LL_USART_IsActiveFlag_IDLE_mock_retval;
|
||||
}
|
||||
|
||||
Return value of the function above can be set by
|
||||
|
||||
MOCK_STORE(LL_USART_IsActiveFlag_IDLE, mock, retval, <value>);
|
||||
|
||||
or
|
||||
|
||||
MOCK_VAR(LL_USART_IsActiveFlag_IDLE, mock, retval) = <value>;
|
||||
|
||||
or
|
||||
|
||||
LL_USART_IsActiveFlag_IDLE_mock_retval = <value>;
|
||||
|
||||
during the test setup.
|
||||
|
||||
<h3>Helper variables for mocking</h3>
|
||||
|
||||
It is quite common that you need to store some data in global variables (can be checked later in from the test code or can be used by other mocks). There are few helper macros to make this easier. You can define a mock helper variable using
|
||||
|
||||
DEFINE_MOCK_VAR(<type>, <function_name>, <decoration>, <variable_name>);
|
||||
|
||||
Example:
|
||||
|
||||
DEFINE_MOCK_VAR(uint32_t, __set_PRIMASK, mock, lastprimask);
|
||||
|
||||
Which will expand to:
|
||||
|
||||
uint32_t __set_PRIMASK_mock_lastprimask;
|
||||
|
||||
You can access these variables using `MOCK_VAR(<function_name>, <decoration>, <name>)` (e.g. `if(MOCK_VAR(__set_PRIMASK, mock, lastprimask) != 0)` or `MOCK_VAR(__set_PRIMASK, mock, lastprimask) = 1;` ) but for setting the value of a mock helper variable you can also use `MOCK_STORE(<function_name>, <decoration>, <varable_name>, <value>);` (e.g `MOCK_STORE(__set_PRIMASK, mock, lastprimask, 1)` which is equivalent to setting the variable using `MOCK_VAR`.
|
||||
|
||||
As it was descibed above, defining a mock function also defines (and administers) a call count variable for that function. For easier access of those variables we have `MOCK_CALLCOUNT(<function_name>, <decoration>)` (e.g. `if(MOCK_CALLCOUNT(__set_PRIMASK, mock) != 5) ...`)
|
||||
|
||||
<h2>Real-life example</h2>
|
||||
|
||||
Test writing using the infrastructure described above is quite straight-forward and easy. Let's assume we would like to write a unit test for the following function:
|
||||
|
||||
void MOCKABLE(Crc_AttachTasks)(struct crcstatus_t *status, struct crcslot_t *slot,
|
||||
struct crctask_t *tasks, uint8_t taskCount)
|
||||
{
|
||||
slot->count = taskCount;
|
||||
slot->tasks = tasks;
|
||||
memset(tasks, 0, sizeof(*tasks)*taskCount);
|
||||
|
||||
uint32_t prim = __get_PRIMASK();
|
||||
__disable_irq();
|
||||
slot->next = status->firstSlot;
|
||||
status->firstSlot = slot;
|
||||
__set_PRIMASK(prim);
|
||||
}
|
||||
|
||||
This function attaches a new tasks to one of the slots of CRC scheduler. As this ;lis is also processed from interrupt context it needs to disable interrupts for the period of the modification and restore the original interrupt enablement status on the end.
|
||||
|
||||
We can identify three platform specific function calls: `__get_PRIMASK(), __disable_irq()` and `__set_PRIMASK()` so we need stubs for them somewhere in the platform stub code:
|
||||
|
||||
Platform stub header:
|
||||
|
||||
void __disable_irq();
|
||||
uint32_t __get_PRIMASK();
|
||||
void __set_PRIMASK(uint32_t priMask);
|
||||
|
||||
Platform stub source:
|
||||
|
||||
void MOCKABLE(__disable_irq)() {}
|
||||
uint32_t MOCKABLE(__get_PRIMASK)() { return 0; }
|
||||
void MOCKABLE(__set_PRIMASK)(uint32_t primask) {}
|
||||
|
||||
In our test code we need to mock these function (making possible to verify that they're called as modification of the linked list of slots need to be guarded against interrupts)
|
||||
|
||||
uint32_t effective_primask = 0;
|
||||
|
||||
DEFINE_MOCK(__set_PRIMASK, mock, uint32_t primask) {
|
||||
effective_primask = primask;
|
||||
LEAVE_MOCK;
|
||||
}
|
||||
|
||||
DEFINE_MOCK_RET(uint32_t, __get_PRIMASK, mock) {
|
||||
RETURN_MOCK(__get_PRIMASK, mock, effective_primask);
|
||||
}
|
||||
|
||||
DEFINE_MOCK_VAR(crcslot_t *, __disable_irq, mock, firstslot_required);
|
||||
DEFINE_MOCK(__disable_irq, mock) {
|
||||
if(MOCK_CALLCOUNT(__disable_irq, mock) < 2) {
|
||||
EXPECT_EQ(crcStatus.firstSlot, MOCK_VAR(__disable_irq, mock, firstslot_required));
|
||||
}
|
||||
effective_primask = 1;
|
||||
LEAVE_MOCK;
|
||||
}
|
||||
|
||||
With these mock functions we actually mock the behaviour of he ARM Cortex PRIMASK register API. We also add some check to `_disable_irq_mock()` that verifies that the firstSlot member of the crcStatus has not changed before disabling interrupts.
|
||||
|
||||
Now we prepared everything for writing our first unit test for Crc_AttachTasks function:
|
||||
|
||||
TEST(CrcScheduler, AttachTask_single) {
|
||||
DMA1 = &dma1;
|
||||
DMA2 = &dma2;
|
||||
effective_primask = 0;
|
||||
Crc_InitStatus(&crcStatus, &fakeCrc, DMA2, LL_DMA_STREAM_4);
|
||||
ACTIVATE_MOCK_RV(__get_PRIMASK, mock, 0);
|
||||
ACTIVATE_MOCK(__set_PRIMASK, mock);
|
||||
ACTIVATE_MOCK(__disable_irq, mock);
|
||||
MOCK_STORE(__disable_irq, mock, firstslot_required, nullptr);
|
||||
|
||||
Crc_AttachTasks(&crcStatus, &slot1, tasks1, 2);
|
||||
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(__get_PRIMASK, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(__set_PRIMASK, mock), 1);
|
||||
EXPECT_EQ(MOCK_CALLCOUNT(__disable_irq, mock), 1);
|
||||
EXPECT_EQ(crcStatus.firstSlot, &slot1);
|
||||
EXPECT_EQ(slot1.next, nullptr);
|
||||
EXPECT_EQ(slot1.count, 2);
|
||||
EXPECT_EQ(crcStatus.activeSlot, nullptr);
|
||||
}
|
||||
|
||||
There are two ways to activate a mock:
|
||||
|
||||
ACTIVATE_MOCK(<function>, <decoration>);
|
||||
|
||||
and
|
||||
|
||||
ACTIVATE_MOCK_RV(<function>, <decoration>, <return_value>)
|
||||
|
||||
Both macros reset the corresponding `callcount` variable of the mock function to zero and divert the mocked function to the mock. In addition to this `ACTIVATE_MOCK_RV` also sets the return value variable of the mock function (created by `DEFINE_MOCK_RET`) to the supplied value. This can be used to define the return valuse of the mock (if the test writer decides to write the mock function this way).
|
||||
|
||||
After preparing everything for the test wi actually call `Crc_AttachTasks` with the appropriate parameters then verifying the results.
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue