1. try to fix uart, irq called not only on brk-irq?

This commit is contained in:
MichaelDvP
2022-04-25 17:21:27 +02:00
parent c70d0352ea
commit 9fe0ee119b
2 changed files with 58 additions and 48 deletions

View File

@@ -53,12 +53,12 @@ void EMSuart::emsuart_recvTask(void * para) {
*/ */
void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) { void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
portENTER_CRITICAL(&mux_); portENTER_CRITICAL(&mux_);
if (EMS_UART.int_st.brk_det) { if (EMSUART.int_st.brk_det) {
EMS_UART.int_clr.brk_det = 1; // clear flag EMSUART.int_clr.brk_det = 1; // clear flag
uint8_t rxbuf[EMS_MAXBUFFERSIZE]; uint8_t rxbuf[EMS_MAXBUFFERSIZE];
uint8_t length = 0; uint8_t length = 0;
while (EMS_UART.status.rxfifo_cnt) { while (EMSUART.status.rxfifo_cnt) {
uint8_t rx = EMS_UART.fifo.rw_byte; // read all bytes from fifo uint8_t rx = EMSUART.fifo.rw_byte; // read all bytes from fifo
if (length < EMS_MAXBUFFERSIZE) { if (length < EMS_MAXBUFFERSIZE) {
if (length || rx) { // skip leading zero if (length || rx) { // skip leading zero
rxbuf[length++] = rx; rxbuf[length++] = rx;
@@ -78,6 +78,8 @@ void IRAM_ATTR EMSuart::emsuart_rx_intr_handler(void * para) {
} }
drop_next_rx_ = false; drop_next_rx_ = false;
} }
EMSUART.int_clr.val = 0xFFFFFFFF; // clear all irq-flags
EMSUART.int_ena.val = 0x80; // enable onyl break-irq
portEXIT_CRITICAL(&mux_); portEXIT_CRITICAL(&mux_);
} }
@@ -93,27 +95,32 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
tx_mode_ = tx_mode; tx_mode_ = tx_mode;
portENTER_CRITICAL(&mux_); portENTER_CRITICAL(&mux_);
uart_config_t uart_config = { uart_config_t uart_config = {
.baud_rate = EMSUART_BAUD, .baud_rate = EMSUART_BAUD,
.data_bits = UART_DATA_8_BITS, .data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE, .parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1, .stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_APB,
}; };
uart_param_config(EMSUART_UART, &uart_config); uart_param_config(EMSUART_NUM, &uart_config);
uart_set_pin(EMSUART_UART, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); uart_set_pin(EMSUART_NUM, tx_gpio, rx_gpio, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
EMS_UART.int_ena.val = 0; // disable all intr. uart_driver_delete(EMSUART_NUM);
EMS_UART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags uart_isr_free(EMSUART_NUM);
EMS_UART.idle_conf.tx_brk_num = 10; // breaklength 10 bit uart_clear_intr_status(EMSUART_NUM, 0xFFFFFFFF);
drop_next_rx_ = true; uart_enable_intr_mask(EMSUART_NUM, 0);
// EMS_UART.idle_conf.rx_idle_thrhd = 256; EMSUART.int_ena.val = 0; // disable all intr.
// EMS_UART.auto_baud.glitch_filt = 192; EMSUART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags
#if (EMSUART_UART != UART_NUM_2) EMSUART.idle_conf.tx_brk_num = 10; // breaklength 10 bit
EMS_UART.conf0.rxfifo_rst = 1; // flush fifos, remove for UART2 drop_next_rx_ = true;
EMS_UART.conf0.txfifo_rst = 1; // EMSUART.idle_conf.rx_idle_thrhd = 256;
// EMSUART.auto_baud.glitch_filt = 192;
#if (EMSUART_NUM != UART_NUM_2)
EMSUART.conf0.rxfifo_rst = 1; // flush fifos, remove for UART2
EMSUART.conf0.txfifo_rst = 1;
#endif #endif
buf_handle_ = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT); buf_handle_ = xRingbufferCreate(128, RINGBUF_TYPE_NOSPLIT);
uart_isr_register(EMSUART_UART, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL); uart_isr_register(EMSUART_NUM, emsuart_rx_intr_handler, NULL, ESP_INTR_FLAG_IRAM, NULL);
xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, configMAX_PRIORITIES - 3, NULL); xTaskCreate(emsuart_recvTask, "emsuart_recvTask", 2048, NULL, configMAX_PRIORITIES - 3, NULL);
portEXIT_CRITICAL(&mux_); portEXIT_CRITICAL(&mux_);
restart(); restart();
@@ -124,7 +131,8 @@ void EMSuart::start(const uint8_t tx_mode, const uint8_t rx_gpio, const uint8_t
*/ */
void EMSuart::stop() { void EMSuart::stop() {
portENTER_CRITICAL(&mux_); portENTER_CRITICAL(&mux_);
EMS_UART.int_ena.val = 0; // disable all intr. // uart_enable_intr_mask(EMSUART_NUM, 0);
EMSUART.int_ena.val = 0; // disable all intr.
portEXIT_CRITICAL(&mux_); portEXIT_CRITICAL(&mux_);
}; };
@@ -132,13 +140,17 @@ void EMSuart::stop() {
* Restart uart and make mode dependent configs. * Restart uart and make mode dependent configs.
*/ */
void EMSuart::restart() { void EMSuart::restart() {
EMSUART.int_ena.val = 0; // disable all intr.
EMSUART.int_clr.val = 0xFFFFFFFF; // clear all intr. flags
EMSUART.idle_conf.tx_brk_num = 10; // breaklength 10 bit
portENTER_CRITICAL(&mux_); portENTER_CRITICAL(&mux_);
if (EMS_UART.int_raw.brk_det) { // we received a break in the meantime if (EMSUART.int_raw.brk_det) { // we received a break in the meantime
EMS_UART.int_clr.brk_det = 1; // clear flag EMSUART.int_clr.brk_det = 1; // clear flag
drop_next_rx_ = true; // and drop first frame drop_next_rx_ = true; // and drop first frame
} }
EMS_UART.int_ena.brk_det = 1; // activate only break // uart_enable_intr_mask(EMSUART_NUM, 0x80);
EMS_UART.conf0.txd_brk = (tx_mode_ == EMS_TXMODE_HW) ? 1 : 0; EMSUART.int_ena.brk_det = 1; // activate only break
EMSUART.conf0.txd_brk = (tx_mode_ == EMS_TXMODE_HW) ? 1 : 0;
portEXIT_CRITICAL(&mux_); portEXIT_CRITICAL(&mux_);
} }
@@ -165,48 +177,48 @@ uint16_t EMSuart::transmit(const uint8_t * buf, const uint8_t len) {
if (tx_mode_ == EMS_TXMODE_HW) { // hardware controlled mode if (tx_mode_ == EMS_TXMODE_HW) { // hardware controlled mode
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
EMS_UART.fifo.rw_byte = buf[i]; EMSUART.fifo.rw_byte = buf[i];
} }
return EMS_TX_STATUS_OK; return EMS_TX_STATUS_OK;
} }
if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ with long delay if (tx_mode_ == EMS_TXMODE_EMSPLUS) { // EMS+ with long delay
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
EMS_UART.fifo.rw_byte = buf[i]; EMSUART.fifo.rw_byte = buf[i];
delayMicroseconds(EMSUART_TX_WAIT_PLUS); delayMicroseconds(EMSUART_TX_WAIT_PLUS);
} }
EMS_UART.conf0.txd_inv = 1; // send <brk> EMSUART.conf0.txd_inv = 1; // send <brk>
delayMicroseconds(EMSUART_TX_BRK_PLUS); delayMicroseconds(EMSUART_TX_BRK_PLUS);
EMS_UART.conf0.txd_inv = 0; EMSUART.conf0.txd_inv = 0;
return EMS_TX_STATUS_OK; return EMS_TX_STATUS_OK;
} }
if (tx_mode_ == EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay if (tx_mode_ == EMS_TXMODE_HT3) { // HT3 with 7 bittimes delay
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
EMS_UART.fifo.rw_byte = buf[i]; EMSUART.fifo.rw_byte = buf[i];
delayMicroseconds(EMSUART_TX_WAIT_HT3); delayMicroseconds(EMSUART_TX_WAIT_HT3);
} }
EMS_UART.conf0.txd_inv = 1; // send <brk> EMSUART.conf0.txd_inv = 1; // send <brk>
delayMicroseconds(EMSUART_TX_BRK_HT3); delayMicroseconds(EMSUART_TX_BRK_HT3);
EMS_UART.conf0.txd_inv = 0; EMSUART.conf0.txd_inv = 0;
return EMS_TX_STATUS_OK; return EMS_TX_STATUS_OK;
} }
// mode 1: wait for echo after each byte // mode 1: wait for echo after each byte
// flush fifos -- not supported in ESP32 uart #2! // flush fifos -- not supported in ESP32 uart #2!
// EMS_UART.conf0.rxfifo_rst = 1; // EMSUART.conf0.rxfifo_rst = 1;
// EMS_UART.conf0.txfifo_rst = 1; // EMSUART.conf0.txfifo_rst = 1;
for (uint8_t i = 0; i < len; i++) { for (uint8_t i = 0; i < len; i++) {
volatile uint8_t _usrxc = EMS_UART.status.rxfifo_cnt; volatile uint8_t _usrxc = EMSUART.status.rxfifo_cnt;
EMS_UART.fifo.rw_byte = buf[i]; // send each Tx byte EMSUART.fifo.rw_byte = buf[i]; // send each Tx byte
uint16_t timeoutcnt = EMSUART_TX_TIMEOUT; uint16_t timeoutcnt = EMSUART_TX_TIMEOUT;
while ((EMS_UART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) { while ((EMSUART.status.rxfifo_cnt == _usrxc) && (--timeoutcnt > 0)) {
delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles... delayMicroseconds(EMSUART_TX_BUSY_WAIT); // burn CPU cycles...
} }
} }
EMS_UART.conf0.txd_inv = 1; EMSUART.conf0.txd_inv = 1;
delayMicroseconds(EMSUART_TX_BRK_EMS); delayMicroseconds(EMSUART_TX_BRK_EMS);
EMS_UART.conf0.txd_inv = 0; EMSUART.conf0.txd_inv = 0;
return EMS_TX_STATUS_OK; return EMS_TX_STATUS_OK;
} }

View File

@@ -25,20 +25,18 @@
#ifndef EMSESP_EMSUART_H #ifndef EMSESP_EMSUART_H
#define EMSESP_EMSUART_H #define EMSESP_EMSUART_H
#include <Arduino.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/ringbuf.h" #include "freertos/ringbuf.h"
#include "freertos/queue.h" #include "freertos/queue.h"
#include <driver/uart.h> #include "driver/uart.h"
#include <driver/timer.h> #include "soc/uart_struct.h"
#define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK #define EMS_MAXBUFFERSIZE 33 // max size of the buffer. EMS packets are max 32 bytes, plus extra for BRK
#define EMSUART_UART UART_NUM_2 // on the ESP32 we're using UART2 #define EMSUART_NUM UART_NUM_2 // on the ESP32 we're using UART2
#define EMS_UART UART2 // for intr setting #define EMSUART UART2 // for intr setting
#define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit #define EMSUART_BAUD 9600 // uart baud rate for the EMS circuit
#define EMS_TXMODE_DEFAULT 1 #define EMS_TXMODE_DEFAULT 1
#define EMS_TXMODE_EMSPLUS 2 #define EMS_TXMODE_EMSPLUS 2