Open FFBoard
Open source force feedback firmware
UART.cpp
Go to the documentation of this file.
1/*
2 * UART.cpp
3 *
4 * Created on: May 4, 2021
5 * Author: Yannick
6 */
7
8#include "UART.h"
9#include "semaphore.hpp"
10#include "cppmain.h"
11
12static bool operator==(const UART_InitTypeDef& lhs, const UART_InitTypeDef& rhs) {
13 return lhs.BaudRate == rhs.BaudRate &&
14 lhs.HwFlowCtl == rhs.HwFlowCtl &&
15 lhs.Mode == rhs.Mode &&
16 lhs.OverSampling == rhs.OverSampling &&
17 lhs.Parity == rhs.Parity &&
18 lhs.StopBits == rhs.StopBits &&
19 lhs.WordLength == rhs.WordLength;
20}
21
22
23/*
24 * Warning: For DMA a DMA stream must be configured in stm32cube and might conflict with other DMA streams
25 * For interrupts and interrupt must be configured and reenabled after each receive (automatic)
26 */
27UARTPort::UARTPort(UART_HandleTypeDef& huart) : huart{huart} {
28 // Do not enable the interrupt just yet.
29}
30
32
33}
34
35bool UARTPort::reconfigurePort(UART_InitTypeDef& config){
36 if(this->huart.Init == config){
37 return false;
38 }
39
40 this->huart.Init = config;
41
42 if(HAL_UART_Init(&this->huart) != HAL_OK){
43 return false;
44 }
45
46 return true;
47}
48
49UART_InitTypeDef& UARTPort::getConfig(){
50 return huart.Init;
51}
52
58 return HAL_UART_Receive_IT(&this->huart,(uint8_t*)this->uart_buf,UART_BUF_SIZE) == HAL_OK;
59}
60
61
62bool UARTPort::transmit_DMA(const char* txbuf,uint16_t size){
63 if(this->device)
64 device->startUartTransfer(this,true);
65 return HAL_UART_Transmit_DMA(&this->huart, (uint8_t*)(txbuf), size) == HAL_OK;
66 // Transfer ends in txinterrupt
67}
68
69bool UARTPort::transmit(const char* txbuf,uint16_t size,uint32_t timeout){
70 if(this->device)
71 device->startUartTransfer(this,true);
72 uint32_t status = HAL_UART_Transmit(&this->huart, (uint8_t*)(txbuf), size,timeout);
73 if(this->device)
74 device->endUartTransfer(this,true);
75 return status == HAL_OK;
76}
77
78bool UARTPort::transmit_IT(const char* txbuf,uint16_t size){
79 if(this->device)
80 device->startUartTransfer(this,true);
81 return HAL_UART_Transmit_IT(&this->huart, (uint8_t*)(txbuf), size) == HAL_OK;
82 // Transfer ends in txinterrupt
83}
84
85bool UARTPort::receive(char* rxbuf,uint16_t size,uint32_t timeout){
86 if(this->device)
87 device->startUartTransfer(this,false);
88 uint32_t status = (HAL_UART_Receive(&this->huart, (uint8_t*)(rxbuf), size, timeout));
89 if(this->device)
90 device->endUartTransfer(this,false);
91 return status == HAL_OK;
92}
93
94bool UARTPort::receive_DMA(char* rxbuf,uint16_t size){
95 if(this->device)
96 device->startUartTransfer(this,false);
97 rxbuf_t = rxbuf;
98 return(HAL_UART_Receive_DMA(&this->huart, (uint8_t*)(rxbuf), size) == HAL_OK);
99}
100
101bool UARTPort::receive_IT(char* rxbuf,uint16_t size){
102 if(this->device)
103 device->startUartTransfer(this,false);
104 rxbuf_t = rxbuf;
105 return(HAL_UART_Receive_IT(&this->huart, (uint8_t*)(rxbuf), size) == HAL_OK);
106}
107
109 if(this->device == nullptr || device == this->device){
110 this->device = device;
111 return true;
112 }
113 return false;
114}
115
117
118 uint32_t status = HAL_UART_AbortReceive(&this->huart);
119 if(device && status == HAL_OK){
120 device->endUartTransfer(this,false);
121 }
122 return status == HAL_OK;
123}
124
125UART_HandleTypeDef* UARTPort::getHuart(){
126 return &this->huart;
127}
128
130 uint32_t status = HAL_UART_AbortTransmit(&this->huart);
131 if(device && status == HAL_OK){
132 device->endUartTransfer(this,true);
133 }
134 return status == HAL_OK;
135}
136
138 if(device == this->device){
139 this->device = nullptr;
140 return true;
141 }
142 return false;
143}
144
145bool UARTPort::takeSemaphore(bool txsem,uint32_t blocktime){
147 bool isIsr = inIsr();
148 BaseType_t taskWoken = 0;
149 bool success = false;
150 if(isIsr)
151 success = sem.TakeFromISR(&taskWoken);
152 else
153 success = sem.Take(blocktime);
154 isTakenFlag = true;
155 portYIELD_FROM_ISR(taskWoken);
156 return success;
157}
158
159bool UARTPort::giveSemaphore(bool txsem){
161 bool isIsr = inIsr();
162 BaseType_t taskWoken = 0;
163 bool success = false;
164 if(isIsr)
165 success = sem.GiveFromISR(&taskWoken);
166 else
167 success = sem.Give();
168 isTakenFlag = false;
169 portYIELD_FROM_ISR(taskWoken);
170 return success;
171}
172
174 return isTakenFlag;
175}
176
178 return huart.ErrorCode;
179}
180
181
182void UARTPort::uartRxComplete(UART_HandleTypeDef *huart){
183 // Check if port matches this port
184 if(huart == &this->huart){
185 if(this->device != nullptr){
186 waitingForSingleBytes = false;
187 if(isTakenFlag)
188 device->endUartTransfer(this,false);
189 if(rxbuf_t){
191 rxbuf_t = nullptr;
192 }else{
193 device->uartRcv((char&)*this->uart_buf);
194 }
195
196 }
197 } // If started by interrupt we need to restart the interrupt transfer again by calling registerInterrupt()
198}
199
200void UARTPort::uartTxComplete(UART_HandleTypeDef *huart){
201 // Check if port matches this port
202 if(huart == &this->huart){
203 if(device){
204 device->endUartTransfer(this,true);
205 }
206 }
207}
208
209
210// UART Device
211
213
214}
215
216UARTDevice::UARTDevice(UARTPort& port) : uartport{&port}{
217 uartport->reservePort(this);
218}
219
221 uartport->freePort(this);
222}
223
224
225void UARTDevice::startUartTransfer(UARTPort* port,bool transmit){
226 port->takeSemaphore(transmit);
227}
228
229void UARTDevice::endUartTransfer(UARTPort* port,bool transmit){
230 port->giveSemaphore(transmit);
231}
232
233
static bool operator==(const UART_InitTypeDef &lhs, const UART_InitTypeDef &rhs)
Definition: UART.cpp:12
UARTPort * uartport
Definition: UART.h:85
virtual ~UARTDevice()
Definition: UART.cpp:220
virtual void endUartTransfer(UARTPort *port, bool transmit)
Definition: UART.cpp:229
virtual void uartRcv(char &buf)
Definition: UART.h:79
UARTDevice()
Definition: UART.cpp:212
virtual void startUartTransfer(UARTPort *port, bool transmit)
Definition: UART.cpp:225
Definition: UART.h:26
UART_InitTypeDef & getConfig()
Definition: UART.cpp:49
cpp_freertos::BinarySemaphore rxsemaphore
Definition: UART.h:63
bool receive(char *rxbuf, uint16_t size, uint32_t timeout=10000)
Definition: UART.cpp:85
uint32_t getErrors()
Definition: UART.cpp:177
UART_HandleTypeDef * getHuart()
Definition: UART.cpp:125
bool giveSemaphore(bool txsem=true)
Definition: UART.cpp:159
bool waitingForSingleBytes
Definition: UART.h:68
bool takeSemaphore(bool txsem=true, uint32_t blocktime=portMAX_DELAY)
Definition: UART.cpp:145
UART_HandleTypeDef & huart
Definition: UART.h:65
volatile char uart_buf[UART_BUF_SIZE]
Definition: UART.h:67
UARTDevice * device
Definition: UART.h:66
bool freePort(UARTDevice *device)
Definition: UART.cpp:137
bool reservePort(UARTDevice *device)
Definition: UART.cpp:108
char * rxbuf_t
Definition: UART.h:70
bool receive_IT(char *rxbuf, uint16_t size)
Definition: UART.cpp:101
bool transmit_IT(const char *txbuf, uint16_t size)
Definition: UART.cpp:78
bool reconfigurePort(UART_InitTypeDef &config)
Definition: UART.cpp:35
bool registerInterrupt()
Definition: UART.cpp:56
bool transmit(const char *txbuf, uint16_t size, uint32_t timeout=10000)
Definition: UART.cpp:69
bool transmit_DMA(const char *txbuf, uint16_t size)
Definition: UART.cpp:62
bool isTaken()
Definition: UART.cpp:173
bool receive_DMA(char *rxbuf, uint16_t size)
Definition: UART.cpp:94
bool isTakenFlag
Definition: UART.h:64
bool abortTransmit()
Definition: UART.cpp:129
UARTPort(UART_HandleTypeDef &huart)
Definition: UART.cpp:27
bool abortReceive()
Definition: UART.cpp:116
virtual ~UARTPort()
Definition: UART.cpp:31
cpp_freertos::BinarySemaphore semaphore
Definition: UART.h:62
void uartTxComplete(UART_HandleTypeDef *huart)
Definition: UART.cpp:200
void uartRxComplete(UART_HandleTypeDef *huart)
Definition: UART.cpp:182
bool GiveFromISR(BaseType_t *pxHigherPriorityTaskWoken)
Definition: csemaphore.cpp:76
bool TakeFromISR(BaseType_t *pxHigherPriorityTaskWoken)
Definition: csemaphore.cpp:56
bool Take(TickType_t Timeout=portMAX_DELAY)
Definition: csemaphore.cpp:46
static bool inIsr()
Definition: cppmain.h:41