/** * 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; }
/******************************************************************************* * 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); }
/*********************************************************** * 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); }
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; }
/******************************************************************************* * 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; } } }
/** * 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; }
/* 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; } }