We have built a frequency acquisition device based on ATmega8 and Python and are using USB for communication.
In the usbdrv.h file it is said that the interrupt takes a maximum of 1200 cycles. We are operating at 16Mhz clock and the communication time is coming out to be 60-80ms. The python code sends a USB control-in transfer once every 250ms and the total number of bytes sent is 200. We are grateful for any help you can give.
here is my firmware code
Code: Select all
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv.h"
#define F_CPU 16000000
uchar pres,prev,mask,ind[4];
short int ch1,ch2,ch3,ch4,chf1,chf2,chf3,chf4;
short int dataBuffer[110];
/*=============================================================================
Timer2 Interrupt routine
=============================================================================*/
ISR(TIMER2_COMP_vect)
{
sei();
ch1++;
ch2++;
ch3++;
ch4++;
}
/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
TCCR2=0;
TIMSK &=!(1<<OCIE2);
usbRequest_t *rq = (void *)data;
if(rq->bRequest == 0) /* echo -- used for reliability tests */
{
dataBuffer[0] = rq->wValue.bytes[0];
dataBuffer[1] = rq->wValue.bytes[1];
dataBuffer[2] = rq->wIndex.bytes[0];
dataBuffer[3] = rq->wIndex.bytes[1];
usbMsgPtr = dataBuffer; /* tell the driver which data to return */
return 4;
}
else if(rq->bRequest == 1) /*reset and restart timer by host request */
{
ch1=ch2=ch3=ch4=0;
ind[0]=1;
ind[1]=26;
ind[2]=51;
ind[3]=76;
TIMSK|=(1<<OCIE2); /*enable compare match interrupt*/
TCCR2=0x09; /*start timer with no prescaler, CTC mode*/
TCNT2=0; /*Clear timer count*/
TIFR&=!(1<<OCF2);
PORTB&=!(1<<1);
return 0;
}
else if(rq->bRequest == 2)
{
dataBuffer[0]=ind[0];
dataBuffer[25]=ind[1];
dataBuffer[50]=ind[2];
dataBuffer[75]=ind[3];
usbMsgPtr = dataBuffer; /* tell the driver which data to return */
PORTB|=(1<<1);
return 200; /* tell the driver to send 200 bytes */
}
return 0; /* default for not implemented requests: return no data back to host */
}
/* ------------------------------------------------------------------------- */
int main(void)
{
uchar i;
wdt_enable(WDTO_1S);
/* Even if you don't use the watchdog, turn it off here. On newer devices,
* the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
*/
usbInit();
usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */
i = 0;
while(--i){ /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
sei();
OCR2=0x78; /* set compare match value */
DDRC=0xf0;
DDRB=0x3f;
DDRD=0xeb;
prev=PINC;
ind[0]=1;
ind[1]=26;
ind[2]=51;
ind[3]=76;
for(;;)
{
/* main event loop */
wdt_reset();
usbPoll();
pres=PINC;
mask=( prev ^ pres ) & pres; /* rising edge */
if(mask)
{
TIMSK&=!(1<<OCIE2);
chf1 = ch1; /* Freeze all the counter value upon transition detection*/
chf2 = ch2;
chf3 = ch3;
chf4 = ch4;
TIMSK|=(1<<OCIE2);
if((mask & 1) && (ind[0]<25))
{
dataBuffer[ind[0]] = chf1;
ind[0]++;
ch1=0;
}
if((mask & (1<<1)) && (ind[1]<50))
{
dataBuffer[ind[1]] = chf2;
ind[1]++;
ch2=0;
}
if((mask & (1<<2)) && (ind[2]<75))
{
dataBuffer[ind[2]] = chf3;
ind[2]++;
ch3=0;
}
if((mask & (1<<3)) && (ind[3]<100))
{
dataBuffer[ind[3]] = chf4;
ind[3]++;
ch4=0;
}
}
prev=pres;
}
return 0;
}
/* ------------------------------------------------------------------------- */