Skip to content

Commit

Permalink
[serial_v2] support half duplex.
Browse files Browse the repository at this point in the history
  • Loading branch information
sulfurandcu committed Sep 27, 2024
1 parent 5562779 commit 925350b
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
14 changes: 12 additions & 2 deletions components/drivers/include/drivers/dev_serial_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define __DEV_SERIAL_V2_H__

#include <rtthread.h>
#include <drivers/dev_pin.h>


/**
Expand Down Expand Up @@ -204,6 +205,10 @@
#define RT_SERIAL_FLOWCONTROL_CTSRTS 1
#define RT_SERIAL_FLOWCONTROL_NONE 0

#define RT_SERIAL_FULL_DUPLEX 0
#define RT_SERIAL_HALF_DUPLEX_TX_HIGH 1
#define RT_SERIAL_HALF_DUPLEX_TX_LOW 2

/* Default config for serial_configure structure */
#define RT_SERIAL_CONFIG_DEFAULT \
{ \
Expand All @@ -216,7 +221,9 @@
RT_SERIAL_RX_MINBUFSZ, /* rxBuf size */ \
RT_SERIAL_TX_MINBUFSZ, /* txBuf size */ \
RT_SERIAL_FLOWCONTROL_NONE, /* Off flowcontrol */ \
0 \
RT_SERIAL_FULL_DUPLEX, /* Full duplex */ \
0, \
PIN_NONE, \
}

/**
Expand All @@ -238,7 +245,10 @@ struct serial_configure
rt_uint32_t rx_bufsz :16;
rt_uint32_t tx_bufsz :16;
rt_uint32_t flowcontrol :1;
rt_uint32_t reserved :5;
rt_uint32_t duplex :2;
rt_uint32_t reserved :3;

rt_base_t duplex_pin;
};

/**
Expand Down
41 changes: 41 additions & 0 deletions components/drivers/serial/dev_serial_v2.c
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,31 @@ static rt_ssize_t rt_serial_update_write_index(struct rt_ringbuffer *rb,
return write_size;
}

static void _serial_half_duplex_tx_on(struct rt_serial_device *serial)
{
RT_ASSERT(serial != RT_NULL);

if (serial->config.duplex_pin != PIN_NONE)
{
if (serial->config.duplex == RT_SERIAL_HALF_DUPLEX_TX_HIGH)
rt_pin_write(serial->config.duplex_pin, PIN_HIGH);
else
rt_pin_write(serial->config.duplex_pin, PIN_LOW);
}
}

static void _serial_half_duplex_tx_off(struct rt_serial_device *serial)
{
RT_ASSERT(serial != RT_NULL);

if (serial->config.duplex_pin != PIN_NONE)
{
if (serial->config.duplex == RT_SERIAL_HALF_DUPLEX_TX_HIGH)
rt_pin_write(serial->config.duplex_pin, PIN_LOW);
else
rt_pin_write(serial->config.duplex_pin, PIN_HIGH);
}
}

/**
* @brief Serial polling receive data routine, This function will receive data
Expand Down Expand Up @@ -368,6 +393,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
putc_buffer = (rt_uint8_t *)buffer;
putc_size = size;

_serial_half_duplex_tx_on(serial);
while (size)
{
if (serial->parent.open_flag & RT_DEVICE_FLAG_STREAM)
Expand All @@ -382,6 +408,7 @@ rt_ssize_t _serial_poll_tx(struct rt_device *dev,
++ putc_buffer;
-- size;
}
_serial_half_duplex_tx_off(serial);

return putc_size - size;
}
Expand Down Expand Up @@ -485,13 +512,15 @@ static rt_ssize_t _serial_fifo_tx_blocking_nbuf(struct rt_device *dev,
if (tx_fifo->activated == RT_TRUE) return 0;

tx_fifo->activated = RT_TRUE;
_serial_half_duplex_tx_on(serial);
/* Call the transmit interface for transmission */
rst = serial->ops->transmit(serial,
(rt_uint8_t *)buffer,
size,
RT_SERIAL_TX_BLOCKING);
/* Waiting for the transmission to complete */
rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER);
_serial_half_duplex_tx_off(serial);
/* Inactive tx mode flag */
tx_fifo->activated = RT_FALSE;
return rst;
Expand Down Expand Up @@ -535,6 +564,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
if (tx_fifo->activated == RT_TRUE) return 0;
tx_fifo->activated = RT_TRUE;

_serial_half_duplex_tx_on(serial);
while (size)
{
/* Copy one piece of data into the ringbuffer at a time
Expand All @@ -554,6 +584,7 @@ static rt_ssize_t _serial_fifo_tx_blocking_buf(struct rt_device *dev,
/* Waiting for the transmission to complete */
rt_completion_wait(&(tx_fifo->tx_cpt), RT_WAITING_FOREVER);
}
_serial_half_duplex_tx_off(serial);
/* Finally Inactivate the tx->fifo */
tx_fifo->activated = RT_FALSE;

Expand Down Expand Up @@ -601,6 +632,7 @@ static rt_ssize_t _serial_fifo_tx_nonblocking(struct rt_device *dev,
rt_uint8_t *put_ptr = RT_NULL;
/* Get the linear length buffer from rinbuffer */
tx_fifo->put_size = rt_serial_get_linear_buffer(&(tx_fifo->rb), &put_ptr);
_serial_half_duplex_tx_on(serial);
/* Call the transmit interface for transmission */
serial->ops->transmit(serial,
put_ptr,
Expand Down Expand Up @@ -1158,6 +1190,11 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
/* set serial configure */
serial->config = *pconfig;
serial->ops->configure(serial, (struct serial_configure *) args);
if (serial->config.duplex_pin != PIN_NONE)
{
rt_pin_mode(serial->config.duplex_pin, PIN_MODE_OUTPUT);
}
_serial_half_duplex_tx_off(serial);
}
break;
case RT_DEVICE_CTRL_NOTIFY_SET:
Expand Down Expand Up @@ -1632,6 +1669,10 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
tx_fifo->put_size,
RT_SERIAL_TX_NON_BLOCKING);
}
else
{
_serial_half_duplex_tx_off(serial);
}

break;
}
Expand Down

0 comments on commit 925350b

Please sign in to comment.