Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cores/arduino/HardwareSerial.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,6 +347,11 @@ void HardwareSerial::begin(unsigned long baud, byte config)
}

uart_init(&_serial, (uint32_t)baud, databits, parity, stopbits);
if (isHalfDuplex()) {
// Start half duplex communication in receive mode.
_rx_enabled = true;
uart_enable_rx(&_serial);
}
uart_attach_rx_callback(&_serial, _rx_complete_irq);
}

Expand Down Expand Up @@ -377,6 +382,15 @@ int HardwareSerial::peek(void)

int HardwareSerial::read(void)
{
if (isHalfDuplex()) {
// In half duplex mode we have to wait for all TX characters to
// be transmitted before we can receive data.
flush();
if (!_rx_enabled) {
_rx_enabled = true;
uart_enable_rx(&_serial);
}
}
// if the head isn't ahead of the tail, we don't have any characters
if (_serial.rx_head == _serial.rx_tail) {
return -1;
Expand Down Expand Up @@ -417,6 +431,12 @@ void HardwareSerial::flush()
size_t HardwareSerial::write(uint8_t c)
{
_written = true;
if (isHalfDuplex()) {
if (_rx_enabled) {
_rx_enabled = false;
uart_enable_tx(&_serial);
}
}

tx_buffer_index_t i = (_serial.tx_head + 1) % SERIAL_TX_BUFFER_SIZE;

Expand Down
12 changes: 12 additions & 0 deletions cores/arduino/HardwareSerial.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,24 @@ class HardwareSerial : public Stream {
void setRx(PinName _rx);
void setTx(PinName _tx);

// Enable half-duplex mode by setting the Rx pin to NC
// This needs to be done before the call to begin()
inline void setHalfDuplex()
{
setRx(NC);
}
inline bool isHalfDuplex() const
{
return _serial.pin_rx == NC;
}

friend class STM32LowPower;

// Interrupt handlers
static void _rx_complete_irq(serial_t *obj);
static int _tx_complete_irq(serial_t *obj);
private:
bool _rx_enabled;
uint8_t _config;
unsigned long _baud;
void init(void);
Expand Down
38 changes: 35 additions & 3 deletions cores/arduino/stm32/uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
USART_TypeDef *uart_rx = pinmap_peripheral(obj->pin_rx, PinMap_UART_RX);

/* Pins Rx/Tx must not be NP */
if (uart_rx == NP || uart_tx == NP) {
if ((obj->pin_rx != NC && uart_rx == NP) || uart_tx == NP) {
core_debug("ERROR: at least one UART pin has no peripheral\n");
return;
}
Expand Down Expand Up @@ -288,7 +288,9 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par

/* Configure UART GPIO pins */
pinmap_pinout(obj->pin_tx, PinMap_UART_TX);
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
if (uart_rx != NP) {
pinmap_pinout(obj->pin_rx, PinMap_UART_RX);
}

/* Configure uart */
uart_handlers[obj->index] = huart;
Expand Down Expand Up @@ -359,7 +361,11 @@ void uart_init(serial_t *obj, uint32_t baudrate, uint32_t databits, uint32_t par
}
#endif

if (HAL_UART_Init(huart) != HAL_OK) {
if (uart_rx == NP) {
if (HAL_HalfDuplex_Init(huart) != HAL_OK) {
return;
}
} else if (HAL_UART_Init(huart) != HAL_OK) {
return;
}
}
Expand Down Expand Up @@ -732,6 +738,32 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *))
HAL_NVIC_EnableIRQ(obj->irq);
}

/**
* Enable transmitter for half-duplex mode. NOOP in full-fuplex mode
*
* @param obj : pointer to serial_t structure
* @retval none
*/
void uart_enable_tx(serial_t *obj)
{
if (obj != NULL && obj->pin_rx == NC) {
HAL_HalfDuplex_EnableTransmitter(uart_handlers[obj->index]);
}
}

/**
* Enable receiver for half-duplex mode. NOOP in full-fuplex mode
*
* @param obj : pointer to serial_t structure
* @retval none
*/
void uart_enable_rx(serial_t *obj)
{
if (obj != NULL && obj->pin_rx == NC) {
HAL_HalfDuplex_EnableReceiver(uart_handlers[obj->index]);
}
}

/**
* @brief Return index of the serial handler
* @param UartHandle pointer on the uart reference
Expand Down
3 changes: 3 additions & 0 deletions cores/arduino/stm32/uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ void uart_attach_tx_callback(serial_t *obj, int (*callback)(serial_t *));
uint8_t serial_tx_active(serial_t *obj);
uint8_t serial_rx_active(serial_t *obj);

void uart_enable_tx(serial_t *obj);
void uart_enable_rx(serial_t *obj);

size_t uart_debug_write(uint8_t *data, uint32_t size);

#endif /* HAL_UART_MODULE_ENABLED */
Expand Down