0
\$\begingroup\$

Speaking generally, given a time-critical module and an MCU (act as buffer),.

If we look at the datasheet of the module, we know the timing diagram. Then, it's possible we can read the module through ISR in MCU and then forward the data to another device.

For example, the OV7670 camera module timing diagram below is for RGB565 format, where one pixel is two bytes.

enter image description here enter image description here

Then, the MCU (act as a buffer) has the job of forwarding any incoming data from the camera into an advanced device (e.g., a server) through an interface (e.g., WiFi/UDP).

For example, esp8266, which has built-in WiFi and is programmable, can be programmed with many ISR function definitions and relies on initialization. Hence, there is no need or less main loop needed. Like this pseudocode:

// camera pinout
uint8 D; //D0-D7

// auxiliary var
volatile uint8 D_BUF[1024]; // to store data
uint16 BUFF_COUNTER; // buffer indexer

void isr_d0_to_gpio0_on_rising(){
// Perform bitwise operation (OR-ing with 1) of D at bit 0.
}

// Similar to isr_d1_to_gpio1_on_rising and so on

void isr_pclk_gpio8_on_falling(){
  D_BUF[BUFFER_COUNTER] = D;
  BUFFER_COUNTER++;
  D = 0; // reset all 8-bits to zero
}

void setup(){
// init wifi, camera resolution, camera format, etc.

// Attach interrupt
  attachInterrupt(GPIO0, isr_d0_to_gpio0_on_rising, RISING);
  // Do the same for d1-d7.
  attachInterrupt(GPIO8, 
  isr_pclk_gpio8_on_falling(), FALLING);
}

void loop(){
  if BUFFER_COUNTER > 512 {
  // transmit current buffer pass through with length approx. 512 bytes into server
  transmitDataUDP(&D_BUF, BUFFER_COUNTER);
  BUFFER_COUNTER=0;
  }
}

So, does it mean relied on many ISRs, mainly hardware interrupts, can benefit faster data transmission? Assume an external factor such as a gateway or router used is fine, so the network is reliable.

\$\endgroup\$
8
  • \$\begingroup\$ You need a FIFO here. \$\endgroup\$ Commented Oct 30, 2024 at 15:00
  • \$\begingroup\$ But why? D_BUF variable is a FIFO basically. \$\endgroup\$ Commented Oct 30, 2024 at 15:08
  • \$\begingroup\$ Often two buffers are used, one for data collection and one for data forwarding or processing. They are swapped each time the input buffer is full. I don't think the esp8266 can follow the pixel clock with interrupts except it does nothing else. \$\endgroup\$ Commented Oct 30, 2024 at 18:04
  • \$\begingroup\$ Why don't you think it can't follow the pixel clock? Is it related with clock frequency? Like mismatch of XCLK between them? \$\endgroup\$ Commented Oct 30, 2024 at 22:44
  • \$\begingroup\$ @Jens collection should be larger size than forwarding, that's why I don't strictly forward until exact 1024 (max buffer) reached, limit until atleast 512 is the minimum threshold of colldction to transmit (forward). \$\endgroup\$ Commented Oct 30, 2024 at 22:57

1 Answer 1

1
\$\begingroup\$

If I were you, I would not bother with any of this - not unless you really want to get intimate with the implementation details of ESP8266. Instead, get a double-ported FIFO chip to act as a hardware buffer between the camera and the MCU. The camera can write pixels to it at its own pace, and an hsync-based interrupt handler can read the FIFO in one go, very efficiently, wasting the least amount of CPU cycles to do so.

At a later time it's easy to lower the cost - and possibly power consumption - by replacing the dedicated FIFO chip with a small, inexpensive FPGA that will do the same job, and could potentially also replace some other glue logic.


The more work you have to do per byte of data, the less throughput you have. Say two pieces of code do an identical job - one with interrupts, one without, or with fewer interrupts per second. The one with fewer interrupts will be able to process more data. Entering and exiting the interrupt handler is overhead. Without the overhead, the cycles can be spent productively.

One way to avoid interrupt overhead is to use DMA. ESP8266 hardware documentation is AFAIK not complete enough to support DMA operation, even though the SoC probably supports it. For whatever reason it's not documented so there may be ugly bugs in the hardware and/or the manufacturer chose to segment the market and not have DMA officially available in ESP8266. So unless you want to do some reverse engineering, DMA is not an option with ESP8266.

A "straightforward" interrupt handler like you suggest will have too much overhead to be invoked at pixel clock rate.

But interrupt handlers do have advantages relative to polled code. The rest of the code doesn't have to be so tightly coupled to the pixel clock rate.

How about: have an interrupt handler that is triggered from HSYNC that acquires a whole line of pixels. Let's call it "line acquisition interrupt". The handler has to read the pixel bus in a loop, with cycle-accurate delays added so that it can get the data "open loop", i.e. without depending on an external clock.

To do this, the camera and the MCU (ESP) will need to be running off the same clock source, so that the instruction cycle will be somewhat synchronized to the pixel clock.

The line acquisition interrupt may lose synchronization with the pixel clock in several scenarios.

  1. An unrelated interrupt is handled while HSYNC occurs, adding variable jitter to the start point of line acquisition.

  2. An "long" opcode like division is executing while HSYNC occurs. The interrupt handler is slightly delayed.

  3. An unrelated nested interrupt is handled while the line acquisition is active, causing pixels to be lost while the nested interrupt is handled.

To prevent those problems:

  1. A timer interrupt-based state machine needs to be activated at various times to enable and disable interrupts so that the line acquisition interrupt has no jitter due to other interrupts.

  2. The timer-based state machine - or the main loop - has to put the core into a HALT just before the line interrupt is about to be triggered. That way the jitter will be at the level of one clock cycle, so pretty good.

  3. The line acquisition interrupt must have highest priority so that it's not preemptible, and/or must run with other interrupts disabled.

None of those issues are insurmountable obstacles. They do take some diligence and effort to resolve.

\$\endgroup\$
4
  • \$\begingroup\$ I might be need to clarify, I was speaking generally, this means it's possible what am I talking about is related to another module input. \$\endgroup\$ Commented Oct 31, 2024 at 14:31
  • \$\begingroup\$ PCLK is the smallest unit of comitting a byte level data. I acknowledge about cycle, interrupt overheads. Hence, esp8266 (or generally another MCU) simply interpret data as byte instead of pixel, line, even frame, or frame stream that can burdening esp8266. At the end, let another device (udp server) that receive this bytes to reconstruct image from corrupted byte with AI. \$\endgroup\$ Commented Oct 31, 2024 at 14:31
  • \$\begingroup\$ Nothing in my answer is specific to pixels :) And there's no reason to corrupt anything. Ultimately, AI makes stuff up. So if you have the means to get real data vs. stuff that was made up, prefer the real data. AI image reconstruction that can be trusted in all scenarios is an incredibly hard problem, and is not resolved at all. It is way, way harder to do it right than to ensure no pixels are lost/corrupted. AI is not a silver bullet. It is marketed as such, so beware. \$\endgroup\$ Commented Nov 1, 2024 at 12:20
  • \$\begingroup\$ Real data vs Generated data. Don't forget, noise is also part of real data since it represents real-world scenerio. \$\endgroup\$ Commented Nov 1, 2024 at 13:22

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.