/** ************************************************************************** * @file at32f421_board.c * @brief set of firmware functions to manage leds and push-button. * initialize delay function. ************************************************************************** * Copyright notice & Disclaimer * * The software Board Support Package (BSP) that is made available to * download from Artery official website is the copyrighted work of Artery. * Artery authorizes customers to use, copy, and distribute the BSP * software and its related documentation for the purpose of design and * development in conjunction with Artery microcontrollers. Use of the * software is governed by this copyright notice and the following disclaimer. * * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES, * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS, * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS, * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. * ************************************************************************** */ #include "at32f421_board.h" /** @addtogroup AT32F421_board * @{ */ /** @defgroup BOARD * @brief onboard periph driver * @{ */ /* delay macros */ #define STEP_DELAY_MS 50 /* at-start led resouce array */ gpio_type *led_gpio_port[LED_NUM] = {LED2_GPIO, LED3_GPIO, LED4_GPIO}; uint16_t led_gpio_pin[LED_NUM] = {LED2_PIN, LED3_PIN, LED4_PIN}; crm_periph_clock_type led_gpio_crm_clk[LED_NUM] = {LED2_GPIO_CRM_CLK, LED3_GPIO_CRM_CLK, LED4_GPIO_CRM_CLK}; /* delay variable */ static __IO uint32_t fac_us; static __IO uint32_t fac_ms; /* support printf function, usemicrolib is unnecessary */ #if (__ARMCC_VERSION > 6000000) __asm (".global __use_no_semihosting\n\t"); void _sys_exit(int x) { x = x; } /* __use_no_semihosting was requested, but _ttywrch was */ void _ttywrch(int ch) { ch = ch; } FILE __stdout; #else #ifdef __CC_ARM #pragma import(__use_no_semihosting) struct __FILE { int handle; }; FILE __stdout; void _sys_exit(int x) { x = x; } /* __use_no_semihosting was requested, but _ttywrch was */ void _ttywrch(int ch) { ch = ch; } #endif #endif #if defined (__GNUC__) && !defined (__clang__) #define PUTCHAR_PROTOTYPE int __io_putchar(int ch) #else #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f) #endif /** * @brief retargets the c library printf function to the usart. * @param none * @retval none */ PUTCHAR_PROTOTYPE { while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET); usart_data_transmit(PRINT_UART, (uint16_t)ch); while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET); return ch; } #if (defined (__GNUC__) && !defined (__clang__)) || (defined (__ICCARM__)) #if defined (__GNUC__) && !defined (__clang__) int _write(int fd, char *pbuffer, int size) #elif defined ( __ICCARM__ ) #pragma module_name = "?__write" int __write(int fd, char *pbuffer, int size) #endif { for(int i = 0; i < size; i ++) { while(usart_flag_get(PRINT_UART, USART_TDBE_FLAG) == RESET); usart_data_transmit(PRINT_UART, (uint16_t)(*pbuffer++)); while(usart_flag_get(PRINT_UART, USART_TDC_FLAG) == RESET); } return size; } #endif /** * @brief initialize uart * @param baudrate: uart baudrate * @retval none */ void uart_print_init(uint32_t baudrate) { gpio_init_type gpio_init_struct; #if defined (__GNUC__) && !defined (__clang__) setvbuf(stdout, NULL, _IONBF, 0); #endif /* enable the uart and gpio clock */ crm_periph_clock_enable(PRINT_UART_CRM_CLK, TRUE); crm_periph_clock_enable(PRINT_UART_TX_GPIO_CRM_CLK, TRUE); gpio_default_para_init(&gpio_init_struct); /* configure the uart tx pin */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_pins = PRINT_UART_TX_PIN; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(PRINT_UART_TX_GPIO, &gpio_init_struct); gpio_pin_mux_config(PRINT_UART_TX_GPIO, PRINT_UART_TX_PIN_SOURCE, PRINT_UART_TX_PIN_MUX_NUM); /* configure uart param */ usart_init(PRINT_UART, baudrate, USART_DATA_8BITS, USART_STOP_1_BIT); usart_transmitter_enable(PRINT_UART, TRUE); usart_enable(PRINT_UART, TRUE); } /** * @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_led_init(LED2); // at32_led_init(LED3); // at32_led_init(LED4); // at32_led_off(LED2); // at32_led_off(LED3); // at32_led_off(LED4); /* configure button in at_start board */ at32_button_init(); } extern uint8_t g_input_div; void loop_timer_io_init(void) { uint8_t i = 0; uint8_t _div = 0; /* enable tmr3/gpioa clock */ crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE); crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE); gpio_init_type gpio_init_struct; #ifdef DEBUG gpio_init_struct.gpio_pins = RLY1_PIN | RLY2_PIN | LED_YELLOW_PIN; #else gpio_init_struct.gpio_pins = RLY1_PIN | RLY2_PIN | LED_GREEN_PIN;// | LED_YELLOW_PIN; #endif gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init(GPIOA, &gpio_init_struct); gpio_init_struct.gpio_pins = LED_YELLOW_PIN; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_OPEN_DRAIN; gpio_init_struct.gpio_pull = GPIO_PULL_UP;//GPIO_PULL_UP;//GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init(GPIOA, &gpio_init_struct); LEDA_OFF; // 绿灭 LEDC_OFF; // 黄灭 RLY1_OFF; RLY2_OFF; /* timer3 input pin Configuration */ gpio_init_struct.gpio_pins = GPIO_PINS_7; gpio_init_struct.gpio_mode = GPIO_MODE_MUX; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init(GPIOA, &gpio_init_struct); gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE7, GPIO_MUX_1); /* tmr3 configuration: input capture mode the external signal is connected to tmr3 ch2 pin (pa.07) the rising edge is used as active edge, the tmr3 c2dt is used to compute the frequency value */ /* tmr3 counter mode configuration */ tmr_base_init(TMR3, 0xFFFF, 0); tmr_cnt_dir_set(TMR3, TMR_COUNT_UP); /* configure tmr3 channel2 to get clock signal */ g_tmr_input_config_struct.input_channel_select = TMR_SELECT_CHANNEL_2; g_tmr_input_config_struct.input_mapped_select = TMR_CC_CHANNEL_MAPPED_DIRECT; g_tmr_input_config_struct.input_polarity_select = TMR_INPUT_RISING_EDGE; _div = TMR_CHANNEL_INPUT_DIV_2; tmr_input_channel_init(TMR3, &g_tmr_input_config_struct, _div); for(i = 0; i< _div; i++){ g_input_div *= 2; } tmr_interrupt_enable(TMR3, TMR_C2_INT, TRUE); /* tmr2 trigger interrupt nvic init */ // nvic_priority_group_config(NVIC_PRIORITY_GROUP_4); nvic_irq_enable(TMR3_GLOBAL_IRQn, 0, 0); /* enable tmr3 */ tmr_counter_enable(TMR3, TRUE); } /** * @brief configure button gpio * @param button: specifies the button to be configured. * @retval none */ void at32_button_init(void) { gpio_init_type gpio_init_struct; /* enable the button clock */ crm_periph_clock_enable(USER_BUTTON_CRM_CLK, TRUE); /* set default parameter */ gpio_default_para_init(&gpio_init_struct); /* configure button pin as input with pull-up/pull-down */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_INPUT; gpio_init_struct.gpio_pins = SW1_BUTTON_PIN | SW2_BUTTON_PIN | SW3_BUTTON_PIN | SW4_BUTTON_PIN | SW5_BUTTON_PIN; gpio_init_struct.gpio_pull = GPIO_PULL_UP; gpio_init(USER_BUTTON_PORT, &gpio_init_struct); } /** * @brief returns the selected button state * @param none * @retval the button gpio pin value */ uint8_t at32_button_state(void) { return gpio_input_data_bit_read(USER_BUTTON_PORT, USER_BUTTON_PIN); } /** * @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() != RESET)) { /* debounce */ pressed = 0; delay_ms(10); if(at32_button_state() != RESET) return USER_BUTTON; } else if(at32_button_state() == RESET) { pressed = 1; } return NO_BUTTON; } /** * @brief configure led gpio * @param led: specifies the led to be configured. * @retval none */ void at32_led_init(led_type led) { gpio_init_type gpio_init_struct; /* enable the led clock */ crm_periph_clock_enable(led_gpio_crm_clk[led], TRUE); /* set default parameter */ gpio_default_para_init(&gpio_init_struct); /* configure the led gpio */ gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER; gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL; gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT; gpio_init_struct.gpio_pins = led_gpio_pin[led]; gpio_init_struct.gpio_pull = GPIO_PULL_NONE; gpio_init(led_gpio_port[led], &gpio_init_struct); } /** * @brief turns selected led on. * @param led: specifies the led to be set on. * this parameter can be one of following parameters: * @arg LED2 * @arg LED3 * @arg LED4 * @retval none */ void at32_led_on(led_type led) { if(led > (LED_NUM - 1)) return; if(led_gpio_pin[led]) led_gpio_port[led]->clr = 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 LED2 * @arg LED3 * @arg LED4 * @retval none */ void at32_led_off(led_type led) { if(led > (LED_NUM - 1)) return; if(led_gpio_pin[led]) led_gpio_port[led]->scr = led_gpio_pin[led]; } /** * @brief turns selected led toggle. * @param led: specifies the led to be set off. * this parameter can be one of following parameters: * @arg LED2 * @arg LED3 * @arg LED4 * @retval none */ void at32_led_toggle(led_type led) { if(led > (LED_NUM - 1)) return; if(led_gpio_pin[led]) led_gpio_port[led]->odt ^= led_gpio_pin[led]; } /** * @brief initialize delay function * @param none * @retval none */ void delay_init() { /* configure systick */ systick_clock_source_config(SYSTICK_CLOCK_SOURCE_AHBCLK_NODIV); fac_us = system_core_clock / (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(uint32_t nus) { uint32_t temp = 0; SysTick->LOAD = (uint32_t)(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(uint16_t nms) { uint32_t temp = 0; while(nms) { if(nms > STEP_DELAY_MS) { SysTick->LOAD = (uint32_t)(STEP_DELAY_MS * fac_ms); nms -= STEP_DELAY_MS; } else { SysTick->LOAD = (uint32_t)(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, in seconds. * @retval none */ void delay_sec(uint16_t sec) { uint16_t index; for(index = 0; index < sec; index++) { delay_ms(500); delay_ms(500); } } /** * @} */ /** * @} */