Last active
October 22, 2020 18:07
-
-
Save al3xsh/3de259f2bf6802d5112fd1111a6d8ec1 to your computer and use it in GitHub Desktop.
Weird USART driver behaviour
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* app_main.c | |
* | |
* this is where we create the main rtos application thread and kick everything | |
* off | |
* | |
* author: Dr. Alex Shenfield | |
* date: 22/10/2020 | |
* purpose: 55-604481 embedded computer networks - lab 103 | |
*/ | |
// include the c standard io library | |
#include <stdio.h> | |
// include the basic headers for the hal drivers and cmsis-rtos2 | |
#include "stm32f7xx_hal.h" | |
#include "cmsis_os2.h" | |
// include the CMSIS Driver for code for the USART | |
#include "Driver_USART.h" | |
// USART DEFINES | |
// we are using usart 1 which is defined elsewhere and enabling an event flag | |
// for notification of usart events | |
extern ARM_DRIVER_USART Driver_USART1; | |
osEventFlagsId_t usart_flag; | |
static const osEventFlagsAttr_t usart_flag_attr = | |
{ | |
.name = "USART_event", | |
}; | |
// USART CALLBACK HANDLER | |
// this is the callback which is triggered when a usrat event occurs | |
void my_usart_callback(uint32_t event) | |
{ | |
// these are what we consider a success ... | |
uint32_t success_mask = ARM_USART_EVENT_RECEIVE_COMPLETE | | |
ARM_USART_EVENT_TRANSFER_COMPLETE | | |
ARM_USART_EVENT_SEND_COMPLETE | | |
ARM_USART_EVENT_TX_COMPLETE ; | |
// if our usart transaction was a success | |
if(event & success_mask) | |
{ | |
// adding this short stall here stops the usart_driver->Receive code | |
// misbehaving | |
for(int i = 0; i < 100000; i++) | |
{ | |
__nop(); | |
} | |
osEventFlagsSet(usart_flag, 0x01); | |
} | |
// error handling (todo: add some proper error handling code - maybe a red | |
// led?) | |
// timeout error | |
if(event & ARM_USART_EVENT_RX_TIMEOUT) | |
{ | |
//__breakpoint(0); | |
} | |
// rx overflow / tx underflow error | |
if(event & (ARM_USART_EVENT_RX_OVERFLOW | ARM_USART_EVENT_TX_UNDERFLOW)) | |
{ | |
__breakpoint(0); | |
} | |
} | |
// WORKER THREAD | |
// uart terminal thread | |
osThreadId_t usart_thread; | |
static const osThreadAttr_t usart_thread_attr = | |
{ | |
.name = "usart_terminal", | |
.priority = osPriorityNormal, | |
}; | |
void my_usart_thread(void *argument) | |
{ | |
// get a pointer to the usart driver object | |
static ARM_DRIVER_USART * usart_driver = &Driver_USART1; | |
// initialise and configure the usart driver (running at 9600bps) | |
usart_driver->Initialize(my_usart_callback); | |
usart_driver->PowerControl(ARM_POWER_FULL); | |
usart_driver->Control(ARM_USART_MODE_ASYNCHRONOUS | | |
ARM_USART_DATA_BITS_8 | | |
ARM_USART_PARITY_NONE | | |
ARM_USART_STOP_BITS_1 | | |
ARM_USART_FLOW_CONTROL_NONE, 9600); | |
// set up rx and tx lines | |
usart_driver->Control(ARM_USART_CONTROL_TX, 1); | |
usart_driver->Control(ARM_USART_CONTROL_RX, 1); | |
// print a status message | |
usart_driver->Send("we are alive ...\r\n", 19); | |
// wait for the usart_flag event flag (i.e. we have been successful) | |
osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever); | |
while(1) | |
{ | |
// weirdly, if you don't reset the cmd character to zero the usart_driver | |
// doesn't overwrite it - it just seems to breeze through the | |
// "usart_driver->Receive()" operation and the osEventFlagsWait | |
char cmd; // = 0; | |
usart_driver->Receive(&cmd, 1); | |
osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever); | |
if(cmd == 13) | |
{ | |
usart_driver->Send("Hello World!\r\n", 15); | |
osEventFlagsWait(usart_flag, 0x01, osFlagsWaitAny, osWaitForever); | |
} | |
} | |
} | |
// APPLICATION MAIN THREAD | |
// provide an increased stack size to the main application thread (to help deal | |
// with the uart printf redirection) | |
static const osThreadAttr_t app_main_attr = | |
{ | |
.stack_size = 8192U | |
}; | |
// application main thread - initialise general peripherals, create the event | |
// flag for uart events, and start the worker thread | |
void app_main(void *argument) | |
{ | |
// create the usrat event flag | |
usart_flag = osEventFlagsNew(&usart_flag_attr); | |
// create the thread | |
usart_thread = osThreadNew(my_usart_thread, NULL, &usart_thread_attr); | |
} | |
// initialise the application (by creating the main thread) | |
void app_initialise(void) | |
{ | |
osThreadNew(app_main, NULL, &app_main_attr); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment