sparkfun / SparkFun_HM01B0_Camera_ArduinoLibrary

Extensible library to use the Himax HM01B0 camera in Arduino
15 stars 4 forks source link

Single-row read function? #7

Open drewhamiltonasdf opened 2 years ago

drewhamiltonasdf commented 2 years ago

Would it be possible to implement a single-row read function in hmo1b0.c? I don't have the camera yet to test this out, but my application requires this, as I can't have a blocking full-frame read in my code. Not sure how to select the row I need however...

Any suggestions? I know this is the only place there is any hope of anyone answering this question.

    // read one row
    while(HM01B0_READ_HSYNC)
    {
        while(0x00 == HM01B0_READ_PCLK);

        *(pui8Buffer + ui32Idx++) = HM01B0_READ_BYTE;

        if (ui32Idx == ui32BufferLen) {
            goto end;
        }

        while(HM01B0_READ_PCLK);
    }

    ui32HsyncCnt++;
oclyke commented 5 months ago

@drewhamiltonasdf Good question. I wish someone had documented the code a little better 🙄

The line while (0x00 == HM01B0_READ_HSYNC); is a synchronization... basically it will hold until the camera loops around and gives another HSYNC pulse (or whatever this camera does - I forget the details its been a while). Once this happens we can start to actually clock in data bytes from the parallel interface once per pixel clock.

Okay, so you can't have blocking code. Makes sense. There are (at least) two logical things to look at:

  1. Use a dedicated system to ingest camera data. Handling the bandwidth out of a camera is a big job. You can make it look transparent (somewhat) by doing this on some system and then sending the (potentially compressed, and definitely all-ready-at-one-time) data to the main system.
  2. If you don't want that complexity you could look at making this routine interrupt based. Brief thoughts on that approach below.

Interrupt based: Assume you know the resolution of your camera. Set up interrupts to fire on the HSYNC, VSYNC, and PIXCLK inputs. The routines that are called when these signals occur collectively manipulate a shared state of the capture. (e.g. when HSYNC fires reset the row counter to zero, when VSYNC fires add one to the row counter and reset the column counter, when PIXCLK fires add one to the column counter and store the data from the camera into a big buffer corresponding to your row/column position)

Depending on system speed, overheads, and a bunch of other things this may or may not actually free up some interstitial processing time for your application. The trick is going to be dealing with any overhead happening at extremely high speeds. It could very well be more efficient just to block and read a frame.

That being said... some really clever use of just the right peripherals could get you the single-line read that you mentioned. Imagine you had a "capture and compare register" (something I used on a PIC a long time ago). Let's say that it can capture VSYNC pulses and generate an interrupt that occurs only after, say, 25 pulses. Then you could read just line 25 and then quit.

Hope that helps in any small way two years two late!