| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "esp32-hal-uart.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | #include "esp32-hal.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/task.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | #include "freertos/queue.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | #include "freertos/semphr.h"
 | 
					
						
							|  |  |  | #include "rom/ets_sys.h"
 | 
					
						
							|  |  |  | #include "esp_attr.h"
 | 
					
						
							|  |  |  | #include "esp_intr.h"
 | 
					
						
							|  |  |  | #include "rom/uart.h"
 | 
					
						
							|  |  |  | #include "soc/uart_reg.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | #include "soc/uart_struct.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | #include "soc/io_mux_reg.h"
 | 
					
						
							|  |  |  | #include "soc/gpio_sig_map.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-10 20:24:41 +03:00
										 |  |  | #include "soc/dport_reg.h"
 | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  | #include "soc/rtc.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  | #include "esp_intr_alloc.h"
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define UART_REG_BASE(u)    ((u==0)?DR_REG_UART_BASE:(      (u==1)?DR_REG_UART1_BASE:(    (u==2)?DR_REG_UART2_BASE:0)))
 | 
					
						
							|  |  |  | #define UART_RXD_IDX(u)     ((u==0)?U0RXD_IN_IDX:(          (u==1)?U1RXD_IN_IDX:(         (u==2)?U2RXD_IN_IDX:0)))
 | 
					
						
							|  |  |  | #define UART_TXD_IDX(u)     ((u==0)?U0TXD_OUT_IDX:(         (u==1)?U1TXD_OUT_IDX:(        (u==2)?U2TXD_OUT_IDX:0)))
 | 
					
						
							|  |  |  | #define UART_INTR_SOURCE(u) ((u==0)?ETS_UART0_INTR_SOURCE:( (u==1)?ETS_UART1_INTR_SOURCE:((u==2)?ETS_UART2_INTR_SOURCE:0)))
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int s_uart_debug_nr = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | struct uart_struct_t { | 
					
						
							|  |  |  |     uart_dev_t * dev; | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #if !CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     xSemaphoreHandle lock; | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uint8_t num; | 
					
						
							|  |  |  |     xQueueHandle queue; | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  |     intr_handle_t intr_handle; | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #if CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							|  |  |  | #define UART_MUTEX_LOCK()
 | 
					
						
							|  |  |  | #define UART_MUTEX_UNLOCK()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static uart_t _uart_bus_array[3] = { | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  |     {(volatile uart_dev_t *)(DR_REG_UART_BASE), 0, NULL, NULL}, | 
					
						
							|  |  |  |     {(volatile uart_dev_t *)(DR_REG_UART1_BASE), 1, NULL, NULL}, | 
					
						
							|  |  |  |     {(volatile uart_dev_t *)(DR_REG_UART2_BASE), 2, NULL, NULL} | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | }; | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  | #define UART_MUTEX_LOCK()    do {} while (xSemaphoreTake(uart->lock, portMAX_DELAY) != pdPASS)
 | 
					
						
							|  |  |  | #define UART_MUTEX_UNLOCK()  xSemaphoreGive(uart->lock)
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | static uart_t _uart_bus_array[3] = { | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  |     {(volatile uart_dev_t *)(DR_REG_UART_BASE), NULL, 0, NULL, NULL}, | 
					
						
							|  |  |  |     {(volatile uart_dev_t *)(DR_REG_UART1_BASE), NULL, 1, NULL, NULL}, | 
					
						
							|  |  |  |     {(volatile uart_dev_t *)(DR_REG_UART2_BASE), NULL, 2, NULL, NULL} | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  | static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | static void IRAM_ATTR _uart_isr(void *arg) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uint8_t i, c; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     BaseType_t xHigherPriorityTaskWoken; | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uart_t* uart; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(i=0;i<3;i++){ | 
					
						
							|  |  |  |         uart = &_uart_bus_array[i]; | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  |         if(uart->intr_handle == NULL){ | 
					
						
							|  |  |  |             continue; | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |         uart->dev->int_clr.rxfifo_full = 1; | 
					
						
							|  |  |  |         uart->dev->int_clr.frm_err = 1; | 
					
						
							|  |  |  |         uart->dev->int_clr.rxfifo_tout = 1; | 
					
						
							| 
									
										
										
										
											2018-09-17 22:19:51 +03:00
										 |  |  |         while(uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |             c = uart->dev->fifo.rw_byte; | 
					
						
							| 
									
										
										
										
											2020-05-05 16:55:58 +02:00
										 |  |  |             if(uart->queue != NULL)  { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |                 xQueueSendFromISR(uart->queue, &c, &xHigherPriorityTaskWoken); | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (xHigherPriorityTaskWoken) { | 
					
						
							|  |  |  |         portYIELD_FROM_ISR(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | void uartEnableInterrupt(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uart->dev->conf1.rxfifo_full_thrhd = 112; | 
					
						
							|  |  |  |     uart->dev->conf1.rx_tout_thrhd = 2; | 
					
						
							|  |  |  |     uart->dev->conf1.rx_tout_en = 1; | 
					
						
							|  |  |  |     uart->dev->int_ena.rxfifo_full = 1; | 
					
						
							|  |  |  |     uart->dev->int_ena.frm_err = 1; | 
					
						
							|  |  |  |     uart->dev->int_ena.rxfifo_tout = 1; | 
					
						
							|  |  |  |     uart->dev->int_clr.val = 0xffffffff; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  |     esp_intr_alloc(UART_INTR_SOURCE(uart->num), (int)ESP_INTR_FLAG_IRAM, _uart_isr, NULL, &uart->intr_handle); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartDisableInterrupt(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uart->dev->conf1.val = 0; | 
					
						
							|  |  |  |     uart->dev->int_ena.val = 0; | 
					
						
							|  |  |  |     uart->dev->int_clr.val = 0xffffffff; | 
					
						
							| 
									
										
										
										
											2017-09-27 13:50:05 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     esp_intr_free(uart->intr_handle); | 
					
						
							|  |  |  |     uart->intr_handle = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  | void uartDetachRx(uart_t* uart, uint8_t rxPin) | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  |     pinMatrixInDetach(rxPin, false, false); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uartDisableInterrupt(uart); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  | void uartDetachTx(uart_t* uart, uint8_t txPin) | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  |     pinMatrixOutDetach(txPin, false, false); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | void uartAttachRx(uart_t* uart, uint8_t rxPin, bool inverted) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL || rxPin > 39) { | 
					
						
							|  |  |  |         return; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     pinMode(rxPin, INPUT); | 
					
						
							|  |  |  |     pinMatrixInAttach(rxPin, UART_RXD_IDX(uart->num), inverted); | 
					
						
							|  |  |  |     uartEnableInterrupt(uart); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | void uartAttachTx(uart_t* uart, uint8_t txPin, bool inverted) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL || txPin > 39) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pinMode(txPin, OUTPUT); | 
					
						
							|  |  |  |     pinMatrixOutAttach(txPin, UART_TXD_IDX(uart->num), inverted, false); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | uart_t* uartBegin(uint8_t uart_nr, uint32_t baudrate, uint32_t config, int8_t rxPin, int8_t txPin, uint16_t queueLen, bool inverted) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(uart_nr > 2) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(rxPin == -1 && txPin == -1) { | 
					
						
							|  |  |  |         return NULL; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uart_t* uart = &_uart_bus_array[uart_nr]; | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #if !CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     if(uart->lock == NULL) { | 
					
						
							|  |  |  |         uart->lock = xSemaphoreCreateMutex(); | 
					
						
							|  |  |  |         if(uart->lock == NULL) { | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(queueLen && uart->queue == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         uart->queue = xQueueCreate(queueLen, sizeof(uint8_t)); //initialize the queue
 | 
					
						
							|  |  |  |         if(uart->queue == NULL) { | 
					
						
							|  |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-09-10 20:24:41 +03:00
										 |  |  |     if(uart_nr == 1){ | 
					
						
							|  |  |  |         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN); | 
					
						
							|  |  |  |         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST); | 
					
						
							|  |  |  |     } else if(uart_nr == 2){ | 
					
						
							|  |  |  |         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN); | 
					
						
							|  |  |  |         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST); | 
					
						
							| 
									
										
										
										
											2017-09-22 14:17:25 +08:00
										 |  |  |     } else { | 
					
						
							|  |  |  |         DPORT_SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN); | 
					
						
							|  |  |  |         DPORT_CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST); | 
					
						
							| 
									
										
										
										
											2017-09-10 20:24:41 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uartFlush(uart); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uartSetBaudRate(uart, baudrate); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uart->dev->conf0.val = config; | 
					
						
							| 
									
										
										
										
											2017-06-22 12:40:31 -05:00
										 |  |  |     #define TWO_STOP_BITS_CONF 0x3
 | 
					
						
							|  |  |  |     #define ONE_STOP_BITS_CONF 0x1
 | 
					
						
							| 
									
										
										
										
											2017-08-04 14:30:51 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-06-22 12:40:31 -05:00
										 |  |  |     if ( uart->dev->conf0.stop_bit_num == TWO_STOP_BITS_CONF) { | 
					
						
							|  |  |  |         uart->dev->conf0.stop_bit_num = ONE_STOP_BITS_CONF; | 
					
						
							|  |  |  |         uart->dev->rs485_conf.dl1_en = 1; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // tx_idle_num : idle interval after tx FIFO is empty(unit: the time it takes to send one bit under current baudrate)
 | 
					
						
							|  |  |  |     // Setting it to 0 prevents line idle time/delays when sending messages with small intervals
 | 
					
						
							|  |  |  |     uart->dev->idle_conf.tx_idle_num = 0;  //
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if(rxPin != -1) { | 
					
						
							|  |  |  |         uartAttachRx(uart, rxPin, inverted); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(txPin != -1) { | 
					
						
							|  |  |  |         uartAttachTx(uart, txPin, inverted); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |     addApbChangeCallback(uart, uart_on_apb_change); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     return uart; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  | void uartEnd(uart_t* uart, uint8_t txPin, uint8_t rxPin) | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |     removeApbChangeCallback(uart, uart_on_apb_change); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart->queue != NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         vQueueDelete(uart->queue); | 
					
						
							| 
									
										
										
										
											2017-08-17 19:04:20 +03:00
										 |  |  |         uart->queue = NULL; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uart->dev->conf0.val = 0; | 
					
						
							| 
									
										
										
										
											2017-08-04 14:30:51 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2017-08-04 14:30:51 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-30 06:04:18 -06:00
										 |  |  |     uartDetachRx(uart, rxPin); | 
					
						
							|  |  |  |     uartDetachTx(uart, txPin); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-17 12:16:18 -07:00
										 |  |  | size_t uartResizeRxBuffer(uart_t * uart, size_t new_size) { | 
					
						
							|  |  |  |     if(uart == NULL) { | 
					
						
							| 
									
										
										
										
											2018-11-19 16:51:55 +01:00
										 |  |  |         return 0; | 
					
						
							| 
									
										
										
										
											2018-09-17 12:16:18 -07:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UART_MUTEX_LOCK(); | 
					
						
							|  |  |  |     if(uart->queue != NULL) { | 
					
						
							|  |  |  |         vQueueDelete(uart->queue); | 
					
						
							|  |  |  |         uart->queue = xQueueCreate(new_size, sizeof(uint8_t)); | 
					
						
							|  |  |  |         if(uart->queue == NULL) { | 
					
						
							| 
									
										
										
										
											2020-09-30 13:56:41 +02:00
										 |  |  |             UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2018-09-17 12:16:18 -07:00
										 |  |  |             return NULL; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return new_size; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-01 06:58:48 -04:00
										 |  |  | void uartSetRxInvert(uart_t* uart, bool invert) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (uart == NULL) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |      | 
					
						
							|  |  |  |     if (invert) | 
					
						
							|  |  |  |         uart->dev->conf0.rxd_inv = 1; | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |         uart->dev->conf0.rxd_inv = 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | uint32_t uartAvailable(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL || uart->queue == NULL) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  |     return (uxQueueMessagesWaiting(uart->queue) + uart->dev->status.rxfifo_cnt) ; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-04-06 18:07:46 +02:00
										 |  |  | uint32_t uartAvailableForWrite(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0x7f - uart->dev->status.txfifo_cnt; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  | void uartRxFifoToQueue(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	uint8_t c; | 
					
						
							|  |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2020-05-05 16:55:58 +02:00
										 |  |  | 	//disable interrupts
 | 
					
						
							|  |  |  | 	uart->dev->int_ena.val = 0; | 
					
						
							|  |  |  | 	uart->dev->int_clr.val = 0xffffffff; | 
					
						
							|  |  |  | 	while (uart->dev->status.rxfifo_cnt || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { | 
					
						
							|  |  |  | 		c = uart->dev->fifo.rw_byte; | 
					
						
							|  |  |  | 		xQueueSend(uart->queue, &c, 0); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	//enable interrupts
 | 
					
						
							|  |  |  | 	uart->dev->int_ena.rxfifo_full = 1; | 
					
						
							|  |  |  | 	uart->dev->int_ena.frm_err = 1; | 
					
						
							|  |  |  | 	uart->dev->int_ena.rxfifo_tout = 1; | 
					
						
							|  |  |  | 	uart->dev->int_clr.val = 0xffffffff; | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | uint8_t uartRead(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL || uart->queue == NULL) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uint8_t c; | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  |     if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     	uartRxFifoToQueue(uart); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     if(xQueueReceive(uart->queue, &c, 0)) { | 
					
						
							|  |  |  |         return c; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | uint8_t uartPeek(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL || uart->queue == NULL) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uint8_t c; | 
					
						
							| 
									
										
										
										
											2020-01-26 23:38:06 +01:00
										 |  |  |     if ((uxQueueMessagesWaiting(uart->queue) == 0) && (uart->dev->status.rxfifo_cnt > 0)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |     	uartRxFifoToQueue(uart); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     if(xQueuePeek(uart->queue, &c, 0)) { | 
					
						
							|  |  |  |         return c; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartWrite(uart_t* uart, uint8_t c) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-29 14:34:18 +03:00
										 |  |  |     while(uart->dev->status.txfifo_cnt == 0x7F); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uart->dev->fifo.rw_byte = c; | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 16:31:28 +03:00
										 |  |  |     while(len) { | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |         while(uart->dev->status.txfifo_cnt == 0x7F); | 
					
						
							|  |  |  |         uart->dev->fifo.rw_byte = *data++; | 
					
						
							|  |  |  |         len--; | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartFlush(uart_t* uart) | 
					
						
							| 
									
										
										
										
											2019-11-11 07:37:35 -07:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-01 14:30:45 +02:00
										 |  |  |     uartFlushTxOnly(uart,true); | 
					
						
							| 
									
										
										
										
											2019-11-11 07:37:35 -07:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartFlushTxOnly(uart_t* uart, bool txOnly) | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2018-11-19 17:04:05 +01:00
										 |  |  |     while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); | 
					
						
							| 
									
										
										
										
											2019-11-11 07:37:35 -07:00
										 |  |  |      | 
					
						
							|  |  |  |     if( !txOnly ){ | 
					
						
							|  |  |  |         //Due to hardware issue, we can not use fifo_rst to reset uart fifo.
 | 
					
						
							|  |  |  |         //See description about UART_TXFIFO_RST and UART_RXFIFO_RST in <<esp32_technical_reference_manual>> v2.6 or later.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // we read the data out and make `fifo_len == 0 && rd_addr == wr_addr`.
 | 
					
						
							|  |  |  |         while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { | 
					
						
							|  |  |  |             READ_PERI_REG(UART_FIFO_REG(uart->num)); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-11-11 07:37:35 -07:00
										 |  |  |         xQueueReset(uart->queue); | 
					
						
							| 
									
										
										
										
											2018-07-03 18:54:08 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-11-11 07:37:35 -07:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void uartSetBaudRate(uart_t* uart, uint32_t baud_rate) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  |     uint32_t clk_div = ((getApbFrequency()<<4)/baud_rate); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |     uart->dev->clk_div.div_int = clk_div>>4 ; | 
					
						
							|  |  |  |     uart->dev->clk_div.div_frag = clk_div & 0xf; | 
					
						
							| 
									
										
										
										
											2016-10-14 03:07:21 +03:00
										 |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  | static void uart_on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     uart_t* uart = (uart_t*)arg; | 
					
						
							|  |  |  |     if(ev_type == APB_BEFORE_CHANGE){ | 
					
						
							|  |  |  |         UART_MUTEX_LOCK(); | 
					
						
							|  |  |  |         //disabple interrupt
 | 
					
						
							|  |  |  |         uart->dev->int_ena.val = 0; | 
					
						
							|  |  |  |         uart->dev->int_clr.val = 0xffffffff; | 
					
						
							|  |  |  |         // read RX fifo
 | 
					
						
							|  |  |  |         uint8_t c; | 
					
						
							| 
									
										
										
										
											2019-12-30 12:35:29 -07:00
										 |  |  |    //     BaseType_t xHigherPriorityTaskWoken;
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |         while(uart->dev->status.rxfifo_cnt != 0 || (uart->dev->mem_rx_status.wr_addr != uart->dev->mem_rx_status.rd_addr)) { | 
					
						
							|  |  |  |             c = uart->dev->fifo.rw_byte; | 
					
						
							| 
									
										
										
										
											2019-12-30 12:35:29 -07:00
										 |  |  |             if(uart->queue != NULL ) { | 
					
						
							|  |  |  |                 xQueueSend(uart->queue, &c, 1); //&xHigherPriorityTaskWoken);
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2019-12-30 12:35:29 -07:00
										 |  |  |         UART_MUTEX_UNLOCK(); | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |         // wait TX empty
 | 
					
						
							|  |  |  |         while(uart->dev->status.txfifo_cnt || uart->dev->status.st_utx_out); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         //todo:
 | 
					
						
							|  |  |  |         // set baudrate
 | 
					
						
							| 
									
										
										
										
											2019-12-30 12:35:29 -07:00
										 |  |  |         UART_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |         uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); | 
					
						
							|  |  |  |         uint32_t baud_rate = ((old_apb<<4)/clk_div); | 
					
						
							|  |  |  |         clk_div = ((new_apb<<4)/baud_rate); | 
					
						
							|  |  |  |         uart->dev->clk_div.div_int = clk_div>>4 ; | 
					
						
							|  |  |  |         uart->dev->clk_div.div_frag = clk_div & 0xf; | 
					
						
							|  |  |  |         //enable interrupts
 | 
					
						
							|  |  |  |         uart->dev->int_ena.rxfifo_full = 1; | 
					
						
							|  |  |  |         uart->dev->int_ena.frm_err = 1; | 
					
						
							|  |  |  |         uart->dev->int_ena.rxfifo_tout = 1; | 
					
						
							|  |  |  |         uart->dev->int_clr.val = 0xffffffff; | 
					
						
							|  |  |  |         UART_MUTEX_UNLOCK(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | uint32_t uartGetBaudRate(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     if(uart == NULL) { | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-09-08 23:59:32 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-14 03:02:40 +03:00
										 |  |  |     uint32_t clk_div = (uart->dev->clk_div.div_int << 4) | (uart->dev->clk_div.div_frag & 0x0F); | 
					
						
							| 
									
										
										
										
											2019-09-08 23:59:32 +02:00
										 |  |  |     if(!clk_div) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |     return ((getApbFrequency()<<4)/clk_div); | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void IRAM_ATTR uart0_write_char(char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while(((ESP_REG(0x01C+DR_REG_UART_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); | 
					
						
							|  |  |  |     ESP_REG(DR_REG_UART_BASE) = c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void IRAM_ATTR uart1_write_char(char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while(((ESP_REG(0x01C+DR_REG_UART1_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); | 
					
						
							|  |  |  |     ESP_REG(DR_REG_UART1_BASE) = c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void IRAM_ATTR uart2_write_char(char c) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while(((ESP_REG(0x01C+DR_REG_UART2_BASE) >> UART_TXFIFO_CNT_S) & 0x7F) == 0x7F); | 
					
						
							|  |  |  |     ESP_REG(DR_REG_UART2_BASE) = c; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  | void uart_install_putc() | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     switch(s_uart_debug_nr) { | 
					
						
							|  |  |  |     case 0: | 
					
						
							|  |  |  |         ets_install_putc1((void (*)(char)) &uart0_write_char); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 1: | 
					
						
							|  |  |  |         ets_install_putc1((void (*)(char)) &uart1_write_char); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     case 2: | 
					
						
							|  |  |  |         ets_install_putc1((void (*)(char)) &uart2_write_char); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     default: | 
					
						
							|  |  |  |         ets_install_putc1(NULL); | 
					
						
							|  |  |  |         break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  | void uartSetDebug(uart_t* uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(uart == NULL || uart->num > 2) { | 
					
						
							|  |  |  |         s_uart_debug_nr = -1; | 
					
						
							|  |  |  |         //ets_install_putc1(NULL);
 | 
					
						
							|  |  |  |         //return;
 | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |     if(s_uart_debug_nr == uart->num) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } else | 
					
						
							|  |  |  |     s_uart_debug_nr = uart->num; | 
					
						
							|  |  |  |     uart_install_putc(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-06 14:21:30 +03:00
										 |  |  | int uartGetDebug() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return s_uart_debug_nr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  | int log_printf(const char *format, ...) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if(s_uart_debug_nr < 0){ | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  |     static char loc_buf[64]; | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     char * temp = loc_buf; | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  |     int len; | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     va_list arg; | 
					
						
							|  |  |  |     va_list copy; | 
					
						
							|  |  |  |     va_start(arg, format); | 
					
						
							|  |  |  |     va_copy(copy, arg); | 
					
						
							|  |  |  |     len = vsnprintf(NULL, 0, format, arg); | 
					
						
							|  |  |  |     va_end(copy); | 
					
						
							|  |  |  |     if(len >= sizeof(loc_buf)){ | 
					
						
							|  |  |  |         temp = (char*)malloc(len+1); | 
					
						
							|  |  |  |         if(temp == NULL) { | 
					
						
							|  |  |  |             return 0; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     vsnprintf(temp, len+1, format, arg); | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #if !CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     if(_uart_bus_array[s_uart_debug_nr].lock){ | 
					
						
							| 
									
										
										
										
											2019-01-09 21:37:31 +01:00
										 |  |  |         xSemaphoreTake(_uart_bus_array[s_uart_debug_nr].lock, portMAX_DELAY); | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  |         ets_printf("%s", temp); | 
					
						
							|  |  |  |         xSemaphoreGive(_uart_bus_array[s_uart_debug_nr].lock); | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     } else { | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  |         ets_printf("%s", temp); | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2017-06-03 20:10:15 +03:00
										 |  |  |     ets_printf("%s", temp); | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |     va_end(arg); | 
					
						
							| 
									
										
										
										
											2019-01-09 21:37:31 +01:00
										 |  |  |     if(len >= sizeof(loc_buf)){ | 
					
						
							| 
									
										
										
										
											2016-11-13 13:40:31 +02:00
										 |  |  |         free(temp); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return len; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-11-19 16:51:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * if enough pulses are detected return the minimum high pulse duration + minimum low pulse duration divided by two.  | 
					
						
							|  |  |  |  * This equals one bit period. If flag is true the function return inmediately, otherwise it waits for enough pulses. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | unsigned long uartBaudrateDetect(uart_t *uart, bool flg) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while(uart->dev->rxd_cnt.edge_cnt < 30) { // UART_PULSE_NUM(uart_num)
 | 
					
						
							|  |  |  |         if(flg) return 0; | 
					
						
							|  |  |  |         ets_delay_us(1000); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     UART_MUTEX_LOCK(); | 
					
						
							|  |  |  |     unsigned long ret = ((uart->dev->lowpulse.min_cnt + uart->dev->highpulse.min_cnt) >> 1) + 12; | 
					
						
							|  |  |  |     UART_MUTEX_UNLOCK(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * To start detection of baud rate with the uart the auto_baud.en bit needs to be cleared and set. The bit period is  | 
					
						
							|  |  |  |  * detected calling uartBadrateDetect(). The raw baudrate is computed using the UART_CLK_FREQ. The raw baudrate is  | 
					
						
							|  |  |  |  * rounded to the closed real baudrate. | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2019-09-08 23:59:32 +02:00
										 |  |  | void uartStartDetectBaudrate(uart_t *uart) { | 
					
						
							|  |  |  |   if(!uart) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   uart->dev->auto_baud.glitch_filt = 0x08; | 
					
						
							|  |  |  |   uart->dev->auto_baud.en = 0; | 
					
						
							|  |  |  |   uart->dev->auto_baud.en = 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-19 16:51:55 +01:00
										 |  |  | unsigned long | 
					
						
							|  |  |  | uartDetectBaudrate(uart_t *uart) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     static bool uartStateDetectingBaudrate = false; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if(!uartStateDetectingBaudrate) { | 
					
						
							|  |  |  |         uart->dev->auto_baud.glitch_filt = 0x08; | 
					
						
							|  |  |  |         uart->dev->auto_baud.en = 0; | 
					
						
							|  |  |  |         uart->dev->auto_baud.en = 1; | 
					
						
							|  |  |  |         uartStateDetectingBaudrate = true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unsigned long divisor = uartBaudrateDetect(uart, true); | 
					
						
							|  |  |  |     if (!divisor) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uart->dev->auto_baud.en = 0; | 
					
						
							|  |  |  |     uartStateDetectingBaudrate = false; // Initialize for the next round
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |     unsigned long baudrate = getApbFrequency() / divisor; | 
					
						
							| 
									
										
										
										
											2018-11-19 16:51:55 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     static const unsigned long default_rates[] = {300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     size_t i; | 
					
						
							|  |  |  |     for (i = 1; i < sizeof(default_rates) / sizeof(default_rates[0]) - 1; i++)	// find the nearest real baudrate
 | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if (baudrate <= default_rates[i]) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             if (baudrate - default_rates[i - 1] < default_rates[i] - baudrate) { | 
					
						
							|  |  |  |                 i--; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return default_rates[i]; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2019-03-03 06:47:24 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							|  |  |  |  * Returns the status of the RX state machine, if the value is non-zero the state machine is active. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | bool uartRxActive(uart_t* uart) { | 
					
						
							|  |  |  |     return uart->dev->status.st_urx_out != 0; | 
					
						
							|  |  |  | } |