With limited time available (this is a hobby project) and lots of other things I wanted to try, I did a last attempt on the project last night and here are my observations:
1. The PIC ADC module is not to blame because when simulating the gameboy analog output with a signal generator, the generated image is perfect and does not exhibit such interference.
2. The delay itself when writing to SD card is also not to blame. I tried simulating the sd card write cycles by adding a delay_us(100), then sent the image data via UART and reconstructed the image on the PC. The constructed image, also did not have such interference.
3. The delay between retrieving pixels (the gameboy camera sends a new pixel upon a new rising edge on its clock line) indeed makes the image brighter (due to an increase in the exposure time). However, as I write to SD card per every pixel, and not per group of pixels - 3 bytes per each pixel for 24-bit bitmap, this would not have caused such a weird patterns of brightness in the image.
4. The distorted image is from the gameboy output itself. I recorded the output voltage using my Rigol oscilloscope, exported it to PC and write software to reconstruct the image. The same inteference effect exists!
5. The point about the ADC conversion clock and the change of the power supply configuration I discovered is somewhat relevant. With the previous shared regulator config, there were random noises when the SD card is being written to (a 7805 in TO-92 form can only deliver 100mA, while the circuit can consume up to 110-140mA). The sampling time has to be longer to reduce the effects of these noises. With the new independent regulator config, there are no longer noises, and the sampling time can be shorter. But that's all to it.
6. To answer your questions, I have also tried decoupling capacitor and moving the ADC stuff to an interrupt. I even tried a buffer of 512 bytes and only write to SD once the buffer is full. Same effect, although the interference pattern is different.
This is my ADC code:
AD1CON1bits.ASAM = 0;
AD1CON1bits.SSRC = 0b111;
AD1CON1bits.ADSIDL = 0;
AD1CON2bits.VCFG = 0b000;
AD1CON3 = 0b0001111100010111;
AD1CHS = 0;
The ADC is in manual sampling mode, I only start sampling after I send the camera the clock pulse:
int getAdcValue()
{
//start a measurement with the ADC
AD1CON1bits.DONE=0; //resets DONE bit
AD1CON1bits.SAMP=1; //start sample
while(AD1CON1bits.DONE==0); //wait for conversion to finish
AD1CON1bits.SAMP=0;
return ADC1BUF0; //get the voltage measurement
}
Although the program cycle changes when writing to the SD card, I don't see how using a delay instead does not result in the same problem. Also reading from card (via fsfread) does not cause such behaviour.
I have also tried various other SD cards, same effect.
One last question regarding connecting from the SD card to the PIC, is a direct connection sufficient, or do I need pull-up/pull down registers for SD_CS, MOSI, MISO and CLOCK? Although I don't see how writing/reading the SD card would still work properly otherwise if any required connection is missing.
Is there also a possibility that writing to SD card generates some sort of noises/inteferences that is interpreted by the camera sensor itself?