mirror of
https://github.com/xiaotianbc/AT32_BSPV1_Clion_Template.git
synced 2026-05-21 09:22:06 +00:00
421 lines
11 KiB
C
421 lines
11 KiB
C
/**
|
|
**************************************************************************
|
|
* File : at32_board.c
|
|
* Version: V1.3.0
|
|
* Date : 2021-03-18
|
|
* Brief : 1. Set of firmware functions to manage Leds, push-button and COM ports.
|
|
* 2. initialize Delay Function and USB
|
|
**************************************************************************
|
|
*/
|
|
|
|
#include "at32_board.h"
|
|
#include "stdio.h"
|
|
|
|
#ifdef __cplusplus
|
|
namespace std
|
|
{
|
|
extern "C" {
|
|
#endif
|
|
|
|
/* Suport printf function, useMicroLib is unnecessary */
|
|
#ifdef __CC_ARM
|
|
#pragma import(__use_no_semihosting)
|
|
struct __FILE
|
|
{
|
|
int handle;
|
|
};
|
|
|
|
FILE __stdout;
|
|
|
|
void _sys_exit(int x)
|
|
{
|
|
x = x;
|
|
}
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
|
|
set to 'Yes') calls __io_putchar() */
|
|
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
|
|
// #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
|
|
#else
|
|
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
|
|
#endif /* __GNUC__ */
|
|
|
|
/**
|
|
* @brief Retargets the C library printf function to the USART.
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
PUTCHAR_PROTOTYPE
|
|
{
|
|
USART_SendData(AT32_PRINT_UART, ch);
|
|
while ( USART_GetFlagStatus(AT32_PRINT_UART, USART_FLAG_TRAC) == RESET );
|
|
return ch;
|
|
}
|
|
|
|
#ifdef __cplusplus
|
|
} /* extern "C" */
|
|
} /* namespace */
|
|
#endif
|
|
|
|
/*delay macros*/
|
|
#define STEP_DELAY_MS 50
|
|
|
|
/*AT-START LED resouce array*/
|
|
GPIO_Type *LED_GPIO_PORT[LED_NUM] = {LED1_GPIO, LED2_GPIO, LED3_GPIO, LED4_GPIO};
|
|
uint16_t LED_GPIO_PIN[LED_NUM] = {LED1_PIN, LED2_PIN, LED3_PIN, LED4_PIN};
|
|
uint32_t LED_GPIO_RCC_CLK[LED_NUM] = {LED1_GPIO_RCC_CLK, LED2_GPIO_RCC_CLK, LED3_GPIO_RCC_CLK, LED4_GPIO_RCC_CLK};
|
|
|
|
/*AT-START Button resouce arry*/
|
|
GPIO_Type *BUTTON_GPIO_PORT[BUTTON_NUM] = {BUTTON_WAKEUP_GPIO, BUTTON_USER_KEY_GPIO};
|
|
uint16_t BUTTON_GPIO_PIN[BUTTON_NUM] = {BUTTON_WAKEUP_PIN, BUTTON_USER_KEY_PIN};
|
|
uint32_t BUTTON_GPIO_RCC_CLK [BUTTON_NUM] = {BUTTON_WAKEUP_RCC_CLK, BUTTON_USER_KEY_RCC_CLK};
|
|
|
|
/*delay variable*/
|
|
static __IO uint32_t fac_us;
|
|
static __IO uint32_t fac_ms;
|
|
|
|
/**
|
|
* @brief Board initialize interface
|
|
* init LED and BUTTON
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void AT32_Board_Init()
|
|
{
|
|
/*initialize Delay Function*/
|
|
Delay_init();
|
|
|
|
/*Configure LED in AT_START_BOARD*/
|
|
AT32_LEDn_Init(LED2);
|
|
AT32_LEDn_Init(LED3);
|
|
AT32_LEDn_Init(LED4);
|
|
AT32_LEDn_OFF(LED2);
|
|
AT32_LEDn_OFF(LED3);
|
|
AT32_LEDn_OFF(LED4);
|
|
|
|
/*Configure Button in AT_START_BOARD*/
|
|
AT32_BUTTON_Init(BUTTON_WAKEUP); /*PA0*/
|
|
AT32_BUTTON_Init(BUTTON_USER_KEY); /*PC13*/
|
|
}
|
|
|
|
/**
|
|
* @brief USB GPIO initialize
|
|
* USB use DP->PA12, DM->PA11
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void AT32_USB_GPIO_init()
|
|
{
|
|
GPIO_InitType GPIO_InitStructure;
|
|
/* Enable the USB Clock*/
|
|
RCC_APB2PeriphClockCmd(USB_GPIO_RCC_CLK, ENABLE);
|
|
|
|
/*Configure DP, DM pin as GPIO_Mode_OUT_PP*/
|
|
GPIO_StructInit(&GPIO_InitStructure);
|
|
GPIO_InitStructure.GPIO_Pins = USB_DP_PIN | USB_DM_PIN;
|
|
#if !defined (AT32F421xx)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
|
|
#else
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
|
GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
|
|
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
|
|
#endif
|
|
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
|
|
GPIO_Init(USB_GPIO, &GPIO_InitStructure);
|
|
GPIO_ResetBits(USB_GPIO, USB_DP_PIN);
|
|
}
|
|
|
|
/**
|
|
* @brief Configure Button GPIO
|
|
* @param Button: Specifies the Button to be configured.
|
|
* @retval None
|
|
*/
|
|
void AT32_BUTTON_Init(BUTTON_Type button)
|
|
{
|
|
GPIO_InitType GPIO_InitStructure;
|
|
|
|
/*Enable the Button Clock*/
|
|
#if defined (AT32F421xx)
|
|
RCC_AHBPeriphClockCmd(BUTTON_GPIO_RCC_CLK[button], ENABLE);
|
|
#else
|
|
RCC_APB2PeriphClockCmd(BUTTON_GPIO_RCC_CLK[button], ENABLE);
|
|
#endif
|
|
|
|
/*Configure Button pin as input with pull-up/pull-down*/
|
|
GPIO_StructInit(&GPIO_InitStructure);
|
|
GPIO_InitStructure.GPIO_Pins = BUTTON_GPIO_PIN[button];
|
|
#if !defined (AT32F421xx)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_PD;
|
|
#else
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
|
|
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PD;
|
|
#endif
|
|
GPIO_Init(BUTTON_GPIO_PORT[button], &GPIO_InitStructure);
|
|
}
|
|
|
|
/**
|
|
* @brief Returns the selected button state
|
|
* @param Button: Specifies the Button to be Checked
|
|
* @retval The Button GPIO Pin value
|
|
*/
|
|
uint8_t AT32_BUTTON_State(BUTTON_Type button)
|
|
{
|
|
return GPIO_ReadInputDataBit(BUTTON_GPIO_PORT[button], BUTTON_GPIO_PIN[button]);
|
|
}
|
|
|
|
/**
|
|
* @brief Returns which Button have press down
|
|
* @param None
|
|
* @retval The Button have press down
|
|
*/
|
|
BUTTON_Type AT32_BUTTON_Press()
|
|
{
|
|
static uint8_t Pressed = 1;
|
|
/*Get Button state in AT_START board*/
|
|
if ((Pressed == 1) && ((AT32_BUTTON_State(BUTTON_WAKEUP) == Bit_SET ) || (AT32_BUTTON_State(BUTTON_USER_KEY) == Bit_SET )))
|
|
{
|
|
/*debounce*/
|
|
Pressed = 0;
|
|
Delay_ms(10);
|
|
if (AT32_BUTTON_State(BUTTON_WAKEUP) == Bit_SET)
|
|
return BUTTON_WAKEUP;
|
|
if (AT32_BUTTON_State(BUTTON_USER_KEY) == Bit_SET)
|
|
return BUTTON_USER_KEY;
|
|
}else if((AT32_BUTTON_State(BUTTON_USER_KEY) == Bit_RESET) && (AT32_BUTTON_State(BUTTON_WAKEUP) == Bit_RESET))
|
|
{
|
|
Pressed = 1;
|
|
}
|
|
return NO_BUTTON;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure LED GPIO
|
|
* @param led: Specifies the LED to be configured.
|
|
* @retval None
|
|
*/
|
|
void AT32_LEDn_Init(LED_Type led)
|
|
{
|
|
GPIO_InitType GPIO_InitStructure;
|
|
/*Enable the LED Clock*/
|
|
#if defined (AT32F421xx)
|
|
RCC_AHBPeriphClockCmd(LED_GPIO_RCC_CLK[led], ENABLE);
|
|
#else
|
|
RCC_APB2PeriphClockCmd(LED_GPIO_RCC_CLK[led], ENABLE);
|
|
#endif
|
|
|
|
/*Configure the LED pin as ouput push-pull*/
|
|
GPIO_StructInit(&GPIO_InitStructure);
|
|
GPIO_InitStructure.GPIO_Pins = LED_GPIO_PIN[led];
|
|
#if !defined (AT32F421xx)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT_PP;
|
|
#else
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
|
|
GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
|
|
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
|
|
#endif
|
|
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
|
|
GPIO_Init(LED_GPIO_PORT[led], &GPIO_InitStructure);
|
|
}
|
|
|
|
/**
|
|
* @brief Turns selected LED On.
|
|
* @param Led: Specifies the Led to be set on.
|
|
* This parameter can be one of following parameters:
|
|
* @arg LED1
|
|
* @arg LED2
|
|
* @arg LED3
|
|
* @arg LED4
|
|
* @retval None
|
|
*/
|
|
void AT32_LEDn_ON(LED_Type led)
|
|
{
|
|
if ( led > (LED_NUM - 1))
|
|
return;
|
|
if ( LED_GPIO_PIN[led] )
|
|
LED_GPIO_PORT[led]->BRE = LED_GPIO_PIN[led];
|
|
}
|
|
|
|
/**
|
|
* @brief Turns selected LED Off.
|
|
* @param Led: Specifies the Led to be set off.
|
|
* This parameter can be one of following parameters:
|
|
* @arg LED1
|
|
* @arg LED2
|
|
* @arg LED3
|
|
* @arg LED4
|
|
* @retval None
|
|
*/
|
|
void AT32_LEDn_OFF(LED_Type led)
|
|
{
|
|
if ( led > (LED_NUM - 1))
|
|
return;
|
|
if ( LED_GPIO_PIN[led] )
|
|
LED_GPIO_PORT[led]->BSRE = LED_GPIO_PIN[led];
|
|
}
|
|
|
|
/**
|
|
* @brief Turns selected LED Tooggle.
|
|
* @param Led: Specifies the Led to be set off.
|
|
* This parameter can be one of following parameters:
|
|
* @arg LED1
|
|
* @arg LED2
|
|
* @arg LED3
|
|
* @arg LED4
|
|
* @retval None
|
|
*/
|
|
void AT32_LEDn_Toggle(LED_Type led)
|
|
{
|
|
if ( led > (LED_NUM - 1))
|
|
return;
|
|
if ( LED_GPIO_PIN[led] )
|
|
LED_GPIO_PORT[led]->OPTDT ^= LED_GPIO_PIN[led];
|
|
}
|
|
|
|
/**
|
|
* @brief initialize UART1
|
|
* @param bound: UART BaudRate
|
|
* @retval None
|
|
*/
|
|
void UART_Print_Init(uint32_t bound)
|
|
{
|
|
GPIO_InitType GPIO_InitStructure;
|
|
USART_InitType USART_InitStructure;
|
|
|
|
/*Enable the UART Clock*/
|
|
#if defined (AT32F421xx)
|
|
RCC_AHBPeriphClockCmd(AT32_PRINT_UARTTX_GPIO_RCC | AT32_PRINT_UARTRX_GPIO_RCC, ENABLE);
|
|
#else
|
|
RCC_APB2PeriphClockCmd(AT32_PRINT_UARTTX_GPIO_RCC | AT32_PRINT_UARTRX_GPIO_RCC, ENABLE);
|
|
#endif
|
|
AT32_PRINT_UART_RCC_CLK_FUNC;
|
|
|
|
/* Configure the UART1 TX pin */
|
|
GPIO_StructInit(&GPIO_InitStructure);
|
|
GPIO_InitStructure.GPIO_Pins = AT32_PRINT_UARTTX_PIN;
|
|
GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
|
|
#if !defined (AT32F421xx)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
#else
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
|
GPIO_InitStructure.GPIO_OutType = GPIO_OutType_PP;
|
|
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_NOPULL;
|
|
#endif
|
|
GPIO_Init(AT32_PRINT_UARTTX_GPIO, &GPIO_InitStructure);
|
|
|
|
/* Configure the UART1 RX pin */
|
|
GPIO_InitStructure.GPIO_Pins = AT32_PRINT_UARTRX_PIN;//PA10
|
|
#if !defined (AT32F421xx)
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
|
#else
|
|
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
|
|
GPIO_InitStructure.GPIO_Pull = GPIO_Pull_PU;
|
|
#endif
|
|
GPIO_Init(AT32_PRINT_UARTRX_GPIO, &GPIO_InitStructure);
|
|
|
|
#if defined (AT32F421xx)
|
|
GPIO_PinAFConfig(GPIOA, GPIO_PinsSource9, GPIO_AF_1);
|
|
GPIO_PinAFConfig(GPIOA, GPIO_PinsSource10, GPIO_AF_1);
|
|
#endif
|
|
|
|
/*Configure UART param*/
|
|
USART_StructInit(&USART_InitStructure);
|
|
USART_InitStructure.USART_BaudRate = bound;
|
|
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
|
|
USART_InitStructure.USART_StopBits = USART_StopBits_1;
|
|
USART_InitStructure.USART_Parity = USART_Parity_No;
|
|
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
|
|
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
|
|
|
|
USART_Init(AT32_PRINT_UART, &USART_InitStructure);
|
|
USART_INTConfig(AT32_PRINT_UART, USART_INT_RDNE, ENABLE);
|
|
USART_Cmd(AT32_PRINT_UART, ENABLE);
|
|
}
|
|
|
|
/**
|
|
* @brief initialize Delay function
|
|
* @param None
|
|
* @retval None
|
|
*/
|
|
void Delay_init()
|
|
{
|
|
/*Config Systick*/
|
|
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
|
|
fac_us = SystemCoreClock / (1000000U);
|
|
fac_ms = fac_us * (1000U);
|
|
}
|
|
|
|
/**
|
|
* @brief Inserts a delay time.
|
|
* @param nus: specifies the delay time length, in microsecond.
|
|
* @retval None
|
|
*/
|
|
void Delay_us(u32 nus)
|
|
{
|
|
u32 temp;
|
|
SysTick->LOAD = (u32)(nus*fac_us);
|
|
SysTick->VAL = 0x00;
|
|
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk ;
|
|
do
|
|
{
|
|
temp = SysTick->CTRL;
|
|
}while((temp & 0x01) &&! (temp & (1<<16)));
|
|
|
|
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
|
SysTick->VAL = 0x00;
|
|
}
|
|
|
|
/**
|
|
* @brief Inserts a delay time.
|
|
* @param nms: specifies the delay time length, in milliseconds.
|
|
* @retval None
|
|
*/
|
|
void Delay_ms(u16 nms)
|
|
{
|
|
u32 temp;
|
|
while(nms)
|
|
{
|
|
if(nms > STEP_DELAY_MS)
|
|
{
|
|
SysTick->LOAD = (u32)(STEP_DELAY_MS * fac_ms);
|
|
nms -= STEP_DELAY_MS;
|
|
}
|
|
else
|
|
{
|
|
SysTick->LOAD = (u32)(nms * fac_ms);
|
|
nms = 0;
|
|
}
|
|
SysTick->VAL = 0x00;
|
|
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
|
|
do
|
|
{
|
|
temp = SysTick->CTRL;
|
|
}while( (temp & 0x01) && !(temp & (1<<16)) );
|
|
|
|
SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
|
|
SysTick->VAL = 0x00;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief Inserts a delay time.
|
|
* @param sec: specifies the delay time length, in seconds.
|
|
* @retval None
|
|
*/
|
|
void Delay_sec(u16 sec)
|
|
{
|
|
u16 i;
|
|
for(i=0; i<sec; i++)
|
|
{
|
|
Delay_ms(500);
|
|
Delay_ms(500);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|