How to poll UART while processing lots of other stuff

I have a GPS device which I need to pull data from (the NMEA strings.) However, many times per second my MCU will be busy processing something else. Is there any way to "pause" an UART/RS232 TTL signal or buffer it while my MCU does stuff? I'm looking at either a dsPIC33FJ128GP802 or an AT32UC38x.

The processing of my OSD cannot be interrupted, so interrupts are out.

-
Do you need any of the gps data while your cpu is busy with the OSD processing? Is there anyway to make the OSD processing more interrupt driven? –  Kellenjb Oct 29 '10 at 1:04
The OSD processing is interrupt driven. On each comparator change it determines the current line of the video and outputs the sequence of pixels to embed on the video. However, it's this critical time during the output stage that the processor is busy. –  Thomas O Oct 29 '10 at 1:06
I edited my answer thomas, did that help at all? –  Kortuk Oct 29 '10 at 14:57

Two things.

1. Make it so you have a buffer and the interrupts just queues up the data into it until you have time. Make it so parsing the GPS string is interrupt driven.
2. I have helped 5 different people do this. This is especially simple when you only need a small part of the string, like position.

I can go into more detail on either method if more clarity is required.

Side note for microchip. I think their wizard for the c18 compiler(have not used the c30 much yet) will give you a library to handle queuing the data from UART for you.

You have other interrupts that cannot ever be delayed?

If your screen controller is all done in interrupts, can you not just put it in a higher level interrupt?

This means that whenever you leave your interrupt the RX data interrupt has time to put the data in a queue. This also means that whenever your other interrupts are triggered they will get the priority you expect.

Then place in your main control loop that is not interrupt driven the processing for your GPS data. This keeps things nicely compartmentalized. Remember at most GPS baud rates you have a long time to pull chars from the character string as 4800 or 9600 baud is slow...

-
The problem is, I can't interrupt the OSD processing or the video will break up and look awful. So during the OSD processing (about 80-90% of the processor's time) the chip is pretty much uninterruptable. –  Thomas O Oct 29 '10 at 0:49
Ahh. I am sorry, I did not realize how intense your interrupt requirement was. I will leave the answer for people with a less critical process. I will write another soon. –  Kortuk Oct 29 '10 at 0:50
Thanks. My GPS device requires a minimum of 9600 baud but I may be able to sneak in reading the bits at the beginning of each line; I'm still unsure though. –  Thomas O Oct 29 '10 at 15:09
You said you are already implementing a second pic, which is what my second option would have been, but others beat me to that. This way you can have the UART go to a FIFO when your other interrupt is not serviced without changing the way that the Video interrupts are handled. –  Kortuk Oct 29 '10 at 15:12

It sounds like you really need to have your PIC dedicated to the display, 80-90% CPU usage is a lot. I see some similarities between a computer and its video card. I think you should strongly consider splitting your project into 2 PICs, 1 will handle all of the video (like a video card) and the other will handle any other processing. This second PIC can have some flow control setup between your video PIC such that the video PIC lets you know when it has some free CPU time. As soon as your 2nd PIC sees that there is extra time it will dump data to it.

Addition: The GPS packet probably includes lot more information then what your display needs, your separate PIC can "clean up" the data to get you exactly what you want/need.

Also, if your second PIC isn't doing much, you can probably get away with a very cheap PIC (sub \$3). This cost is probably well worth the time you will save in coding and debugging on a single PIC.

-
That's what I'm currently doing, using a dsPIC33F and a PIC24F. I2C can be paused, so that is how data is sent between the two devices. –  Thomas O Oct 29 '10 at 10:05
Are you having any issue with this method? –  Kellenjb Oct 29 '10 at 13:17
Well, it's more expensive, and it's bigger. If I can avoid doing it then it will be better. –  Thomas O Oct 29 '10 at 14:43
You seemed to have asked a question that you are unwilling to accept anything but magic as your answer. You say interrupts are not an option and adding extra cost or ICs is not an options. Also, you should have included in your question that you were already doing this method. If you continue on asking questions in this manner the community will assume you are asking questions just to gain more rep and treat you as spam. I don't think this will be good for anyone. –  Kellenjb Oct 29 '10 at 14:50

I believe some of the dsPIC family have DMA support in the MSSP peripheral, that will allow buffering of the input stream without cpu intervention up to a point, limited by available memory.

Use an interrupt for processing the GPS data in chunks, just make sure the interrupt for your video processing work is set to a higher priority so it can bump the GPS handling interrupt.

-

Another possible reason to go with the Propeller chip that was discussed in the other thread -- built-in timing for the video, and you can use a separate cog for RS232 without impacting the video.

It appears the AT32UC3B1256 also has a peripheral DMA capability, so you can receive data from the GPS without using interrupts.

-

I've done video overlay in an application which required polling during the data display. If you have a spare FSR available, insert:

  btfsc  INTCONx,RCIF   ; I forget which INTCON it's in
movff RCREG,POSTINC2 ; Or whichever FSR is free


at least once every 16 lines (it may be most convenient to do it every line). Only three cycles per line. If you do not have a spare FSR available, but your display code is expanded out rather than looped, then at least once every sixteen lines you need to use:

  movff  INTCONx,SerStatus+N  ; N=0 for the first one, 1 for the next, etc.
... and then (not necessarily immediately)
btfsc  SerStatus+N
movff RCREG,SerData+N


at a cost of three cycles on one line and two on another; at the end of the display:

  lfsr   0,SerData
btfsc  SerStatus+0
movff SerData+0,POSTINC0
btfsc  SerStatus+1
movff SerData+1,POSTINC0
btfsc  SerStatus+2
movff SerData+2,POSTINC0
...
movlw  (SerData & 255)
subwf  FSR0L,w
; W will now hold number of bytes received
; Data will be in SerData+0 to SerData+(W-1)


The trick is not to worry about figuring out what to do with data while showing the display. Just throw it someplace and sort it out later.

-

Assuming that your GPS unit is outputting NMEA strings at 4800bps - you should be able to find a few spare cycles in your video generator to decode a serial bitstream.

Failing that:

• If your GPS unit supports hardware flow control, you might be able to service it between frames or when your device is idle

• Another option would be an external SPI/I2C to UART bridge. Some of these devices have reasonable sized FIFOs, allowing it to buffer up outside of your PIC. Again, service it during your idle time

-
I would imagine the cost of an SPI/I2C UART bridge is probably close to the cost of an additional PIC. –  Kellenjb Oct 29 '10 at 2:40