3
\$\begingroup\$

I have been thinking about my design for a while but couldn't figure out a better way to deal with buffer overrun in multiple interrupts.

A dsPIC33EP chip is connected to a TFT display, a UART sensor, a micro-SD card and a UART camera. The baudrate of the UART sensor is 921600 and the camera (50k per pic) is 57600. The SD card sector write (512 bytes) time is a little bit less than 2ms. The screen (EVE FT800) takes 20ms to update.

The goal is to respond to the UART sensor (at least every 30ms) and update screen accordingly (update labels) and at the same time write pictures into the SD card.

To break down the task, I have successfully saved multiple pictures to the SD card using interrupts when only camera and SD card are running.

The interrupt routine:

volatile unsigned char buff[512];
volatile unsigned int ptr=0;
volatile unsigned char EOF=0;
volatile unsigned char buffReady=0;
void ISR(){
    static unsigned char temp;
    temp=UART_Read();
    buff[ptr++]=temp;
    if(ptr==512){ptr=0;buffReady=1;}
    if(...){EOF=1;}
}

While the program is stuck in a loop to check EOF flag

while(1){
   if(buffReady){SD_Write_Sector(buff);buffReady=0;}//write 512 bytes of image to SD card
   if(EOF){break;}//jump out if the image has been finished
}

My concern is, how do I incorporate the routines to update the screen while receiving data from the UART sensor? It looks like the buffReady flag must be checked constantly. Any delay between each check may lose couple bytes since they are overwritten with new bytes.

Since the picture size is around 50K and the baudrate is 57600, there will be six bytes coming from the camera every millisecond. If the screen introduces a 20ms delay in between, the picture will sure be corrupted.

I thought about using a larger buffer to store pictures but larger buffer needs more time to be written to the SD card.

How should I arrange update screen and write image to SD card?

\$\endgroup\$
3
\$\begingroup\$

The dsPIC33EP provides a DMA interface to the UART (see chapter 8 of the datasheet). If you configure a buffer large enough for 20ms of data, you can configure the DMA to write into that buffer and then read the results between screen updates. Note that: $$ 57,600~bps \cdot 0.02~sec = 1152~bits = 144~bytes $$ If you are using SPI to write to the SD card, DMA can also be used there to limit the CPU load during the larger writes (the driver might already have built-in DMA support).

Alternatively, you could perform the actual buffer read in the interrupt (instead of polling for a flag). This is a bad idea in most cases, however, for multiple reasons:

  • As little code as possible should be placed in interrupts, to reduce system latency;
  • It depends on the method being used to drive the display, but it is likely that read interrupts received during a screen refresh will result in visual glitches;
  • Function calls from within interrupts are rarely a good idea--they typically increase the pre- and post-interrupt code written by the compiler (to save off registers, etc.), and introduce opportunities for deadlock that would be more obvious with inline code.

In short, DMA is made for the situation you describe. It is usually a painful process to set up and debug multiple DMA transfers, but it will allow clean display refreshes due to the longer reads and writes without CPU intervention.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the suggestion. I was thinking about DMA before but the SD card driver doesn't support it. I'm still testing it using proper interrupt and larger buffer. If it doesn't work out, I guess adding another chip is the final solution. \$\endgroup\$ – Timtianyang Sep 25 '13 at 3:04
  • \$\begingroup\$ If you have the source code for the SD card driver, you may be able to modify it to use DMA for writes. That is probably going to be easier than adding another micro to the design. Often the reason DMA isn't supported in a driver is that it introduces the potential for conflicts with other uses of DMA in the system, but since you own the system, this isn't an issue. \$\endgroup\$ – Scott Winder Sep 25 '13 at 12:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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