170 lines
5.5 KiB
C
170 lines
5.5 KiB
C
|
|
/* ----------------------------------------------------------------------
|
||
|
|
* 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;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|