CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Interrupt Problem with Acquisition Board

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
daniaccount



Joined: 04 Apr 2012
Posts: 1

View user's profile Send private message

Interrupt Problem with Acquisition Board
PostPosted: Thu Apr 05, 2012 7:35 am     Reply with quote

Acquisition board
My application is to get an acquisition of 50KHZ store them in ping and pong buffers then put them trough usb port to the PC.
I'm using timer2 (20 microsecond) to get the analog data. I developed a c++ application to read from usb and trace the acquisition in a file. Comparing this acquisition file with the original one, I notice that some data are lost I put a toggling in timer 2. So I notice that a drift occurs in this toggle just when I use the command usb_puts to put the buffer to usb port, otherwise everything is ok. I put timer2 to high priority but nothing is changed. I tried to send just one packet of 64 bytes with usb_puts and eliminated the whole code in timer2 except toggling but the drift problem is the same. I didn't find any relation between this command or usb interrupt and timers interrupt. This problem is the same with timer0 and timer1.
This is my code:
Code:

#include <18F4550.h>
 
#DEVICE HIGH_INTS=TRUE
#PRIORITY TIMER2
#DEVICE ADC=16
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN
#use delay(clock=20000000)

/////////////////////////////////////////////////////////////////////////////
//
// CCS Library dynamic defines.  For dynamic configuration of the CCS Library
// for your application several defines need to be made.  See the comments
// at usb.h for more information
//
/////////////////////////////////////////////////////////////////////////////
#DEFINE USB_HID_DEVICE     FALSE
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK  //turn on EP1 for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK  //turn on EP1 for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    64  //size to allocate for the tx endpoint 1 buffer
#define USB_EP1_RX_SIZE    64   //size to allocate for the rx endpoint 1 buffer

#include <pic18_usb.h>
#include <usb_desc.h>   //USB Configuration and Device descriptors for this UBS device
#include <usb.c>           //handles usb setup tokens and get descriptor reports

//#define size 294
#define size 8
#define LED1 PIN_D0
#define LED2 PIN_D1
unsigned int16 packet_size;

static int16 index;

#LOCATE index = 0x31
int16 i ;
int1 BUFFER_COMPLETE_FLAG ;
int16 value;

int8 PingBuffer[size];
int8 PongBuffer[size];
int8 PingPong;

int8 Ext_Buffer[size];

 #INT_TIMER2  HIGH
void   TIMER2_isr(void)  {
                   
  output_toggle(LED1);
 
  value=read_adc(ADC_READ_ONLY );
  read_adc(ADC_START_ONLY );
  value=(int16)((int16)value ^ 0x8000);
 
 if (PingPong)
  {
  PingBuffer[index]=make8(value,1);
 
  index++;
  PingBuffer[index]=make8(value,0);

 if(index<(size-1)) index++; else {index=0; BUFFER_COMPLETE_FLAG=1;PingPong = 0;}
  }
  else
  {
   PongBuffer[index]=make8(value,1);
   index++;
   PongBuffer[index]=make8(value,0);
  if(index<(size-1)) index++; else {index=0; BUFFER_COMPLETE_FLAG=1;PingPong = 1;}
  }
 
}

#zero_ram

void main( void )
{
   PingPong = 1;
   
  BUFFER_COMPLETE_FLAG=0;
   setup_adc_ports(AN0|VSS_VDD);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); 
   setup_timer_2(T2_DIV_BY_1,112,2); //20 micro second
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER2);
   enable_interrupts(GLOBAL);
 
   usb_init_cs();

   while( TRUE )
   {
    if (BUFFER_COMPLETE_FLAG)
      {
       BUFFER_COMPLETE_FLAG=0;
       
   usb_task();
     
     if (PingPong)
     usb_puts( 1,PongBuffer,size,10);
       else
     usb_puts( 1,PingBuffer,size,10);
 
     }
     
    }
}

Please can I get help with this issue?!

Best Regards.
_________________
DAN
RF_Developer



Joined: 07 Feb 2011
Posts: 839

View user's profile Send private message

PostPosted: Thu Apr 05, 2012 8:35 am     Reply with quote

Some questions for you:

What is the total conversion time when using the internal clock?

What is the interrupt latency time?

How much time does your interrupt code take to run?

If am pretty sure that your interrupt code is taking too long and your ADC won't convert fast enough, remembering that the processor will take the interrupt latency time BEFORE it can service the ADC, so the absolute minimum cycle time is the latency PLUS the ADC conversion time, and that doesn't take into account any code in ISR, which in any case looks to be more complicated than it really needs to be. With any 18 series all that is always going longer than 20us, so you are going to miss interrupts and sample slower than you expect.

Its good to see you're overlapping conversions with processing but even so 50kHz for an 18 series is not realistic. Crying or Very sad
It may/should be possible on a 24, dsPIC or 32 series.

RF Developer
Ttelmah



Joined: 11 Mar 2010
Posts: 19546

View user's profile Send private message

PostPosted: Thu Apr 05, 2012 9:06 am     Reply with quote

Seriously, you are not going to do this.
You are running the ADC off the internal clock. Typical cycle time for this is 4uSec. An ADC sample takes 11 cycles off the clock. Then the ADC takes a minimum of Tacq to reacquire the signal after the reading (6.4uSec). So the absolute fastest that readings can be taken, and reflect the incoming signal at all well, is 50.4uSec/sample. Just over 20KHz.....
First thing to do is change to the right clock. Boost your CPU frequency to 40MHz, and use CLOCK/64 for the ADC, which then gives 1.6uSec/cycle, and brings the maximum allowable sample rate up to 41.6KHz. At this the CPU will be able to do basically nothing else.
However you then have to realise that sampling will have to stop for USB interrupts. USB transactions _have_ to be serviced, with minimal delays, or the interface will fail. Switching buffers means the delays can be quite short, but they will still be present.

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group