示例#1
0
/* 
 * ===  FUNCTION  ======================================================================
 *         Name:  ring_buf_write_char
 *  Description:  Copy a char from a user buffer and put it into the circular buffer.  
 *				Restrict to the amount of space available.
 *       Return:  1, success; otherwise return 0.
 *         Note:  
 * =====================================================================================
 */
int ring_buf_write_char(ring_buffer_t *cb, char data)
{
	ring_buffer_t *temp = cb;
    if (!ring_buf_full(temp)) {
        cb->buffer[temp->tail] = data;

        cb->tail++;
        if (temp->tail >= temp->size)
            temp->tail -= temp->size;
        return 1;
    }

    return 0;
}
示例#2
0
文件: usbdev_core.c 项目: checko/F4OS
void usbdev_fifo_read(volatile struct ring_buffer *ring, int size) {
    int words = (size+3)/4;

    /* Allow us to read into NULL */
    if (ring == NULL) {
        uint32_t null;
        while (words > 0) {
            null = *USB_FS_DFIFO_EP(0);
            words--;
        }
        /* Tricks GCC into thinking null is used */
        if (null) {
            return;
        }
    }
    else {
        while (words > 0 && size > 0) {
            union uint8_uint32 data;
            data.uint32 = *USB_FS_DFIFO_EP(0);
            words--;

            for (int i = 0; i < 4; i++) {
                if (size <= 0) {
                    data.uint8[i] = 0;
                    continue;
                }

                ring->buf[ring->end] = data.uint8[i];
                size--;

                if (ring_buf_full(ring)) {
                    DEBUG_PRINT("Warning: USB: Buffer full.\r\n");
                    ring->start = (ring->start + 1) % ring->len;
                }
                ring->end = (ring->end + 1) % ring->len;
            }
        }
    }
}
示例#3
0
文件: usbdev_core.c 项目: checko/F4OS
/* Returns bytes written, negative on error */
int usbdev_write(struct endpoint *ep, uint8_t *packet, int size) {
    if (ep == NULL) {
        DEBUG_PRINT("Warning: Invalid endpoint in usbdev_write. ");
        return -1;
    }
    if (ep->num != 0 && !usb_ready) {
        return -1;
    }
    if (ep->tx.buf == NULL) {
        DEBUG_PRINT("Warning: Endpoint has no tx buffer in usbdev_write. ");
        return -1;
    }

    /* Wait until current buffer is empty */
    while (!ring_buf_empty(&ep->tx)) {
        yield_if_possible();
    }

    int filled_buffer = 0;
    int written = 0;

    /* Copy to ring buffer */
    while (size > 0 && !ring_buf_full(&ep->tx)) {
        ep->tx.buf[ep->tx.end] = *packet++;
        size--;
        written++;

        ep->tx.end = (ep->tx.end + 1) % ep->tx.len;
    }

    if (ring_buf_full(&ep->tx)) {
        filled_buffer = 1;
    }

    uint8_t packets = written % ep->mpsize ? written/ep->mpsize + 1 : written/ep->mpsize;
    if (!packets) {
        packets = 1;
    }

    int count = 500;
    /* Setup endpoint for transmit */
    if (ep->num == 0) {
        /* Wait for ep to disable */
        while (*USB_FS_DIEPCTL0 & USB_FS_DIEPCTL0_EPENA && count > 0) {
            count--;
        }

        /* Abort timed out transfer */
        if (count <= 0) {
            ep->request_disable = 1;

            *USB_FS_DIEPCTL0 |= USB_FS_DIEPCTL0_SNAK;
            *USB_FS_DIEPMSK |= USB_FS_DIEPMSK_INEPNEM | USB_FS_DIEPMSK_EPDM;

            /* Wait for endpoint to disable */
            while(ep->request_disable);

            *USB_FS_DIEPMSK &= ~(USB_FS_DIEPMSK_INEPNEM | USB_FS_DIEPMSK_EPDM);
        }

        *USB_FS_DIEPTSIZ0 = USB_FS_DIEPTSIZ0_PKTCNT(packets) | USB_FS_DIEPTSIZ0_XFRSIZ(written);
        *USB_FS_DIEPCTL0 |= USB_FS_DIEPCTL0_CNAK | USB_FS_DIEPCTL0_EPENA;
    }
    else {
        /* Wait for ep to disable */
        while (*USB_FS_DIEPCTL(ep->num) & USB_FS_DIEPCTLx_EPENA && count > 0) {
            count--;
        }

        /* Abort timed out transfer */
        if (count <= 0) {
            ep->request_disable = 1;

            *USB_FS_DIEPCTL(ep->num) |= USB_FS_DIEPCTLx_SNAK;
            *USB_FS_DIEPMSK |= USB_FS_DIEPMSK_INEPNEM | USB_FS_DIEPMSK_EPDM;

            /* Wait for endpoint to disable */
            while(ep->request_disable);

            *USB_FS_DIEPMSK &= ~(USB_FS_DIEPMSK_INEPNEM | USB_FS_DIEPMSK_EPDM);
        }

        *USB_FS_DIEPTSIZ(ep->num) = USB_FS_DIEPTSIZx_PKTCNT(packets) | USB_FS_DIEPTSIZx_XFRSIZ(written);
        *USB_FS_DIEPCTL(ep->num) |= USB_FS_DIEPCTLx_CNAK | USB_FS_DIEPCTLx_EPENA;
    }

    /* Enable TX FIFO empty interrupt */
    *USB_FS_DIEPEMPMSK |= (1 << ep->num);

    /* Filled buffer, call recursively until packet finishes */
    if (filled_buffer && size) {
        int ret = usbdev_write(ep, packet, size);
        if (ret >= 0) {
            written += ret;
        }
        else {
            written = ret;
        }
    }

    return written;
}