/**
 * This function will handle system sof event.
 *
 * @param device the usb device object.
 *
 * @return RT_EOK on successful.
 */
static rt_err_t _class_sof_handler(udevice_t device, uclass_t cls)
{
    rt_uint32_t level;
    rt_size_t size;
    static rt_uint32_t frame_count = 0;
    cdc_eps_t eps;

    if(vcom_connected != RT_TRUE) return -RT_ERROR;
    
    eps = (cdc_eps_t)cls->eps;
    if (frame_count ++ == 5)
    {
        rt_size_t mps = eps->ep_in->ep_desc->wMaxPacketSize;

        /* reset the frame counter */
        frame_count = 0;

        size = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
        if(size == 0) return -RT_EFULL;

        size = size > mps ? mps : size;
        
        level = rt_hw_interrupt_disable();
        rt_ringbuffer_get(&tx_ringbuffer, eps->ep_in->buffer, size);
        rt_hw_interrupt_enable(level);                     
        
        /* send data to host */
        dcd_ep_write(device->dcd, eps->ep_in, eps->ep_in->buffer, size);
    }

    return RT_EOK;
}
예제 #2
0
/*******************************************************************************
* Function Name  : Handle_USBAsynchXfer.
* Description    : send data to USB.
* Input          : None.
* Return         : none.
*******************************************************************************/
void Handle_USBAsynchXfer (void)
{
  rt_uint32_t level;
  rt_uint32_t remain;
  
  if(USB_Tx_State != 1)
  {
  	level = rt_hw_interrupt_disable();
	  remain = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
    
    if(remain == 0) 
    {
      USB_Tx_State = 0;
	  rt_hw_interrupt_enable(level);
      return;
    }
    
    if (remain > VIRTUAL_COM_PORT_DATA_SIZE)
    {
      remain = VIRTUAL_COM_PORT_DATA_SIZE;	
    }
	rt_ringbuffer_get(&tx_ringbuffer, tx_buf, remain);
	rt_hw_interrupt_enable(level);

    USB_Tx_State = 1; 
    UserToPMABufferCopy(tx_buf, ENDP1_TXADDR, remain);
    SetEPTxCount(ENDP1, remain);
    SetEPTxValid(ENDP1); 
  }  
}
static rt_size_t wrtnode2r_spi_bridge_read(rt_device_t dev,
                                           rt_off_t pos,
                                           void* buffer,
                                           rt_size_t size)
{
    return rt_ringbuffer_get(&spi_bridge.read_buf, buffer, size);
}
예제 #4
0
/***********************************************************
* Function:gps_read
* Description:数据模式下读取数据
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static rt_size_t dev_vuart_read( rt_device_t dev, rt_off_t pos, void* buff, rt_size_t count )
{
	if(count>1)
		return rt_ringbuffer_get(&rb_vuart,buff,count);
	else
		return rt_ringbuffer_getchar(&rb_vuart,buff);

}
예제 #5
0
파일: telnet.c 프로젝트: onelife/rt-thread
static rt_size_t telnet_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
{
    rt_size_t result;

    /* read from rx ring buffer */
    rt_mutex_take(telnet->rx_ringbuffer_lock, RT_WAITING_FOREVER);
    result = rt_ringbuffer_get(&(telnet->rx_ringbuffer), buffer, size);
    rt_mutex_release(telnet->rx_ringbuffer_lock);

    return result;
}
예제 #6
0
/*******************************************************************************
* Function Name  : EP1_IN_Callback
* Description    :
* Input          : None.
* Output         : None.
* Return         : None.
*******************************************************************************/
void EP1_IN_Callback (void)
{
  rt_uint32_t level;
  rt_uint32_t remain;

  if (USB_Tx_State == 1)
  {
	  level = rt_hw_interrupt_disable();
	  remain = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
	  if (remain == 0) 
	    {
	      USB_Tx_State = 0;
		  rt_hw_interrupt_enable(level);
		  return;
	    }
	    else
	    {
	    	if (remain > VIRTUAL_COM_PORT_DATA_SIZE)
	    	{
				remain = VIRTUAL_COM_PORT_DATA_SIZE;
			}
	        /* although vcom_in_sending is set in SOF handler in the very
	         * beginning, we have to guarantee the state is right when start
	         * sending. There is at least one extreme case where we have finished the
	         * last IN transaction but the vcom_in_sending is RT_FALSE.
	         *
	         * Ok, what the extreme case is: pour data into vcom in loop. Open
	         * terminal on the PC, you will see the data. Then close it. So the
	         * data will be sent to the PC in the back. When the buffer of the PC
	         * driver is full. It will not send IN packet to the board and you will
	         * have no chance to clear vcom_in_sending in this function. The data
	         * will fill into the ringbuffer until it is full, and we will reset
	         * the state machine and clear vcom_in_sending. When you open the
	         * terminal on the PC again. The IN packet will appear on the line and
	         * we will, eventually, reach here with vcom_in_sending is clear.
	         */
	        vcom_in_sending = RT_TRUE;
	        rt_ringbuffer_get(&tx_ringbuffer, tx_buf, remain);
	        rt_hw_interrupt_enable(level);

	        /* send data to host */
			UserToPMABufferCopy(tx_buf, ENDP1_TXADDR, remain);
	        SetEPTxCount(ENDP1, remain);
	        SetEPTxValid(ENDP1); 

	        //return RT_EOK;
	    }
  	}

}
예제 #7
0
/**
 * This function will handle cdc bulk in endpoint request.
 *
 * @param device the usb device object.
 * @param size request size.
 *
 * @return RT_EOK.
 */
static rt_err_t _ep_in_handler(udevice_t device, rt_size_t size)
{
    rt_uint32_t level;
    rt_size_t length;

    rt_size_t mps = ep_in->ep_desc->wMaxPacketSize;
    size = RT_RINGBUFFER_SIZE(&tx_ringbuffer);
    if(size == 0) return RT_EOK;

    length = size > mps ? mps : size;

    level = rt_hw_interrupt_disable();
    rt_ringbuffer_get(&tx_ringbuffer, ep_in->buffer, length);
    rt_hw_interrupt_enable(level);

    /* send data to host */
    dcd_ep_write(device->dcd, ep_in, ep_in->buffer, length);

    return RT_EOK;
}
예제 #8
0
파일: telnet.c 프로젝트: onelife/rt-thread
/* process tx data */
static void send_to_client(struct telnet_session* telnet)
{
    rt_size_t length;
    rt_uint8_t tx_buffer[32];

    while (1)
    {
        rt_memset(tx_buffer, 0, sizeof(tx_buffer));
        rt_mutex_take(telnet->tx_ringbuffer_lock, RT_WAITING_FOREVER);
        /* get buffer from ringbuffer */
        length = rt_ringbuffer_get(&(telnet->tx_ringbuffer), tx_buffer, sizeof(tx_buffer));
        rt_mutex_release(telnet->tx_ringbuffer_lock);

        /* do a tx procedure */
        if (length > 0)
        {
            send(telnet->client_fd, tx_buffer, length, 0);
        }
        else break;
    }
}