Esempio n. 1
0
// see pic18_usb.h for documentation
int1 usb_flush_in(int8 endpoint, int16 len, USB_DTS_BIT tgl) 
{
   unsigned int8 i;

   debug_usb(debug_putc,"\r\nPUT %X %U %LU",endpoint, tgl, len);

   if (usb_tbe(endpoint)) 
   {
      EP_BDxCNT_I(endpoint)=len;

      debug_display_ram(len, EP_BDxADR_I(endpoint));

     #if USB_IGNORE_TX_DTS
      i=0x80;
     #else
      if (tgl == USB_DTS_TOGGLE) 
      {
         i = EP_BDxST_I(endpoint);
         if (bit_test(i,6))
            tgl = USB_DTS_DATA0;  //was DATA1, goto DATA0
         else
            tgl = USB_DTS_DATA1;  //was DATA0, goto DATA1
      }
      else if (tgl == USB_DTS_USERX) 
      {
         i = EP_BDxST_O(endpoint);
         if (bit_test(i,6))
            tgl = USB_DTS_DATA1;
         else
            tgl = USB_DTS_DATA0;
      }
      if (tgl == USB_DTS_DATA1) 
         i=0xC8;  //DATA1, UOWN
      else //if (tgl == USB_DTS_DATA0) 
         i=0x88; //DATA0, UOWN
     #endif

      //set BC8 and BC9
      if (bit_test(len,8)) {bit_set(i,0);}
      if (bit_test(len,9)) {bit_set(i,1);}

      debug_usb(debug_putc, " %X", i);

      EP_BDxST_I(endpoint) = i;//save changes
      
      //putc('!');
      
      return(1);
   }
   else 
   {
      //putc('_');
      debug_usb(debug_putc,"\r\nPUT ERR");
   }
   return(0);
}
Esempio n. 2
0
void usb_isr_rst(void) 
{
   debug_usb(debug_putc,"R");

   UEIR = 0;
   UIR = 0;
   UEIE = 0x9F;
   UIE = STANDARD_INTS & ~__USB_UIF_ACTIVE;

   UADDR = 0;

   usb_disable_endpoints();
   
   usb_token_reset();

   UEP(0) = ENDPT_CONTROL | 0x10;

   while (UIR_TRN) 
   {
      usb_clear_trn();
   }

   UCON_PKTDIS = 0; //SIE token and packet processing enabled

   usb_init_ep0_setup();

   usb_state = USB_STATE_DEFAULT; //put usb mcu into default state
}
Esempio n. 3
0
// SOF interrupt not handled.  user must add this depending on application
void usb_isr_sof(void) 
{
   debug_usb(debug_putc, "\r\nSOF");
   
   //UIR_SOF = 0;
   UIR &= ~(1 << BIT_SOF);
}
Esempio n. 4
0
void usb_isr_uerr(void)
{
  #if USB_USE_ERROR_COUNTER
   int ints;
  #endif

   debug_usb(debug_putc,"E %X ",UEIR);

  #if USB_USE_ERROR_COUNTER
   ints=UEIR & UEIE; //mask off the flags with the ones that are enabled

   if ( bit_test(ints,0) ) 
   { 
      //increment pid_error counter
      debug_usb(debug_putc,"PID ");
      ERROR_COUNTER[0]++;
   }

   if ( bit_test(ints,1) ) 
   {  
      //increment crc5 error counter
      debug_usb(debug_putc,"CRC5 ");
      ERROR_COUNTER[1]++;
   }

   if ( bit_test(ints,2) ) 
   {
      //increment crc16 error counter
      debug_usb(debug_putc,"CRC16 ");
      ERROR_COUNTER[2]++;
   }

   if ( bit_test(ints,3) ) 
   {  
      //increment dfn8 error counter
      debug_usb(debug_putc,"DFN8 ");
      ERROR_COUNTER[3]++;
   }

   if ( bit_test(ints,4) ) 
   {  
      //increment bto error counter
      debug_usb(debug_putc,"BTO ");
      ERROR_COUNTER[4]++;
   }

   if ( bit_test(ints,7) ) 
   { 
      //increment bts error counter
      debug_usb(debug_putc,"BTS ");
      ERROR_COUNTER[5]++;
   }
  #endif

   UEIR = 0;
   
   //UIR_UERR = 0;
   UIR &= ~(1 << BIT_UERR);
}
Esempio n. 5
0
void ep0_init(void) {
	debug_usb("ep0_init\r\n");
	init_dfu();
	ep0_state = WAIT_SETUP;
	EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
	EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer;
	EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT0 | BDS_DTSEN;
	EP_IN_BD(0).Stat.uc = BDS_UCPU;
	UEP0 = EPINEN_EN | EPOUTEN_EN | EPHSHK_EN;
}
Esempio n. 6
0
void usb_isr_uidle(void)
{
   debug_usb(debug_putc, "I");

   UIE_ACTV = 1;   //enable activity interrupt flag. (we are now suspended until we get an activity interrupt. nice)
   
   //UIR_IDLE = 0; //clear idle interrupt flag
   UIR &= ~(1 << BIT_IDLE);
   
   UCON_SUSPND = 1; //set suspend. we are now suspended
}
Esempio n. 7
0
// see usb_hw_layer.h for documentation
void usb_task(void) 
{
  #if defined(USB_ISR_POLLING)
   if (interrupt_active(INT_USB))
   {
      usb_isr();
   }
  #endif

   if (usb_attached()) 
   {
      if (UCON_USBEN==0) 
      {
         debug_usb(debug_putc, "\r\n\nUSB TASK: ATTACH");
         usb_attach();
      }
   }
   else 
   {
      if (UCON_USBEN==1)  
      {
         debug_usb(debug_putc, "\r\n\nUSB TASK: DE-ATTACH");
         usb_detach();
      }
   }

   if ((usb_state == USB_STATE_ATTACHED)&&(!UCON_SE0)) 
   {
      UIR=0;
      UIE=0;
     #if !defined(USB_ISR_POLLING)
      enable_interrupts(INT_USB);
      enable_interrupts(GLOBAL);
     #endif
      UIE=__USB_UIF_IDLE | __USB_UIF_RESET;  //enable IDLE and RESET USB ISR
      usb_state=USB_STATE_POWERED;
      debug_usb(debug_putc, "\r\n\nUSB TASK: POWERED");
   }
}
Esempio n. 8
0
void usb_isr_activity(void)
{
   debug_usb(debug_putc, "A");

   UCON_SUSPND = 0; //turn off low power suspending
   UIE_ACTV = 0; //clear activity interupt enabling
   
   while(UIR_ACTV)
   {
      //UIR_ACTV = 0;
      UIR &= ~(1 << BIT_ACTV);
   }
}
Esempio n. 9
0
void usb_isr_stall(void) 
{
   debug_usb(debug_putc, "S");
   
   
   if (bit_test(UEP(0),0)) 
   {
      usb_init_ep0_setup();
      bit_clear(UEP(0), 0);
   }
   
   //UIR_STALL = 0;
   UIR &= ~(1 << BIT_STALL);
}
Esempio n. 10
0
// see pic18_usb.h for documentation
void usb_flush_out(int8 endpoint, USB_DTS_BIT tgl) 
{
   unsigned int8 i;
   unsigned int16 len;

  #if USB_IGNORE_RX_DTS
   if (tgl == USB_DTS_STALL) 
   {
      debug_usb(debug_putc, '*');
      EP_BDxCNT_O(endpoint) = 0x84;
      EP_BDxST_I(endpoint) = 0x84;
      return;
   }
   else
      i=0x80;
  #else
   i = EP_BDxST_O(endpoint);
   if (tgl == USB_DTS_TOGGLE) 
   {
      if (bit_test(i,6))
         tgl = USB_DTS_DATA0;  //was DATA1, goto DATA0
      else
         tgl = USB_DTS_DATA1;  //was DATA0, goto DATA1
   }
   if (tgl == USB_DTS_STALL) 
   {
      i = 0x84;
      EP_BDxST_I(endpoint) = 0x84; //stall both in and out endpoints
   }
   else if (tgl == USB_DTS_DATA1)
      i = 0xC8;  //DATA1, UOWN
   else //if (tgl == USB_DTS_DATA0) 
      i = 0x88; //DATA0, UOWN
  #endif

   //bit_clear(__usb_kbhit_status,endpoint);

   len = usb_ep_rx_size[endpoint];
   EP_BDxCNT_O(endpoint) = len;
   if (bit_test(len,8)) {bit_set(i,0);}
   if (bit_test(len,9)) {bit_set(i,1);}

   EP_BDxST_O(endpoint) = i;
}
Esempio n. 11
0
// see usb_hw_layer.h for documentation
int1 usb_put_packet(unsigned int8 endpoint, unsigned int8 * ptr, unsigned int16 len, USB_DTS_BIT tgl) 
{
   unsigned int8 * buff_add;    

   if (usb_tbe(endpoint)) 
   {
      buff_add = EP_BDxADR_I(endpoint);
      memcpy(buff_add, ptr, len);     
      
      return(usb_flush_in(endpoint, len, tgl));
   }
   else 
   {
      //putc('-');
      //printf("%X", EP_BDxST_I(endpoint));
      debug_usb(debug_putc,"\r\nPUT ERR");
   }

   return(0);
}
Esempio n. 12
0
void usb_isr(void)
{
   unsigned int8 TRNAttempts;
   
   clear_interrupt(INT_USB);
   
   if (usb_state == USB_STATE_DETACHED) return;   //should never happen, though
   if (UIR) 
   {
      debug_usb(debug_putc,"\r\n\n[%X] ",UIR);

      //activity detected.  (only enable after sleep)
      if (UIR_ACTV && UIE_ACTV) {usb_isr_activity();}

      if (UCON_SUSPND) return;

      if (UIR_STALL && UIE_STALL) {usb_isr_stall();}        //a stall handshake was sent

      if (UIR_UERR && UIE_UERR) {usb_isr_uerr();}          //error has been detected

      if (UIR_URST && UIE_URST) {usb_isr_rst();}        //usb reset has been detected

      if (UIR_IDLE && UIE_IDLE) {usb_isr_uidle();}        //idle time, we can go to sleep
      
      if (UIR_SOF && UIE_SOF) {usb_isr_sof();}

      TRNAttempts = 0;
      do
      {
         if (UIR_TRN && UIE_TRN) 
         {
            USTATCopy = U1STAT;
            usb_clear_trn();
            usb_isr_tok_dne();
         }
         else
            break;
      } while (TRNAttempts++ < 4);
   }
}
Esempio n. 13
0
u8 ep0_usb_std_request(void) {
	// hack to avoid register allocation bug in sdcc
	static u8 unknown_request;

	unknown_request = FALSE;

	if (SetupBuffer.request_type != STANDARD) {
		return FALSE;
	}

	switch (SetupBuffer.bRequest) {
	case CLEAR_FEATURE:
		debug_usb("CLEAR_FEATURE\n");
		// TODO not implemented
		break;
	case GET_CONFIGURATION:
		debug_usb("GET_CONFIGURATION\n");
		sourceData = &GET_ACTIVE_CONFIGURATION();
		num_bytes_to_be_send = 1;
		break;
	case GET_DESCRIPTOR:
		debug_usb("GET_DESCRIPTOR\n");
		switch (SetupBuffer.bDescType) {

		case DEVICE_DESCRIPTOR:
			debug_usb("device\n");
			sourceData = (u8 *) device_descriptor;
			num_bytes_to_be_send = device_descriptor->bLength;
			break;
		case CONFIGURATION_DESCRIPTOR:
			debug_usb("configuration\n");
			sourceData = configuration_descriptor[SetupBuffer.bDescIndex];
			num_bytes_to_be_send =
					((USB_Configuration_Descriptor*) sourceData)->wTotalLength;
			break;
		case STRING_DESCRIPTOR:
			debug_usb("string\n");
			sourceData = string_descriptor[SetupBuffer.bDescIndex];
			num_bytes_to_be_send = sourceData[0];
			break;
		default:
			debug_usb("unknown\n");
			// This is required to stall the DEVICE_QUALIFIER request
			unknown_request = TRUE;
			break;
		}
		break;
	case GET_INTERFACE:
		debug_usb("GET_INTERFACE\n");
		// TODO not implemented
		break;
	case GET_STATUS:
		debug_usb("GET_STATUS\n");
		// TODO not implemented
		break;
	case SET_ADDRESS:
		debug_usb("SET_ADDRESS\n");
		SET_DEVICE_STATE(ADDRESS_PENDING_STATE)
		;
		break;
	case SET_CONFIGURATION:
		debug_usb("SET_CONFIGURATION\n");
		// is this configuration valid ?
		if (device_descriptor->bNumConfigurations
				>= SetupBuffer.bConfigurationValue) {
			coming_cfg = SetupBuffer.bConfigurationValue;
			SET_DEVICE_STATE(CONFIGURATION_PENDING_STATE);
		} else // invalid configuration
		{
			debug_usb("invalid configuration\n");
			// Reply with a request error (STALL)
			unknown_request = TRUE;
		}

		break;
	case SET_FEATURE:
		debug_usb("SET_FEATURE\n");
		// TODO not implemented
		break;
	case SET_INTERFACE:
		debug_usb("SET_INTERFACE\n");
		// TODO not implemented
		break;
//        case SYNCH_FRAME:
// only for isochronous synchronization
//            break;
	default:
		unknown_request = TRUE;
		break;
	}
	return !unknown_request;
}
Esempio n. 14
0
void ep0_setup(void) {
	debug_usb("ep0_setup\n");

	ep0_state = WAIT_SETUP;
	num_bytes_to_be_send = 0;

	if (ep0_usb_std_request()) {
		UCONbits.PKTDIS = 0;
		if (SetupBuffer.data_transfer_direction == DEVICE_TO_HOST) {
			ep0_state = WAIT_IN;

			EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
			EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer;
			EP_OUT_BD(0).Stat.uc = BDS_USIE;

			EP_IN_BD(0).ADR = (u8 __data *)InBuffer;
			if (SetupBuffer.wLength < num_bytes_to_be_send) {
				num_bytes_to_be_send = SetupBuffer.wLength;
			} debug2_usb("bytes to send: %d\r\n", num_bytes_to_be_send);
			fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE,
					&num_bytes_to_be_send);
			EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;

		} else // HOST_TO_DEVICE
		{
			ep0_state = WAIT_OUT;

			EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
			EP_OUT_BD(0).ADR = (u8 __data *)InBuffer;
			EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;

			EP_IN_BD(0).Cnt = 0;
			EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;
		}
	} else if (ep0_dfu_request()) {
		UCONbits.PKTDIS = 0;
		if (SetupBuffer.data_transfer_direction == DEVICE_TO_HOST) {
			ep0_state = WAIT_DFU_IN;

			EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
			EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer;
			EP_OUT_BD(0).Stat.uc = BDS_USIE;

			EP_IN_BD(0).ADR = (u8 __data *)InBuffer;
			if (SetupBuffer.wLength < num_bytes_to_be_send) {
				num_bytes_to_be_send = SetupBuffer.wLength;
			}
			debug2_usb("bytes to send: %d\n", num_bytes_to_be_send);
			// debug2("2: %x\n", sourceData[0]);
			fill_in_buffer(0, &sourceData, EP0_BUFFER_SIZE,
					&num_bytes_to_be_send);
			EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;

		} else // HOST_TO_DEVICE
		{
			ep0_state = WAIT_DFU_OUT;

			EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
			EP_OUT_BD(0).ADR = (u8 __data *)InBuffer;
			EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;

			EP_IN_BD(0).Cnt = 0;
			EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_DAT1 | BDS_DTSEN;

		}
	} else {
		debug_usb("unknown request\n");
		UCONbits.PKTDIS = 0;
		EP_OUT_BD(0).Cnt = EP0_BUFFER_SIZE;
		EP_OUT_BD(0).ADR = (u8 __data *)&SetupBuffer;
		EP_OUT_BD(0).Stat.uc = BDS_USIE | BDS_BSTALL;

		EP_IN_BD(0).Stat.uc = BDS_USIE | BDS_BSTALL;
	}
}
Esempio n. 15
0
void usb_isr_tok_dne(void) 
{
   unsigned int8 en;

   en = USTATCopy>>3;

   debug_usb(debug_putc, "T ");
   debug_usb(debug_putc, "%X ", USTATCopy);

   if (USTATCopy == USTAT_OUT_SETUP_E0) 
   {
      //new out or setup token in the buffer
      int8 pidKey;
      
      debug_usb(debug_putc,"%X ", EP_BDxST_O(0));
      
      pidKey = EP_BDxST_O(0) & 0x3C;  //save PID
      
      EP_BDxST_O(0) &= 0x43;  //clear pid, prevent bdstal/pid confusion
      
      if (pidKey == USB_PIC_PID_SETUP) 
      {
         if ((EP_BDxST_I(0) & 0x80) != 0x00)
            EP_BDxST_I(0)=0;   // return the in buffer to us (dequeue any pending requests)

         debug_usb(debug_putc,"(%U) ", EP_BDxCNT_O(0));
         debug_display_ram(EP_BDxCNT_O(0), usb_ep0_rx_buffer);

         usb_isr_tok_setup_dne();

         UCON_PKTDIS=0;       // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit

         //if setup_0_tx_size==0xFF - stall ep0 (unhandled request) (see usb_request_stall())
         //if setup_0_tx_size==0xFE - get EP0OUT ready for a data packet, leave EP0IN alone (see usb_request_get_data())
         //else setup_0_tx_size=size of response, get EP0OUT ready for a setup packet, mark EPOIN ready for transmit (see usb_request_send_response())
         if (__setup_0_tx_size == 0xFF)
            usb_flush_out(0, USB_DTS_STALL);
         else 
         {
            usb_flush_out(0, USB_DTS_TOGGLE);
            if (__setup_0_tx_size != 0xFE)
               usb_flush_in(0 ,__setup_0_tx_size, USB_DTS_USERX);
         }
         //why was this here?
         //UCON_PKTDIS=0;       // UCON,PKT_DIS ; Assuming there is nothing to dequeue, clear the packet disable bit
      }
      else if (pidKey == USB_PIC_PID_OUT) 
      {
         usb_isr_tok_out_dne(0);
         usb_flush_out(0, USB_DTS_TOGGLE);
         if ((__setup_0_tx_size!=0xFE) && (__setup_0_tx_size!=0xFF))
         {
            usb_flush_in(0,__setup_0_tx_size,USB_DTS_DATA1);   //send response (usually a 0len)
         }
      }
      else
      {
         debug_usb(debug_putc, "!!! ");
      }
   }
   else if (USTATCopy == USTAT_IN_E0) 
   {   
      //pic -> host transfer completed
      //EP_BDxST_I(0) = EP_BDxST_I(0) & 0xC3;   //clear up any BDSTAL confusion
      __setup_0_tx_size = 0xFF;
      usb_isr_tok_in_dne(0);
      if (__setup_0_tx_size!=0xFF)
         usb_flush_in(0, __setup_0_tx_size, USB_DTS_TOGGLE);
      else
      {
         //usb_init_ep0_setup(); //REMOVED JUN/9/2009
      }  
   }
   else 
   {
      if (!bit_test(USTATCopy, 2)) 
      {
         //EP_BDxST_O(en) = EP_BDxST_O(en) & 0xC3;   //clear up any BDSTAL confusion
         usb_isr_tok_out_dne(en);
      }
      else 
      {
         //EP_BDxST_I(en) = EP_BDxST_I(en) & 0xC3;   //clear up any BDSTAL confusion
         usb_isr_tok_in_dne(en);
      }
   }
}