mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2025-12-11 10:19:55 +03:00
susisstrolch's Tx "take two" mod
This commit is contained in:
@@ -200,7 +200,7 @@ static inline void ICACHE_FLASH_ATTR emsuart_loopback(bool enable) {
|
|||||||
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
|
|
||||||
// backward compatibility
|
// backwards compatibility
|
||||||
if (EMS_Sys_Status.emsTxDelay < 2) {
|
if (EMS_Sys_Status.emsTxDelay < 2) {
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
USF(EMSUART_UART) = buf[i];
|
USF(EMSUART_UART) = buf[i];
|
||||||
@@ -213,46 +213,43 @@ void ICACHE_FLASH_ATTR emsuart_tx_buffer(uint8_t * buf, uint8_t len) {
|
|||||||
}
|
}
|
||||||
emsuart_tx_brk(); // send <BRK>
|
emsuart_tx_brk(); // send <BRK>
|
||||||
} else {
|
} else {
|
||||||
// smart Tx
|
/* smart Tx - take two - https://github.com/proddy/EMS-ESP/issues/103 by @susisstrolch
|
||||||
|
* changed logic...
|
||||||
|
* we emit the whole telegram, with Rx interrupt disabled, collecting busmaster response in FIFO.
|
||||||
|
* after sending the last char we poll the Rx status until either
|
||||||
|
* - size(Rx FIFO) == size(Tx-Telegram)
|
||||||
|
* - <BRK> is detected
|
||||||
|
* At end of receive we re-enable Rx-INT and send a Tx-BRK in loopback mode.
|
||||||
|
*/
|
||||||
|
|
||||||
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
ETS_UART_INTR_DISABLE(); // disable rx interrupt
|
||||||
emsuart_flush_fifos();
|
emsuart_flush_fifos();
|
||||||
emsuart_loopback(true); // reset FIFOs & enable loopback
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < len; i++) {
|
// throw out the telegram...
|
||||||
|
for (uint8_t i = 0; i < len; i++)
|
||||||
USF(EMSUART_UART) = buf[i]; // send byte
|
USF(EMSUART_UART) = buf[i]; // send byte
|
||||||
|
|
||||||
delayMicroseconds(10 * EMSUART_BIT_TIME);
|
// wait until we received sizeof(telegram) or RxBRK (== collision detect)
|
||||||
|
while ((((USS(EMSUART_UART) >> USRXC) & 0xFF) < len) || (U0IS & (1 << UIBD)))
|
||||||
|
delayMicroseconds(11 * EMSUART_BIT_TIME); // burn CPU cycles...
|
||||||
|
|
||||||
/* wait until
|
// we got the whole telegram in Rx buffer
|
||||||
* ° loopback char is received
|
// on Rx-BRK (bus collision), we simply enable Rx and leave
|
||||||
* ° Rx-FIFO full (unlikely)
|
// otherwise, we send the final Tx-BRK in loopback and enable Rx-INT.
|
||||||
* ° Rx-TimeOut (unlikely)
|
// worst case, we'll see an additional Rx-BRK...
|
||||||
* ° Break detected (bus collision) - not handled now...
|
if (!(U0IS & (1 << UIBD))) {
|
||||||
*/
|
// no bus collision - send terminating BRK signal
|
||||||
for (uint8_t l = 0; l < 13; l++) {
|
emsuart_loopback(true);
|
||||||
if (((USS(EMSUART_UART) >> USRXC) & 0xFF) || (U0IS & ((1 << UIFF) | (1 << UITO) | (1 << UIBD))))
|
USC0(EMSUART_UART) |= (1 << UCBRK); // set <BRK>
|
||||||
break;
|
|
||||||
|
while (!(U0IS & (1 << UIBD))) // wait until BRK detected...
|
||||||
delayMicroseconds(EMSUART_BIT_TIME / 8); // ~13µs
|
delayMicroseconds(EMSUART_BIT_TIME / 8); // ~13µs
|
||||||
}
|
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
||||||
|
|
||||||
uint32_t break_detect = (U0IS & (1 << UIBD)); // keep break detect interrupt
|
U0IC = (1 << UIBD); // clear BRK detect IRQ
|
||||||
(void)(USF(EMSUART_UART)); // read out fifo, also clears FIFO counter
|
emsuart_loopback(false); // disable loopback mode
|
||||||
U0IC = (1 << UIFF) | (1 << UITO) | (1 << UIBD); // clear pending interrupts
|
|
||||||
if (break_detect)
|
|
||||||
break; // collision / abort from master
|
|
||||||
}
|
}
|
||||||
|
ETS_UART_INTR_ENABLE(); // receive anything from FIFO...
|
||||||
// send <BRK> - wait until <BRK> detect
|
|
||||||
USC0(EMSUART_UART) |= (1 << UCBRK); // send <BRK>
|
|
||||||
while (!(U0IS & (1 << UIBD)))
|
|
||||||
delayMicroseconds(EMSUART_BIT_TIME / 8); // ~13µs
|
|
||||||
USC0(EMSUART_UART) &= ~(1 << UCBRK); // clear <BRK>
|
|
||||||
|
|
||||||
U0IC = (1 << UIFF) | (1 << UITO) | (1 << UIBD); // clear pending interrupts
|
|
||||||
emsuart_flush_fifos();
|
|
||||||
emsuart_loopback(false); // disable loopback mode
|
|
||||||
ETS_UART_INTR_ENABLE(); // enable rx interrupt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user