#include "stm32f0xx.h" #include "FreeRTOSConfig.h" #include #include "stm32f0xx_hal.h" #include "cmsis_os.h" #define BAUD 57600; UART_HandleTypeDef g_huart3; volatile __IO ITStatus g_Uart3RxReady = SET; volatile __IO ITStatus g_Uart3TxReady = SET; volatile uint8_t g_Uart3RxStatus=1; volatile uint8_t g_Uart3TxStatus=1; #define BUF_LEN 5 char g_rx_buf3[BUF_LEN]; char *g_msg="BBBB\n"; void SystemClock_Config(void); void MX_GPIO_Init(void); void MX_USART3_UART_Init(void); osThreadId rxtx_pid; void rxtx_process(void const * argument); osThreadDef(rxtx, rxtx_process, osPriorityNormal, 0, 128); int main(void){ HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART3_UART_Init(); rxtx_pid = osThreadCreate(osThread(rxtx), NULL); osKernelStart(); /* We should never get here as control is now taken by the scheduler */ while (1) {} } //------------------------------------------------------ // transmit_function void transmit_function(UART_HandleTypeDef *huart, volatile __IO ITStatus *txReady, volatile uint8_t *txStatus, uint8_t *message, int msg_len) { HAL_StatusTypeDef hal_retc; if (*txReady != SET) { // wait for Tx availability osDelay(1); } *txReady=RESET; *txStatus=1; hal_retc=HAL_UART_Transmit_IT(huart, message, msg_len); if(hal_retc!=HAL_OK) { *txStatus=0; // do something with error return; } // why does this have to wait for transmit to complete? Without it, TX errors. if (*txReady != SET) { osDelay(1); } return; } //------------------------------------------------------ // set_receive void set_receive(UART_HandleTypeDef *huart, uint8_t *buf, uint16_t buf_len, volatile uint8_t *readyFlag, volatile uint8_t *statusFlag) { HAL_StatusTypeDef hal_retc; uint8_t failed=1; *readyFlag=RESET; // mark busy *statusFlag=1; while(failed) { hal_retc=HAL_UART_Receive_IT(huart, buf, buf_len); if (hal_retc != HAL_OK) { osDelay(1); } else { failed=0; } } return; } //--------------------------------------------------- // rxtx_process void rxtx_process(void const *argument) { int count=0; set_receive(&g_huart3, (uint8_t *)g_rx_buf3, BUF_LEN, &g_Uart3RxReady, &g_Uart3RxStatus); while(1) { while(g_Uart3RxReady==RESET) { // wait until for receive is done osDelay(1); if (count++ > 1000) { transmit_function(&g_huart3, &g_Uart3TxReady, &g_Uart3TxStatus, (uint8_t *)g_msg, BUF_LEN); count=0; } } if (g_Uart3RxReady==SET) { // received, echo if there wasn't an error if (g_Uart3RxStatus==1) { transmit_function(&g_huart3, &g_Uart3TxReady, &g_Uart3TxStatus, (uint8_t *)g_rx_buf3, BUF_LEN); } set_receive(&g_huart3, (uint8_t *)g_rx_buf3, BUF_LEN, &g_Uart3RxReady, &g_Uart3RxStatus); } } } void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle) { if (UartHandle->Instance==USART3) { g_Uart3TxReady = SET; } } void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance==USART3) { g_Uart3RxReady=SET; } } void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle) { char mode='t'; if((__HAL_UART_GET_IT(UartHandle, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(UartHandle, UART_IT_RXNE) != RESET)) { mode='r'; __HAL_UART_SEND_REQ(UartHandle, UART_RXDATA_FLUSH_REQUEST); __HAL_UART_CLEAR_IT(UartHandle, UART_CLEAR_OREF); } // ignore errors for now if (UartHandle->Instance==USART3) { if (mode=='r') { g_Uart3RxReady=SET; g_Uart3RxStatus=0; } else { g_Uart3TxReady=SET; g_Uart3TxStatus=0; } } return; } void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = 16; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; HAL_RCC_OscConfig(&RCC_OscInitStruct); RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0); HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } void MX_USART3_UART_Init(void) { g_huart3.Instance = USART3; g_huart3.Init.BaudRate = BAUD; g_huart3.Init.WordLength = UART_WORDLENGTH_8B; g_huart3.Init.StopBits = UART_STOPBITS_1; g_huart3.Init.Parity = UART_PARITY_NONE; g_huart3.Init.Mode = UART_MODE_TX_RX; g_huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; g_huart3.Init.OverSampling = UART_OVERSAMPLING_8; g_huart3.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ; g_huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT; HAL_UART_Init(&g_huart3); } void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __GPIOB_CLK_ENABLE(); /* set up USART3 GPIO */ GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11; GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Alternate = GPIO_AF4_USART3; GPIO_InitStruct.Pull = GPIO_PULLUP; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); } void USART3_4_IRQHandler(void) { HAL_UART_StateTypeDef uart3_state, uart4_state; uart3_state=HAL_UART_GetState(&g_huart3); if (uart3_state == HAL_UART_STATE_BUSY_TX || uart3_state == HAL_UART_STATE_BUSY_RX || uart3_state == HAL_UART_STATE_BUSY_TX_RX ) { HAL_UART_IRQHandler(&g_huart3); } } void assert_failed(uint8_t* file, uint32_t line) { while(1) {} }