Store › Forums › Video Experimenter › General Discussion › Overlay-> Seeeduino done! ->Arduino MEGA done->Serial GPS
- This topic has 30 replies, 3 voices, and was last updated 10 years, 3 months ago by xiaoyouyou1hao.
-
AuthorPosts
-
July 5, 2014 at 6:23 pm #697pistolero992000Participant
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 CaptureWith 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/ArduinoBoardMega25603.- there is a function called pulseIn()…. Would this work to capture vsync?
http://arduino.cc/es/Reference/PulseInI 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
July 6, 2014 at 1:41 pm #1936MichaelKeymasterThe 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.
July 6, 2014 at 7:35 pm #1937pistolero992000ParticipantThanks 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!!
July 6, 2014 at 10:42 pm #1938MichaelKeymasterNo, 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.
July 7, 2014 at 2:54 am #1944pistolero992000ParticipantOK, I stand my case…
Seeeduino Mega and Video Experimenter it is!!
thanks a lot for your time Michael!!
cheers
July 8, 2014 at 11:06 am #1945pistolero992000ParticipantHi 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!!
July 8, 2014 at 1:31 pm #1946MichaelKeymasterYes, 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.htmlThe shipping is pretty fast.
July 8, 2014 at 1:34 pm #1947MichaelKeymasterYeah, 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.
July 9, 2014 at 12:56 pm #1948pistolero992000ParticipantHi 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
July 9, 2014 at 2:39 pm #1949MichaelKeymasterNo 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.
July 9, 2014 at 4:10 pm #1941pistolero992000Participant@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
July 9, 2014 at 4:44 pm #1942pistolero992000Participanthttp://chipkit.net/tag/converting-arduino/
Anyone who understand this and translate it to english? ๐ ๐ ๐ ๐ ๐ ๐ ๐ ๐ ๐ ๐ ๐
??? ??? ??? ??? ??? ??? ???
July 9, 2014 at 4:59 pm #1943MichaelKeymasterI’m afraid I don’t know anyone doing stuff with PICs. I’m just not in that community…
July 30, 2014 at 2:49 am #1968pistolero992000ParticipantHi 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!!!!July 30, 2014 at 1:01 pm #1970pistolero992000Participantwhat 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 ExperimenterBasically 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
-
AuthorPosts
- You must be logged in to reply to this topic.