# UART Wrapper Module

## Overview

The UART wrapper module provides a C++ object-oriented interface for ESP-IDF UART functionality. This module encapsulates the ESP-IDF UART driver functions and provides a clean, easy-to-use API for serial communication.

## Features

- **Multi-Port Support**: Support for UART0, UART1, and UART2
- **Configurable Parameters**: Baudrate, data bits, parity, stop bits, flow control
- **Buffer Management**: Configurable TX/RX buffer sizes
- **Timeout Support**: Configurable timeouts for read/write operations
- **Flow Control**: Hardware flow control support (RTS/CTS)
- **Error Handling**: Comprehensive error checking and logging

## Architecture

### Class Diagram

```
┌─────────────────────────────────────┐
│              Uart                   │
├─────────────────────────────────────┤
│ - m_isInitialized_[3]: bool         │
├─────────────────────────────────────┤
│ + Uart()                            │
│ + ~Uart()                           │
│ + initialize(port, config): bool    │
│ + deinitialize(port): bool          │
│ + transmit(...): int32_t            │
│ + receive(...): int32_t             │
│ + getBytesAvailable(port): int32_t  │
│ + flushTx(port): bool               │
│ + flushRx(port): bool               │
│ + setBaudrate(port, baud): bool     │
│ + isInitialized(port): bool         │
│ + getDefaultConfig(): UartConfig    │
│ - convertPort(port): uart_port_t    │
│ - convertConfig(cfg): uart_config_t │
└─────────────────────────────────────┘
```

### Enumerations

#### UartPort
- `PORT_0`: UART port 0
- `PORT_1`: UART port 1
- `PORT_2`: UART port 2

#### UartBaudrate
- `BAUD_9600`: 9600 bps
- `BAUD_19200`: 19200 bps
- `BAUD_38400`: 38400 bps
- `BAUD_57600`: 57600 bps
- `BAUD_115200`: 115200 bps
- `BAUD_230400`: 230400 bps
- `BAUD_460800`: 460800 bps
- `BAUD_921600`: 921600 bps

#### UartDataBits
- `DATA_5_BITS`: 5 data bits
- `DATA_6_BITS`: 6 data bits
- `DATA_7_BITS`: 7 data bits
- `DATA_8_BITS`: 8 data bits

#### UartParity
- `PARITY_DISABLE`: No parity
- `PARITY_EVEN`: Even parity
- `PARITY_ODD`: Odd parity

#### UartStopBits
- `STOP_BITS_1`: 1 stop bit
- `STOP_BITS_1_5`: 1.5 stop bits
- `STOP_BITS_2`: 2 stop bits

#### UartFlowControl
- `FLOW_CTRL_DISABLE`: No flow control
- `FLOW_CTRL_RTS`: RTS flow control
- `FLOW_CTRL_CTS`: CTS flow control
- `FLOW_CTRL_CTS_RTS`: RTS/CTS flow control

### Configuration Structure

```cpp
struct UartConfig {
    UartBaudrate baudrate;          // UART baudrate
    uint32_t txPin;                 // TX pin number
    uint32_t rxPin;                 // RX pin number
    uint32_t rtsPin;                // RTS pin number (optional)
    uint32_t ctsPin;                // CTS pin number (optional)
    UartDataBits dataBits;          // Number of data bits
    UartParity parity;              // Parity setting
    UartStopBits stopBits;          // Number of stop bits
    UartFlowControl flowControl;    // Flow control setting
    uint32_t rxBufferSize;          // RX buffer size
    uint32_t txBufferSize;          // TX buffer size
    uint32_t eventQueueSize;        // Event queue size
};
```

## Usage Examples

### Basic UART Communication

```cpp
#include "uart.hpp"

// Create UART instance
Uart uart;

// Get default configuration
UartConfig config = Uart::getDefaultConfig();
config.baudrate = UartBaudrate::BAUD_115200;
config.txPin = 1;
config.rxPin = 3;

// Initialize UART
uart.initialize(UartPort::PORT_0, config);

// Transmit data
const char* message = "Hello World!";
uart.transmit(UartPort::PORT_0, (uint8_t*)message, strlen(message));

// Receive data
uint8_t buffer[100];
int32_t bytesReceived = uart.receive(UartPort::PORT_0, buffer, sizeof(buffer), 1000);
```

### Advanced Configuration

```cpp
// Configure UART with flow control
UartConfig config = {};
config.baudrate = UartBaudrate::BAUD_921600;
config.txPin = 4;
config.rxPin = 5;
config.rtsPin = 18;
config.ctsPin = 19;
config.dataBits = UartDataBits::DATA_8_BITS;
config.parity = UartParity::PARITY_EVEN;
config.stopBits = UartStopBits::STOP_BITS_2;
config.flowControl = UartFlowControl::FLOW_CTRL_CTS_RTS;
config.rxBufferSize = 2048;
config.txBufferSize = 2048;

uart.initialize(UartPort::PORT_1, config);
```

### Buffer Management

```cpp
// Check available bytes
int32_t available = uart.getBytesAvailable(UartPort::PORT_0);

// Flush buffers
uart.flushRx(UartPort::PORT_0);
uart.flushTx(UartPort::PORT_0);

// Change baudrate at runtime
uart.setBaudrate(UartPort::PORT_0, UartBaudrate::BAUD_460800);
```

## API Reference

### Constructor/Destructor

- **Uart()**: Initialize UART wrapper instance
- **~Uart()**: Clean up resources and deinitialize all ports

### Configuration Methods

- **initialize(port, config)**: Initialize UART port with configuration
- **deinitialize(port)**: Deinitialize UART port
- **isInitialized(port)**: Check if port is initialized
- **getDefaultConfig()**: Get default configuration structure

### Communication Methods

- **transmit(port, data, length, timeout)**: Transmit data with timeout
- **receive(port, buffer, maxLength, timeout)**: Receive data with timeout
- **getBytesAvailable(port)**: Get number of bytes in RX buffer

### Buffer Management

- **flushTx(port)**: Flush TX buffer
- **flushRx(port)**: Flush RX buffer

### Runtime Configuration

- **setBaudrate(port, baudrate)**: Change baudrate at runtime

## Error Handling

The module provides comprehensive error handling:
- Port validation and initialization checks
- ESP-IDF error codes are caught and logged
- Return values indicate success/failure for all operations
- Detailed logging for debugging and troubleshooting

## Dependencies

- ESP-IDF UART driver (`driver/uart.h`)
- ESP-IDF error handling (`esp_err.h`)
- ESP-IDF logging (`esp_log.h`)
- FreeRTOS (`freertos/FreeRTOS.h`, `freertos/task.h`)

## Thread Safety

The UART wrapper uses ESP-IDF's thread-safe UART driver. Multiple tasks can safely use different UART ports simultaneously.

## Memory Usage

- Fixed memory footprint per instance
- Configurable buffer sizes for each port
- No dynamic memory allocation in wrapper layer

## Performance Considerations

- Direct ESP-IDF function calls for optimal performance
- Minimal overhead over raw ESP-IDF calls
- Configurable buffer sizes for throughput optimization
- Hardware flow control support for high-speed communication