/* * usart.c * * Created on: Jun 23, 2023 * Author: true */ #include "hk32f030m.h" #include "usart.h" #include #define BAUDRATE 115200 #define USART_DEVICE USART1 #define USART_TX_GPIO_CLK RCC_AHBPeriph_GPIOD #define USART_TX_PORT GPIOD #define USART_TX_PIN 1 #define USART_TX_PINSRC GPIO_PinSource1 #define USART_RX_GPIO_CLK RCC_AHBPeriph_GPIOB #define USART_RX_PORT GPIOB #define USART_RX_PIN 4 #define USART_RX_PINSRC GPIO_PinSource4 // inefficient, but we have time and space #define RX_BUF_LEN 1040 uint8_t rxbuf[RX_BUF_LEN]; uint16_t rxptr = 0; uint16_t rxlen = 0; /** * @brief Initializes USART peripheral at fixed baud rate. */ void comm_init() { // enable GPIO clock // RCC_AHBPeriphClockCmd(USART_TX_GPIO_CLK | USART_RX_GPIO_CLK, ENABLE); // attach USART peripheral to pins // GPIO_PinAFConfig(USART_TX_PORT, USART_TX_PINSRC, GPIO_AF_1); // GPIO_PinAFConfig(USART_RX_PORT, USART_RX_PINSRC, GPIO_AF_1); GPIOB->AFR[0] = 0x00010000; GPIOD->AFR[0] = 0x00000010; /* these have been configured in user_io.c to save space USART_RX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_RX_PIN); USART_RX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_RX_PIN); // alt function USART_TX_PORT->MODER &= ~(GPIO_MODER_MODER0 << 2 * USART_TX_PIN); USART_TX_PORT->OTYPER &= ~(GPIO_OTYPER_OT_0 << USART_TX_PIN); // push pull USART_TX_PORT->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEEDR0 << 2 * USART_TX_PIN); // slow USART_TX_PORT->MODER |= (GPIO_Mode_AF << 2 * USART_TX_PIN); // alt function */ // enable USART clock // RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // configure USART peripheral manually // we do this as the library bloats flash space (division, verbose, ...) USART1->CR1 = 0; // disable USART USART1->CR2 = 0; // 1 stop bit USART1->CR3 = 0; USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx; // 8 bits, no parity, tx/rx enabled USART1->BRR = 0x45; // 115200 baud rate @8MHz (per datasheet) // enable USART USART1->CR1 = USART_Mode_Rx | USART_Mode_Tx | USART_CR1_UE; } /** * @brief Receives data from USART in a polling manner. * @param *data: Array to save the received data. * @param length: Size of the data. * @return status: Report about the success of the receiving. */ BL_comm_status comm_rx(uint8_t *data, uint16_t length) { uint16_t i; uint16_t timeout; for (i = 0; i < length; i++) { timeout = COMM_TIMEOUT; while (!(USART1->ISR & USART_ISR_RXNE) && timeout) { timeout--; } if (timeout) { // we didn't time out and now there is new data waiting for us data[i] = USART1->RDR; } else { // no data returned in time return COMM_ERROR; } } return COMM_OK; } /** * @brief Transmits a single char to UART. * @param *data: The char. * @return status: Report about the success of the transmission. */ BL_comm_status comm_tx_byte(uint8_t data) { USART_SendData(USART1, data); while (!(USART1->ISR & USART_ISR_TXE)); return COMM_OK; } /** * @brief Transmits a null-terminated string over USART. * @param *data: String array. * @return status: Report about the success of the transmission. */ BL_comm_status comm_tx_str(char *data) { uint8_t i; uint16_t len = 0; len = strlen((const char *)data); for (i = 0; i < len; i++) { comm_tx_byte(data[i]); } while (!(USART1->ISR & USART_ISR_TC)); return COMM_OK; }