9 years, 10 months ago.

Is there a faster getc() for UART?

I am trying to communicate with some Dynamixel servos at 3Mbps using the UART Serial on an LPC1768. The hardware serial works fine at this speed, but I hooked it up to an oscilloscope and while each byte is transmitted in the expected 2.7us, a call to getc() seems to take 12us. This of course slows my program down, and I'm not getting the benefit of running at 3Mbps. I tried waiting first to make sure that something is in the buffer, since that could maybe be worked around, but it seems to be constant. I'm wondering if there is a lower level version of the getc() function that could allow me to communicate with the UART peripheral directly in order to increase the speed?

Relevant portion of read/write code

    // Transmit the packet in one burst with no pausing
    for (int i = 0; i<8 ; i++) {
        mx12_out.putc(TxBuf[i]);
    }
    
    wait_us(100); // Optionally wait first, to make sure it's not a readiness issue

    // Read
    for (int i = 0; i<8 ; i++) {
        profileOut=i%2; //Alternate a digital out pin for O-scope timing
        mx12_in.getc();
    }

Thanks,

-John

1 Answer

9 years, 10 months ago.

A first step might be replacing Serial by RawSerial, this skips the whole stdio layer which regular Serial uses and should be hopefully alot faster. You can also try SerialBase and _base_putc/_base_getc, but I don't know if that class can be instantiated (no virtual functions) and I don't know how much the speed advantage is compared to RawSerial.

Accepted Answer

And ultimately there is nothing stopping you directly accessing the UART registers but that is then getting device specific.

e.g.

if ( LPC_UART0->LSR & 0x01 ) // bit 0 of LSR = data waiting flag.
  mx12_in = LPC_UART0->RBR;

should (I think, I've not checked this) check if there is data waiting on UART0 of an LPC1768 and if so read it. Note that this is UART0 as defined by the CPU documentation not by the mbed board pinout diagrams, I've seen differences between them in some situations so you need to check schematics and pinouts to be sure.

posted by Andy A 21 Jan 2015

Thanks for the answer, I burned out my UART peripheral yesterday so I am unable to test this theory until I get another mbed, but this is exactly what I was looking for so thanks!

posted by MRD Lab 21 Jan 2015

How did you do that :P. I once connected my LPC1768 to some stepper motors + controllers (dunno which brand, maybe same :P) where I didn't realise they thought it was funny to use actual RS232 levels. And my LPC1768 survived that :D.

posted by Erik - 21 Jan 2015

I plugged the Dynamixel in backwards, so instead of GND-12V-SERIAL, I plugged it in SERIAL-12V-GND, causing the servo to try to sink an amp worth of 12V from the digital pins. I am now getting weird errors and am unable even to echo a character back to myself, so I can only assume I burned out the peripheral. I guess I learned my lesson, even on a breadboard make yourself dummy-proof connectors!

posted by MRD Lab 22 Jan 2015