MoistureSoftware/.pack/Keil/STM32F1xx_DFP.2.3.0/RTE_Driver/GPIO_STM32F10x.c

170 lines
5.5 KiB
C
Raw Normal View History

2025-09-28 09:17:22 +00:00
/* ----------------------------------------------------------------------
* Copyright (C) 2016 ARM Limited. All rights reserved.
*
* $Date: 26. April 2016
* $Revision: V1.3
*
* Project: GPIO Driver for ST STM32F10x
* -------------------------------------------------------------------- */
#include "GPIO_STM32F10x.h"
/* History:
* Version 1.3
* Corrected corruption of Serial wire JTAG pins alternate function configuration.
* Version 1.2
* Added GPIO_GetPortClockState function
* GPIO_PinConfigure function enables GPIO peripheral clock, if not already enabled
* Version 1.1
* GPIO_PortClock and GPIO_PinConfigure functions rewritten
* GPIO_STM32F1xx header file cleaned up and simplified
* GPIO_AFConfigure function and accompanying definitions added
* Version 1.0
* Initial release
*/
/* Serial wire JTAG pins alternate function Configuration
* Can be user defined by C preprocessor:
* AFIO_SWJ_FULL, AFIO_SWJ_FULL_NO_NJTRST, AFIO_SWJ_JTAG_NO_SW, AFIO_SWJ_NO_JTAG_NO_SW
*/
#ifndef AFIO_MAPR_SWJ_CFG_VAL
#define AFIO_MAPR_SWJ_CFG_VAL (AFIO_SWJ_FULL) // Full SWJ (JTAG-DP + SW-DP)
#endif
/**
\fn void GPIO_PortClock (GPIO_TypeDef *GPIOx, bool en)
\brief Port Clock Control
\param[in] GPIOx Pointer to GPIO peripheral
\param[in] enable Enable or disable clock
*/
void GPIO_PortClock (GPIO_TypeDef *GPIOx, bool enable) {
if (enable) {
if (GPIOx == GPIOA) RCC->APB2ENR |= (1U << 2);
else if (GPIOx == GPIOB) RCC->APB2ENR |= (1U << 3);
else if (GPIOx == GPIOC) RCC->APB2ENR |= (1U << 4);
else if (GPIOx == GPIOD) RCC->APB2ENR |= (1U << 5);
else if (GPIOx == GPIOE) RCC->APB2ENR |= (1U << 6);
else if (GPIOx == GPIOF) RCC->APB2ENR |= (1U << 7);
else if (GPIOx == GPIOG) RCC->APB2ENR |= (1U << 8);
} else {
if (GPIOx == GPIOA) RCC->APB2ENR &= ~(1U << 2);
else if (GPIOx == GPIOB) RCC->APB2ENR &= ~(1U << 3);
else if (GPIOx == GPIOC) RCC->APB2ENR &= ~(1U << 4);
else if (GPIOx == GPIOD) RCC->APB2ENR &= ~(1U << 5);
else if (GPIOx == GPIOE) RCC->APB2ENR &= ~(1U << 6);
else if (GPIOx == GPIOF) RCC->APB2ENR &= ~(1U << 7);
else if (GPIOx == GPIOG) RCC->APB2ENR &= ~(1U << 8);
}
}
/**
\fn bool GPIO_GetPortClockState (GPIO_TypeDef *GPIOx)
\brief Get GPIO port clock state
\param[in] GPIOx Pointer to GPIO peripheral
\return true - enabled
false - disabled
*/
bool GPIO_GetPortClockState (GPIO_TypeDef *GPIOx) {
if (GPIOx == GPIOA) { return ((RCC->APB2ENR & (1U << 2)) != 0U); }
else if (GPIOx == GPIOB) { return ((RCC->APB2ENR & (1U << 3)) != 0U); }
else if (GPIOx == GPIOC) { return ((RCC->APB2ENR & (1U << 4)) != 0U); }
else if (GPIOx == GPIOD) { return ((RCC->APB2ENR & (1U << 5)) != 0U); }
else if (GPIOx == GPIOE) { return ((RCC->APB2ENR & (1U << 6)) != 0U); }
else if (GPIOx == GPIOF) { return ((RCC->APB2ENR & (1U << 7)) != 0U); }
else if (GPIOx == GPIOG) { return ((RCC->APB2ENR & (1U << 8)) != 0U); }
return false;
}
/**
\fn bool GPIO_PinConfigure (GPIO_TypeDef *GPIOx,
uint32_t num,
GPIO_CONF conf,
GPIO_MODE mode)
\brief Configure port pin
\param[in] GPIOx Pointer to GPIO peripheral
\param[in] num Port pin number
\param[in] mode \ref GPIO_MODE
\param[in] conf \ref GPIO_CONF
\return true - success
false - error
*/
bool GPIO_PinConfigure(GPIO_TypeDef *GPIOx, uint32_t num, GPIO_CONF conf,
GPIO_MODE mode) {
__IO uint32_t *reg;
if (num > 15) return false;
if (GPIO_GetPortClockState(GPIOx) == false) {
/* Enable GPIOx peripheral clock */
GPIO_PortClock (GPIOx, true);
}
if (mode == GPIO_MODE_INPUT) {
if (conf == GPIO_IN_PULL_DOWN) {
/* Enable pull down on selected input */
GPIOx->ODR &= ~(1 << num);
}
else if (conf == GPIO_IN_PULL_UP) {
/* Enable pull up on selected input */
conf &= ~1;
GPIOx->ODR |= (1 << num);
}
}
if (num < 8) {
reg = &GPIOx->CRL;
}
else {
num -= 8;
reg = &GPIOx->CRH;
}
*reg &= ~(0xF << (num << 2));
*reg |= ((conf << 2) | mode) << (num << 2);
return true;
}
/**
\fn void GPIO_AFConfigure (AFIO_REMAP af_type)
\brief Configure alternate functions
\param[in] af_type Alternate function remap type
*/
void GPIO_AFConfigure (AFIO_REMAP af_type) {
uint32_t msk, val;
volatile uint32_t mapr;
if (af_type != AFIO_UNAVAILABLE_REMAP) {
msk = (af_type >> 5) & 0x07;
val = (af_type >> 8) & 0x0F;
if (!(RCC->APB2ENR & RCC_APB2ENR_AFIOEN)) {
/* Enable AFIO peripheral clock */
RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;
}
if (af_type & (1 << 12)) {
/* AF remap and debug I/O config register 2 */
mapr = AFIO->MAPR2;
mapr &= ~(msk << (af_type & 0x1F));
mapr |= (val << (af_type & 0x1F));
AFIO->MAPR2 = mapr;
}
else {
/* AF remap and debug I/O config register */
mapr = AFIO->MAPR;
mapr &= ~(msk << (af_type & 0x1F));
mapr |= (val << (af_type & 0x1F));
/* Serial wire JTAG configuration */
msk = (AFIO_MAPR_SWJ_CFG_VAL >> 5) & 0x07;
val = (AFIO_MAPR_SWJ_CFG_VAL >> 8) & 0x0F;
mapr &= ~(msk << (AFIO_MAPR_SWJ_CFG_VAL & 0x1F));
mapr |= (val << (AFIO_MAPR_SWJ_CFG_VAL & 0x1F));
AFIO->MAPR = mapr;
}
}
}