UART USER'S GUIDE
QUEUE_HANDLE fnOpenUART(void)
{
TTYTABLE tInterfaceParameters; // table for passing information to driver
QUEUE_HANDLE SerialPortID; // UART handle to be obtained during open
tInterfaceParameters.Channel = 1; // set UART channel for serial use
tInterfaceParameters.ucSpeed = SERIAL_BAUD_19200; // baud rate 19’200
tInterfaceParameters.Rx_tx_sizes.RxQueueSize = 256; // input buffer size
tInterfaceParameters.Rx_tx_sizes.TxQueueSize = 512; // output buffer size
tInterfaceParameters.Task_to_wake = TASK_APPLICATION; // wake task on rx
#ifdef SUPPORT_FLOW_HIGH_LOW
tInterfaceParameters.ucFlowHighWater = 80; // set the flow control high in %
tInterfaceParameters.ucFlowLowWater = 20; // set the flow control low in %
#endif
tInterfaceParameters.usConfig =
(CHAR_8 + NO_PARITY + ONE_STOP + USE_XON_OFF + CHAR_MODE);
#ifdef SERIAL_SUPPORT_DMA
tInterfaceParameters.ucDMAConfig = UART_TX_DMA; // activate DMA on transmission
#endif
if ((SerialPortID = fnOpen( TYPE_TTY, FOR_I_O, &tInterfaceParameters )) != 0) {
// open the channel with defined configurations (initially inactive)
fnDriver(SerialPortID, ( TX_ON | RX_ON ), 0 ); // enable rx and tx
}
return SerialPortID; // return the serial port handle for this UART
}
Code 1 – example of UART initialization
SerialPortID = fnOpen(
TYPE_TTY, // serial interface driver type (UART)
FOR_I_O, // for use as input/output device (Rx/Tx)
&tInterfaceParameters);// configuration details
Code 2 – the fnOpen() function used to open a serial interface
fnDriver(
SerialPortID, // the serial interface handle
( TX_ON | RX_ON ), // enable rx and tx
0 ); // unused parameter in this case
Code 3 – the fnDriver() function used to enable receiver and transmitter
extern void fnApplication(TTASKTABLE *ptrTaskTable)
{
unsigned char ucInputByte;
while (fnRead( SerialPortID, &ucInputByte, 1) != 0) {
while (ucInputByte--) {
toggle_output();
}
}
}
Code 4 – a task receiving characters from a UART with handle SerialPortID
extern void fnApplication(TTASKTABLE *ptrTaskTable)
{
QUEUE_TRANSFER length;
unsigned char ucInputBuffer[100];
while ((length = fnMsgs(SerialPortID)) != 0) {// get number of waiting bytes
if (length > sizeof(ucInputBuffer)) { // ensure buffer can’t be overrun
length = sizeof(ucInputBuffer);
}
fnRead(SerialPortID, ucInputBuffer, length); // read to a local buffer
}
}
Code 5 – a task filling a buffer from a UART with handle SerialPortID
fnWrite(SerialPortID, (unsigned char *)"1234567890", 10);
Code 6 – transmission of a string to a UART with handle SerialPortID
if (fnWrite(SerialPortID, 0, 10) == 0) {
fnDriver(SerialPortID, MODIFY_WAKEUP, (MODIFY_TX | OWN_TASK));
// enable TX_FREE event
}
else {
fnWrite(SerialPortID, (unsigned char *)"1234567890", 10);
}
Code 7 – check of output buffer space before transmission
extern void fnDebug(TTASKTABLE *ptrTaskTable)
{
QUEUE_HANDLE PortIDInternal = ptrTaskTable->TaskID; // queue ID for task input
unsigned char ucInputMessage[SMALL_MESSAGE]; // space for receiving messages
while ( fnRead( PortIDInternal, ucInputMessage, HEADER_LENGTH)) { // read input
switch ( ucInputMessage[ MSG_SOURCE_TASK ] ) { // switch on source
case INTERRUPT_EVENT:
if (TX_FREE == ucInputMessage[MSG_INTERRUPT_EVENT]) {
fnDisplayHelp(iMenuLocation);// continue sending further menu items
}
break;
}
}
Code 8 – Example of specific handling the TX_FREE event
// Initialisation code for RS485 mode
//
tInterfaceParameters.usConfig |= INFORM_ON_FRAME_TRANSMISSION;
SerialPortID = fnOpen( TYPE_TTY, FOR_I_O, &tInterfaceParameters ):
...
fnDriver(SerialHandle, (MODIFY_CONTROL | CONFIG_RTS_PIN), 0);
// configure RTS pin for control use
fnDriver(SerialHandle, (MODIFY_CONTROL | SET_RTS), 0); // initially drive '0'
// Message transmission code for RS485 mode
//
fnDriver(SerialHandle, (MODIFY_CONTROL | CLEAR_RTS), 0); // driver RTS ‘1’
fnWrite(SerialHandle, ucMessageData, length); // start message frame transmission
Code 9 – Example of configuring for RS485 mode operation and controlling the RTS line when starting message frame transmission
// The UART is informing that it has just completed transmission of the last character in a frame.
// This is used to control RTS de-assertion, usually after a delay
//
extern void fnUARTFrameTermination(QUEUE_HANDLE Channel)
{
if (Channel == 2) {
//fnDriver(SerialHandle, (MODIFY_CONTROL | SET_RTS), 0);
can only be used for certain processor types
fnConfigureInterrupt(&timer_setup_RTS_negate);
// start delay to RTS negation
}
}
Code 10 – example of controlling negation of the RTS line on message termination
static TIMER_INTERRUPT_SETUP timer_setup_RTS_negate;
timer_setup_RTS_negate.int_type = TIMER_INTERRUPT
timer_setup_RTS_negate.timer_reference = 2;
timer_setup_RTS_negate.int_priority = 3;
timer_setup_RTS_negate.int_handler = fnTimer_RTS;
timer_setup_RTS_negate.timer_mode = (TIMER_SINGLE_SHOT | TIMER_US_VALUE);
timer_setup_RTS_negate.timer_value = 620; // 620us delay before RTS negation
Code 11 – Example of RTS timer configuration
// Initialisation code for RS485 mode
//
fnDriver(SerialHandle, (MODIFY_CONTROL | CONFIG_RTS_PIN | SET_RS485_MODE), 0);
// configure RTS pin for control use
Code 12 – Configuring for HW RS485 mode operation
extern QUEUE_TRANSFER fnNetworkTx(unsigned char *output_buffer, QUEUE_TRANSFER nr_of_bytes)
{
fnWrite(SerialPortID, output_buffer, nr_of_bytes);
fnWrite(SerialPortID2, output_buffer, nr_of_bytes);
fnWrite(USB_handle, output_buffer, nr_of_bytes);
return (fnSendBufTCP(Telnet_socket, output_buffer, nr_of_bytes, (TCP_BUF_SEND | TCP_BUF_SEND_REPORT_COPY)));
}
Code 13 – Example of sending debug output to multiple interfaces