Enhanced Serial Port Communications Accelerator Version 2.0 Technical Notes DISCLAIMER: THE PRODUCT IS PROVIDED TO DEVELOPER "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PRODUCT IS ASSUMED BY DEVELOPER, INCLUDING ALL COSTS OF SERVICING, REPAIRS OR CORRECTIONS. DEVELOPER AGREES THAT HAYES WILL NOT BE LIABLE FOR ANY DAMAGES DIRECTLY OR INDIRECTLY RELATED TO THE USE OF THE PRODUCT, INCLUDING BUT NOT LIMITED TO, LOST PROFITS, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES, WHETHER BASED ON CONTRACT, TORT OR ANY OTHER LEGAL THEORY. DEVELOPER ACKNOWLEDGES THAT THE PRODUCT IS STILL UNDER DEVELOPMENT AND THAT HAYES DOES NOT WARRANT THAT THE PRODUCT IN ITS PRESENT OR FUTURE FORM WILL MEET DEVELOPER'S NEEDS. References: - Hayes Enhanced Serial Interface Version 2.0 - Hayes ESP2 test code. - National Semiconductor Data Communications/LAN/UARTS Handbook Acronyms: ESP - Enhanced Serial Port ESP2 - Enhanced Serial Port Version 2 ESI - Enhanced Serial Interface AT - ISA Bus PC MCA - Micro Channel Architecture Bus PS/2 IN - Input from Port OUT - Output to Port Identifying An ESP2 Port: The master and slave ports go through the same identification routine. Using the default ESP2 (AT) master base address of: 100h, 140h, 180h, 200h, 240h, 280h, 300h, 380h use the following id algorithm. - Do a read (IN) of the base IO address. - If the value read = 0F3h then issue the ESI Get Self Test command (01h). - Read from the STAT2 register (Base IO + 5). The bits 6,5,4 should be equal to or greater than 010b. The current rev of the COM-bic chip is 010b. The slave ports can use the same algorithm. To determine the slaves base IO address add 8 to the Master base address. EXAMPLE: - 2 Port Adapter Master Base IO address = 200h Slave 1 Base IO address = 208h To determine how many slaves are associated with a master continue the last base IO + 8 and execute the algorithm. EXAMPLE: - 4 Port Adapter Master Base IO address = 300h Passed Slave 1 Base IO address = 308h Passed Slave 2 Base IO address = 310h Passed Slave 3 Base IO address = 318h Passed Slave 4 Base IO address = 320h Failed Found 4 ESP2 ports. Identifying An ESP2 Port's COM Port Selection: To identify what COM Port the ESP2 port is associated with issue an ESI Get Compatibility Mode command (02h). Bits 1,0 of the STAT1 register (base IO+4) identify the COM port. The values of these bits are as follows: BIT 10 Assignment ---------------------------------------- 00 COM1 01 COM2 10 COM3 11 COM4 Initialization and Configuration of an ESP2 Port For Enhanced Programmed IO mode (See ESP2 test code for the configuration of memory mapped, DMA and programmed IO): - Upon identifying the port, assure a known state for the port by issuing the ESI Reset command (00h). - Place your Interrupt Service Routine into the proper vector slot. - Turn on the Enhanced interrupt capabilities by issuing the ESI Set Enhanced Interrupt Enable command (04h). The CMD2 value should have bit 0 set to 1. - Issue the ESI Set Enhanced Interrupt level (1Fh). If this is a slave port that is sharing from the master the value of CMD2 is 13h (share IRQ value) otherwise it is one of the following IRQ values 3,4,5,7,9,10,11,12,14,15. Please note that if in an eight bit slot the only valid IRQ values are 3,4,5 7 and 9. - Flush the transmit and receive FIFO's by issuing the ESI commands Flush Receive FIFO (1Bh) and Flush Transmit FIFO (1Ch). - Set the chip into Enhanced mode. Issue the ESI command Set Mode (10h) with the CMD2 byte = 1. NOTE: All three modes programmed IO, memory mapped and DMA are set using this command. Programmed IO is the default. - Set the chip to allow transmitting by issuing the ESI Flow On local transmitter (19h) command. - If we are sharing the IRQ with the master port then issue the following commands to the MASTER address: - Issue the ESI Set Enhanced Interrupt Enabled command (04h). The CMD2 value should have bit 0 set to 1. - Issue the ESI Set Enhanced Interrupt Level (1Fh) with CMD2 equal to the IRQ level that the master will use. - Issue the ESI Set Mode command (10h) to put the Master into enhanced mode (bit 0 set to 1). - Set the service mask value that is appropriate using the ESI com- mand Set Service Mask (06h). - Calculate the baud divisor and issue ESI command Set UART Baud Rate (1Dh). - Issue the ESI Set FIFO Trigger Levels (0Bh). - Issue the ESI Set Receive Character Time-out (0Ch). Be aware that in the first rev of the P38 chip the timers are off by a multiple of 10. So if your calculation for time-out is 10 milliseconds be sure to multiply by 10 to get 100 timer ticks. - Set the line control register data bits, stopbits and parity by issuing the ESI Write to Uart Register command (0Eh). - Set the flow control by issuing the ESI Set Flow Control Type command (08h). NOTE 1: Hardware floc control requires the setting of DTR and RTS be done through the UART by issuing the ESI Write to Uart Register command (0Eh). NOTE 2: The hardware Xon/Xoff flow control does not work. See the software work around that handles this problem. The ESPTEST.EXE source code DOES NOT give an example of the work around. - Set the flow control characters by issuing the ESI Set Flow Control Characters command(09h). - Set the flow control levels by issuing the ESI Set Flow Control Levels command (0Ah). - Set the error interrupt mask by issuing the ESI command Set Error Error Status mask (07h). This forces an error interrupt of the P38 chip. - Set the Uart prescaler by issuing the ESI Set UART Clock Prescaler command (23h). This command changes the speed rate. For example, if you wish to run at 115200, then you set the baud divisor for 115200 and the UART prescaler to 0. If you wish to run at 230400, then you set the baud divisor for 115200 and the UART prescaler to 1. NOTE: Be sure to set the WAIT state bit (bit 2) for enhanced mode only. - Set the pacing by issuing the ESI Set Re-Interrupt Pacing command (20h). If the slave is sharing the IRQ of the master then this command should be issued to the Master's address. - At this point read the Service ID port (BaseIO + 1) of both slave and master (if applicable) to get rid of any spurious activity due to the configuration of the chip. Also it would be good to read the error status (ESI command 12h) of slave and master (if applic- able) to clear any errors that popped up during configuration. - The chip is now set for communications. Interrupt Service Routine: Upon entry into the Interrupt Service Routine the data structure for the interrupting port is passed. See ESPENTRY.ASM and ESPISR.C for the mechanism used for controlling what structure is passed in the ESPTEST code. Depending on the operating system this method is different. Before getting into the reason for the interrupt the ISR should determine if the slave is sharing the master's IRQ. This implies that multiple ports are active and it is possible that more than one port needs to be serviced. The test code was not written to share the IRQ, but assumes only one port active. The following are the reasons for the chip to interrupt: - Receive FIFO level reached. Determined by the Set FIFO Trigger Level for receive FIFO. This means that we get a receive interrupt when the receive FIFO reaches this number of characters. EXAMPLE:: If the Receive FIFO trigger was set for 200 characters we will get an interrupt when the receive FIFO has 200 or more characters. At this point the ISR can remove all (or portion) of data from the receive FIFO and store it in it's internal queue's. - Transmit FIFO level reached. Determined by the Set FIFO Trigger Level for the transmit FIFO. This means that we get a transmit interrupt when the transmit FIFO contains space for the trigger level characters. EXAMPLE:: If the Transmit FIFO trigger was set for 200 characters we will get an interrupt when the transmit FIFO has room for 200 or more characters. At this point the ISR can attempt to transfer as much as the transmit FIFO can hold. NOTE: The transmit FIFO level reached bit in the Service Request Mask should not be set until there is data to transmit, otherwise the transmit interrupt will continue interrupting because the FIFO normally reaches the trigger level in the idle state. This will place a major stress on the system due to the large number of un-necessary interrupt requests. - Error status. The status interrupt is defined by the Set Error Status Mask. This means for any error that has been defined in the error mask the P38 chip will cause an interrupt when that condition has occurred. EXAMPLE: If the Set Error Mask is set for UART Status then we receive an error interrupt for every Modem Status change. At this point service the error interrupt. NOTE: If the chip is in DMA mode then two other interrupts are possible. - DMA Terminal Count - Indicates that DMA transfers completed. - DMA Time-out - Indicates that a DMA transfer time-out occurred and not all the data transmission had completed. Software Work-Arounds for the First Revision of the ESP2: 1. Problem: Internal timebase for all ESP programmable timers is off by a factor of 10x (faster) when compared to the current ESP which was the design goal. (e.g. 10mS -> 1mS) Solution: Scale the formulas for computing timeout values up by a factor of 10x. 2. Problem: Issuing the "Get Rx Bytes Available" command repetitively causes the internal latch for this value to not be updated after the first command. Note: that the same holds true for the "Get Tx Space Available" and "Get Rx Error Count" commands. Solution: The issuance of any other valid or invalid ESI command will release (open) the latch for updates. To be safe issue an FFh prior to the above mentioned commands. 3. Problem: When using Xon/Xoff or transparent Xon/Xoff flow control the ESP2 starts the Rx timer upon receiving a flow control character when the Rx FIFO is empty. At this point the timer operates in a free running mode causing periodic Rx time-out interrupts until actual data is received. The ill effects of this will be most apparent when transmitting large blocks of data with little or no receive activity where Tx throughput may be reduced in slower (286, 386SX) machines. Solution: When entering the Interrupt Service Routine (ISR) set the Rx time-out to 00h and then back to its programmed value before checking the Enhanced Error Status bit in the Service ID (SID) register and issuing the "Get Error Status" command. This action restarts the timer which effectively re-synchronizes the time-out as to insure that it will not occur until well after the ISR call is completed (which reduces the number of occurrences). Note that when the timer is turned off and then on the Rx time-out error status bit gets glitched (and therefore set to 1) which makes it a good idea to perform this operation before the error status handling which will clear the bit. Since hardware controlled Xon/Xoff does not work properly it should not be used. See problem 4 for the software Xon/Xoff support. 4. Problem: When using Xon/Xoff or transparent Xon/Xoff flow control the ESP2 will send an Xoff when the high-water mark is reached and an Xon when the low-water mark is reached only once when the Tx FIFO is empty. The flow control function will not respond until the Tx Flow Control State Machine (FCSM) is reset by the host application. Note that hardware flow control is not affected by the above bug. This proved to be the most difficult bug to work around. I would suggest that Xon/Xoff not be implemented in this rev of the chip. Solution: Regulate the transmit buffer to allow for reloading the transmit FIFO when an Xon or Xoff needs to be sent. The P38 does not do true transmit immediate data, so if we have reached an Xoff limit the remote station needs to be Xoff'd. This requires flushing the transmit FIFO, transmitting the Xoff character and (when transmit is available to the driver) then retransmit the flushed data before sending any new data. This retransmission of the flushed data requires that the driver have enough buffer space to retain data already out in the FIFO. The software Xon/Xoff control requires that we evaluate the receive data for any Xon characters. The receive code resorts to reading a byte at a time from the receive FIFO and compare for the Xon character. The Xon/Xoff solution requires work to be done on all the possible P38 interrupts ( receive, transmit and error), this means checking on what type of flow control is enacted and what rev of the chip we are in constantly throughout the ISR. This impacts not only Xon/Xoff perfor- mance but the working Rts/Cts and Dtr/Dsr flow controls as well. Xon/Xoff Software (with some help from hardware) control: - If Xon/Xoff flow control is enacted be sure to set bit 7 of the first byte issued with the ESI Set Flow Control Type command (08h). This bit forces the local transmitter to respond to Xon/Xoff flow control. This works in conjunction with the ESI Set Error Mask command (07h), specifically the Local Flowed off and Local Flow on bits (bits 1 and 2 of the second byte). If the transmitter is flowed off or on we get an error interrupt indicating such. - In the error interrupt routine if we receive the indication that the Local transmitter was flowed off, then we issue the ESI command Flow Off Local Transmitter (18h) and clear bit 7 of the first byte issued with the ESI Set Flow Control Type Command (08h). - The receive FIFO interrupt routine needs to handle sending XON or XOFF characters according to the XON and XOFF limits. The receive routine (for Xon/Xoff only) receives one character at a time so that it can respond to an Xon character. - The transmit interrupt needs to determine if we have a pending XON character that needs to go out. It also need to retransmit any data that might have been removed from the transmit FIFO because of the need to send out a Xoff character. 5. Problem: On some buses when doing 16 bit io we got garbled data. Solution: Set the Wait-state bit in the ESI SetUartClock command. 6. Problem: The DMA mode select bit in the 16550 is not set. This could cause performance problems. Solution: Set the DMA mode select bit in the FIFO Control register.