Next is exploring the possibility of adding RTS/CTS signalling to the demo.
Doing the outbound RTS/DTR signals were pretty easy, and only add an additional 22 bytes to the code. (22 bytes, I just happened to have made available) Just set up an IO port for the signals (3 instructions, 6 bytes) and add an additional case to the class request handler (8 instructions, 16 bytes). However, putting out these signals is only somewhat useful if we can't detect these signals from a remote device using the CTS&DSR inputs.
CASE CDC_SETCONTROLSTA
read2w wValueL
xorwf LATB, W, ACCESS
andlw 0x03
xorwf LATB, F, ACCESS ;bit 0=DTR, 1=RTS
bra setdone_xmitzero
Adding support for CTS/DSR is where it gets ugly. I've considered using interrupts for this, however, noisy inputs could easily generate unwanted state updates to the host. The next best solution is to check if the input pins for CTS/DSR change when handling the USB Start Of Frame (SOF) interrupt. This works, and guarantees we see at most 1 update per millisecond, however sending this SERIAL_STATUS message to the USB host requires not only this change detection, but also sending a 10-byte message to the host.
lfsr FSR1, 0x418
rcall fsr2_to_fsr1
movlw 0xA1
movwf POSTINC2, ACCESS ;bmRequestType
movlw 0x20
movwf POSTINC2, ACCESS ;bRequest
clrf POSTINC2, ACCESS ;wValue
clrf POSTINC2, ACCESS
movlw 0x01
movwf POSTINC2, ACCESS ;wIndex
clrf POSTINC2, ACCESS
movlw 0x02
movwf POSTINC2, ACCESS ;wLength
clrf POSTINC2, ACCESS
rrncf ctsdtr, W, BANKED
andlw 0x03
movwf POSTINC2, ACCESS ;UART state
clrf POSTINC2, ACCESS
movlw 0x0A
movwf PREINC1, ACCESS ; respond with 10 bytes
decf FSR1L, F, ACCESS
movlw 0x80 | USBPARITY
movwf INDF1, ACCESS
My naive attempts to do this add at most 37 instructions, totaling 74 bytes! Even under ideal circumstances, like more USB ram for data buffering will still require at least 62 additional bytes of code.
Lets consider for a moment, instead of sending the SERIAL_STATE header inline as in the snippet above, what if I load the 8 byte-header into flash and send it from there? The 8 byte header is currently 12 instructions, that take 24 bytes of code space. Instead, it could be 8 bytes for the header itself, and the existing send_descriptor function used to send at a cost of 4 instructions for 8 bytes to setup and make the function call. That could reduce the size to a possible 54 additional bytes.
At this point, I doubt that kind of memory is hiding in the code base to be scavenged. Though, perhaps it would be possible if I scrap the baud-rate divider, and hard-code support for 2 or 3 baudrates.
Sorry flow control, looks like you won't make the cut.
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.