예제 #1
0
파일: usb.c 프로젝트: yagui/programador
// ----------------------------------------------------------------------
// Poll USB driver:
// - check for incoming USB packets
// - refill an empty transmit buffer
// - check for USB bus reset
// ----------------------------------------------------------------------
extern	void	usb_poll ( void )
{
    byte_t	i;

    // check for incoming USB packets
    if	( usb_rx_len != 0 )
    {
        usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 );
        usb_tx_len = 0;	// abort pending transmission
        usb_rx_len = 0;	// accept next packet
    }
    // refill an empty transmit buffer, when the transmitter is active
    if	( usb_tx_len == 0 && usb_tx_state != TX_STATE_IDLE )
    {
        usb_transmit();
    }
    // check for USB bus reset
    for	( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- )
    {
    }
    if	( i == 0 )
    {   // SE0 for more than 2.5uS is a reset
        usb_new_address = 0;
        usb_address = 0;
#ifdef	USBTINY_USB_OK_LED
        CLR(USBTINY_USB_OK_LED);	// LED off
#endif
    }
}
예제 #2
0
파일: usb.c 프로젝트: bluefix/picsdr
// ----------------------------------------------------------------------
// Poll USB driver:
// - check for incoming USB packets
// - refill an empty transmit buffer
// - check for USB bus reset
// ----------------------------------------------------------------------
extern	void	usb_poll ( void )
{
	byte_t	i;

	// check for incoming USB packets
	if	( usb_rx_len != 0 )
	{
		usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 );
		usb_tx_len = 0;	// abort pending transmission
		usb_rx_len = 0;	// accept next packet
	}
	// refill an empty transmit buffer, when the transmitter is active
	if	( usb_tx_len == 0 )
	{
		if	( usb_tx_state != TX_STATE_IDLE )
		{
			usb_transmit();
		}
		else
		{	// change the USB address at the end of a transfer
			usb_address = new_address;
		}
	}
	// check for USB bus reset
	for	( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- )
	{
	}
	if	( i == 0 )
	{	// SE0 for more than 2.5uS is a reset
		new_address = 0;
	}
}
예제 #3
0
int do_usbslave (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	size_t len = ~0UL;
	char buf[32];

	/* download_run为1时表示将文件保存在USB Host发送工具dnw指定的位置
	 * download_run为0时表示将文件保存在参数argv[2]指定的位置
	 * 要下载程序到内存,然后直接运行时,要设置download_run=1,这也是这个参数名字的来由
	 */
	download_run = 1;
	switch (argc) {
	case 1:
		{
			break;
		}
	case 2:
		{
			g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
			break;
		}

	case 3:
		{
			g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
			load_addr = simple_strtoul(argv[2], NULL, 16);
			download_run = 0;
			break;
		}

	default:
		{
			printf ("Usage:\n%s\n", cmdtp->usage);
			return 1;
		}
	}

	dwUSBBufBase = load_addr;
	dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
	if (g_bUSBWait)
		len = FREE_RAM_SIZE;

	g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
	sprintf(buf, "%lx", g_dwDownloadLen);
	setenv("filesize", buf);
	if (NF_ReadID() == 0x76)
	{
		sprintf(buf, "%lx", g_dwDownloadLen%(512*32) == 0 ? g_dwDownloadLen : (g_dwDownloadLen/(512*32)+1)*32*512);
	}
	else
	{
		sprintf(buf, "%lx", g_dwDownloadLen%(2048*64) == 0 ? g_dwDownloadLen : (g_dwDownloadLen/(2048*64)+1)*64*2048);
	}
	setenv("filesize+1", buf);

	sprintf(buf, "%lX", (unsigned long)load_addr);
	setenv("fileaddr", buf);

	return 0;
}
예제 #4
0
static void usb_receive_block(unsigned char *buf, int min_len,
                              int max_len,
                              void (*in_done)(int, unsigned char *, int),
                              int ep)
{
    endpoints[ep].in_done = in_done;
    endpoints[ep].in_buf = buf;
    endpoints[ep].in_max_len = max_len;
    endpoints[ep].in_min_len = min_len;
    endpoints[ep].in_ptr = 0;
    usb_receive(ep);
}
예제 #5
0
/*****************************************************************************
 * USB callback function. Is called by the USB driver if a non standard
 * request is received from the HOST. This callback extends the known
 * requests by masstorage related ones.
 ****************************************************************************/
callback_state_t usb_ep0_callback(void)
{
  hcc_u8 *pdata=usb_get_rx_pptr(0);

  callback_state_t r=clbst_error;

  /* A request to the command interface. */
  if (STP_INDEX(pdata) == CMD_IFC_INDEX)
  {
    switch(STP_REQU_TYPE(pdata))
    {
    /* Class specific in request. */
    case ((1<<7) | (1<<5) | 1):
      /* Host wants to get a descriptor */
      switch (STP_REQUEST(pdata))
      {
      case CDCRQ_GET_SERIAL_STATE:
        usb_send(0, 0, (void*)&uart_state, 2, STP_LENGTH(pdata));
        r=clbst_in;  
        break;      
      case CDCRQ_GET_LINE_CODING:
        usb_send(0, (void *) 0, (void *)&line_coding, 7, STP_LENGTH(pdata));
        r=clbst_in;
        break;
      case CDCRQ_GET_ENCAPSULATED_RESPONSE:
      default:
        break;
      }
      break;
    /* Class specific out request. */
    case ((0<<7) | (1<<5) | 1):
      switch (STP_REQUEST(pdata))
      {
      case CDCRQ_SET_LINE_CODING:
        usb_receive(0, got_line_coding, (void *)&line_coding, 7);
        r=clbst_out;
        break;
      case CDCRQ_SET_CONTROL_LINE_STATE:
        ctrl_line_state=(hcc_u8)STP_VALUE_LO(pdata);
        r=clbst_out;
        break;
      case CDCRQ_SEND_ENCAPSULATED_COMMAND:
      default:
        break;
      }
      break;
    default:
      break;
    }
  }
  return(r);
}
예제 #6
0
int do_usbslave (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int i;
    size_t len = ~0UL;
    char buf[32];

    /* download_run为1时表示将文件保存在USB Host发送工具dnw指定的位置
     * download_run为0时表示将文件保存在参数argv[2]指定的位置
     * 要下载程序到内存,然后直接运行时,要设置download_run=1,这也是这个参数名字的来由
     */
    download_run = 1;
    switch (argc) {
        case 1:
        {
            break;
        }
        case 2:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            break;
        }

        case 3:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            load_addr = simple_strtoul(argv[2], NULL, 16);
            download_run = 0;
            break;
        }
        
        default: 
        {
            printf ("Usage:\n%s\n", cmdtp->usage);
    		return 1;
        }
    }

    dwUSBBufBase = load_addr;  
    dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));  
    if (g_bUSBWait)
        len = FREE_RAM_SIZE;

    g_dwDownloadLen = usb_receive(dwUSBBufBase, len, g_bUSBWait);
    sprintf(buf, "%X", g_dwDownloadLen);
    setenv("filesize", buf);
    
	return 0;
}
예제 #7
0
int do_usbload (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    size_t len = ~0UL;
    char buf[32];

    download_run = 1;
    switch (argc) {
        case 1:
        {
            break;
        }
        case 2:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            break;
        }

        case 3:
        {
            g_bUSBWait = (int)simple_strtoul(argv[1], NULL, 16);
            load_addr = simple_strtoul(argv[2], NULL, 16);
            download_run = 0;
            break;
        }
        
        default:
        {
            printf ("Usage:\n%s\n", cmdtp->usage);
            return 1;
        }
    }

    dwUSBBufBase = load_addr;
    dwUSBBufSize = (FREE_RAM_SIZE&(~(0x80000-1)));
    if (g_bUSBWait)
        len = FREE_RAM_SIZE;

    g_dwDownloadLen = usb_receive((char *)dwUSBBufBase, len, g_bUSBWait);

    sprintf(buf, "%X", g_dwDownloadLen);
    setenv("filesize", buf);
    
    downloadFileSize = 0;    
    
    return 0;
}
예제 #8
0
void cdc_process(void)
{
  /* See if USB is in usable state. */    
  if (usb_get_state() == USBST_CONFIGURED)
  {    
    /*  If endpoint is not busy, and receive buffer is empty */
    if (!usb_ep_is_busy(CDC_RX_EP_NO) && (rx_length <= rx_ndx))
    {
      /* Read out error status of endpoint. The reception may be aborted due
         to a status change on the USB (disconnect, sleep, etc..) or due to
         an error (CRC, bit stuffing, etc...). In both case wee need to restart
         reception if possible.  */
      switch(usb_ep_error(CDC_RX_EP_NO))
      {
      case USBEPERR_NONE: /* Reception finished with no error. */
        /* If received bytes are not yet handled. */
        if (rx_length == 0)
        {          
          /* Read out number of received bytes. This will make us to return
             received characters for the next call. Note: the transfer may
             contain 0 characters, so we return the first character only when
             the next call is made. */
          rx_length=(hcc_u8)usb_get_done(CDC_RX_EP_NO);
          rx_ndx=0;
          /* If we did not received any data, then we need to start a new receive. */
          if (rx_length)
          {
            break;          
          }
        }
      case USBEPERR_PROTOCOL_ERROR:
        /* restart the reception */
        rx_length=0;
        usb_receive(CDC_RX_EP_NO, (void *) 0, (void *) rx_buffer, sizeof(rx_buffer));
        break;      
      case USBEPERR_HOST_ABORT:        
        /* This error can only be detected if error happens after execution of thefirst if
           in this function and before the switch. This is unlikely to happen. On the other
           hand this error meand usb has been disconnected or put to low power mode and thus
           we may safely ignore it. */
        break;
      case USBEPERR_USER_ABORT:
      case USBEPERR_TO_MANY_DATA:
      default:
        /* Upps! unexpected error. Stop here. */
        CMX_ASSERT(0);
      }
    }

    /* If tx buffer is not empty, start transmission. */
    if (!usb_ep_is_busy(CDC_TX_EP_NO) && (tx_ndx != 0))
    {
      /* Check the status of the next transfer. */
      switch (usb_ep_error(CDC_TX_EP_NO))
      {
      case USBEPERR_PROTOCOL_ERROR:   /* Ignore error, send next chunk. */
      case USBEPERR_HOST_ABORT:
      case USBEPERR_NONE: /* Finished with no error. */
        /* Start sending next chunk. */
        usb_send(CDC_TX_EP_NO, (void *) 0, (void *) cur_tx_buffer, tx_ndx, tx_ndx);
        /* Switch buffer. */
        tx_ndx=0;
        cur_tx_buffer = (hcc_u8*)((cur_tx_buffer == (hcc_u8*)tx_buffer1) ? tx_buffer2 : tx_buffer1);
        break;
      case USBEPERR_USER_ABORT:
      case USBEPERR_TO_MANY_DATA:
      default:
        /* Upps! unexpected error. Stop here. */
        CMX_ASSERT(0);
      }
    }
  }
}
예제 #9
0
/* one command cycle */
void usb_call(void *cmd,   int cmd_len,
              void *reply, int reply_len) {
    usb_send(cmd, cmd_len);
    if (reply_len) usb_receive(reply, reply_len); // PK2 doesn't send empty buffers
}