USB interrupt - when to read data?

General discussion on mikroC PRO for PIC.
Post Reply
Author
Message
Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

USB interrupt - when to read data?

#1 Post by Sobrietytest » 09 Jun 2021 05:56

Hi, I'm working on a coil winding machine which is controlled by software on a PC. I chose to use a PIC Clicker (18F47J53) as the USB interface and motor controller.

Using the Clicker's USB interrupt demo is fine because the only thing it does is respond to USB input messages. In my case, the main() loop will be triggering various functions which drive the machine, so where do I put the code to respond to incoming USB messages from the PC? For example, if I I want to pause or raise/lower the speed while the machine is running?

The PC sends commands such as this...

Code: Select all

$MS600
(motor speed) and they need to be decoded accordingly.

I tried calling the USB decoder from within the interrupt but the Clicker would no longer connect to the PC...

Code: Select all

void interrupt(){
   USB_Interrupt_Proc();               // USB interrupt servicing
   USB_Comms_Decoder();                 // USB message decoder (reads incoming data and decodes it)
}
Also, where is the code for the USB_Interrupt_Proc(); function?

Any help/examples appreciated.

ST.

paulfjujo
Posts: 1555
Joined: 24 Jun 2007 19:27
Location: 01800 St Maurice de Gourdans France
Contact:

Re: USB interrupt - when to read data?

#2 Post by paulfjujo » 09 Jun 2021 08:55

hello,


i didn't check it on 18F47J53 but OK on 18F2550

use of a timer to pool the USB flag ...and with non blocking situation

Code: Select all


unsigned char readbuff[64]  absolute 0x500; // place the arrays to USB section
unsigned char writebuff[64] absolute 0x540;
volatile int Flag_Timer1;


void Interrupts() iv 0x0018 ics ICS_AUTO
{
   // ------  timer 1  ----------------
  if  ( (TMR1IE_bit==1) && ( TMR1IF_bit==1))
   {  // Test "Peripheral Interrupt Request Register 1" for Timer1 Flag

     Count1++;
     if (Count1>=Nb_Count1)
       {
        Count1=0;
        Flag_Timer1=1;
        TMR1IE_bit=0;
      }
      // 24 * 41.666mS = 1 seconde et init timer1 à 3035  et prescaler=1/8  at 48MHz
      TMR1H= 0x0B; // Hi (3035);
      TMR1L= 0xDB; // Lo (3035);
      PIR1.TMR1IF=0;
   }
}


void interrupt(){
   USB_Interrupt_Proc();                 // USB servicing is done inside the interrupt
}

void Init_Timer1(void)
 {
  T1CON=0;
  T1CKPS1_bit=1;  //prescal select=11 => 1/8
  T1CKPS0_bit=1;
 // T1GCON=0;
  TMR1H= 0x0B; // Hi (3035);     // 41mS at 49MHZ
  TMR1L= 0xDB; // Lo (3035);
 // TMR1H= NbCycles_T1>>8;
 // TMR1L= NbCycles_T1 & 0x00FF;
   Count1=0;
  Flag_Timer1=0;
  PIR1.TMR1IF=0;     // Reset Timer1 Flag
  PIE1.TMR1IE=0;  //Disable interrupt TMR1
  IPR1.TMR1IP=0;  // disable High level interrupt
  INTCON.PEIE=0;  // disable peripheral interrupt
  TMR1ON_bit=0;   // timer1 OFF
}


... in main loop .....
  ......
  ......

 HID_Enable(&readbuff,&writebuff);      // Enable HID communication
   // delay necessaire pour avoir le temps
  // de commuter le HID terminal sur le bon device
  Delay_ms(15000);

       // armement Timer1 pour attente Cde clavier

   Flag_Timer1=0;
  Init_Timer1();
  TMR1IE_bit=1;
  TMR1ON_bit=1;
  PEIE_bit=1;
  GIE_bit=1;

   // boucle d'attente pour 1 seconde ecoulee
   while((!HID_Read()) && (Flag_Timer1==0));          // wait for data on USB
 
   if(Flag_Timer1==1)
   {
    Flag_Timer1=0;
    Count1=0;
    TMR1IE_bit=1;
    }
   else
   {   
       k=strlen(&readbuff);
        if(strncmp(&readbuff,"RED_ON",6)==0 )
        {
          LED_Sup=1;
           strConstRamCpy( &writebuff,"Fire RED Led\r\n");
           while(!HID_Write(&writebuff,64));
         }
        if(strncmp(&readbuff,"RED_OFF",7)==0 )
        {
          LED_Sup=0;
            strConstRamCpy( &writebuff,"Shutdown RED Led\r\n");
            while(!HID_Write(&writebuff,64));
         }
        if(strncmp(&readbuff,"GREEN_ON",8)==0)
        {
           LED_Inf=1;
           strConstRamCpy( &writebuff,"Fire GREEN Led\r\n");
           while(!HID_Write(&writebuff,64));
         }
        if(strncmp(&readbuff,"GREEN_OFF",9)==0)
        {
            LED_Inf=0;
             strConstRamCpy( &writebuff,"Shutdown Green Led\r\n");
            while(!HID_Write(&writebuff,64));
         }
       
      
    }

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: USB interrupt - when to read data?

#3 Post by Sobrietytest » 09 Jun 2021 11:35

Hmm, I thought the purpose of the USB interrupt was so you didn't need to poll the USB flag?

Sobrietytest
Posts: 619
Joined: 05 Jul 2008 06:05
Location: Thailand

Re: USB interrupt - when to read data?

#4 Post by Sobrietytest » 09 Jun 2021 15:21

Solved...

Code: Select all

// USB INTERRUPT ******************************************************
void interrupt(){
   USB_Interrupt_Proc();               // USB interrupt servicing
   if(HID_Read()){
      USB_Comms_Decoder();
      }
}
//*********************************************************************
So, calling the USB decoder directly within the interrupt disables the USB link, adding the 'if' condition allows the USB connection and the decoder to work perfectly.

I wish I knew why but the mE C help files aren't much help. And I would still like to know exactly what the USB_Interrupt_Proc(); function does.

ST.

User avatar
filip
mikroElektronika team
Posts: 11874
Joined: 25 Jan 2008 09:56

Re: USB interrupt - when to read data?

#5 Post by filip » 17 Jun 2021 14:04

Hi,

It basically runs a USB device state machine where it checks for certain flags and executes appropriate code :
- Service USB Activity Interrupt
- Service USB Bus Reset Interrupt
- Service other USB interrupts
- Servicing USB Transaction Complete Interrupt

Since the library is not open I'm not in liberty to reveal specifics.

Regards,
Filip.

Post Reply

Return to “mikroC PRO for PIC General”