Teensy 3.0 UART0 MSBF/LSBF Not switchable

Status
Not open for further replies.

HaaTa

New member
I'm trying to use the Teensy 3.0 to interface with an older keyboard using UART0. Since the Arduino libraries do not do what I want (I need very fine grain control of the UART), I have to modify the registers directly.

Anyways, my code is nearly working, but I'm having an issue getting the Freescale chip to output as MSBF rather than LSBF (Datasheet page 1062). Something I'm doing (or not doing) is forcing it in LSBF mode.

The code for the UART0 control is as follows:

Code:
	// Setup the the UART interface for keyboard data input
	SIM_SCGC4 |= SIM_SCGC4_UART0; // Disable clock gating

	// Pin Setup for UART0
	PORTB_PCR16 = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); // RX Pin
	PORTB_PCR17 = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); // TX Pin

	// Setup baud rate - 1205 Baud
	// 48 MHz / ( 16 * Baud ) = BDH/L
	// Baud: 1205 -> 48 MHz / ( 16 * 1205 ) = 2489.6266
	// Thus baud setting = 2490
	// NOTE: If finer baud adjustment is needed see UARTx_C4 -> BRFA in the datasheet
	uint16_t baud = 2490; // Max setting of 8191
	UART0_BDH = (uint8_t)(baud >> 8);
	UART0_BDL = (uint8_t)baud;

	// 8 bit, Even Parity, Idle Character bit after stop
	UART0_C1 = ~UART_C1_M | ~UART_C1_PE | UART_C1_PT | UART_C1_ILT;

	// Number of bytes in FIFO before TX Interrupt
	UART0_TWFIFO = 1;

	// Number of bytes in FIFO before RX Interrupt
	UART0_RWFIFO = 1;

	// TX FIFO Disabled, TX FIFO Size 1 (Max 8 datawords), RX FIFO Enabled, RX FIFO Size 1 (Max 8 datawords)
	// TX/RX FIFO Size:
	//  0x0 - 1 dataword
	//  0x1 - 4 dataword
	//  0x2 - 8 dataword
	UART0_PFIFO = ~UART_PFIFO_TXFE | /*TXFIFOSIZE*/ (0x0 << 4) | ~UART_PFIFO_RXFE | /*RXFIFOSIZE*/ (0x0);

	// Reciever Inversion Disabled, LSBF
	UART0_S2 = ~UART_S2_RXINV | UART_S2_MSBF;

	// Transmit Inversion Disabled
	UART0_C3 = ~UART_S2_TXINV;

	// TX Disabled, RX Enabled, RX Interrupt Enabled
	UART0_C2 = UART_C2_TE | UART_C2_RE | UART_C2_RIE;

	// Add interrupt to the vector table
	NVIC_ENABLE_IRQ( IRQ_UART0_STATUS );

Afterwards, I just write to UART0_D.

I have added a few things to mk20dx128.h which is located at Lib/mk20dx128.h

Posting all of the code would fill many pages, so to build:
  • git clone git://gitorious.org/kiibohd-controller/head.git
  • cd head
  • mkdir build
  • cd build
  • cmake ..
  • make

This will generate a kiibohd.hex to load onto the Teensy 3. Only an arm-none-eabi installation is necessary.
 
I'm curious why you need such fine-grained control of the uart, especially at such a slow baud rate?

Anyway, something you might consider is the effect of lines like this:

Code:
	// Transmit Inversion Disabled
	UART0_C3 = ~UART_S2_TXINV;

I'm guessing you intended to clear the TXINV bit. But did you also intend to set the other 7 bits to all 1s? Maybe you meant to write this?

Code:
	UART0_C3 &= ~UART_S2_TXINV;
 
Well, the whole goal of this code is to be an example for my other keyboard converters. Some need bit inversion. Others have odd parity. Some have no parity. A few need 9 bit (one needs 22 bit, but I have to bit bang for that). There are a couple that had issues with the interrupt processing were too slow on the AVR so bytes would be lost (hence trying to get the FIFOs setup), my original solution was to get an interrupt, then disable interrupts and keep scanning the UART until the next few bytes came in. A few need MSBF, others LSBF.

Hmm, interesting, didn't notice that the Teensy 3.0 doesn't have a synchronous mode for the UART. I did use it at least once for a keyboard.
Also, it seems you have to enabled 9 bit mode if you want to use parity with 8 bit data.

Anyways, thanks a lot. Guess that's what happens when I write code late at night :p.
 
Status
Not open for further replies.
Back
Top