/* * usart.c * * Created on: Dec 6, 2017 * Author: maximilian */ #include "usart.h" #include "stm32f10x_gpio.h" #include "stm32f10x_usart.h" #include "porting.h" static uint8_t tx_overflow = 0; static osQUEUE_t usart_rx_q, usart_tx_q; static uint8_t usart_rx_data[USART_QUEUE_SIZE]; static uint8_t usart_tx_data[USART_QUEUE_SIZE]; void usart2Init(void) { /* Enable clocks. */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOA , ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); /* Initialize used GPIOs. */ GPIO_InitTypeDef GPIO_InitStruct; GPIO_StructInit(&GPIO_InitStruct); /* Initialize USART2_TX */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); /* Init. USART2_RX */ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStruct); /* Init. USART2 peripheral. */ USART_InitTypeDef USART_InitStructure ; USART_StructInit(&USART_InitStructure ); USART_InitStructure.USART_BaudRate = 230400; USART_InitStructure.USART_WordLength = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_Init(USART2, &USART_InitStructure); USART_Cmd(USART2, ENABLE); /* Config. interrupts. */ USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); NVIC_EnableIRQ(USART2_IRQn); /* Init. SW queues. */ osQInit(&usart_rx_q, sizeof(uint8_t), USART_QUEUE_SIZE, usart_rx_data); osQInit(&usart_tx_q, sizeof(uint8_t), USART_QUEUE_SIZE, usart_tx_data); } void USART2_IRQHandler(void) { /* USART2 receive buffer contains a char. */ if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET) { uint8_t data; data = USART_ReceiveData(USART2) & 0xFF; if(!osEnqueue(&usart_rx_q, (void*)&data)) THROW_ERROR(E_USART_RX_BUFFER_OVERLOW); } /* USART2 transmit buffer empty. */ if(USART_GetITStatus(USART2, USART_IT_TXE) == SET) { uint8_t data; if(osDequeue(&usart_tx_q, &data)) USART_SendData(USART2, data); else { /* Nothing to send. Disable interrupt. */ USART_ITConfig(USART2, USART_IT_TXE, DISABLE); tx_overflow = 0; } } } static uint8_t usart2PutChar(uint8_t data) { /* Signal, that the buffer has overflowed. */ if(tx_overflow) return 0; /* Put data in the q. */ if(!osEnqueue(&usart_tx_q, (void*)&data)) { tx_overflow = 1; return 0; } /* Enable interrupt. */ USART_ITConfig(USART2, USART_IT_TXE, ENABLE); return 1; } static uint8_t usart2GetChar(void) { uint8_t data; /* Wait until data arrives. */ while(!osDequeue(&usart_rx_q, &data)){} return data; } uint8_t usart2PutString(uint8_t* word, size_t size) { /* Push data as long as it needs that it comes through. */ for(uint8_t i=0; i