1

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?

SoreDakeNoKoto
2,4222 gold badges14 silver badges23 bronze badges
asked Jun 23, 2016 at 8:23

1 Answer 1

1

I figure out the issue , I just add a small delay in ISR and my code is running fine now. I don't know reason behind it but anyway my code is running now. Here is my new 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++;
 }
 USARTWriteChar('\n');
}
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;
_delay_us(13);
 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;
 }
 }
}
answered Jun 24, 2016 at 5:11
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.