UART Half duplex operation over RS485

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

UART Half duplex operation over RS485

Jump to solution
6,024 Views
Jetoleg
Contributor II

Hi,

I have another UART question:

I need to turn off RS485 TX drivers when TX buffer emptied out. It has to be  done quickly, 10mS delay after last char left UART is already too long. 

So far I found only one way of doing it:

IO_IOCTL_SERIAL_TRANSMIT_DONE check through ioctl.

So far I had very bad lack with this ioctl feature, probably because my task priority issues.

Is MQX offer any callback functions or IRQ vectors for TX Over condition? Can I use any hardware flow control signals? I saw one topic which suggested that hardware flow control is not a working feature. Any suggestions?

1 Solution
1,001 Views
PetrL
NXP Employee
NXP Employee

Answers to your questions:

 

 

Is there anyway to check how many bytes sitting in RX or TX buffers?

 - not via current driver API - you would have to change internal implementation.

 

Is interrupts UART blocks other tasks until he is done sending bytes?

 - Uart interrupts runs on background. It does not block task, it interrupts all tasks, reacting on IRQ TIE(Transmit Data Register Empty). In isr it sends next byte from OS buffer. After last byte it disables transmit interrupt.

 

 

Is flush() essentially blocks everything else until UART completed the send?

 - flush() internal implementation is while(){} waiting till all OS device buffer is emptied. 

   Other task with higher priority can run.

 

Is IO_IOCTL_SERIAL_TRANSMIT_DONE sets when last byte of the OS buffer been send out to UART buffer or when hardware UART buffer been emptied?

 -  Current implementation of both - IO_IOCTL_SERIAL_TRANSMIT_DONE and flush() function are dependent only on OS buffer sending.  Neither of them check UART HW buffer.

 

-------------------------

 

I think you would need to wait for Transmission Complete FLAG of the last send byte. In current driver implementation there is no way how to do it. 

We will investigate this problem and change it in next MQX version.(probably modify IO_IOCTL_SERIAL_TRANSMIT_DONE ioctl to check TC flag.

 

Currently I would suggest you to modify driver to check TC flag. And in your application you should call flush() - waits till last byte is send, then check Transmit Complete flag.

View solution in original post

0 Kudos
8 Replies
1,001 Views
PetrL
NXP Employee
NXP Employee

Hi,

 

there was bug in flush(fflush did not wait for buffer empty) implementation if version 3.1.0 and older. Correction is in attached file - src\mqx\sourc\io\serial\int\serl_int.c .

 

In attached version fflush suspends current task till all data are send. 

 

 

      case IO_IOCTL_FLUSH_OUTPUT:
         while(!_CHARQ_EMPTY(int_io_dev_ptr->OUT_QUEUE)) {
            /* wait untill all chars are sent from output queue*/
            _taskq_suspend(int_io_dev_ptr->OUT_WAITING_TASKS);
         };
         break;

 

 

 

 

PetrL

 

serl_int.c

Message Edited by t.dowe on 2009-10-15 06:22 PM
0 Kudos
1,001 Views
Jetoleg
Contributor II

Hi,

I am still trying to come up with clean solution for Half duplex RS485 coms. MSF52259 chip seams to have required hardware option. It looks like tx driver control will be properly operated by RTS hardware handshake line if  bit TXRTS set in UMR2n register.

I noticed MQX serial driver has an option for hardware flow control.

Could you tell me if opening serial port in IO_SERIAL_HW_FLOW_CONTROL mode sets proper bit for flow control? If not, would it be possible to alter UMR1n and UMR2n register values for custom flow control in MQX serial driver code?

What register values and where in MQX library currently past to the chip under IO_SERIAL_HW_FLOW_CONTROL flow control mode? Unfortunately not much description is available in MQX manual on this particular option.

0 Kudos
1,001 Views
PetrL
NXP Employee
NXP Employee

Hi,

 

Functionality of driver depends on type you are using:

 

In the polled driver write() blocks untill all data are written to SCI HW output buffer(SCID register).

In interrupt driven serial driver, are data after calling write() data is stored in internal driver ring buffer of BSPCFG_SCI1_QUEUE_SIZE size. Driver is then sending data on the background.

 

I guess you are using interrupt driver.

There is no callback function from driver to signalize empty internal send-buffer. You can either use fflush()(fixed in MQX 3.2.1) or check IO_IOCTL_SERIAL_TRANSMIT_DONE ictl result.

 

PetrL



PetrL

 

0 Kudos
1,001 Views
Jetoleg
Contributor II

Thanks for the advice. For clarification, I use interrupt driven UART.

Looks like I need to know more about this UART driver  implementation.

Is there anyway to check how many bytes sitting in RX or TX buffers?

Is interrupts UART blocks other tasks until he is done sending bytes?

Is flush() essentially blocks everything else until UART completed the send?

Is IO_IOCTL_SERIAL_TRANSMIT_DONE sets when last byte of the OS buffer been send out to UART buffer or when hardware UART buffer been emptied?

Sorry to be so annoying, but documentation on MQX is so scares. 

0 Kudos
1,002 Views
PetrL
NXP Employee
NXP Employee

Answers to your questions:

 

 

Is there anyway to check how many bytes sitting in RX or TX buffers?

 - not via current driver API - you would have to change internal implementation.

 

Is interrupts UART blocks other tasks until he is done sending bytes?

 - Uart interrupts runs on background. It does not block task, it interrupts all tasks, reacting on IRQ TIE(Transmit Data Register Empty). In isr it sends next byte from OS buffer. After last byte it disables transmit interrupt.

 

 

Is flush() essentially blocks everything else until UART completed the send?

 - flush() internal implementation is while(){} waiting till all OS device buffer is emptied. 

   Other task with higher priority can run.

 

Is IO_IOCTL_SERIAL_TRANSMIT_DONE sets when last byte of the OS buffer been send out to UART buffer or when hardware UART buffer been emptied?

 -  Current implementation of both - IO_IOCTL_SERIAL_TRANSMIT_DONE and flush() function are dependent only on OS buffer sending.  Neither of them check UART HW buffer.

 

-------------------------

 

I think you would need to wait for Transmission Complete FLAG of the last send byte. In current driver implementation there is no way how to do it. 

We will investigate this problem and change it in next MQX version.(probably modify IO_IOCTL_SERIAL_TRANSMIT_DONE ioctl to check TC flag.

 

Currently I would suggest you to modify driver to check TC flag. And in your application you should call flush() - waits till last byte is send, then check Transmit Complete flag.

0 Kudos
1,001 Views
Jetoleg
Contributor II
Thanks for looking into it. I will use flush() for now.
0 Kudos
1,001 Views
EAI
Contributor IV

I would modify the interrupt driven driver to support 485 mode.

In _mcf51xx_sci_int_putc, enable the driver. In _mcf51xx_sci_int_tx_isr, disable the driver if _io_serial_int_nextc returns -1. You can add a new flag bit to FLAGS in IO_SERIAL_INT_DEVICE_STRUCT to specify if it is a 485 channel.

0 Kudos
1,001 Views
Jetoleg
Contributor II

Thanks,

If no other way, it's worth a shot. I'll look into it. Would be nice to have this issue addressed in next MQX release.

0 Kudos