функции write tuneDelay перенесены в рам, в ld скрипте из-за этого новая секция внутри data, но при сборке есть предупреждения. запись работает на скоростях вплоть до 115200, чтение в процессе, на 2400 читается норм
This commit is contained in:
1 parent
1d5ffdc6f0
commit
69e1e10a05
4 files changed
+117
-171
No files matched your search
@@ -53,6 +53,7 @@ SECTIONS {
|
|||||||
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)
|
||||||
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
|
*(.sdata .sdata.* .sdata* .sdata*.* .gnu.linkonce.s.*)
|
||||||
*(.data .data.*)
|
*(.data .data.*)
|
||||||
|
*(.ramfunc)
|
||||||
. = ALIGN(CL_SIZE);
|
. = ALIGN(CL_SIZE);
|
||||||
} >ram
|
} >ram
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,16 @@ void __attribute__((weak)) wire_handler_wrapper(void)
|
|||||||
{
|
{
|
||||||
// dummy function for case when wire library is not in use
|
// dummy function for case when wire library is not in use
|
||||||
}
|
}
|
||||||
|
extern void softSerial_handler_wrapper(void);
|
||||||
|
|
||||||
// ---------------------------------------------- //
|
// ---------------------------------------------- //
|
||||||
void trap_handler(void)
|
void trap_handler(void)
|
||||||
{
|
{
|
||||||
|
// gpio interrupt
|
||||||
|
if (EPIC_CHECK_GPIO_IRQ())
|
||||||
|
// gpio_interrupts_handler();
|
||||||
|
softSerial_handler_wrapper();
|
||||||
|
|
||||||
// tone timer interrupt
|
// tone timer interrupt
|
||||||
if (EPIC_CHECK_TIMER16_1())
|
if (EPIC_CHECK_TIMER16_1())
|
||||||
tone_interrupt_handler();
|
tone_interrupt_handler();
|
||||||
@@ -24,10 +30,6 @@ void trap_handler(void)
|
|||||||
if (EPIC_CHECK_UART_1())
|
if (EPIC_CHECK_UART_1())
|
||||||
serial_handler_wrapper(1);
|
serial_handler_wrapper(1);
|
||||||
|
|
||||||
// gpio interrupt
|
|
||||||
if (EPIC_CHECK_GPIO_IRQ())
|
|
||||||
gpio_interrupts_handler();
|
|
||||||
|
|
||||||
// i2c interrupt
|
// i2c interrupt
|
||||||
if (EPIC_CHECK_I2C_1())
|
if (EPIC_CHECK_I2C_1())
|
||||||
wire_handler_wrapper();
|
wire_handler_wrapper();
|
||||||
|
|||||||
@@ -17,66 +17,39 @@ The latest version of this library can always be found at
|
|||||||
http://arduiniana.org.
|
http://arduiniana.org.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// When set, _DEBUG co-opts pins 11 and 13 for debugging with an
|
|
||||||
// oscilloscope or logic analyzer. Beware: it also slightly modifies
|
|
||||||
// the bit times, so don't rely on it too much at high baud rates
|
|
||||||
#define _DEBUG 0
|
|
||||||
#define _DEBUG_PIN1 11
|
|
||||||
#define _DEBUG_PIN2 13
|
|
||||||
|
|
||||||
#define MAX_SOFT_SERIAL_SPEED 115200
|
|
||||||
#define MIN_SOFT_SERIAL_SPEED 300
|
|
||||||
//
|
|
||||||
// Includes
|
|
||||||
//
|
|
||||||
// #include <avr/pgmspace.h>
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <SoftwareSerial.h>
|
#include <SoftwareSerial.h>
|
||||||
#include "mik32_hal_irq.h"
|
#include "mik32_hal_irq.h"
|
||||||
#include "mik32_hal_gpio.h"
|
#include "mik32_hal_gpio.h"
|
||||||
#include "mik32_hal_scr1_timer.h"
|
#include "mik32_hal_scr1_timer.h"
|
||||||
|
|
||||||
//
|
#define MAX_SOFT_SERIAL_SPEED 115200
|
||||||
|
#define MIN_SOFT_SERIAL_SPEED 300
|
||||||
|
|
||||||
|
// --------- TO LL ---------
|
||||||
|
// get ticks from systick
|
||||||
|
#define SYSTICK_GET_TICKS() ((uint64_t)(SCR1_TIMER->MTIMEH)<<32 | SCR1_TIMER->MTIME)
|
||||||
|
#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)
|
||||||
|
|
||||||
|
// --------- TO LL ---------
|
||||||
|
|
||||||
|
|
||||||
// Statics
|
// Statics
|
||||||
//
|
// static variable is common to all class instances
|
||||||
SoftwareSerial *SoftwareSerial::active_object = 0;
|
SoftwareSerial *SoftwareSerial::active_object = 0;
|
||||||
uint8_t SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
|
uint8_t SoftwareSerial::_receive_buffer[_SS_MAX_RX_BUFF];
|
||||||
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
|
volatile uint8_t SoftwareSerial::_receive_buffer_tail = 0;
|
||||||
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
|
volatile uint8_t SoftwareSerial::_receive_buffer_head = 0;
|
||||||
|
|
||||||
//
|
|
||||||
// Debugging
|
|
||||||
//
|
|
||||||
// This function generates a brief pulse
|
|
||||||
// for debugging or measuring on an oscilloscope.
|
|
||||||
// #if _DEBUG
|
|
||||||
// inline void DebugPulse(uint8_t pin, uint8_t count)
|
|
||||||
// {
|
|
||||||
// volatile uint8_t *pport = portOutputRegister(digitalPinToPort(pin));
|
|
||||||
|
|
||||||
// uint8_t val = *pport;
|
|
||||||
// while (count--)
|
|
||||||
// {
|
|
||||||
// *pport = val | digitalPinToBitMask(pin);
|
|
||||||
// *pport = val;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// #else
|
|
||||||
// inline void DebugPulse(uint8_t, uint8_t) {}
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Private methods
|
// Private methods
|
||||||
//
|
|
||||||
|
|
||||||
// get ticks from systick
|
|
||||||
#define CURRENT_TICKS ((uint64_t)(SCR1_TIMER->MTIMEH)<<32 | SCR1_TIMER->MTIME)
|
|
||||||
|
|
||||||
// function placed in ram. Should not call other function placed in flash
|
// function placed in ram. Should not call other function placed in flash
|
||||||
void SoftwareSerial::tunedDelay(uint32_t delayTicks)
|
void SoftwareSerial::tunedDelay(uint32_t delayTicks)
|
||||||
{
|
{
|
||||||
uint64_t startTicks = CURRENT_TICKS;
|
uint64_t startTicks = SYSTICK_GET_TICKS();
|
||||||
while ((CURRENT_TICKS - startTicks) < delayTicks)
|
while ((SYSTICK_GET_TICKS() - startTicks) < delayTicks)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,71 +93,68 @@ bool SoftwareSerial::stopListening()
|
|||||||
//
|
//
|
||||||
void SoftwareSerial::recv()
|
void SoftwareSerial::recv()
|
||||||
{
|
{
|
||||||
// if (active_object)
|
uint8_t data = 0;
|
||||||
// {
|
// If RX line is high, then we don't see any start bit
|
||||||
// uint8_t data = 0;
|
// 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);
|
||||||
|
// Disable further interrupts during reception, this prevents
|
||||||
|
// triggering another interrupt directly after we return, which can
|
||||||
|
// cause problems at higher baudrates.
|
||||||
|
setRxIntMsk(false);
|
||||||
|
|
||||||
// // If RX line is high, then we don't see any start bit
|
// Wait approximately 1/2 of a bit width to "center" the sample
|
||||||
// // so interrupt is probably not for us
|
tunedDelay(_rx_delay_centering);
|
||||||
// if (_inverse_logic ? rx_pin_read() : !rx_pin_read())
|
// DebugPulse(_DEBUG_PIN2, 1);
|
||||||
// {
|
|
||||||
// // Disable further interrupts during reception, this prevents
|
|
||||||
// // triggering another interrupt directly after we return, which can
|
|
||||||
// // cause problems at higher baudrates.
|
|
||||||
// setRxIntMsk(false);
|
|
||||||
|
|
||||||
// // Wait approximately 1/2 of a bit width to "center" the sample
|
// Read each of the 8 bits
|
||||||
// tunedDelay(_rx_delay_centering);
|
for (uint8_t i=8; i > 0; --i)
|
||||||
// // DebugPulse(_DEBUG_PIN2, 1);
|
{
|
||||||
|
tunedDelay(_rx_delay_intrabit);
|
||||||
|
data >>= 1;
|
||||||
|
// DebugPulse(_DEBUG_PIN2, 1);
|
||||||
|
if (rx_pin_read())
|
||||||
|
data |= 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
// // Read each of the 8 bits
|
if (_inverse_logic)
|
||||||
// for (uint8_t i=8; i > 0; --i)
|
data = ~data;
|
||||||
// {
|
|
||||||
// tunedDelay(_rx_delay_intrabit);
|
|
||||||
// data >>= 1;
|
|
||||||
// // DebugPulse(_DEBUG_PIN2, 1);
|
|
||||||
// if (rx_pin_read())
|
|
||||||
// data |= 0x80;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (_inverse_logic)
|
// if buffer full, set the overflow flag and return
|
||||||
// data = ~data;
|
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
||||||
|
if (next != _receive_buffer_head)
|
||||||
|
{
|
||||||
|
// save new data in buffer: tail points to where byte goes
|
||||||
|
_receive_buffer[_receive_buffer_tail] = data; // save new byte
|
||||||
|
_receive_buffer_tail = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// DebugPulse(_DEBUG_PIN1, 1);
|
||||||
|
_buffer_overflow = true;
|
||||||
|
}
|
||||||
|
|
||||||
// // if buffer full, set the overflow flag and return
|
// skip the stop bit
|
||||||
// uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
|
tunedDelay(_rx_delay_stopbit);
|
||||||
// if (next != _receive_buffer_head)
|
// DebugPulse(_DEBUG_PIN1, 1);
|
||||||
// {
|
|
||||||
// // save new data in buffer: tail points to where byte goes
|
|
||||||
// _receive_buffer[_receive_buffer_tail] = data; // save new byte
|
|
||||||
// _receive_buffer_tail = next;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// // DebugPulse(_DEBUG_PIN1, 1);
|
|
||||||
// _buffer_overflow = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // skip the stop bit
|
// Re-enable interrupts when we're sure to be inside the stop bit
|
||||||
// tunedDelay(_rx_delay_stopbit);
|
setRxIntMsk(true);
|
||||||
// // DebugPulse(_DEBUG_PIN1, 1);
|
HAL_GPIO_WritePin(GPIO_0, GPIO_PIN_8, GPIO_PIN_LOW);
|
||||||
|
}
|
||||||
// // Re-enable interrupts when we're sure to be inside the stop bit
|
HAL_GPIO_ClearInterrupts();
|
||||||
// setRxIntMsk(true);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t SoftwareSerial::rx_pin_read()
|
uint8_t SoftwareSerial::rx_pin_read()
|
||||||
{
|
{
|
||||||
return (uint8_t)HAL_GPIO_ReadPin((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask);
|
return (uint8_t)GPIO_READ_PIN((GPIO_TypeDef *)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
|
||||||
// Interrupt handling
|
// Interrupt handling
|
||||||
//
|
|
||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
inline void SoftwareSerial::handle_interrupt() // todo унести в обработчик прерываний
|
inline void SoftwareSerial::handle_interrupt()
|
||||||
{
|
{
|
||||||
if (active_object)
|
if (active_object)
|
||||||
{
|
{
|
||||||
@@ -192,12 +162,11 @@ inline void SoftwareSerial::handle_interrupt() // todo унести в обра
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #if defined(PCINT0_vect)
|
extern "C" void softSerial_handler_wrapper(void)
|
||||||
// ISR(PCINT0_vect)
|
{
|
||||||
// {
|
SoftwareSerial::handle_interrupt();
|
||||||
// SoftwareSerial::handle_interrupt();
|
}
|
||||||
// }
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Constructor
|
// Constructor
|
||||||
@@ -235,10 +204,8 @@ void SoftwareSerial::setRX(uint8_t rx)
|
|||||||
{
|
{
|
||||||
_receiveBitMask = (uint16_t)digitalPinToBitMask(rx); // save rx bit mask
|
_receiveBitMask = (uint16_t)digitalPinToBitMask(rx); // save rx bit mask
|
||||||
_receivePortRegister = (uint32_t)digitalPinToPort(rx); // save rx port adress
|
_receivePortRegister = (uint32_t)digitalPinToPort(rx); // save rx port adress
|
||||||
// attachInterrupt(digitalPinToInterrupt(rx), [this]() { this->recv(); }, _inverse_logic ? RISING : FALLING);
|
|
||||||
if (!_inverse_logic)
|
if (!_inverse_logic)
|
||||||
pinMode(rx, INPUT_PULLUP); // pullup for normal logic
|
pinMode(rx, INPUT_PULLUP); // pullup for normal logic
|
||||||
// HAL_GPIO_PinConfig((GPIO_TypeDef*)_receivePortRegister, (HAL_PinsTypeDef)_receiveBitMask, HAL_GPIO_MODE_GPIO_INPUT, HAL_GPIO_PULL_UP, HAL_GPIO_DS_2MA);
|
|
||||||
else
|
else
|
||||||
pinMode(rx, INPUT);
|
pinMode(rx, INPUT);
|
||||||
}
|
}
|
||||||
@@ -269,78 +236,54 @@ void SoftwareSerial::begin(long speed)
|
|||||||
// Precalculate the various delays in number of ticks
|
// Precalculate the various delays in number of ticks
|
||||||
uint32_t bit_delay = F_CPU / speed;
|
uint32_t bit_delay = F_CPU / speed;
|
||||||
|
|
||||||
// 12 (gcc 4.8.2) or 13 (gcc 4.3.2) cycles from start bit to first bit,
|
// empirical value
|
||||||
// 15 (gcc 4.8.2) or 16 (gcc 4.3.2) cycles between bits,
|
|
||||||
// 12 (gcc 4.8.2) or 14 (gcc 4.3.2) cycles from last bit to stop bit
|
|
||||||
// These are all close enough to just use 15 cycles, since the inter-bit
|
|
||||||
// timings are the most critical (deviations stack 8 times)
|
|
||||||
_tx_delay = subtract_cap(bit_delay, 35); // 15
|
_tx_delay = subtract_cap(bit_delay, 35); // 15
|
||||||
|
|
||||||
// Only setup rx when we have a valid INT for this pin
|
// Only setup rx when we have a valid INT for this pin
|
||||||
if (digitalPinToInterrupt(_receivePin) != NOT_AN_INTERRUPT)
|
if (digitalPinToInterrupt(_receivePin) != NOT_AN_INTERRUPT)
|
||||||
{
|
{
|
||||||
// #if GCC_VERSION > 40800
|
|
||||||
// // Timings counted from gcc 4.8.2 output. This works up to 115200 on
|
|
||||||
// // 16Mhz and 57600 on 8Mhz.
|
|
||||||
// //
|
|
||||||
// // 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, (4 + 4 + 75 + 17 - 23));
|
// 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));
|
||||||
|
|
||||||
// // There are 23 cycles in each loop iteration (excluding the delay)
|
// 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, 23);
|
||||||
|
_rx_delay_intrabit = subtract_cap(bit_delay, 11);
|
||||||
|
|
||||||
// // There are 37 cycles from the last bit read to the start of
|
// There are 37 cycles from the last bit read to the start of
|
||||||
// // stopbit delay and 11 cycles from the delay until the interrupt
|
// stopbit delay and 11 cycles from the delay until the interrupt
|
||||||
// // mask is enabled again (which _must_ happen during the stopbit).
|
// 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
|
// 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
|
// 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
|
// time for ISR cleanup, which makes 115200 baud at 16Mhz work more
|
||||||
// // reliably
|
// reliably
|
||||||
// _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (37 + 11));
|
// _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (48));
|
||||||
// #else // Timings counted from gcc 4.3.2 output
|
_rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (61));
|
||||||
// // Note that this code is a _lot_ slower, mostly due to bad register
|
|
||||||
// // allocation choices of gcc. This works up to 57600 on 16Mhz and
|
|
||||||
// // 38400 on 8Mhz.
|
|
||||||
// _rx_delay_centering = subtract_cap(bit_delay / 2, (4 + 4 + 97 + 29 - 11));
|
|
||||||
// _rx_delay_intrabit = subtract_cap(bit_delay, 11);
|
|
||||||
// _rx_delay_stopbit = subtract_cap(bit_delay * 3 / 4, (44 + 17));
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// Enable the INT for the entire port here, but never disable it
|
// Save start bit polarity - low to high if _inverse_logic
|
||||||
// (others might also need it, so we disable the interrupt by using
|
_int_mode = _inverse_logic ? (uint8_t)GPIO_INT_MODE_RISING : (uint8_t)GPIO_INT_MODE_FALLING;
|
||||||
// the per-pin PCMSK register).
|
// Save gpio_mux and gpio_line for on/off interrupts
|
||||||
// if (_inverse_logic)
|
_int_maskMux = digitalPinToGpioIntMux(_receivePin); // gpio mux value
|
||||||
// _int_mode = GPIO_INT_MODE_RISING; // start bit: low to high
|
_int_maskLine = digitalPinToGpioIntLine(_receivePin); // gpio irq line value
|
||||||
// else
|
HAL_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); // turn on the mask in EPIC
|
||||||
// _int_mode = GPIO_INT_MODE_FALLING; // start bit: high to low
|
|
||||||
// // 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_EPIC_MaskEdgeSet(HAL_EPIC_GPIO_IRQ_MASK); // turn on the mask in EPIC
|
|
||||||
|
|
||||||
// *digitalPinToPCICR((int8_t)_receivePin) |= _BV(digitalPinToPCICRbit(_receivePin));
|
|
||||||
// _pcint_maskreg = digitalPinToPCMSK(_receivePin);
|
|
||||||
// _pcint_maskvalue = _BV(digitalPinToPCMSKbit(_receivePin));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorMsgHandler("SoftwareSerial.begin(): Rx pin does not support interrupts, use different pin");
|
ErrorMsgHandler("SoftwareSerial.begin(): Rx pin does not support interrupts, use different pin");
|
||||||
|
|
||||||
tunedDelay(_tx_delay); // if we were low this establishes the end
|
tunedDelay(_tx_delay); // if we were low this establishes the end
|
||||||
|
|
||||||
// #if _DEBUG
|
HAL_GPIO_PinConfig(GPIO_0, GPIO_PIN_8, HAL_GPIO_MODE_GPIO_OUTPUT, HAL_GPIO_PULL_NONE, HAL_GPIO_DS_2MA);
|
||||||
// pinMode(_DEBUG_PIN1, OUTPUT);
|
|
||||||
// pinMode(_DEBUG_PIN2, OUTPUT);
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
listen();
|
listen();
|
||||||
}
|
}
|
||||||
@@ -348,11 +291,11 @@ void SoftwareSerial::begin(long speed)
|
|||||||
void SoftwareSerial::setRxIntMsk(bool enable)
|
void SoftwareSerial::setRxIntMsk(bool enable)
|
||||||
{
|
{
|
||||||
if (enable)
|
if (enable)
|
||||||
|
// enable line interrupt
|
||||||
HAL_GPIO_InitInterruptLine((HAL_GPIO_Line_Config)_int_maskMux, (HAL_GPIO_InterruptMode)_int_mode);
|
HAL_GPIO_InitInterruptLine((HAL_GPIO_Line_Config)_int_maskMux, (HAL_GPIO_InterruptMode)_int_mode);
|
||||||
// *_pcint_maskreg |= _pcint_maskvalue;
|
|
||||||
else
|
else
|
||||||
|
// disable line interrupt
|
||||||
HAL_GPIO_DeInitInterruptLine((HAL_GPIO_Line)_int_maskLine);
|
HAL_GPIO_DeInitInterruptLine((HAL_GPIO_Line)_int_maskLine);
|
||||||
// *_pcint_maskreg &= ~_pcint_maskvalue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoftwareSerial::end()
|
void SoftwareSerial::end()
|
||||||
@@ -373,27 +316,27 @@ size_t SoftwareSerial::write(uint8_t byte)
|
|||||||
|
|
||||||
// Write the start bit
|
// Write the start bit
|
||||||
if (_inverse_logic)
|
if (_inverse_logic)
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->SET = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_SET_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
else
|
else
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->CLEAR = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_CLEAR_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
tunedDelay(_tx_delay); // wait start bit
|
tunedDelay(_tx_delay); // wait start bit
|
||||||
|
|
||||||
// Write each of the 8 bits in LSB mode
|
// Write each of the 8 bits in LSB mode
|
||||||
for (uint8_t i = 8; i > 0; --i)
|
for (uint8_t i = 8; i > 0; --i)
|
||||||
{
|
{
|
||||||
if (byte & 1) // choose bit
|
if (byte & 1) // choose bit
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->SET = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_SET_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
else
|
else
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->CLEAR = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_CLEAR_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
tunedDelay(_tx_delay);
|
tunedDelay(_tx_delay);
|
||||||
byte >>= 1;
|
byte >>= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore pin to natural state - stop bit
|
// restore pin to natural state - stop bit
|
||||||
if (_inverse_logic)
|
if (_inverse_logic)
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->CLEAR = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_CLEAR_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
else
|
else
|
||||||
((GPIO_TypeDef *)_transmitPortRegister)->SET = (HAL_PinsTypeDef)_transmitBitMask;
|
GPIO_SET_PIN((GPIO_TypeDef *)_transmitPortRegister, (HAL_PinsTypeDef)_transmitBitMask);
|
||||||
|
|
||||||
// enable interrupts
|
// enable interrupts
|
||||||
set_csr(mstatus, MSTATUS_MIE);
|
set_csr(mstatus, MSTATUS_MIE);
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ private:
|
|||||||
static uint32_t subtract_cap(uint32_t num, uint16_t sub);
|
static uint32_t subtract_cap(uint32_t num, uint16_t sub);
|
||||||
|
|
||||||
// private static method for timing
|
// private static method for timing
|
||||||
static void tunedDelay(uint32_t delayTicks) __attribute__((noinline, section(".data"))) ;
|
static void tunedDelay(uint32_t delayTicks) __attribute__((noinline, section(".ramfunc")));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// public methods
|
// public methods
|
||||||
@@ -96,7 +96,7 @@ public:
|
|||||||
}
|
}
|
||||||
int peek();
|
int peek();
|
||||||
|
|
||||||
virtual size_t write(uint8_t byte) __attribute__((noinline, section(".data")));
|
virtual size_t write(uint8_t byte) __attribute__((noinline, section(".ramfunc")));
|
||||||
virtual int read();
|
virtual int read();
|
||||||
virtual int available();
|
virtual int available();
|
||||||
virtual void flush();
|
virtual void flush();
|
||||||
|
|||||||
Reference in new issue
Block a user