Weighing anchor
Of course, there is no reason to put this receiver routine code in macro. However, it still makes sense for lower baud rates. These macros would be similar to RS_bodySEND* with few additions – time expired after start bit edge depend on how the application detects start bit and what is done before macro starts. Thus, macro should accept as a parameter number of cycles expired since start bit. Additionally, as the example above indicates, there may be a need of storing data to a different file, not to the predefined one, so this is also added to the parameter’s list. With such macro, receiver routine for 115200 would look like:
IV CODE 0x04
movwf | TMP_WREG | ; 4: save W |
V CODE 0x05
swapf | STATUS, W | ; 5: load STATUS | |
movwf | TMP_STATUS | ; 6: save STATUS | |
btfss | INTCON, INTF | ; 7: what caused this interrupt? | |
goto | not_INT | ; 8: not INT | |
clrf | INDF | ; 9: |
RS_bodyRECEIVE .115200, RS_BITCOUNT, RX, 0, INDF, .9
incf | FSR, F | ; 76: forward buffer pointer | |
incf | RS_COUNTER, F | ; 77: count this byte | |
swapf | TMP_STATUS, W | ; 78: | |
movwf | STATUS | ; 79: restore STATUS | |
swapf | TMP_WREG, F | ; 80: | |
swapf | TMP_WREG, W | ; 81: restore W | |
bcf | INTCON, INTF | ; 82: interrupt handled | |
retfie | ; 83: leave routine - 2 cycles of one stop bit left |
not_INT
; other handlers
Estimating the speed
As it was shown, the receiver routine has two factors that limit baud rate – bit timing error and start-bit latency. Bit timing error has two constituents, and, being averaged, gives us approximately 1 IC. With this error estimated baud rate limit is BAUD RATE=CLOCK/20 or 200000 baud at 4 MHz. Shortest possible start-bit latency is 4 IC, which gives us BAUD RATE=CLOCK*3/32 » CLOCK/10 or 400000 baud @ 4MHz. Practical start-bit latencies will be longer, so we may conclude that CLOCK/20 is a good estimation for the high limit.
Steering the ship
While writing receiver routine, we have assumed that FSR is properly set before an interrupt occurs. This means that PC should start sending data only if PIC is ready to receive them. Another implicit assumption is that PC may stop sending data before the PIC’s buffer is overflowed. Since PC application may not be aware of application’s state in PIC, latter should somehow indicate these conditions or, in other words, use flow control. RS-232 interface has dedicated lines for hardware flow control: CTS and RTS. According to RS standard (see [7],[8]) PC sets RTS to the SPACE voltage to indicate that more data is ready to be sent. PIC should set CTS to the SPACE voltage when it is ready to receive data. In fact, we are interested in particular implementation of RS-232 on PC running MS Windows. This implementation usually includes a UART chip and the serial port driver. I have not found a well-documented description on hardware flow control in MS Windows. The pieces I have found (see Addendum A) and result of my experiments indicate that despite its hardware name, flow control is actually implemented in software, more specifically, in the serial port driver. A device may enable transmission by setting CTS to SPACE voltage and suspend it by setting to MARK voltage. However, this does not affect data already placed in UART transmit buffer and PC does not stop sending data immediately, it sends reminder of the buffer and stops before a new portion is loaded in the buffer. Another issue is that there is certain delay between events of polling CTS state and loading the buffer. In other words, PC may occasionally miss fact that CTS is already hold MARK and load data to the transmit buffer, which UART will send. PC will detect MARK on CTS after the buffer is already loaded. Receiver routine must take into account all these issues and establish some relaxation period between setting CTS to MARK and exiting. Although, hardware flow control is often assumed as CTS/RTS, RTS line is not that necessary for the flow control as CTS is. Receiver may be implemented with two pins only (RX, CTS). In this case, it should periodically set CTS to SPACE, wait for data to come and exit by timeout. With additional pin for RTS, application may periodically poll RTS (or awake on RTS) and enter receiving routine only if PC has data to send and holds SPACE on RTS. Nevertheless, even with RTS line, receiver should exit by timeout since PC may hold SPACE on RTS permanently4.
Post a Comment