From cb95c51a3fc9d36f6d7052c2c63e0a03f51940e8 Mon Sep 17 00:00:00 2001 From: klassents Date: Thu, 19 Sep 2024 14:32:57 +0700 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=BE=D0=BA=D1=80=D1=83=D1=82=D0=B8?= =?UTF-8?q?=D0=BB=D0=B0=20=D1=82=D0=B0=D0=B9=D0=BC=D0=B8=D0=BD=D0=B3=D0=B8?= =?UTF-8?q?=20=D0=BD=D0=B0=20=D0=BF=D1=80=D0=B8=D0=B5=D0=BC,=20=D1=87?= =?UTF-8?q?=D1=82=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B9=D1=82=D0=B0?= =?UTF-8?q?=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0=D0=B5=D1=82=20=D0=BE?= =?UTF-8?q?=D1=82=20300=20=D0=B4=D0=BE=209600,=20=D0=B4=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D1=88=D0=B5=20=D0=BD=D0=B0=D0=B4=D0=BE=20=D1=83=D1=81=D0=BA?= =?UTF-8?q?=D0=BE=D1=80=D1=8F=D1=82=D1=8C=20=D1=84=D1=83=D0=BD=D0=BA=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SoftwareSerial/src/SoftwareSerial.cpp | 50 ++++++++----------- libraries/SoftwareSerial/src/SoftwareSerial.h | 8 +-- 2 files changed, 24 insertions(+), 34 deletions(-) diff --git a/libraries/SoftwareSerial/src/SoftwareSerial.cpp b/libraries/SoftwareSerial/src/SoftwareSerial.cpp index f3611f9..fe3a8ed 100644 --- a/libraries/SoftwareSerial/src/SoftwareSerial.cpp +++ b/libraries/SoftwareSerial/src/SoftwareSerial.cpp @@ -98,7 +98,8 @@ void SoftwareSerial::recv() // so interrupt is probably not for us if (_inverse_logic ? rx_pin_read() : !rx_pin_read()) { - HAL_GPIO_WritePin(GPIO_0, GPIO_PIN_8, GPIO_PIN_HIGH); + GPIO_SET_PIN(GPIO_0, GPIO_PIN_8); + GPIO_CLEAR_PIN(GPIO_0, GPIO_PIN_1); // Disable further interrupts during reception, this prevents // triggering another interrupt directly after we return, which can // cause problems at higher baudrates. @@ -106,14 +107,16 @@ void SoftwareSerial::recv() // Wait approximately 1/2 of a bit width to "center" the sample tunedDelay(_rx_delay_centering); - // DebugPulse(_DEBUG_PIN2, 1); + GPIO_0->OUTPUT_ ^= GPIO_PIN_1; // Read each of the 8 bits for (uint8_t i=8; i > 0; --i) { tunedDelay(_rx_delay_intrabit); data >>= 1; - // DebugPulse(_DEBUG_PIN2, 1); + + GPIO_0->OUTPUT_ ^= GPIO_PIN_1; + if (rx_pin_read()) data |= 0x80; } @@ -131,17 +134,16 @@ void SoftwareSerial::recv() } else { - // DebugPulse(_DEBUG_PIN1, 1); _buffer_overflow = true; } // skip the stop bit tunedDelay(_rx_delay_stopbit); - // DebugPulse(_DEBUG_PIN1, 1); + GPIO_0->OUTPUT_ ^= GPIO_PIN_1; // Re-enable interrupts when we're sure to be inside the stop bit setRxIntMsk(true); - HAL_GPIO_WritePin(GPIO_0, GPIO_PIN_8, GPIO_PIN_LOW); + GPIO_CLEAR_PIN(GPIO_0, GPIO_PIN_8); } HAL_GPIO_ClearInterrupts(); } @@ -236,39 +238,27 @@ void SoftwareSerial::begin(long speed) // Precalculate the various delays in number of ticks uint32_t bit_delay = F_CPU / speed; - // empirical value - _tx_delay = subtract_cap(bit_delay, 35); // 15 + // delays are empirical values here + + // 1 bit delay while transmitting data + _tx_delay = subtract_cap(bit_delay, 35); // Only setup rx when we have a valid INT for this pin if (digitalPinToInterrupt(_receivePin) != NOT_AN_INTERRUPT) { + // We want to have a total delay of 1.5 bit time from start bit. + // Inside the loop, we already wait for 1 bit time, so here we + // wait for 0.5 bit time + _rx_delay_centering = subtract_cap(bit_delay / 2, 750); - // When the start bit occurs, there are 3 or 4 cycles before the - // interrupt flag is set, 4 cycles before the PC is set to the right - // interrupt vector address and the old PC is pushed on the stack, - // and then 75 cycles of instructions (including the RJMP in the - // ISR vector table) until the first delay. After the delay, there - // are 17 more cycles until the pin value is read (excluding the - // delay in the loop). - // We want to have a total delay of 1.5 bit time. Inside the loop, - // we already wait for 1 bit time - 23 cycles, so here we wait for - // 0.5 bit time - (71 + 18 - 22) cycles. - // _rx_delay_centering = subtract_cap(bit_delay / 2, (77)); - _rx_delay_centering = subtract_cap(bit_delay / 2, (123)); + // 1 bit time + _rx_delay_intrabit = subtract_cap(bit_delay, 200); - // There are 23 cycles in each loop iteration (excluding the delay) - // _rx_delay_intrabit = subtract_cap(bit_delay, 23); - _rx_delay_intrabit = subtract_cap(bit_delay, 11); - - // There are 37 cycles from the last bit read to the start of - // stopbit delay and 11 cycles from the delay until the interrupt - // mask is enabled again (which _must_ happen during the stopbit). // This delay aims at 3/4 of a bit time, meaning the end of the // delay will be at 1/4th of the stopbit. This allows some extra // time for ISR cleanup, which makes 115200 baud at 16Mhz work more // reliably - // _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (48)); - _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (61)); + _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, 950); // Save start bit polarity - low to high if _inverse_logic _int_mode = _inverse_logic ? (uint8_t)GPIO_INT_MODE_RISING : (uint8_t)GPIO_INT_MODE_FALLING; @@ -283,7 +273,7 @@ void SoftwareSerial::begin(long speed) tunedDelay(_tx_delay); // if we were low this establishes the end HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_8, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); - + HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_1, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA); listen(); } diff --git a/libraries/SoftwareSerial/src/SoftwareSerial.h b/libraries/SoftwareSerial/src/SoftwareSerial.h index cfb706d..4a23ee4 100644 --- a/libraries/SoftwareSerial/src/SoftwareSerial.h +++ b/libraries/SoftwareSerial/src/SoftwareSerial.h @@ -50,10 +50,10 @@ private: uint8_t _int_maskLine; uint8_t _int_mode; - // Expressed as 4-cycle delays (must never be 0!) - uint16_t _rx_delay_centering; - uint16_t _rx_delay_intrabit; - uint16_t _rx_delay_stopbit; + // must never be 0! + uint32_t _rx_delay_centering; + uint32_t _rx_delay_intrabit; + uint32_t _rx_delay_stopbit; uint32_t _tx_delay; uint16_t _buffer_overflow:1;