| 231 | } |
| 232 | |
| 233 | static error_t open(Device* device) { |
| 234 | ESP_LOGI(TAG, "%s open", device->name); |
| 235 | if (xPortInIsrContext()) return ERROR_ISR_STATUS; |
| 236 | auto* driver_data = GET_DATA(device); |
| 237 | auto* dts_config = GET_CONFIG(device); |
| 238 | |
| 239 | lock(driver_data); |
| 240 | if (driver_data->is_open) { |
| 241 | unlock(driver_data); |
| 242 | LOG_W(TAG, "%s is already open", device->name); |
| 243 | return ERROR_INVALID_STATE; |
| 244 | } |
| 245 | |
| 246 | if (!driver_data->config_set) { |
| 247 | unlock(driver_data); |
| 248 | LOG_E(TAG, "%s open failed: config not set", device->name); |
| 249 | return ERROR_INVALID_STATE; |
| 250 | } |
| 251 | |
| 252 | esp_err_t esp_error = uart_driver_install(dts_config->port, 1024, 0, 0, NULL, 0); |
| 253 | if (esp_error != ESP_OK) { |
| 254 | LOG_E(TAG, "%s failed to install: %s", device->name, esp_err_to_name(esp_error)); |
| 255 | unlock(driver_data); |
| 256 | return esp_err_to_error(esp_error); |
| 257 | } |
| 258 | |
| 259 | uart_config_t uart_config = { |
| 260 | .baud_rate = (int)driver_data->config.baud_rate, |
| 261 | .data_bits = to_esp32_data_bits(driver_data->config.data_bits), |
| 262 | .parity = to_esp32_parity(driver_data->config.parity), |
| 263 | .stop_bits = to_esp32_stop_bits(driver_data->config.stop_bits), |
| 264 | .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, // Flow control is not yet exposed via UartConfig |
| 265 | .rx_flow_ctrl_thresh = 0, |
| 266 | .source_clk = UART_SCLK_DEFAULT, |
| 267 | .flags = { |
| 268 | .allow_pd = 0, |
| 269 | .backup_before_sleep = 0 |
| 270 | } |
| 271 | }; |
| 272 | |
| 273 | if (dts_config->pin_cts.gpio_controller != nullptr || dts_config->pin_rts.gpio_controller != nullptr) { |
| 274 | LOG_W(TAG, "%s: CTS/RTS pins are defined but hardware flow control is disabled (not supported in UartConfig)", device->name); |
| 275 | } |
| 276 | |
| 277 | esp_error = uart_param_config(dts_config->port, &uart_config); |
| 278 | if (esp_error != ESP_OK) { |
| 279 | LOG_E(TAG, "%s failed to configure: %s", device->name, esp_err_to_name(esp_error)); |
| 280 | uart_driver_delete(dts_config->port); |
| 281 | unlock(driver_data); |
| 282 | return ERROR_RESOURCE; |
| 283 | } |
| 284 | |
| 285 | // Acquire pins from the specified GPIO pin specs. Optional pins are allowed. |
| 286 | bool pins_ok = |
| 287 | acquire_pin_or_set_null(dts_config->pin_tx, &driver_data->tx_descriptor) && |
| 288 | acquire_pin_or_set_null(dts_config->pin_rx, &driver_data->rx_descriptor) && |
| 289 | acquire_pin_or_set_null(dts_config->pin_cts, &driver_data->cts_descriptor) && |
| 290 | acquire_pin_or_set_null(dts_config->pin_rts, &driver_data->rts_descriptor); |