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

USB versus Timer interrupt on 18F4550

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







USB versus Timer interrupt on 18F4550
PostPosted: Tue Jun 24, 2008 9:01 pm     Reply with quote

Hi everybody,

In first place, sorry for my English. If you don´t understand something that i wrote, please tell me.
I´m working with the 18F4550, and i try to read some digital bits on ports A and B and send this as a integer by the USB to the computer.
So, i wrote a main function to manage the commands sent by computer, and a timer0 interruption to read digital ports and put the data in a buffer.
Then, the computer send a command to start acquisition and then, sends a sequence of commands make PIC send data until it reaches the number of samples desired.
The problem is when PIC receives a "send data" command and it coincides with a interrupt. The pic does not respond to the computer and _MPUSBRead return me an error from this point.
The only way that i founded to inhibit this behaviour is disable interrupts if usb_kbhit(1) returns true. But the problem on this is the low sampling rate generated (around 1,5 ms), because of the break to process usb messages.
Some one has some idea to fix it without disable interrupts?

Thanks,

Rodrigo

My code:
Code:

#include <18F4550.h>


#fuses USBDIV,CPUDIV1

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HSPLL                    //Internal Oscillator, HS used by USB
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOPUT                    //No Power Up Timer
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                      //ALTERADO Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOPBADEN                   //ALTERADO PORTB pins are configured as analog input channels on RESET
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES WRTB                   //ALTERADO Boot block not write protected
#FUSES EBTRB                  //ALTERADO Boot block not protected from table reads
#FUSES CPB                    //ALTERADO No Boot Block code protection
#FUSES MCLR                     //Master Clear pin enabled
#FUSES VREGEN                   // ALTERADO
#FUSES PLL5                     //ALTERADO PLL PreScaler



// Reservando espaço pro Bootloader: 
// OBS: Se for gravar sem ser via bootloader, comentar essas linhas!
#build(reset=0x800, interrupt=0x808) 
#org 0x000, 0x7ff { }
/////////////////////////////////////

#use delay(clock=48M)
#use fast_io(ALL) //tem q definir o tris para o sentido das portas!

/////////////////////////////////////////////////////////////////////////////
//
// 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             //deshabilitamos el uso de las directivas HID
#define USB_EP1_TX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for IN bulk/interrupt transfers
#define USB_EP1_RX_ENABLE  USB_ENABLE_BULK   //turn on EP1(EndPoint1) for OUT bulk/interrupt transfers
#define USB_EP1_TX_SIZE    64  //2                 //size to allocate for the tx endpoint 1 buffer   // mudar para 2
#define USB_EP1_RX_SIZE    64 //33                 //size to allocate for the rx endpoint 1 buffer  // mudar para 33


#include <pic18_usb.h>     //Microchip PIC18Fxx5x Hardware layer for CCS's PIC USB driver
#include <PicUSB.h>         //Configuración del USB y los descriptores para este dispositivo
#include <usb.c>           //handles usb setup tokens and get descriptor reports
#include <fifo.h>

#define modo      entrada[0]
#define param1    entrada[1]
#define param2    entrada[2]
#define param3    entrada[3]
#define param4    entrada[4]
#define param5    entrada[5]

#define DELAYELETRONICO 5 // delay em us

#define TEMPO 100

#priority timer0

//variáveis globais:
   int16 dados;
   int32 amostrasaquisitadas;
   int32 amostrasenviadas;
   int8 byterecebe;
   int32 totalamostras;
   int1 aquisitando;

#int_timer0
void Aquisitadados()
{

   int1 gravoubuffer;

   set_timer0(250-get_timer0());
           
      //recebe os dados:
      // 8 bits mais significativos

      dados = input_b();
      dados >>= 8;
      byterecebe = input_a();

      // ignora os dados de b4-7
      byterecebe >>= 4;
      byterecebe <<= 4;
      dados += byterecebe;
         
      //coloca os dados no buffer:
      if (insere(dados) && gravoubuffer) { //insere: put data in buffer
         amostrasaquisitadas++;
      } else {
         output_high(pin_D0);
         aquisitando = 0;
         disable_interrupts(int_timer0); //termina a aquisição
         set_tris_a(0b00000000); //Todos os pinos da porta 'A' como saídas. (porta B do PG-29)
         set_tris_b(0b00000000); //Todos os pinos da porta 'B' como saídas. (porta A do Pg-29)
      }
     
      if (totalamostras <= amostrasaquisitadas) {
         aquisitando = 0;   
         disable_interrupts(int_timer0); //termina a aquisição
         set_tris_a(0b00000000); //Todos os pinos da porta 'A' como saídas. (porta B do PG-29)
         set_tris_b(0b00000000); //Todos os pinos da porta 'B' como saídas. (porta A do Pg-29)
         output_high(Pin_A3);
      }     
}

void main(void) {

   int8 entrada[6];               
   int8 envia[64];
   int8 i;
   int8 numamostras;
   
   set_tris_a(0b00000000);
   set_tris_b(0b00000000);
   set_tris_d(0b00000000);
           
   OUTPUT_A(0x00);
   OUTPUT_B(0x00);
   OUTPUT_D(0x00);
   
   aquisitando = 0;
   amostrasaquisitadas = 0;
   amostrasenviadas = 0;

   SETUP_TIMER_1(T1_DISABLED);             
   SETUP_TIMER_2(T2_DISABLED,255,5);     
   SETUP_TIMER_3(T3_DISABLED);             
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT);
     
   set_timer0(250);
   disable_interrupts(global);
   
   // Inicialização da USB e enumeração
   usb_init();                      //inicializamos a USB
   usb_task();                      //habilita periferico usb e interrupciones
   usb_wait_for_enumeration();      //esperamos hasta que el PicUSB sea configurado por el host
   
   while (TRUE)
   {
      if(usb_enumerated())         
      {
         if (usb_kbhit(1))         
         {
            if (aquisitando == 1) {
               disable_interrupts(int_timer0);
            }
            usb_get_packet(1, entrada, 6);

           
            if (modo == 4) //Starts acquisition
            {

               set_tris_a(0b11111111);
               set_tris_b(0b11111111);
               
               // start acquisition:
               output_high(pin_D4);
               amostrasaquisitadas = 0;
               amostrasenviadas = 0;
               aquisitando = 1;
               totalamostras = (param1*256) + param2;
               enable_interrupts(int_timer0);
               
            }
            if (modo == 6) // send samples
            {
               numamostras = (amostrasaquisitadas*2)-amostrasenviadas;
               envia[1] = 0; //amostras excedentes
               if (numamostras > 60) {
                 numamostras = 60;
                 envia[1] = 1;
               }
               envia[0] = numamostras;
               envia[2] = param1;
               for (i=3;i<=63;i++){
                  // amostra de tensão
                  if (i <= numamostras+3){
                     envia[i] = remove(); //remove:removes data from buffer
                  } else {
                     envia[i] = 0;
                  }
               }
               amostrasenviadas = amostrasenviadas + numamostras;
               disable_interrupts(int_timer0);
               usb_put_packet(1, envia,64, USB_DTS_TOGGLE);
               enable_interrupts(int_timer0);

            }
            if (aquisitando == 1) {
               enable_interrupts(int_timer0);
            }
         }
      }
   }
}
stewart



Joined: 28 Nov 2005
Posts: 12

View user's profile Send private message

PostPosted: Tue Jun 24, 2008 11:41 pm     Reply with quote

Sinister,

I have looked over your code, not in great detail, but I can suggest that you do FAR LESS in the TMR0 interrupt routine.

There are many discussions related to trying to do too much in an interrupt service routine (ISR).

In your case, have the main code do the reading of the ports and then just use that data to respond within the ISR

Have fun

Stewart
Guest








PostPosted: Wed Jun 25, 2008 10:01 am     Reply with quote

stewart wrote:
Sinister,

I have looked over your code, not in great detail, but I can suggest that you do FAR LESS in the TMR0 interrupt routine.

There are many discussions related to trying to do too much in an interrupt service routine (ISR).

In your case, have the main code do the reading of the ports and then just use that data to respond within the ISR

Have fun

Stewart


Thank you for fast response Stewart!

I will try to do this. But i have only one question, can i use int_usb to manage data sended by computer via usb?

Rodrigo
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