I am trying to replicate an LTC Audio Decoder code from Arduino Uno into AVR ATmega8 which I got from here.
My Arduino Uno code is working great. Here is my Arduino Uno code:
#define one_time_max 588 // these values are setup for NTSC video
#define one_time_min 422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max 1080 // 80bits times 29.97 frames per sec
#define zero_time_min 922 // equals 833 (divide by 8 clock pulses)
#define icpPin 8 // ICP input pin on arduino
#define end_data_position 63
#define end_sync_position 77
#define end_smpte_position 80
volatile unsigned int bit_time;
volatile boolean valid_tc_word;
volatile boolean ones_bit_count;
volatile boolean tc_sync;
volatile boolean write_tc_out;
volatile boolean drop_frame_flag;
volatile byte total_bits;
volatile byte current_bit;
volatile byte sync_count;
volatile byte tc[8];
volatile char timeCode[11];
/* ICR interrupt vector */
ISR(TIMER1_CAPT_vect)
{
//toggleCaptureEdge
TCCR1B ^= _BV(ICES1);
//Serial.println("Inter");
bit_time = ICR1;
//resetTimer1
TCNT1 = 0;
if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
{
//Serial.println(bit_time, DEC);
total_bits = 0;
}
else
{
if (ones_bit_count == true) // only count the second ones pluse
ones_bit_count = false;
else
{
if (bit_time > zero_time_min)
{
current_bit = 0;
sync_count = 0;
}
else //if (bit_time < one_time_max)
{
ones_bit_count = true;
current_bit = 1;
sync_count++;
if (sync_count == 12) // part of the last two bytes of a timecode word
{
sync_count = 0;
tc_sync = true;
total_bits = end_sync_position;
}
}
if (total_bits <= end_data_position) // timecode runs least to most so we need
{ // to shift things around
tc[0] = tc[0] >> 1;
for(int n=1;n<8;n++)
{
if(tc[n] & 1)
tc[n-1] |= 0x80;
tc[n] = tc[n] >> 1;
}
if(current_bit == 1)
tc[7] |= 0x80;
}
total_bits++;
}
if (total_bits == end_smpte_position) // we have the 80th bit
{
total_bits = 0;
if (tc_sync)
{
tc_sync = false;
valid_tc_word = true;
}
}
if (valid_tc_word)
{
valid_tc_word = false;
timeCode[11]= '\0';
timeCode[10] = (tc[0]&0x0F)+0x30; // frames
timeCode[9] = (tc[1]&0x03)+0x30; // 10's of frames
timeCode[8] = '-';
timeCode[7] = (tc[2]&0x0F)+0x30; // seconds
timeCode[6] = (tc[3]&0x07)+0x30; // 10's of seconds
timeCode[5] = '-';
timeCode[4] = (tc[4]&0x0F)+0x30; // minutes
timeCode[3] = (tc[5]&0x07)+0x30; // 10's of minutes
timeCode[2] = '-';
timeCode[1] = (tc[6]&0x0F)+0x30; // hours
timeCode[0] = (tc[7]&0x03)+0x30; // 10's of hours
drop_frame_flag = bit_is_set(tc[1], 2);
write_tc_out = true;
}
}
}
void setup()
{
Serial.begin(9600);
pinMode(8, INPUT); // ICP pin (digital pin 8 on arduino) as input
bit_time = 0;
valid_tc_word = false;
ones_bit_count = false;
tc_sync = false;
write_tc_out = false;
drop_frame_flag = false;
total_bits = 0;
current_bit = 0;
sync_count = 0;
Serial.println("Finished setup ");
delay (1000);
TCCR1A = B00000000; // clear all
TCCR1B = B11000010; // ICNC1 noise reduction + ICES1 start on rising edge + CS11 divide by 8
TCCR1C = B00000000; // clear all
TIMSK1 = B00100000; // ICIE1 enable the icp
TCNT1 = 0; // clear timer1
}
void loop()
{
if (write_tc_out)
{
write_tc_out = false;
//if (drop_frame_flag)
//Serial.print("TC-[df] ");
//else
//Serial.print("TC-[nd] ");
Serial.println((char*)timeCode);
// Serial.print(" ");
//Serial.print("\r");
}
}
Now to replicate this code for AVR ATmega8, I just copy this code in AVR studio and make small changes like initializing UART, initializing Input Capture Mode etc. Here is my AVR ATmega8 code:
#define F_CPU 16000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/sfr_defs.h>
#define one_time_max 588 // these values are setup for NTSC video
#define one_time_min 422 // PAL would be around 1000 for 0 and 500 for 1
#define zero_time_max 1080 // 80bits times 29.97 frames per sec
#define zero_time_min 922 // equals 833 (divide by 8 clock pulses)
#define icpPin 8 // ICP input pin on arduino
#define end_data_position 63
#define end_sync_position 77
#define end_smpte_position 80
volatile unsigned int bit_time;
volatile char valid_tc_word;
volatile char ones_bit_count;
volatile char tc_sync;
volatile char write_tc_out;
volatile char drop_frame_flag;
volatile unsigned char total_bits;
volatile unsigned char current_bit;
volatile unsigned char sync_count;
volatile unsigned char tc[8];
volatile char timeCode[11];
void USARTInit(uint16_t ubrr_value)
{
UBRRL = ubrr_value;
UBRRH = (ubrr_value>>8);
UCSRC|=(1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
UCSRB=(1<<RXCIE)|(1<<RXEN)|(1<<TXEN);
}
unsigned char USARTReadChar()
{
while(!(UCSRA & (1<<RXC)));
return UDR;
}
void USARTWriteChar(char data)
{
while(!(UCSRA & (1<<UDRE)));
UDR=data;
}
void send_string(char s[])
{
int i =0;
while (s[i] != 0x00)
{
USARTWriteChar(s[i]);
i++;
}
}
int main(void)
{
USARTInit(103);
DDRB=0;
bit_time = 0;
valid_tc_word = 0;
ones_bit_count = 0;
tc_sync = 0;
write_tc_out = 0;
drop_frame_flag = 0;
total_bits = 0;
current_bit = 0;
sync_count = 0;
send_string("FINISHED SETUP");
_delay_ms(1000);
TCCR1A = 0;
TCCR1B = (1<<ICNC1)|(1<<ICES1)|(1<<CS11);
TIMSK = (1<<TICIE1);
TCNT1 = 0;
sei();
while(1)
{
if (write_tc_out==1)
{
write_tc_out = 0;
send_string((char*)timeCode);
}
}
}
ISR(TIMER1_CAPT_vect)
{
//toggleCaptureEdge
TCCR1B ^= _BV(ICES1);
//Serial.println("Inter");
bit_time = ICR1;
//resetTimer1
TCNT1 = 0;
if ((bit_time < one_time_min) || (bit_time > zero_time_max)) // get rid of anything way outside the norm
{
//Serial.println(bit_time, DEC);
total_bits = 0;
}
else
{
if (ones_bit_count == 1) // only count the second ones pluse
ones_bit_count = 0;
else
{
if (bit_time > zero_time_min)
{
current_bit = 0;
sync_count = 0;
}
else //if (bit_time < one_time_max)
{
ones_bit_count = 1;
current_bit = 1;
sync_count++;
if (sync_count == 12) // part of the last two bytes of a timecode word
{
sync_count = 0;
tc_sync = 1;
total_bits = end_sync_position;
}
}
if (total_bits <= end_data_position) // timecode runs least to most so we need
{
// to shift things around
tc[0] = tc[0] >> 1;
for(int n=1;n<8;n++)
{
if(tc[n] & 1)
tc[n-1] |= 0x80;
tc[n] = tc[n] >> 1;
}
if(current_bit == 1)
tc[7] |= 0x80;
}
total_bits++;
}
if (total_bits == end_smpte_position) // we have the 80th bit
{
total_bits = 0;
if (tc_sync)
{
tc_sync = 0;
valid_tc_word = 1;
}
}
if (valid_tc_word==1)
{
valid_tc_word = 0;
timeCode[11]= '\0';
timeCode[10] = (tc[0]&0x0F)+0x30; // frames
timeCode[9] = (tc[1]&0x03)+0x30; // 10's of frames
timeCode[8] = '-';
timeCode[7] = (tc[2]&0x0F)+0x30; // seconds
timeCode[6] = (tc[3]&0x07)+0x30; // 10's of seconds
timeCode[5] = '-';
timeCode[4] = (tc[4]&0x0F)+0x30; // minutes
timeCode[3] = (tc[5]&0x07)+0x30; // 10's of minutes
timeCode[2] = '-';
timeCode[1] = (tc[6]&0x0F)+0x30; // hours
timeCode[0] = (tc[7]&0x03)+0x30; // 10's of hours
drop_frame_flag = bit_is_set(tc[1], 2);
write_tc_out = 1;
}
}
}
Now when I run this code, I don't get any time stamps. I have gone through this code many times but I am unable to figure out the mistake in my code. Can any one help me figure out the issue?