The BaseUart class provides a comprehensive UART abstraction that serves as the unified interface
for all Universal Asynchronous Receiver-Transmitter operations in the HardFOC system.
It supports configurable baud rates, data formats, and flow control.
β¨ Key Features
π‘ Configurable Baud Rates - Support for standard and custom baud rates
π§ Flexible Data Formats - Configurable data bits, stop bits, and parity
π Flow Control - Hardware and software flow control support
π DMA Support - Hardware-accelerated data transfer
π‘οΈ Robust Error Handling - Comprehensive validation and error reporting
ποΈ Performance Optimized - Minimal overhead for critical applications
π Platform Agnostic - Works with various UART hardware implementations
π Real-time Control - Low-latency communication for time-critical applications
/**
* @brief Transmit data
* @param data Data buffer to transmit
* @param length Number of bytes to transmit
* @return hf_uart_err_t error code
*
* π€ Transmits data over UART. Blocks until transmission is complete
* or timeout occurs.
*
* @example
* const char* message = "Hello, World!\r\n";
* hf_uart_err_t result = uart.Transmit(
* reinterpret_cast<const uint8_t*>(message), strlen(message));
* if (result == hf_uart_err_t::UART_SUCCESS) {
* printf("β Message transmitted\n");
* }
*/virtualhf_uart_err_tTransmit(constuint8_t*data,size_tlength)noexcept=0;/**
* @brief Transmit data with timeout
* @param data Data buffer to transmit
* @param length Number of bytes to transmit
* @param timeout_ms Timeout in milliseconds
* @return hf_uart_err_t error code
*
* π€ Transmits data with specified timeout.
*/virtualhf_uart_err_tTransmit(constuint8_t*data,size_tlength,uint32_ttimeout_ms)noexcept=0;/**
* @brief Get number of bytes available for transmission
* @return Number of bytes that can be transmitted
*
* π Returns the number of bytes that can be transmitted without blocking.
*/virtualsize_tGetTransmitSpace()constnoexcept=0;
/**
* @brief Receive data
* @param data Buffer to store received data
* @param length Number of bytes to receive
* @return hf_uart_err_t error code
*
* π₯ Receives data from UART. Blocks until requested number of bytes
* is received or timeout occurs.
*
* @example
* uint8_t buffer[64];
* hf_uart_err_t result = uart.Receive(buffer, 64);
* if (result == hf_uart_err_t::UART_SUCCESS) {
* printf("π₯ Received %zu bytes\n", 64);
* }
*/virtualhf_uart_err_tReceive(uint8_t*data,size_tlength)noexcept=0;/**
* @brief Receive data with timeout
* @param data Buffer to store received data
* @param length Number of bytes to receive
* @param timeout_ms Timeout in milliseconds
* @return hf_uart_err_t error code
*
* π₯ Receives data with specified timeout.
*/virtualhf_uart_err_tReceive(uint8_t*data,size_tlength,uint32_ttimeout_ms)noexcept=0;/**
* @brief Get number of bytes available for reception
* @return Number of bytes available to receive
*
* π Returns the number of bytes available to receive without blocking.
*/virtualsize_tGetReceiveSpace()constnoexcept=0;/**
* @brief Flush receive buffer
* @return hf_uart_err_t error code
*
* π§Ή Clears all data in the receive buffer.
*/virtualhf_uart_err_tFlushReceive()noexcept=0;
π Status and Capabilities
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* @brief Get UART status information
* @param status [out] Status information structure
* @return hf_uart_err_t error code
*
* π Retrieves comprehensive status information about UART.
*/virtualhf_uart_err_tGetStatus(hf_uart_status_t&status)constnoexcept=0;/**
* @brief Get UART capabilities
* @param capabilities [out] Capability information structure
* @return hf_uart_err_t error code
*
* π Retrieves hardware capabilities and limitations.
*/virtualhf_uart_err_tGetCapabilities(hf_uart_capabilities_t&capabilities)constnoexcept=0;
π Data Structures
βοΈ UART Configuration
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
structhf_uart_config_t{uint32_tbaud_rate;///< Baud rate in bits per secondhf_uart_data_bits_tdata_bits;///< Number of data bitshf_uart_stop_bits_tstop_bits;///< Number of stop bitshf_uart_parity_tparity;///< Parity settinghf_uart_flow_control_tflow_control;///< Flow control settinghf_pin_num_ttx_pin;///< Transmit pinhf_pin_num_trx_pin;///< Receive pinhf_pin_num_trts_pin;///< RTS pin (-1 if not used)hf_pin_num_tcts_pin;///< CTS pin (-1 if not used)uint32_ttimeout_ms;///< Default timeout in millisecondsbooluse_dma;///< Use DMA for transferssize_trx_buffer_size;///< Receive buffer sizesize_ttx_buffer_size;///< Transmit buffer size};
π UART Status
1
2
3
4
5
6
7
8
9
10
11
structhf_uart_status_t{boolis_initialized;///< UART is initializedboolis_configured;///< UART is configureduint32_tcurrent_baud_rate;///< Current baud ratesize_trx_bytes_available;///< Bytes available to receivesize_ttx_space_available;///< Space available for transmissionuint32_trx_errors;///< Number of receive errorsuint32_ttx_errors;///< Number of transmit errorshf_uart_err_tlast_error;///< Last error that occurreduint32_ttimestamp_us;///< Timestamp of last operation};
π UART Capabilities
1
2
3
4
5
6
7
8
9
10
11
12
structhf_uart_capabilities_t{uint8_tmax_ports;///< Maximum number of UART portsuint32_tmin_baud_rate;///< Minimum baud rateuint32_tmax_baud_rate;///< Maximum baud rateuint8_tsupported_data_bits;///< Bit mask of supported data bitsuint8_tsupported_stop_bits;///< Bit mask of supported stop bitsuint8_tsupported_parity;///< Bit mask of supported parityboolsupports_flow_control;///< Supports hardware flow controlboolsupports_dma;///< Supports DMA transferssize_tmax_buffer_size;///< Maximum buffer sizeuint32_tmax_timeout_ms;///< Maximum timeout value};
π UART Statistics
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
structhf_uart_statistics_t{uint32_ttotal_transmissions;///< Total transmissions performeduint32_tsuccessful_transmissions;///< Successful transmissionsuint32_tfailed_transmissions;///< Failed transmissionsuint32_ttotal_receptions;///< Total receptions performeduint32_tsuccessful_receptions;///< Successful receptionsuint32_tfailed_receptions;///< Failed receptionsuint32_tbytes_transmitted;///< Total bytes transmitteduint32_tbytes_received;///< Total bytes receiveduint32_tframe_errors;///< Number of frame errorsuint32_tparity_errors;///< Number of parity errorsuint32_tbuffer_overflows;///< Number of buffer overflowsuint32_taverage_transmit_time_us;///< Average transmit timeuint32_tmax_transmit_time_us;///< Maximum transmit timeuint32_tmin_transmit_time_us;///< Minimum transmit time};
#include"mcu/esp32/EspUart.h"classGpsController{private:EspUartuart*;staticconstexprsize_tGPS_BUFFER_SIZE=512;chargps_buffer*[GPS_BUFFER_SIZE];public:boolinitialize(){uart*=EspUart(UART_NUM_1);if(!uart*.EnsureInitialized()){returnfalse;}// Configure for GPS communicationhf_uart_config_tconfig;config.baud_rate=9600;// Standard GPS baud rateconfig.data_bits=hf_uart_data_bits_t::DATA_8BIT;config.stop_bits=hf_uart_stop_bits_t::STOP_1BIT;config.parity=hf_uart_parity_t::PARITY_NONE;config.flow_control=hf_uart_flow_control_t::FLOW_NONE;config.tx_pin=17;// GPS TXconfig.rx_pin=16;// GPS RXconfig.rts_pin=-1;config.cts_pin=-1;config.timeout_ms=5000;// 5 second timeoutconfig.use_dma=false;config.rx_buffer_size=GPS_BUFFER_SIZE;config.tx_buffer_size=256;hf_uart_err_tresult=uart*.Configure(config);if(result!=hf_uart_err_t::UART_SUCCESS){printf("β GPS configuration failed\n");returnfalse;}printf("β GPS controller initialized\n");returntrue;}boolread_gps_data(){// Read GPS data with timeouthf_uart_err_tresult=uart*.Receive(reinterpret_cast<uint8_t*>(gps_buffer*),GPS_BUFFER_SIZE-1,1000);if(result==hf_uart_err_t::UART_SUCCESS){gps_buffer*[GPS_BUFFER_SIZE-1]='\0';// Parse NMEA sentencesparse_nmea_data(gps_buffer*);returntrue;}elseif(result==hf_uart_err_t::UART_ERR_RECEIVE_TIMEOUT){printf("β° GPS timeout - no data received\n");returnfalse;}else{printf("β GPS read failed: %s\n",HfUartErrToString(result));returnfalse;}}private:voidparse_nmea_data(constchar*data){// Simple NMEA parser - look for GPRMC sentenceschar*line=strtok(const_cast<char*>(data),"\r\n");while(line!=nullptr){if(strncmp(line,"$GPRMC",6)==0){parse_gprmc(line);}elseif(strncmp(line,"$GPGGA",6)==0){parse_gpgga(line);}line=strtok(nullptr,"\r\n");}}voidparse_gprmc(constchar*sentence){// Parse GPRMC sentence for time, date, position, speedprintf("π GPRMC: %s\n",sentence);// Add actual parsing logic here}voidparse_gpgga(constchar*sentence){// Parse GPGGA sentence for position and altitudeprintf("π GPGGA: %s\n",sentence);// Add actual parsing logic here}public:voidsend_gps_command(constchar*command){// Send command to GPS modulesize_tlength=strlen(command);hf_uart_err_tresult=uart*.Transmit(reinterpret_cast<constuint8_t*>(command),length);if(result==hf_uart_err_t::UART_SUCCESS){printf("π€ GPS Command: %s",command);}else{printf("β GPS command failed: %s\n",HfUartErrToString(result));}}voidgps_monitoring_task(){printf("πΊοΈ Starting GPS monitoring...\n");while(true){if(read_gps_data()){// Data received and parsedvTaskDelay(pdMS_TO_TICKS(100));}else{// No data or errorvTaskDelay(pdMS_TO_TICKS(1000));}}}};
#include"mcu/esp32/EspUart.h"classBluetoothController{private:EspUartuart*;staticconstexprsize_tBT_BUFFER_SIZE=1024;charbt_buffer*[BT_BUFFER_SIZE];public:boolinitialize(){uart*=EspUart(UART_NUM_2);if(!uart*.EnsureInitialized()){returnfalse;}// Configure for Bluetooth communicationhf_uart_config_tconfig;config.baud_rate=115200;// Standard BT baud rateconfig.data_bits=hf_uart_data_bits_t::DATA_8BIT;config.stop_bits=hf_uart_stop_bits_t::STOP_1BIT;config.parity=hf_uart_parity_t::PARITY_NONE;config.flow_control=hf_uart_flow_control_t::FLOW_NONE;config.tx_pin=25;// BT TXconfig.rx_pin=26;// BT RXconfig.rts_pin=-1;config.cts_pin=-1;config.timeout_ms=1000;config.use_dma=true;// Use DMA for BTconfig.rx_buffer_size=BT_BUFFER_SIZE;config.tx_buffer_size=BT_BUFFER_SIZE;hf_uart_err_tresult=uart*.Configure(config);if(result!=hf_uart_err_t::UART_SUCCESS){printf("β Bluetooth configuration failed\n");returnfalse;}printf("β Bluetooth controller initialized\n");returntrue;}voidsend_data(constchar*data){size_tlength=strlen(data);hf_uart_err_tresult=uart*.Transmit(reinterpret_cast<constuint8_t*>(data),length);if(result==hf_uart_err_t::UART_SUCCESS){printf("π€ BT Sent: %s",data);}else{printf("β BT send failed: %s\n",HfUartErrToString(result));}}boolreceive_data(char*buffer,size_tmax_length){hf_uart_err_tresult=uart*.Receive(reinterpret_cast<uint8_t*>(buffer),max_length-1,100);if(result==hf_uart_err_t::UART_SUCCESS){buffer[max_length-1]='\0';printf("π₯ BT Received: %s",buffer);returntrue;}elseif(result==hf_uart_err_t::UART_ERR_RECEIVE_TIMEOUT){returnfalse;// No data available}else{printf("β BT receive failed: %s\n",HfUartErrToString(result));returnfalse;}}voidbluetooth_chat_task(){printf("π΅ Starting Bluetooth chat...\n");charinput_buffer[256];charoutput_buffer[256];while(true){// Check for incoming dataif(receive_data(input_buffer,sizeof(input_buffer))){// Process received datasnprintf(output_buffer,sizeof(output_buffer),"Echo: %s",input_buffer);send_data(output_buffer);}// Check for local input (simulated)if(/* local input available */){snprintf(output_buffer,sizeof(output_buffer),"Local: Hello from ESP32!\n");send_data(output_buffer);}vTaskDelay(pdMS_TO_TICKS(100));}}};
// β Always check initializationif(!uart.EnsureInitialized()){printf("β UART initialization failed\n");returnfalse;}// β Use appropriate baud rates// Debug: 115200// GPS: 9600// Bluetooth: 115200// Modbus: 9600-115200// β Handle timeouts gracefullyhf_uart_err_tresult=uart.Receive(buffer,length,1000);if(result==hf_uart_err_t::UART_ERR_RECEIVE_TIMEOUT){printf("β° No data received within timeout\n");returnfalse;}// β Check buffer space before operationsif(uart.GetReceiveSpace()>0){// Data available to receive}if(uart.GetTransmitSpace()>=length){// Space available to transmit}// β Use appropriate data formats// Most applications: 8N1 (8 data bits, no parity, 1 stop bit)// Modbus: 8E1 (8 data bits, even parity, 1 stop bit)// β Monitor statistics for system healthhf_uart_statistics_tstats;if(uart.GetStatistics(stats)==hf_uart_err_t::UART_SUCCESS){if(stats.frame_errors>10){printf("β οΈ High frame error rate detected\n");}}
β Common Pitfalls
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// β Don't ignore initializationuart.Transmit(data,length);// May fail silently// β Don't use mismatched baud rates// Both devices must use the same baud rate// β Don't ignore buffer overflows// Check buffer space before large transfers// β Don't use without error checking in critical applications// Always check return values in safety-critical systems// β Don't forget to handle flow control// Some devices require hardware flow control// β Don't assume all data formats are supported// Check capabilities before using specific formats
π― Performance Optimization
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// π Use DMA for large transfersconfig.use_dma=(transfer_size>64);// Use DMA for transfers > 64 bytes// π Use appropriate buffer sizes// Small buffers: Lower memory usage, more frequent interrupts// Large buffers: Higher memory usage, fewer interrupts// π Minimize timeout values// Short timeouts for fast devices// Longer timeouts for slow devices// π Use appropriate baud rates// Higher baud rate = faster communication but may cause errors// π Batch operations when possible// Send multiple commands in one transfer// π Use flow control when needed// Prevents buffer overflows in high-speed communication