After writing Spin and PASM code for many years, I finally had something that's worthy of uploading to OBEX: a fast serial transmitter that can be used by PASM as well as Spin code.
I needed an alternative for the FullDuplexSerial driver for my S/PDIF receiver project (https://hackaday.io/project/24911
). I needed it to be faster than FullDuplexSerial, and I needed it to be easy to use from PASM: in particular, I wanted it to generate hex dumps without going through Spin code.
Current features are:
- Supports bitrates up to 8 megabits per second at 80MHz (minimum 10 cycles per bit).
- Measured maximum throughput when printing a nul-terminated string at 3mbps (highest supported speed of the Parallax Serial Terminal) with an 80MHz clock is about 250,000 characters per second (320 clock cycles per character). Theoretical throughput at 8mbps should be around 500,000 characters per second.
- The slowest command is a request to print the signed decimal representation of $8000_0000 ("-2147483648") which takes 17916 cycles at 3mbps with an 80MHz clock (223.95 microseconds).
- Reads bytes, words or longs from the hub and formats them as human-readable numbers in unsigned decimal, signed decimal, hexadecimal or binary. Printing of arrays of numbers is supported (elements of the array will be separated by a space in the output).
- Reads nul-terminated strings or fixed-length buffers and transmits them straight to the output, either directly or after replacing unprintable characters with a period "." .
- Baud rate and pin number for serial output can be changed without stopping the cog. Lowest baudrate is about 76bps (@80MHz) because of the number of bits used in the command to pass the bit time.
- Can automatically generate a formatted hexdump of up to 4KB of hub memory, with ASCII representation.
- All functionality is controlled by changing a single command longword in hub memory; this makes it easy to control the transmitter cog from Spin as well as PASM.
- Default values of the bit fields in the command longword are such that setting the command to a hub address (bit-extended with zero-bits) will print a nul-terminated string from that address.
- Includes self-benchmarking feature: When processing of a command has completed, the code stores the number of elapsed cycles in the hub..
- Spin demo module implements various spin helper functions and demonstrates the functionality with benchmark testing.
- Txx.spin module compiles to 310 longs at this time.
UPDATE: I changed the code so that it shifts out the bits via the PHSA timer register, and uses an unrolled loop to improve the maximum speed from 4 to 8 megabits per second. Thanks for the tip, @Kuroneko