Overlay-> Seeeduino done! ->Arduino MEGA done->Serial GPS

Store Forums Video Experimenter General Discussion Overlay-> Seeeduino done! ->Arduino MEGA done->Serial GPS

Viewing 15 posts - 1 through 15 (of 31 total)
  • Author
    Posts
  • #697
    pistolero992000
    Participant

    Hi

    I’m really new to video experimenting…. So new that I haven’t bought the shield yet because I have only arduino mega and Due…

    Unfortunately in the specs it’s said that video experimenter shield won’t work in neither boards… Because of three issues…

    1.- Analog Comparator
    2.- External Interrupt and
    3.- Input Capture

    With the absolute intention of buying the shield along with an arduino Uno, I need to be sure that the mega won’t work….

    I ask this because I’ve read some forums and found this: ??? ???

    1.- analog comparator library which works with mega
    http://www.leonardomiliani.com/en/2012/analogcomp-una-libreria-per-gestire-il-comparatore-analogico/

    2.- on the arduino mega description it is said that the board has many external interrupts.
    http://arduino.cc/en/Main/ArduinoBoardMega2560

    3.- there is a function called pulseIn()…. Would this work to capture vsync?
    http://arduino.cc/es/Reference/PulseIn

    I really like what the video experimenter is able to do and I would include it in my project but my concern is the speed and available memory to display certain graphics and text with an acceptable frame rate…

    Hoping to hear soon from you!!!!

    Cheers

    #1936
    Michael
    Keymaster

    The Video Experimenter will not work on an Arduino Mega. The analog comparator pin on the microcontroller chip is not even connected to the board. I tried to make that clear here: http://nootropicdesign.com/ve/whynotmega.html

    You can use a Seeeduino Mega, which will give you more memory for higher resolution.
    http://nootropicdesign.com/projectlab/2011/07/13/ve-on-the-seeeduino-mega/

    It is not faster, though. Framerate is typically not an issue for Video Experimenter projects, as you can update the pixel frame buffer very fast.

    #1937
    pistolero992000
    Participant

    Thanks for the reply Michael!

    As you said, I understood the reasons, not that I don’t know how to read ;D ;D ;D

    What I need for now is just the text and graphics overlay. I’ve checked the demo code in the projects page and I realized that you only need to capture the falling edge of the vsync, using an interrupt to sync the overlayed image/text… So, just for overlaying texts and simple primitives, aren’t the mega or due external interrupts enough for that?

    I really don’t want you to feel that I’m questioning your knowledge, which surely is far more advanced in this matter… It’s that I have a LM1881N IC and I want to spend my money wisely… And one concern I have about buying the arduino uno r3 is the lack of enough memory to do what I need to do…

    Which brings me to another question. I found an arduino UNO R3 SMD edition which uses another version of, I believe, the same processor… Would that be right?

    Thanks again for your reply and I will check on the seedling as suggested.

    Cheers!!

    #1938
    Michael
    Keymaster

    No, external interrupts are not enough. One of the microcontroller’s input capture pins needs to be connected. That’s not the same as an external interrupt. From my article about the problems with the Arduino Mega:

    To perform video overlay, the Video Experimenter relies on an input capture pin (to capture the exact time that the pin has changed state). Even though the ATmega1280/ATmega2560 has 4 input capture pins, none of them are connected!

    The Due will absolutely not work because it has 3.3V operating voltage.

    The Uno R3 SMD edition is functionally the same as any other Uno.

    #1944
    pistolero992000
    Participant

    OK, I stand my case…

    Seeeduino Mega and Video Experimenter it is!!

    thanks a lot for your time Michael!!

    cheers

    #1945
    pistolero992000
    Participant

    Hi again,

    Is this the seeeduino you were talking about?

    http://www.ebay.com/itm/231014003200

    Another subject…

    Have you seen this solution for Arduino Due? http://stimmer.github.io/DueVGA/

    Maybe you can create a Video Experimenter DE (Due Edition) ๐Ÿ˜‰ ::) ::) ::) ::)

    Cheers!!

    #1946
    Michael
    Keymaster

    Yes, that’s the Seeeduino Mega. I don’t buy off of eBay, though, because the boards are often counterfeit. You can buy directly from Seeed Studio:
    http://www.seeedstudio.com/depot/Seeeduino-Mega-p-717.html

    The shipping is pretty fast.

    #1947
    Michael
    Keymaster

    Yeah, that Due demo is impressive. I personally wouldn’t design a product for the Due, though, because there are so few out there. There are probably 100X as many customers that have Uno vs. Due.

    #1948
    pistolero992000
    Participant

    Hi Michael,

    I have in storage a Digilent chipKit max32 with the Microchipยฎ PIC32MX795F512 processor… Today I checked the processor manual and it appears to have all the required stuff to make the video experimenter CONCEPT work… It has AIN0/AIN1, input capture and external interrupts… (Forget about plugging the shield since only the PIN numbers match but not the internal meaning of each one….except for the 3v3-5v-GND …etc… ๐Ÿ™‚ )

    My problem is that I haven’t been able to make any of my arduino projects work on that board so I’m actually storing it….

    May I asked the pro (you) to check on this and advice me if it is possible to use the max32 as a ‘graphic overlaying card’ along with my arduino projects, taking advantage of the processor speed (80mhz) and the memory available (more resolution)?

    As I might understand, the programming of that board may be different in the words but not the structure and concept so some ‘translation’ maybe needed to make the Enhanced TVOut library work with a PIC processor… Am I right about this?

    Sorry to bother…. ;D

    #1949
    Michael
    Keymaster

    No bother at all. Yes, it would be great to use that fast processor for video. You would have to port the TVout code to PIC, though. The guts of the TVout code are written in AVR assembly, so it would be a significant undertaking, but should be possible. Look around and see if anyone has done composite video generation for that processor.

    #1941
    pistolero992000
    Participant

    @Michael wrote:

    No bother at all. Yes, it would be great to use that fast processor for video. You would have to port the TVout code to PIC, though. The guts of the TVout code are written in AVR assembly, so it would be a significant undertaking, but should be possible. Look around and see if anyone has done composite video generation for that processor.

    I have done some research and the only thing I found is http://www.nathandumont.com/blog/pong-version-2-and-vgalib-for-chipkit

    unfortunately it is an UNO32 implementation … I tried it on the max32 and nothing… but may be a start…

    Do you know about someone who’s willing to do the job? … honestly I have absolutely no clue onhow to merge TVOut lib from AVR to PIC…

    aparently no one has tried to implement a composite output with PIC processors… I’ll continue the research but any help would be apreciated!!

    cheers

    #1942
    pistolero992000
    Participant

    http://chipkit.net/tag/converting-arduino/

    Anyone who understand this and translate it to english? ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€ ๐Ÿ˜€

    ??? ??? ??? ??? ??? ??? ???

    #1943
    Michael
    Keymaster

    I’m afraid I don’t know anyone doing stuff with PICs. I’m just not in that community…

    #1968
    pistolero992000
    Participant

    Hi Michael,

    I have read a lot and finally got to Input Capture 5 on the Arduino MEGA…

    Changed from Timer 1 to Timer 5, set pinMode(2, INPUT) and voilรก… I got the overlay…. BUT with a few bugs??…

    The image is horizontally stabilized and clear…. but a few ghosts appear … maybe is a timing issue.

    The biggest problem is that the overlayed video is vertically stabilized but shifted half screen up.

    I tried it in PAL with a resolution of 192×144 with the aboce results.

    PAL 240×180 it works but the timing issues are evident.
    PAL 136×102 works better than the above but ghosting is an issue
    PAL 152×114 works much better, much less ghosting but the overlayed video is scrolling up permanently at a relatively slow speed, meaning that everything is perfectly readable.

    Maybe what I’m trying to say is that the ARDUINO MEGA has two input capture available (ICP4 & ICP5, on Board pins 49 & 48 respectively), as I donยดt understand asm in the videogen.cpp, maybe it’s just a matter of adjusting the timing and you can get at least the overlay function of the shield working…
    As you siad, the AIN0 is disconnected so no video capture.

    Can you please help me figuring out the timing issues? …. I will post a video on youtube shortly showing the results so you can see what I’m talking about, and maybe you can give it a try and manage to solve it.

    this is what I changed in the initoverlay()


    // Initialize ATMega registers for video overlay capability.
    // Must be called after tv.begin().
    void initOverlay() {
    TCCR5A = 0;
    // Enable timer1. ICES0 is set to 0 for falling edge detection on input capture pin.
    TCCR5B = _BV(CS10);

    // Enable input capture interrupt
    TIMSK5 |= _BV(ICIE5);

    // Enable external interrupt INT0 on pin 2 with falling edge.
    EIMSK = _BV(INT3);
    EICRA = _BV(ISC31);
    }

    // Required to reset the scan line when the vertical sync occurs
    ISR(INT3_vect) {
    display.scanLine = 0;
    }

    Regarding the Video Pin and the Sync pinc, they remain the same as briefed in the TVOut website… VID PIN is D29 and SYNC PIN is D46 (OC5A) on the Arduino MEGA.

    Hope somebody can help with the timing and ghosting…solved…..
    cheers!!!!

    #1970
    pistolero992000
    Participant

    what I’ve changed in videogen.cpp

    /
    #include
    #include

    #include "video_gen.h"
    #include "spec/video_properties.h"
    #include "spec/asm_macros.h"
    #include "spec/hardware_setup.h"

    //#define REMOVE6C
    //#define REMOVE5C
    //#define REMOVE4C
    //#define REMOVE3C

    int renderLine;
    TVout_vid display;
    void (*render_line)(); //remove me
    void (*line_handler)(); //remove me
    void (*hbi_hook)() = ∅
    void (*vbi_hook)() = ∅

    // BEGIN Video Experimenter
    volatile char captureFlag = 0;
    void (*save_render_line)();
    int dataCaptureLine;
    int dataCaptureWait;
    uint8_t *dataCaptureBuf = 0;
    // END Video Experimenter

    // sound properties
    volatile long remainingToneVsyncs;

    // BEGIN Video Experimenter
    void resume_render() {
    render_line = save_render_line;
    }
    // END Video Experimenter

    void empty() {}

    void render_setup(uint8_t mode, uint8_t x, uint8_t y, uint8_t *scrnptr) {

    display.screen = scrnptr;
    display.hres = x;
    display.vres = y;
    display.frames = 0;

    if (mode)
    display.vscale_const = _PAL_LINE_DISPLAY/display.vres - 1;
    else
    display.vscale_const = _NTSC_LINE_DISPLAY/display.vres - 1;
    display.vscale = display.vscale_const;

    //selects the widest render method that fits in 46us
    //as of 9/16/10 rendermode 3 will not work for resolutions lower than
    //192(display.hres lower than 24)
    unsigned char rmethod = (_TIME_ACTIVE*_CYCLES_PER_US)/(display.hres*8);
    switch(rmethod) {
    case 6:
    render_line = &render_line6c;
    break;
    case 5:
    render_line = &render_line5c;
    //render_line = &renderACO_line5c;
    // BEGIN Video Experimenter
    save_render_line = &render_line5c;
    // END Video Experimenter
    break;
    case 4:
    render_line = &render_line4c;
    break;
    case 3:
    render_line = &render_line3c;
    break;
    default:
    if (rmethod > 6)
    render_line = &render_line6c;
    else
    render_line = &render_line3c;
    }


    DDR_VID |= _BV(VID_PIN);
    DDR_SYNC |= _BV(SYNC_PIN);
    PORT_VID &= ~_BV(VID_PIN);
    PORT_SYNC |= _BV(SYNC_PIN);
    DDR_SND |= _BV(SND_PIN); // for tone generation.

    // inverted fast pwm mode on timer 1
    TCCR5A = _BV(COM5A1) | _BV(COM5A0) | _BV(WGM11);
    TCCR5B = _BV(WGM13) | _BV(WGM12) | _BV(CS10);

    if (mode) {
    display.start_render = _PAL_LINE_MID - ((display.vres * (display.vscale_const+1))/2);
    display.output_delay = _PAL_CYCLES_OUTPUT_START;
    display.vsync_end = _PAL_LINE_STOP_VSYNC;
    display.lines_frame = _PAL_LINE_FRAME;
    ICR5 = _PAL_CYCLES_SCANLINE;
    OCR5A = _CYCLES_HORZ_SYNC;
    }
    else {
    display.start_render = _NTSC_LINE_MID - ((display.vres * (display.vscale_const+1))/2) + 8;
    display.output_delay = _NTSC_CYCLES_OUTPUT_START;
    display.vsync_end = _NTSC_LINE_STOP_VSYNC;
    display.lines_frame = _NTSC_LINE_FRAME;
    ICR5 = _NTSC_CYCLES_SCANLINE;
    OCR5A = _CYCLES_HORZ_SYNC;
    }
    display.scanLine = display.lines_frame+1;
    line_handler = &vsync_line;
    TIMSK5 = _BV(TOIE5);
    sei();
    }

    // render a line
    ISR(TIMER5_OVF_vect) {
    hbi_hook();
    line_handler();
    }

    void blank_line() {

    if ( display.scanLine == display.start_render) {
    renderLine = 0;

    // BEGIN Video Experimenter
    if (captureFlag == 1) { // frame capture requested
    captureFlag = 2; // capturing
    render_line = &capture_line5c;
    } else {
    if (captureFlag == 2) {
    captureFlag = 0; // capture done
    render_line = ∅
    }
    }
    // END Video Experimenter

    display.vscale = display.vscale_const;
    line_handler = &active_line;
    }
    else if (display.scanLine == display.lines_frame) {
    line_handler = &vsync_line;
    vbi_hook();
    }

    // BEGIN Video Experimenter
    // odd capture (odd/even is HIGH)
    //if ((display.scanLine == dataCaptureLine) && ((PINB & 0x4) > 0)) {

    // even capture (odd/even is LOW)
    //if ((display.scanLine == dataCaptureLine) && ((PINB & 0x4) == 0)) {
    if ((dataCaptureBuf != 0) && (display.scanLine == dataCaptureLine)) {
    render_line = &dataCapture_line5c;
    wait_until(dataCaptureWait);
    render_line();
    render_line = save_render_line;
    }
    display.scanLine++;
    }

    void active_line() {
    wait_until(display.output_delay);
    render_line();
    if (!display.vscale) {
    display.vscale = display.vscale_const;
    renderLine += display.hres;
    }
    else
    display.vscale--;

    if ((display.scanLine + 1) == (int)(display.start_render + (display.vres*(display.vscale_const+1))))
    line_handler = &blank_line;

    display.scanLine++;
    }

    void vsync_line() {
    if (display.scanLine >= display.lines_frame) {
    OCR5A = _CYCLES_VIRT_SYNC;
    display.scanLine = 0;
    display.frames++;

    if (remainingToneVsyncs != 0)
    {
    if (remainingToneVsyncs > 0)
    {
    remainingToneVsyncs--;
    }

    } else
    {
    TCCR2B = 0; //stop the tone
    PORTB &= ~(_BV(SND_PIN));
    }

    }
    else if (display.scanLine == display.vsync_end) {
    OCR5A = _CYCLES_HORZ_SYNC;
    line_handler = &blank_line;
    }
    display.scanLine++;
    }


    static void inline wait_until(uint8_t time) {
    __asm__ __volatile__ (
    "subi %[time], 10n"
    "sub %[time], %[tcnt1l]nt"
    "100:nt"
    "subi %[time], 3nt"
    "brcc 100bnt"
    "subi %[time], 0-3nt"
    "breq 101fnt"
    "dec %[time]nt"
    "breq 102fnt"
    "rjmp 102fn"
    "101:nt"
    "nopn"
    "102:n"
    :
    : [time] "a" (time),
    [tcnt1l] "a" (TCNT5L)
    );
    }

    void render_line6c() {
    #ifndef REMOVE6C
    __asm__ __volatile__ (
    "ADD r26,r28nt"
    "ADC r27,r29nt"
    //save PORTB
    "svprt %[port]nt"

    "rjmp enter6n"
    "loop6:nt"
    "bst __tmp_reg__,0nt" //8
    "o1bs %[port]n"
    "enter6:nt"
    "LD __tmp_reg__,X+nt" //1
    "delay1nt"
    "bst __tmp_reg__,7nt"
    "o1bs %[port]nt"
    "delay3nt" //2
    "bst __tmp_reg__,6nt"
    "o1bs %[port]nt"
    "delay3nt" //3
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay3nt" //4
    "bst __tmp_reg__,4nt"
    "o1bs %[port]nt"
    "delay3nt" //5
    "bst __tmp_reg__,3nt"
    "o1bs %[port]nt"
    "delay3nt" //6
    "bst __tmp_reg__,2nt"
    "o1bs %[port]nt"
    "delay3nt" //7
    "bst __tmp_reg__,1nt"
    "o1bs %[port]nt"
    "dec %[hres]nt"
    "brne loop6nt" //go too loopsix
    "delay2nt"
    "bst __tmp_reg__,0nt" //8
    "o1bs %[port]n"

    "svprt %[port]nt"
    BST_HWS
    "o1bs %[port]nt"
    :
    : [port] "i" (_SFR_IO_ADDR(PORT_VID)),
    "x" (display.screen),
    "y" (renderLine),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    #endif
    }

    void render_line5c() {
    #ifndef REMOVE5C
    __asm__ __volatile__ (
    "ADD r26,r28nt"
    "ADC r27,r29nt"
    //save PORTB
    "svprt %[port]nt"

    "rjmp enter5n"
    "loop5:nt"
    "bst __tmp_reg__,0nt" //8
    "o1bs %[port]n"
    "enter5:nt"
    "LD __tmp_reg__,X+nt" //1
    "bst __tmp_reg__,7nt"
    "o1bs %[port]nt"
    "delay2nt" //2
    "bst __tmp_reg__,6nt"
    "o1bs %[port]nt"
    "delay2nt" //3
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay2nt" //4
    "bst __tmp_reg__,4nt"
    "o1bs %[port]nt"
    "delay2nt" //5
    "bst __tmp_reg__,3nt"
    "o1bs %[port]nt"
    "delay2nt" //6
    "bst __tmp_reg__,2nt"
    "o1bs %[port]nt"
    "delay1nt" //7
    "dec %[hres]nt"
    "bst __tmp_reg__,1nt"
    "o1bs %[port]nt"
    "brne loop5nt" //go too loop5
    "delay1nt"
    "bst __tmp_reg__,0nt" //8
    "o1bs %[port]n"

    "svprt %[port]nt"
    BST_HWS
    "o1bs %[port]nt"
    :
    : [port] "i" (_SFR_IO_ADDR(PORT_VID)),
    "x" (display.screen),
    "y" (renderLine),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    #endif
    }

    void render_line4c() {
    #ifndef REMOVE4C
    __asm__ __volatile__ (
    "ADD r26,r28nt"
    "ADC r27,r29nt"

    "rjmp enter4n"
    "loop4:nt"
    "lsl __tmp_reg__nt" //8
    "out %[port],__tmp_reg__nt"
    "enter4:nt"
    "LD __tmp_reg__,X+nt" //1
    "delay1nt"
    "out %[port],__tmp_reg__nt"
    "delay2nt" //2
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay2nt" //3
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay2nt" //4
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay2nt" //5
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay2nt" //6
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay1nt" //7
    "lsl __tmp_reg__nt"
    "dec %[hres]nt"
    "out %[port],__tmp_reg__nt"
    "brne loop4nt" //go too loop4
    "delay1nt" //8
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt"
    "delay3nt"
    "cbi %[port],7nt"
    :
    : [port] "i" (_SFR_IO_ADDR(PORT_VID)),
    "x" (display.screen),
    "y" (renderLine),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    #endif
    }

    // only 16mhz right now!!!
    void render_line3c() {
    #ifndef REMOVE3C
    __asm__ __volatile__ (
    ".macro byteshiftnt"
    "LD __tmp_reg__,X+nt"
    "out %[port],__tmp_reg__nt" //0
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //1
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //2
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //3
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //4
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //5
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //6
    "nopnt"
    "lsl __tmp_reg__nt"
    "out %[port],__tmp_reg__nt" //7
    ".endmnt"

    "ADD r26,r28nt"
    "ADC r27,r29nt"

    "cpi %[hres],30nt" //615
    "breq skip0nt"
    "cpi %[hres],29nt"
    "breq jumpto1nt"
    "cpi %[hres],28nt"
    "breq jumpto2nt"
    "cpi %[hres],27nt"
    "breq jumpto3nt"
    "cpi %[hres],26nt"
    "breq jumpto4nt"
    "cpi %[hres],25nt"
    "breq jumpto5nt"
    "cpi %[hres],24nt"
    "breq jumpto6nt"
    "jumpto1:nt"
    "rjmp skip1nt"
    "jumpto2:nt"
    "rjmp skip2nt"
    "jumpto3:nt"
    "rjmp skip3nt"
    "jumpto4:nt"
    "rjmp skip4nt"
    "jumpto5:nt"
    "rjmp skip5nt"
    "jumpto6:nt"
    "rjmp skip6nt"
    "skip0:nt"
    "byteshiftnt" //1 \643
    "skip1:nt"
    "byteshiftnt" //2
    "skip2:nt"
    "byteshiftnt" //3
    "skip3:nt"
    "byteshiftnt" //4
    "skip4:nt"
    "byteshiftnt" //5
    "skip5:nt"
    "byteshiftnt" //6
    "skip6:nt"
    "byteshiftnt" //7
    "byteshiftnt" //8
    "byteshiftnt" //9
    "byteshiftnt" //10
    "byteshiftnt" //11
    "byteshiftnt" //12
    "byteshiftnt" //13
    "byteshiftnt" //14
    "byteshiftnt" //15
    "byteshiftnt" //16
    "byteshiftnt" //17
    "byteshiftnt" //18
    "byteshiftnt" //19
    "byteshiftnt" //20
    "byteshiftnt" //21
    "byteshiftnt" //22
    "byteshiftnt" //23
    "byteshiftnt" //24
    "byteshiftnt" //25
    "byteshiftnt" //26
    "byteshiftnt" //27
    "byteshiftnt" //28
    "byteshiftnt" //29
    "byteshiftnt" //30

    "delay2nt"
    "cbi %[port],7nt"
    :
    : [port] "i" (_SFR_IO_ADDR(PORT_VID)),
    "x" (display.screen),
    "y" (renderLine),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    #endif
    }

    // BEGIN Video Experimenter
    ISR(TIMER5_CAPT_vect) {
    TCNT5 -= ICR5;
    hbi_hook();
    line_handler();
    }

    /*
    ISR(INT0_vect) {
    display.scanLine = 0;
    }
    */
    // Render a line based on the analog comparator output instead of display memory
    void renderACO_line5c() {
    __asm__ __volatile__ (
    "delay2nt" // replaces ADD and ADC
    //save PORTB
    "svprt %[port]nt"

    "rjmp enterACO5n"
    "loopACO5:nt"
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]n"
    "enterACO5:nt"
    "delay1nt" //1
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay1nt" //2
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay1nt" //3
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay1nt" //4
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay1nt" //5
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "delay1nt" //6
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "dec %[hres]nt" //7
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]nt"
    "brne loopACO5nt" //8
    "in __tmp_reg__,%[acsr]nt"
    "bst __tmp_reg__,5nt"
    "o1bs %[port]n"

    "svprt %[port]nt"
    BST_HWS
    "o1bs %[port]nt"
    :
    : [port] "i" (_SFR_IO_ADDR(PORT_VID)),
    [acsr] "i" (_SFR_IO_ADDR(ACSR)),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    }

    // Capture a line using the analog comparator output and store the data in the display memory
    void capture_line5c() {
    __asm__ __volatile__ (
    "ADD r26,r28nt"
    "ADC r27,r29nt"
    "rjmp entercapture5n"
    "loopcapture5:nt"
    "in __tmp_reg__,%[acsr]nt" //8
    "bst __tmp_reg__,5nt"
    "bld r16,0nt"
    "st X+,r16nt"
    "entercapture5:nt"
    "in __tmp_reg__,%[acsr]nt" //1
    "bst __tmp_reg__,5nt"
    "bld r16,7nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //2
    "bst __tmp_reg__,5nt"
    "bld r16,6nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //3
    "bst __tmp_reg__,5nt"
    "bld r16,5nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //4
    "bst __tmp_reg__,5nt"
    "bld r16,4nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //5
    "bst __tmp_reg__,5nt"
    "bld r16,3nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //6
    "bst __tmp_reg__,5nt"
    "bld r16,2nt"
    "delay1nt"
    "dec %[hres]nt"
    "in __tmp_reg__,%[acsr]nt" //7
    "bst __tmp_reg__,5nt"
    "bld r16,1nt"
    "brne loopcapture5nt"
    "delay1nt"
    "in __tmp_reg__,%[acsr]nt" //8
    "bst __tmp_reg__,5nt"
    "bld r16,0nt"
    "st X,r16nt"
    :
    : [acsr] "i" (_SFR_IO_ADDR(ACSR)),
    "x" (display.screen),
    "y" (renderLine),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    }

    // Capture a line using the analog comparator output and store the data in
    // the data capture buffer
    void dataCapture_line5c() {
    __asm__ __volatile__ (
    "rjmp enterdcapture5n"
    "loopdcapture5:nt"
    "in __tmp_reg__,%[acsr]nt" //8
    "bst __tmp_reg__,5nt"
    "bld r16,0nt"
    "st X+,r16nt"
    "enterdcapture5:nt"
    "in __tmp_reg__,%[acsr]nt" //1
    "bst __tmp_reg__,5nt"
    "bld r16,7nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //2
    "bst __tmp_reg__,5nt"
    "bld r16,6nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //3
    "bst __tmp_reg__,5nt"
    "bld r16,5nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //4
    "bst __tmp_reg__,5nt"
    "bld r16,4nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //5
    "bst __tmp_reg__,5nt"
    "bld r16,3nt"
    "delay2nt"
    "in __tmp_reg__,%[acsr]nt" //6
    "bst __tmp_reg__,5nt"
    "bld r16,2nt"
    "delay1nt"
    "dec %[hres]nt"
    "in __tmp_reg__,%[acsr]nt" //7
    "bst __tmp_reg__,5nt"
    "bld r16,1nt"
    "brne loopdcapture5nt"
    "delay1nt"
    "in __tmp_reg__,%[acsr]nt" //8
    "bst __tmp_reg__,5nt"
    "bld r16,0nt"
    "st X,r16nt"
    :
    : [acsr] "i" (_SFR_IO_ADDR(ACSR)),
    "x" (dataCaptureBuf),
    [hres] "d" (display.hres)
    : "r16" // try to remove this clobber later...
    );
    }

    // END Video Experimenter

    Basically from Timer1 to Timer5, which has access to the ICP5 pin.
    Both NTSC and PAL have the same problem about the horizontal ghosting…. even testing the output directly from arduino (as original TVOut) has some ghosting.

    Here I posted a video showing results with the PAL 152×114 pixel resolution:

    https://www.youtube.com/watch?v=2UQGLTtM2V4&feature=youtu.be

Viewing 15 posts - 1 through 15 (of 31 total)
  • You must be logged in to reply to this topic.