6
\$\begingroup\$

I have two UART ports on an MSP430 that need to stream data between a Host Controller (Freescale IMX6) and potential devices that can be hooked up on the other side. The Host Controller communicates (read/write) data with MSP430 (including serial data from devices) over an I2C bus.

IMX6 --writes I2C--> MSP430 --writes `UART`0--> Device 0
IMX6 <---reads I2C-- MSP430 <---reads `UART`0-- Device 0

IMX6 --writes I2C--> MSP430 --writes `UART`1--> Device 1
IMX6 <---reads I2C-- MSP430 <---reads `UART`1-- Device 1

Currently, UART receives are interrupt-based on the MSP430. When a byte comes in, it interrupts the MSP and tosses the byte into a ring buffer.

UART writes, on the other hand, are polling-based. In my main loop, I have a UART_process that runs. In that process, I check if the UART TX hardware single-byte buffer is ready for a byte. If it is, I write in a new byte, set of the transfer, and exit the function. With this functionality, it could be (for example) 1 millisecond before I send out another byte to the UART device, even though the MSP's UART may have been ready to transmit another byte much sooner.

My concern is that if I have to manage 2 UART ports from the MSP430 that are both running at 115200 Baud, will writing a byte out every 1ms (potentially a little more or less) be sufficient for the device? The baud rate transmission will still be at 115,200 obviously, but the bytes will be streaming over slowly. Some quick n rough calcs:

  • 1 bit @115,200 takes about 8µs.
  • 1 byte @115,200 will take about (8µs * 8bits) = 64µs.

So as you can see, a new byte can be transmitted from the UART driver, let's say every 100 µs. If I'm sending a byte out every 1 ms, I'm not transmitting to the device very fast (about 1/10) compared to the potential max speed.

I don't want to transmit UART via interrupt, because I fear that 2 UARTS with both RX and TX being interrupt based could take over my CPU. I have other important things I am doing as well on the MSP430. Like constantly accepting I2C messages via interrupts and handling a timer interrupt based IR process.

I've considered adding a simple task scheduler. But that wouldn't do much to speed things up because I'd probably run the task scheduler at 1ms intervals. This would only guarantee a UART byte write every 1 ms (which was what I was proposing above anyway). The other option is to look into using the DMA with the UART transmit. But I only want to explore these options if I have to.

From your experience, will most UART devices/implementations be OK with receiving bytes at a slow rate compared to the Baud rate? Any general suggestions? Let me know if I'm being unclear on any points. Thanks!

\$\endgroup\$
5
  • 1
    \$\begingroup\$ A byte will take 10 bit times with start and stop bit. \$\endgroup\$
    – starblue
    Apr 15, 2014 at 19:51
  • \$\begingroup\$ Can you run the Tx interrupt at a lower priority (I don't know MSP430)? Why do you run the Tx in the main loop only every millisecond? \$\endgroup\$
    – starblue
    Apr 15, 2014 at 19:54
  • \$\begingroup\$ Interrupt priorities can't be modified on the chip I am using (MSP430FR5739). Priorities are based on vector address. The lower the address, the higher the priority. I have the Tx in the main loop where it gets processed twice per main loop cycle. It likely gets serviced about about every 300us most of the time. But there has been times where it's taken longer (when I have heavy interrupt load from I2C and an infrared emitter timer). The 1ms was kind of arbitrary. I think I will just move to interrupt based tx'ing though (encouraged by Gustavo). \$\endgroup\$
    – gtozzi
    Apr 16, 2014 at 13:01
  • \$\begingroup\$ Btw, good point about the 10 bits per byte. I never bothered to look up the exact bit count for UART byte transfers! \$\endgroup\$
    – gtozzi
    Apr 16, 2014 at 13:03
  • \$\begingroup\$ Maybe your MSP430 is at its limit and you need something better. \$\endgroup\$
    – starblue
    Apr 16, 2014 at 19:15

3 Answers 3

2
\$\begingroup\$

Yes, most software that receives data over an asynch channel is agnostic to how fast the data arrives (up to the point where timeouts come into play). For the receiver, your situation is comparable to a baudrate that allows 1char/ms.

\$\endgroup\$
1
  • \$\begingroup\$ This most directly answers my primary question. The other comments have been very informative as well. \$\endgroup\$
    – gtozzi
    Apr 16, 2014 at 12:53
4
\$\begingroup\$

Interrupt based routines will not take over thr CPU unless you let them.

I've written many MSP430 uart drivers and the way to approach TX is to make the ISR send the bytes. Trigger the interrupt flag and then let the ISR manage sending the bytes from a buffer. You need a couple of variables in memory to manage this, but it works very well.

Remeber that it is you that trigger the ISR to send the data. You know how many bytes to send. The ISR is quite fast, so there isn't any taking over.

You are using polling which is in fact eating up your CPU time. No reason for this. Interrupts shouldn't be feared, they should be mastered.

You didn't mention which MSP430 you're using but I've been running many MSP430 based design with multiple interfaces and never had an issue with interrupts loading the CPU. In fact customers have been extatic that issues they had before due to polling and other things were gone when I re-architected them.

You mentioned RTOS. Depending on the MSP430 this might not be practical, and you don't need it. An RTOS won't solve these kind of issues.

\$\endgroup\$
2
\$\begingroup\$

I often use polling for transmission and interrupts for reception; whether that approach is adequate will depend upon what sort of buffering the UART has, and how your polling rate compares with the rate at which you actually need to send data.

Some chips have a UART which require that a byte be fully transmitted before code can load the next byte. Most chips allow the processor to load at least one byte in addition to the one which is presently being clocked out. Some may allow the processor to preload 16 bytes or even more.

If your port is set for 115,200 baud, your UART can buffer one character plus the one being transmitted, and your polling interval is 100us, then you will likely be able to transmit almost but not quite continuously, since on some occasions you will poll when the UART is almost done transmitting a byte, you will load one byte, and that byte will end up getting fully sent before your next polling operation. If your polling interval is much longer than 100us and the chip is as described, you will likely be able to send two characters per polling interval; whether that is adequate will depend upon your application.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.