PDA

View Full Version : Teensy 3.0 UART0 MSBF/LSBF Not switchable



HaaTa
02-01-2013, 05:27 PM
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:



// 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.

PaulStoffregen
02-01-2013, 06:14 PM
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:



// 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?



UART0_C3 &= ~UART_S2_TXINV;

HaaTa
02-01-2013, 07:45 PM
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.