тесты с приемом данных. работаем из ram, в обработчике прерываний только нужные сейчас прерывания. все функции в модуле SS по максимуму заменены на дефайны для ускорения. в таких парниковых условиях работает и прием, и отправка нескольких байт до 115200 включительно

This commit is contained in:
klassents committed 2024-09-25 10:29:59 +07:00
1 parent fbe6abaa4f
commit 5d5ec4de22
4 files changed
+83 -38

No files matched your search

+37 -21
View File
@@ -32,7 +32,9 @@ http://arduiniana.org.
#define GPIO_SET_PIN(GPIO_x, pin) ((GPIO_x)->SET = (pin))
#define GPIO_CLEAR_PIN(GPIO_x, pin) ((GPIO_x)->CLEAR = (pin))
#define GPIO_READ_PIN(GPIO_x, pin) (((GPIO_x)->SET & (pin)) != (uint32_t)GPIO_PIN_LOW ? GPIO_PIN_HIGH : GPIO_PIN_LOW)
#define GPIO_IRQ_LINE_ENABLE(lineMask) ( GPIO_IRQ->ENABLE_SET = (1 << (lineMask >> GPIO_IRQ_LINE_S)) )
#define GPIO_IRQ_LINE_DISABLE(lineMask) ( GPIO_IRQ->ENABLE_CLEAR = (1 << (lineMask >> GPIO_IRQ_LINE_S)) )
#define GPIO_IRQ_CLEAR_ALL() (GPIO_IRQ->CLEAR = 0b11111111)
// --------- TO LL ---------
@@ -48,9 +50,12 @@ volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
// function placed in ram. Should not call other function placed in flash
void SoftwareSerial::tunedDelay(uint32_t delayTicks)
{
uint64_t startTicks = SYSTICK_GET_TICKS();
while ((SYSTICK_GET_TICKS() - startTicks) < delayTicks)
;
if (delayTicks > 1)
{
uint64_t startTicks = SYSTICK_GET_TICKS();
while ((SYSTICK_GET_TICKS() - startTicks) < delayTicks)
;
}
}
// This function sets the current object as the "listening"
@@ -92,21 +97,21 @@ bool SoftwareSerial::stopListening()
// The receive routine called by the interrupt handler
//
void SoftwareSerial::recv()
{
{
uint8_t data = 0;
// If RX line is high, then we don't see any start bit
// so interrupt is probably not for us
if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
bool rxState = (bool)GPIO_READ_PIN((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask);
if (_inverse_logic ? rxState : !rxState)
{
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.
setRxIntMsk(false);
setRxIntMsk(false); // __always_inline__
// Wait approximately 1/2 of a bit width to "center" the sample
tunedDelay(_rx_delay_centering);
tunedDelay(_rx_delay_centering); // __always_inline__
GPIO_0->OUTPUT_ ^= GPIO_PIN_1;
// Read each of the 8 bits
@@ -117,7 +122,7 @@ void SoftwareSerial::recv()
GPIO_0->OUTPUT_ ^= GPIO_PIN_1;
if (rx_pin_read())
if (GPIO_READ_PIN((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask))
data |= 0x80;
}
@@ -143,9 +148,9 @@ void SoftwareSerial::recv()
// Re-enable interrupts when we're sure to be inside the stop bit
setRxIntMsk(true);
GPIO_CLEAR_PIN(GPIO_0, GPIO_PIN_8);
}
HAL_GPIO_ClearInterrupts();
GPIO_IRQ_CLEAR_ALL();
}
uint8_t SoftwareSerial::rx_pin_read()
@@ -249,22 +254,33 @@ void SoftwareSerial::begin(long speed)
// 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);
// _rx_delay_centering = subtract_cap(bit_delay / 2, 750); // spifi
_rx_delay_centering = subtract_cap(bit_delay / 2, 315); // ram
// 1 bit time
_rx_delay_intrabit = subtract_cap(bit_delay, 200);
// _rx_delay_intrabit = subtract_cap(bit_delay, 200); // spifi
_rx_delay_intrabit = subtract_cap(bit_delay, 60); // ram
// 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, 950);
// _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, 950); // spifi
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, 142); // ram
if (speed==115200)
{
_rx_delay_intrabit = subtract_cap(_rx_delay_intrabit, 10);
_rx_delay_stopbit+=30;
}
// 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;
// Save gpio_mux and gpio_line for on/off interrupts
_int_maskMux = digitalPinToGpioIntMux(_receivePin); // gpio mux value
_int_maskLine = digitalPinToGpioIntLine(_receivePin); // gpio irq line value
HAL_GPIO_InitInterruptLine((HAL_GPIO_Line_Config) _int_maskMux, (HAL_GPIO_InterruptMode)_int_mode);
GPIO_IRQ_LINE_DISABLE(_int_maskLine); // turn off int
HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); // turn on the mask in EPIC
}
else
@@ -281,11 +297,11 @@ void SoftwareSerial::begin(long speed)
void SoftwareSerial::setRxIntMsk(bool enable)
{
if (enable)
// enable line interrupt
HAL_GPIO_InitInterruptLine((HAL_GPIO_Line_Config)_int_maskMux, (HAL_GPIO_InterruptMode)_int_mode);
// enable interrupt line
GPIO_IRQ_LINE_ENABLE(_int_maskLine);
else
// disable line interrupt
HAL_GPIO_DeInitInterruptLine((HAL_GPIO_Line)_int_maskLine);
// disable interrupt line
GPIO_IRQ_LINE_DISABLE(_int_maskLine);
}
void SoftwareSerial::end()