@@ -109,6 +109,14 @@ struct serial_configure
|
||||
rt_uint32_t reserved :5;
|
||||
};
|
||||
|
||||
struct serial_sem_cfg
|
||||
{
|
||||
rt_sem_t sem_rx;
|
||||
rt_sem_t sem_tx;
|
||||
};
|
||||
|
||||
#define RT_SERIAL_CTRL_CONFIG_SEM 0x30
|
||||
|
||||
/*
|
||||
* Serial FIFO mode
|
||||
*/
|
||||
@@ -150,6 +158,9 @@ struct rt_serial_device
|
||||
|
||||
void *serial_rx;
|
||||
void *serial_tx;
|
||||
|
||||
rt_sem_t sem_rx;
|
||||
rt_sem_t sem_tx;
|
||||
};
|
||||
typedef struct rt_serial_device rt_serial_t;
|
||||
|
||||
|
@@ -1225,6 +1225,20 @@ static rt_err_t rt_serial_control(struct rt_device *dev,
|
||||
}
|
||||
break;
|
||||
#endif /* RT_USING_POSIX_STDIO */
|
||||
case RT_SERIAL_CTRL_CONFIG_SEM:
|
||||
if (args && serial->parent.ref_count)
|
||||
{
|
||||
ret = RT_EBUSY;
|
||||
break;
|
||||
}
|
||||
|
||||
if (args)
|
||||
{
|
||||
struct serial_sem_cfg *cfg = args;
|
||||
serial->sem_rx = cfg->sem_rx;
|
||||
serial->sem_tx = cfg->sem_tx;
|
||||
}
|
||||
break;
|
||||
default :
|
||||
/* control device */
|
||||
ret = serial->ops->control(serial, cmd, args);
|
||||
@@ -1330,7 +1344,7 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
}
|
||||
|
||||
/* invoke callback */
|
||||
if (serial->parent.rx_indicate != RT_NULL)
|
||||
if (serial->parent.rx_indicate != RT_NULL || serial->sem_rx != RT_NULL)
|
||||
{
|
||||
rt_size_t rx_length;
|
||||
|
||||
@@ -1342,7 +1356,11 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
|
||||
if (rx_length)
|
||||
{
|
||||
serial->parent.rx_indicate(&serial->parent, rx_length);
|
||||
if (serial->sem_rx != RT_NULL)
|
||||
rt_sem_release(serial->sem_rx);
|
||||
|
||||
if (serial->parent.rx_indicate != RT_NULL)
|
||||
serial->parent.rx_indicate(&serial->parent, rx_length);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1378,6 +1396,9 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
}
|
||||
|
||||
/* invoke callback */
|
||||
if (serial->sem_tx != RT_NULL)
|
||||
rt_sem_release(serial->sem_tx);
|
||||
|
||||
if (serial->parent.tx_complete != RT_NULL)
|
||||
{
|
||||
serial->parent.tx_complete(&serial->parent, (void*)last_data_ptr);
|
||||
@@ -1414,6 +1435,9 @@ void rt_hw_serial_isr(struct rt_serial_device *serial, int event)
|
||||
/* enable interrupt */
|
||||
rt_hw_interrupt_enable(level);
|
||||
/* invoke callback */
|
||||
if (serial->sem_rx != RT_NULL)
|
||||
rt_sem_release(serial->sem_rx);
|
||||
|
||||
if (serial->parent.rx_indicate != RT_NULL)
|
||||
{
|
||||
serial->parent.rx_indicate(&(serial->parent), length);
|
||||
|
Reference in New Issue
Block a user