XTV - XMega TV output v1.00

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

I find in "XTV.C" this:

ISR( RENDER_INTERRUPT )
{
#define TWEAK 8
	// First remove any jitter!

	// This interrupt will have up to 4 cycles of jitter, depending on what instruction was
	// executing at the point of firing. This jitter looks awful on video signals.

	// Fortunately, we can adjust for it, because our scanline timer runs 1:1 with the CPU clock

	// TODO: Find out if larger XMegas have longer instructions. If so, this adjustment
	// routine will need to handle more than 4 cycles of jitter.

A standart prolog for C function and call another function as first action:

 out  SPH, r28
 out  SPL, r29
 call a_function

make jitter of 5 cycles (for 2-byte address XMEGA), IMHO.

Ilya

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Op is referring to this project I believe:

http://www.avrfreaks.net/index.p...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

(thanks, 501-q for nudging me via PM about this thread!)

XTV.c includes a short lump of code designed to allow for the small variable latency on AVR interrupt calls.
The variable latency is caused because an interrupt can't be called until the current instruction has been completed. On AVRs, different instructions take different lengths of time to run.

This is not normally important, however when generating video signals, this jitter is noticeable:

The lump of code referred to by the OP can cater for up to 4 cycles of jitter, so I think the OP's code snippet:

501-q wrote:

 out  SPH, r28
 out  SPL, r29
 call a_function


would be just fine. The longest instruction is the CALL, which is 3 cycles long (unless I've missed something, and these three instructions are atomic for some reason?)
I think it should therefore work fine.

Or have I answered the wrong question? (I'm good at that!)

[edit: The latest version of the code (which includes bitmap output) will cater for the larger latencies of bigger XMegas. Larger XMegas (>128kb flash) have slightly longer instructions]

Nigel Batten
www.batsocks.co.uk

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

condemned wrote:

The lump of code referred to by the OP can cater for up to 4 cycles of jitter,

Yes, I made a mistake: the code snippet make 4 cycles of jitter on 2-byte address xmegas, IMHO.

Quote:
so I think the OP's code snippet:
501-q wrote:

 out  SPH, r28
 out  SPL, r29
 call a_function


would be just fine. The longest instruction is the CALL, which is 3 cycles long (unless I've missed something, and these three instructions are atomic for some reason?)
I think it should therefore work fine.

Command:

out SPH, r28

disable interrupts till command:

out SPL, r28

the next command:

call a_function

will execute immediately without any interrupt between 'out' and 'call', IMHO. So "the longest instruction" should be considered 5 cycles long that introduce 4 cycles jitter. The code in XTV.c (brilliant code!):

 // The following assembler will introduce a 
 // delay of 4c to 7c, depending on the bottom two bits of 'now'.
 asm(
  "sbrs %0, 1 ; Skip next instruction if bit 1 is set. (1c if noskip, 2c if skipping) \n\t"
  "lpm   ; equiv. to 3c NOP \n\t"
  "sbrs %0, 0 ; skip next instruction if bit 0 is set. (1c if noskip, 2c if skipping) \n\t"
  "rjmp .+0   ; equiv. to 2c NOP \n\t"
  :
  : "r" (now)
  ) ;
 

eliminate only 3 cycles of jitter.

I use this code:

macro wait reg 
; take pause (from 10 to 255+10=265 ticks) 
; that in end of macro TCNT1L == reg 
; (TIMER1 prescaller == 1) 
; reg cannot be ZL 
; use regs: ZL and reg 
lds ZL, TCNT1L ; +2: 2 
sub \reg, ZL ; +1: 3 
subi \reg, 10 ; +1: 4 
100: subi \reg, 3 ; +1: 5 
brcc 100b ; +1: 6 
; reg from -3 to -1 
subi \reg, 0-3 ; +1: 7 
; reg from 0 to 2 ; ---- 
breq 101f ; 0: 3 ; +3: 10 
dec \reg 
breq 102f ; 1: 4 ; +1: 11 
rjmp 102f ; 2: 5 ; +1: 12 
101: nop 
102: 
; ok! toggle pin now 
.endm ; wait

Ilya

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah ha! I've just managed to find where this "disable interrupts" when accessing SPL is documented:

XMega AU manual, Section 3.8 'Stack and Stack Pointer wrote:
To prevent corruption when updating the stack pointer from software, a write to SPL will auto-
matically disable interrupts for up to four instructions or until the next I/O memory write.

Interestingly, I've not seen this cause a problem in the video signal - it's been rock-solid, regardless of the code that's running in the main-loop.

Fortunately, as you say, there are ways of extending the anti-jitter code. The latest XTV (2) code already has a more capable bit of code::

/*======================================================================================*/
// Following quad of instructions introduce a delta of 4c if bit 2 is set.
sbrs	%0 ,2    ; Skip next instruction if bit 2 is set. (1c if noskip, 2c if skipping)
lpm             ; equiv. to 3c NOP
sbrs	%0 ,2    ; Skip next instruction if bit 2 is set. (1c if noskip, 2c if skipping)
lpm             ; equiv. to 3c NOP

// Following pair of instructions introduce a delta of 2c if bit 1 is set.
sbrs	%0 ,1    ; Skip next instruction if bit 1 is set. (1c if noskip, 2c if skipping)
lpm             ; equiv. to 3c NOP

// Following pair of instructions introduce a delta of 1c if bit 0 is set.
sbrs 	%0 ,0	; skip next instruction if bit 0 is set. (1c if noskip, 2c if skipping)
rjmp	.+0		; equiv. to 2c NOP

I can't claim credit for the idea (but I did write the code). AtomicZombie did something similar in this 'Glitchy interrupt timing' thread.

I'd previously achieved jitter-free interrupts by going to sleep just before it's due to fire.

Nigel Batten
www.batsocks.co.uk