ATTiny 8-clock quanta? (for NTSC chroma)

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

I've been working the last day or two and have an ATTiny producing color NTSC without a sync chip or anything (passives only). I just have a problem.

I'm running into an unusual 8-clock cycle quanta. If I add 1-7 nop's before my line kernel (Which includes colorburst), my color information is corrupted. I've tried resetting timer 0 which is being used to trigger the USI, I've tried resetting the USI, too. They reset alright, but unless I still have the right number of nop's, everything falls apart.

I even tried hiding my code inside something that did an rcall. Still, no success. If I inserted nops before the rcall, things fail.

Has anyone ever seen a situation in which the processors exhibit some sort of clock quanta, where the same code behaves differently depending on which of the eight clock cycles it falls on? If so, how can I detect this, and plan around it?

My hardware has some resistors hooked up to PORTA, and a cap/resistor combo on the output of the USI.

My kernel is as follows:

volatile unsigned char LineInfo[3*10];

void __attribute__((noinline)) DoLine() 
{
	asm volatile(
/*Step 1: Load next segment */
"L_d11%=:"		"\n\t" /* RSTART = L_d11%= */
"ld r26, %a0+"		"\n\t" /*2/0*/
"ld r25, %a0+"		"\n\t" /*2/2*/
"out %[chro], r25"	"\n\t" /*1/4*/ 
"ld r24, %a0+"		"\n\t" /*2/5*/
"out %[port], r24"	"\n\t" /*1/7*/
"tst r26"		"\n\t" /*1/0 */
"breq L_d13%="		"\n\t" /*1/1 (or two)*/
"L_d12%=:"		"\n\t" /* DOTCLOCK = L_d12%= */
"nop"			"\n\t" /*1/2 */
"nop"			"\n\t" /*1/3 */
"out %[chro], r25"	"\n\t" /*1/4 */
"dec r26"		"\n\t" /*1/5 */
/*Step 2: Loop this segment until complete, then move to next segment*/
"breq L_d11%="		"\n\t" /*1/6 */
"nop"			"\n\t" /*1/7 */
"rjmp L_d12%="		"\n\t" /*2/0 */
"L_d13%=:"		"\n\t" /* END = L_d13%= */
: 
: "e" (LineInfo), [port] "I" (_SFR_IO_ADDR(PORTA)), [chro] "I" (_SFR_IO_ADDR(USIDR))
: "r0","r24", "r25", "r26"
);
}

I guess I should include the code that goes into LineInfo

	//1.5us * 3.579545 = 5.369 (round down to 5, .369 left over)
	LineInfo[0] = 5-1; //Front Porch
	LineInfo[1] = 0x00; //USIDR
	LineInfo[2] = 0x84; //PORTA  

	//4.7us * 3.579545 = 16.8238 (round up to 17, .192 left over)
	LineInfo[3] = 17-1; //Sync Tip
	LineInfo[4] = 0;
	LineInfo[5] = 0x04;

	//1.1us * 3.579545 = 3.9375 (round up to 4,, .129 left over)
	LineInfo[6] = 4-1; //pre-colorburst
	LineInfo[7] = 0;
	LineInfo[8] = 0x84;

	//2.5us * 3.579545 = 7.875 (round up to 8, .004 left over)
	LineInfo[9] = 10-1;//Colorburst
	LineInfo[10] = 0x80; 
	LineInfo[11] = 0x80;

	//1.1us * 3.579545 = 3.9375 (round up to 4,, .058 in debt)
	LineInfo[12] = 4-1; //Post-colorburst
	LineInfo[13] = 0;
	LineInfo[14] = 0x84;

	//52.6 = 188.284067 (round up to 189)
	LineInfo[15] = 94-1;//(Dark Blue Bar)
	LineInfo[16] = 0x0F;
	LineInfo[17] = 0x01;

	LineInfo[18] = 94-1;//(Light Blue Bar)
	LineInfo[19] = 0x0F;
	LineInfo[20] = 0x0F;


	LineInfo[21] = 0;
	LineInfo[22] = 0x00;
	LineInfo[23] = 0xFF;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I figured I should post my solution:

Turns out, the only way around this I could find was to set up Timer1 with a known value at a known clock location, run the code of unknown clock count... Then, once done, sleep until timer1 gets triggered. Code continues executing at known quanta.