OpenCores
URL https://opencores.org/ocsvn/usb_device_core/usb_device_core/trunk

Subversion Repositories usb_device_core

[/] [usb_device_core/] [trunk/] [sw/] [usb_uart.c] - Rev 5

Compare with Previous | Blame | View Log

//-----------------------------------------------------------------
//                         USB CDC Device SW
//                               V0.1
//                         Ultra-Embedded.com
//                          Copyright 2014
//
//                  Email: admin@ultra-embedded.com
//
//                          License: GPL
// If you would like a version with a more permissive license for use in
// closed source commercial applications please contact me for details.
//-----------------------------------------------------------------
//
// This file is part of USB CDC Device SW.
//
// USB CDC Device SW is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// USB CDC Device SW is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with USB CDC Device SW; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//-----------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "usbf_hw.h"
#include "usb_cdc.h"
#include "usb_device.h"
#include "usb_uart.h"
#include "usb_log.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define USB_UART_TX_TIMEOUT             100
 
//-----------------------------------------------------------------
// Locals:
//-----------------------------------------------------------------
static int _tx_count;
static int _rx_count;
 
//-----------------------------------------------------------------
// usb_uart_init:
//-----------------------------------------------------------------
void usb_uart_init(void)
{
    _tx_count = 0;
    _rx_count = 0;
 
    usb_cdc_init();
}
//-----------------------------------------------------------------
// usb_uart_haschar:
//-----------------------------------------------------------------
int usb_uart_haschar(void)
{
    if (_rx_count == 0)
    {
        if (usbhw_is_rx_ready(CDC_ENDPOINT_BULK_OUT))
        {
            _rx_count = usbhw_get_rx_count(CDC_ENDPOINT_BULK_OUT);
 
            // ZLP received? Clear rx status
            if (_rx_count == 0)
                usbhw_clear_rx_ready(CDC_ENDPOINT_BULK_OUT);
        }
    }
    return (_rx_count != 0);
}
//-----------------------------------------------------------------
// usb_uart_getchar:
//-----------------------------------------------------------------
int usb_uart_getchar(void)
{
    int data = -1;
 
    // Some data is ready?
    if (usb_uart_haschar())
    {
        // Get a byte
        data = (int)usbhw_get_rx_byte(CDC_ENDPOINT_BULK_OUT);
        _rx_count--;
 
        // All data received, clear rx status
        if (_rx_count == 0) 
            usbhw_clear_rx_ready(CDC_ENDPOINT_BULK_OUT);
    }
 
    return  data;
}
//-----------------------------------------------------------------
// usb_uart_getblock:
//-----------------------------------------------------------------
int usb_uart_getblock(unsigned char *data, int max_length)
{
    int count;
 
    // Block until some data is ready
    while (!usb_uart_haschar())
        ;
 
    // Limit to buffer size or amount ready
    if (_rx_count > max_length)
        count = max_length;
    else
        count = _rx_count;
 
    usbhw_get_rx_data(CDC_ENDPOINT_BULK_OUT, data, count);
    _rx_count -= count;
 
    // All data received, clear rx status
    if (_rx_count == 0) 
        usbhw_clear_rx_ready(CDC_ENDPOINT_BULK_OUT);
 
    return count;
}
//-----------------------------------------------------------------
// usb_uart_putblock:
//-----------------------------------------------------------------
int usb_uart_putblock(unsigned char *data, int length)
{
    int count = 0;
 
    do
    {
        int chunk = length;
 
        // Wait until space available (or timeout)
        t_time tS = usbhw_timer_now();
        while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN))
        {
            if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT)
                return 0;
        }
 
        usbhw_load_tx_buffer(CDC_ENDPOINT_BULK_IN, data, chunk);
 
        count += chunk;
        data  += chunk;
    }
    while (count < length);
 
    return length;
}
//-----------------------------------------------------------------
// usb_uart_putchar:
//-----------------------------------------------------------------
int usb_uart_putchar(char data)
{
    if (data == '\n')
        usb_uart_putchar('\r');
 
    // Wait until space available (or timeout)
    t_time tS = usbhw_timer_now();
    while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN))
    {
        if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT)
            return 0;
    }
 
    // Load byte into tx buffer
    usbhw_write_tx_byte(CDC_ENDPOINT_BULK_IN, data);
    _tx_count++;
 
    // Flush on buffer full or end of line
    if ( _tx_count >= EP2_MAX_PACKET_SIZE || data == '\n') 
        usb_uart_flush();
 
    return (int)data;
}
//-----------------------------------------------------------------
// usb_uart_flush:
//-----------------------------------------------------------------
void usb_uart_flush(void)
{
    // If some data present in output buffer
    if (_tx_count)
    {
        // Enable tx to start on next IN transfer
        usbhw_start_tx(CDC_ENDPOINT_BULK_IN);
 
        // If multiple of endpoint size, send ZLP
        if ( _tx_count == EP2_MAX_PACKET_SIZE )
        {
            t_time tS = usbhw_timer_now();
 
            // Wait for TX ready and then send ZLP
            while (!usbhw_has_tx_space(CDC_ENDPOINT_BULK_IN))
            {
                if (usbhw_timer_diff(usbhw_timer_now(), tS) > USB_UART_TX_TIMEOUT)
                {
                    log_printf(USBLOG_ERR, "UART: Flush timeout\n");
                    return ;
                }
            }
 
            usbhw_load_tx_buffer(CDC_ENDPOINT_BULK_IN, 0, 0);
        }
 
        _tx_count = 0;
    }
}
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.