Sample rate detector - port from AVR8 to 32

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi guys,

 

I've got some asm code which detects the sample rate of an audio signal (44.1, 48, 88.2, 96, 176.4, 196kHz). Timer resources are scarce and the sequential code does a good job. (See below.)

 

Now I'd like to do the same thing on the completely different instruction set of the AVR32 (UC3A3). The routine takes little time, so I can afford to turn off global interrupts. But to be on the sure side I'll add a timeout counter so that the routine doesn't hang the CPU. On the AVR8 code there wasn't time for those extra ticks. The IO pin in question is PX56.

 

Anybody care to lend a hand in porting the asm part of the code? (The timeout I can figure out myself once I see a couple functional lines of AVR32 code.)

 

 

Thanks,

Borge

 

// Be very careful with this code, as it will halt the MCU! 
// FIX: Add some sort of watchdog!
uint8_t mcu_get_freq(void) {
	uint8_t count;							// Assembly counter
	uint8_t freq;							// Detected frequency
	
	#if F_CPU != 3686400UL					// External 3.6864MHz oscillator
		#warning UNKNOWN MCU FREQUENCY!		// is only supported poll rate this far...
	#endif
		
	// Wait until DA_LRCK is 0
	// Wait until DA_LRCK is 1
	// While DA_LRCK is 0: increase value
	// While DA_LRCK is 1: increase value
	// While DA_LRCK is 0: increase value
	// While DA_LRCK is 1: increase value
	// While DA_LRCK is 0: increase value
	// While DA_LRCK is 1: increase value

	asm volatile(
		"cli				\n\t" 
		"clr  %0			\n\t" 
		"wait0:				\n\t" 
		"sbis %1, 6			\n\t" 
		"rjmp wait0			\n\t" 
		"wait1:				\n\t" 
		"sbic %1, 6			\n\t" 
		"rjmp wait1			\n\t" 
		"wait2:				\n\t" 
		"inc  %0			\n\t" 
		"sbis %1, 6			\n\t" 
		"rjmp wait2			\n\t" 
		"wait3:				\n\t" 
		"inc  %0			\n\t" 
		"sbic %1, 6			\n\t" 
		"rjmp wait3			\n\t" 
		"wait4:				\n\t" 
		"inc  %0			\n\t" 
		"sbis %1, 6			\n\t" 
		"rjmp wait4			\n\t" 
		"wait5:				\n\t" 
		"inc  %0			\n\t" 
		"sbic %1, 6			\n\t" 
		"rjmp wait5			\n\t" 
		"wait6:				\n\t" 
		"inc  %0			\n\t" 
		"sbis %1, 6			\n\t" 
		"rjmp wait6			\n\t" 
		"wait7:				\n\t" 
		"inc  %0			\n\t" 
		"sbic %1, 6			\n\t" 
		"rjmp wait7			\n\t" 
		"sei				\n\t" 
		: "=r" (count) : "I" (_SFR_IO_ADDR(PIND)) );
		
	if ((count >= 0x40) && (count <= 0x41))
		freq = HZ_44100;
	else if ((count >= 0x3B) && (count <= 0x3C))
		freq = HZ_48000;
	else if ((count >= 0x20) && (count <= 0x22))	// Interpolated
		freq = HZ_88200;
	else if ((count >= 0x1E) && (count <= 0x1F))
		freq = HZ_96000;
	else if ((count >= 0x11) && (count <= 0x12))	// Interpolated
		freq = HZ_176400;
	else if ((count >= 0x09) && (count <= 0x10))
		freq = HZ_192000;
	else
		freq = HZ_FAULT;

	return freq;
}