/** ************************************************************************** * @file at32f435_437_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 "at32f435_437_board.h" /** @addtogroup AT32F435_437_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, ch); return ch; } #if defined (__GNUC__) && !defined (__clang__) int _write(int fd, char *pbuffer, int size) { for(int i = 0; i < size; i ++) { __io_putchar(*pbuffer++); } 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(); } /** * @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 = USER_BUTTON_PIN; gpio_init_struct.gpio_pull = GPIO_PULL_DOWN; 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); } } /** * @} */ /** * @} */