Someone asked a while ago about 31.25kbps UART for Midi. I also needed
115.2kbps and 250kbps for DMX lighting control, and I've got it worked
The main zipit clock is by default 90Mhz. There is a 3.6864Mhz crystal
on the board and the cpu has a PLL frequency multiplier which can dial
up a variety of multiples of that. The default setting of the register
'PLLW' (32 bit, mapped in at 0xFF002610, write byte value to bits
24-31) is 0x31 or 49, which works out as:
49 * 1.8432Mhz = 90.3168Mz.
You can pretty much dial-a-clock speed on your zipit, (although I
believe the audio will stop working), and mine here will overclock to
100Mhz and more. I think the guys with the liquid nitrogen rigs will
probably overlook the crazy world of zipit overclocking though...
Ok, the serial ports use basically the PLL clock as follows:
UART rate = (PLL clock / 320) / (UART divider+1)
So, for a standard 90Mhz clock, you get a basic UART rate of 90.3168 /
320 = 282.240KBps, which when divided by 5 (you write divider-1 to the
register so 4) gives 56448bps which is the standard setting for 56k
Ok, so the factory 90Mhz clock setting won't give us 115.2kbps, (only
either 94k or 141kbps), nor can we get Midi etc. Boo.
However... tweak the system clock speed (this will break the audio
driver I believe - unverified) and you can can dial-a-UART-speed...
Setting PWM multiplier to 40 = 73.72Mhz, which gives you a nice clean
115187bps with a divider of 2.
Set PWM to 43 = 79.2576Mhz , gives you UARTClock (set divider = 0 )of
247kbps which I think will work for DMX lighting - I tried it with a
Zipit->FDDI serial->USB interface at 250Kbps port setting and it
worked beautifully. A divider of 8 in this case will give you
30960bps, which might just pass for Midi...
As for setting these; I did it the ugly way and ran this in user mode
to just hit the registers...
int volatile* UBLDR2 = (int*)(0xff0014c0);
*UBLDR2=0x00070000|uartspeed; // low byte sets baud rate as : (PLL
Clock / 320) / (uartspeed+1). Note that 0 is valid (at 80Mhz PLL,
value of 0 gives 250kbps, works great)
int volatile* PLLW = (int*)(0xff002610);
*PLLW=speed<<24; // * 1.8432Mhz, so 49 = 90mhz
For more info see pages 17-2 (UART) and 2-11 (PLL) in the
For those new to serial stuff, I super recommend the (windows) serial
terminal freeware 'RealTerm' - it's great and also allows you to dial
up unusual baudrates on your serial port.
Note also that hax0ring your zipit registers in user mode like this
will leave system stuff confused; e.g. the clock will start to run