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

Subversion Repositories xulalx25soc

[/] [xulalx25soc/] [trunk/] [sw/] [usbi.cpp] - Diff between revs 41 and 46

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 41 Rev 46
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Filename:    usbi.cpp
// Filename:    usbi.cpp
//
//
// Project:     XuLA2 board
// Project:     XuLA2 board
//
//
// Purpose:     Creates a USB port, similar to a serial port, out of the
// Purpose:     Creates a USB port, similar to a serial port, out of the
//              XuLA2 JTAG interface S/W.
//              XuLA2 JTAG interface S/W.
//
//
//
//
// Creator:     Dan Gisselquist, Ph.D.
// Creator:     Dan Gisselquist, Ph.D.
//              Gisselquist Technology, LLC
//              Gisselquist Technology, LLC
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
// Copyright (C) 2015, Gisselquist Technology, LLC
// Copyright (C) 2015, Gisselquist Technology, LLC
//
//
// This program is free software (firmware): you can redistribute it and/or
// This program is free software (firmware): you can redistribute it and/or
// modify it under the terms of  the GNU General Public License as published
// modify it under the terms of  the GNU General Public License as published
// by the Free Software Foundation, either version 3 of the License, or (at
// by the Free Software Foundation, either version 3 of the License, or (at
// your option) any later version.
// your option) any later version.
//
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// for more details.
//
//
// License:     GPL, v3, as defined and found on www.gnu.org,
// License:     GPL, v3, as defined and found on www.gnu.org,
//              http://www.gnu.org/licenses/gpl.html
//              http://www.gnu.org/licenses/gpl.html
//
//
//
//
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//
//
//
//
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>
#include <string.h>
#include <string.h>
#include <ctype.h>
#include <ctype.h>
// #include <usb.h>
// #include <usb.h>
 
 
#include <libusb.h>
#include <libusb.h>
 
 
#include "llcomms.h"
#include "llcomms.h"
#include "usbi.h"
#include "usbi.h"
 
 
// Walk us through the JTAG Chain:
// Walk us through the JTAG Chain:
//      5-1's to go to test/reset
//      5-1's to go to test/reset
//      0        to go to Run-Test/Idle
//      0        to go to Run-Test/Idle
//      1       to go to select-dr-scan
//      1       to go to select-dr-scan
//      1       to go to select-ir-scan
//      1       to go to select-ir-scan
//      0        to go to capture-ir
//      0        to go to capture-ir
//      0        to go to shift-ir
//      0        to go to shift-ir
//      (6-bit code 0x02 through TDI to IR, while sending 0-bits to TMS)
//      (6-bit code 0x02 through TDI to IR, while sending 0-bits to TMS)
//      1       to leave shift IR and go to exit1-ir
//      1       to leave shift IR and go to exit1-ir
//      1       to go to update-ir
//      1       to go to update-ir
//      1       to go to select-dr-scan
//      1       to go to select-dr-scan
//      0        to go to capture-dr
//      0        to go to capture-dr
//      0        to go to shift-dr
//      0        to go to shift-dr
#define RESET_JTAG_LEN  12
#define RESET_JTAG_LEN  12
static const char       RESET_TO_USER_DR[RESET_JTAG_LEN] = {
static const char       RESET_TO_USER_DR[RESET_JTAG_LEN] = {
        JTAG_CMD,
        JTAG_CMD,
        21, // clocks
        21, // clocks
        0,0,0,     // Also clocks, higher order bits
        0,0,0,     // Also clocks, higher order bits
        PUT_TMS_MASK | PUT_TDI_MASK, // flags
        PUT_TMS_MASK | PUT_TDI_MASK, // flags
        (char)(0x0df),  // TMS: Five ones, then one zero, and two ones -- low bits first
        (char)(0x0df),  // TMS: Five ones, then one zero, and two ones -- low bits first
        0x00,   // TDI: irrelevant here
        0x00,   // TDI: irrelevant here
        (char)0x80,     // TMS: two zeros, then six zeros
        (char)0x80,     // TMS: two zeros, then six zeros
        0x08,   // TDI: user command #1, bit reversed
        0x08,   // TDI: user command #1, bit reversed
        0x03,   // TMS: three ones, then two zeros
        0x03,   // TMS: three ones, then two zeros
        0x00    // TDI byte -- irrelevant here
        0x00    // TDI byte -- irrelevant here
        //
        //
        // 0xc0, // TDI byte -- user command #2
        // 0xc0, // TDI byte -- user command #2
        // 0x40,        // TDI: user command #1
        // 0x40,        // TDI: user command #1
        // 0x0c, // TDI byte -- user command #2, bit reversed
        // 0x0c, // TDI byte -- user command #2, bit reversed
};
};
 
 
//
//
//      TMS: 
//      TMS: 
#define TX_DR_LEN       12
#define TX_DR_LEN       12
static const    char    TX_DR_BITS[TX_DR_LEN] = {
static const    char    TX_DR_BITS[TX_DR_LEN] = {
        JTAG_CMD,
        JTAG_CMD,
        48, // clocks
        48, // clocks
        0,0,0,     // Also clocks, higher order bits
        0,0,0,     // Also clocks, higher order bits
        PUT_TDI_MASK, // flags
        PUT_TDI_MASK, // flags
        (char)0x0ff, 0, 0, 0, 0, 0   // Six data bytes
        (char)0x0ff, 0, 0, 0, 0, 0   // Six data bytes
        // module_id = 255
        // module_id = 255
        // 32'h(payload.length)
        // 32'h(payload.length)
        // payload
        // payload
        // module_id + payload.len + num_result_bits, length=32 + payload ???
        // module_id + payload.len + num_result_bits, length=32 + payload ???
};
};
 
 
//
//
//      TMS: 
//      TMS: 
//      
//      
#define REQ_RX_LEN      6
#define REQ_RX_LEN      6
static const    char    REQ_RX_BITS[REQ_RX_LEN] = {
static const    char    REQ_RX_BITS[REQ_RX_LEN] = {
        JTAG_CMD,
        JTAG_CMD,
        (const char)((USB_PKTLEN-REQ_RX_LEN)*8), // bits-requested
        (const char)((USB_PKTLEN-REQ_RX_LEN)*8), // bits-requested
        0,0,0,     // Also clocks, higher order bits
        0,0,0,     // Also clocks, higher order bits
        GET_TDO_MASK|TDI_VAL_MASK, // flags:TDI is kept low here, so no TDI flag
        GET_TDO_MASK|TDI_VAL_MASK, // flags:TDI is kept low here, so no TDI flag
        // No data given, since there's no info to send or receive
        // No data given, since there's no info to send or receive
        // Leave the result in shift-DR mode
        // Leave the result in shift-DR mode
};
};
 
 
/*
/*
#define RETURN_TO_RESET_LEN     7
#define RETURN_TO_RESET_LEN     7
static const char       RETURN_TO_RESET[RETURN_TO_RESET_LEN] = {
static const char       RETURN_TO_RESET[RETURN_TO_RESET_LEN] = {
        JTAG_CMD,
        JTAG_CMD,
        5, // clocks
        5, // clocks
        0,0,0,  // Also clocks, higher order bits
        0,0,0,  // Also clocks, higher order bits
        PUT_TMS_MASK, // flags
        PUT_TMS_MASK, // flags
        (char)0x0ff, // Five ones
        (char)0x0ff, // Five ones
};
};
*/
*/
 
 
USBI::USBI(void) {
USBI::USBI(void) {
        int     config;
        int     config;
 
 
        m_total_nread = 0;
        m_total_nread = 0;
 
 
        if (0 != libusb_init(&m_usb_context)) {
        if (0 != libusb_init(&m_usb_context)) {
                fprintf(stderr, "Error initializing the USB library\n");
                fprintf(stderr, "Error initializing the USB library\n");
                perror("O/S Err:");
                perror("O/S Err:");
                exit(-1);
                exit(-1);
        }
        }
 
 
        m_xula_usb_device = libusb_open_device_with_vid_pid(m_usb_context,
        m_xula_usb_device = libusb_open_device_with_vid_pid(m_usb_context,
                VENDOR_ID, PRODUCT_ID);
                VENDOR_ID, PRODUCT_ID);
        if (!m_xula_usb_device) {
        if (!m_xula_usb_device) {
                fprintf(stderr, "Could not open XuLA device\n");
                fprintf(stderr, "Could not open XuLA device\n");
                perror("O/S Err:");
                perror("O/S Err:");
 
 
                libusb_exit(m_usb_context);
                libusb_exit(m_usb_context);
                exit(-1);
                exit(-1);
        }
        }
 
 
        if (0 != libusb_get_configuration(m_xula_usb_device, &config)) {
        if (0 != libusb_get_configuration(m_xula_usb_device, &config)) {
                fprintf(stderr, "Could not get configuration\n");
                fprintf(stderr, "Could not get configuration\n");
                perror("O/S Err:");
                perror("O/S Err:");
 
 
                libusb_close(m_xula_usb_device);
                libusb_close(m_xula_usb_device);
                libusb_exit(m_usb_context);
                libusb_exit(m_usb_context);
                exit(-1);
                exit(-1);
        }
        }
 
 
        if (0 != libusb_claim_interface(m_xula_usb_device, XESS_INTERFACE)) {
        if (0 != libusb_claim_interface(m_xula_usb_device, XESS_INTERFACE)) {
                fprintf(stderr, "Could not claim interface\n");
                fprintf(stderr, "Could not claim interface\n");
                perror("O/S Err:");
                perror("O/S Err:");
 
 
                libusb_close(m_xula_usb_device);
                libusb_close(m_xula_usb_device);
                libusb_exit(m_usb_context);
                libusb_exit(m_usb_context);
                exit(-1);
                exit(-1);
        }
        }
 
 
        unsigned char   abuf[RESET_JTAG_LEN];
        unsigned char   abuf[RESET_JTAG_LEN];
        int     actual_length = RESET_JTAG_LEN, r;
        int     actual_length = RESET_JTAG_LEN, r;
 
 
        memcpy(abuf, RESET_TO_USER_DR, RESET_JTAG_LEN);
        memcpy(abuf, RESET_TO_USER_DR, RESET_JTAG_LEN);
        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                abuf, RESET_JTAG_LEN, &actual_length, 4);
                abuf, RESET_JTAG_LEN, &actual_length, 4);
        if ((r!=0)||(actual_length != RESET_JTAG_LEN)) {
        if ((r!=0)||(actual_length != RESET_JTAG_LEN)) {
                // Try clearing the queue twice, then doing this
                // Try clearing the queue twice, then doing this
                do {
                do {
                        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
                        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
                                (unsigned char *)m_rxbuf, USB_PKTLEN, &actual_length, 20);
                                (unsigned char *)m_rxbuf, USB_PKTLEN, &actual_length, 20);
                } while((r==0)&&(actual_length > 0));
                } while((r==0)&&(actual_length > 0));
 
 
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                        abuf, RESET_JTAG_LEN, &actual_length, 4);
                        abuf, RESET_JTAG_LEN, &actual_length, 4);
                if ((r != 0)||(actual_length != RESET_JTAG_LEN)) {
                if ((r != 0)||(actual_length != RESET_JTAG_LEN)) {
                        printf("Some error took place requesting RESET_TO_USER_DR\n");
                        printf("Some error took place requesting RESET_TO_USER_DR\n");
                        printf("r = %d, actual_length = %d (vs %d requested)\n",
                        printf("r = %d, actual_length = %d (vs %d requested)\n",
                                r, actual_length, RESET_JTAG_LEN);
                                r, actual_length, RESET_JTAG_LEN);
                        perror("O/S Err");
                        perror("O/S Err");
                        exit(-2);
                        exit(-2);
                }
                }
        }
        }
 
 
        // Initialize our read FIFO
        // Initialize our read FIFO
        m_rbeg = m_rend = 0;
        m_rbeg = m_rend = 0;
 
 
        flush_read();
        flush_read();
}
}
 
 
void    USBI::close(void) {
void    USBI::close(void) {
        // Release our interface
        // Release our interface
        if (0 != libusb_release_interface(m_xula_usb_device, XESS_INTERFACE)) {
        if (0 != libusb_release_interface(m_xula_usb_device, XESS_INTERFACE)) {
                fprintf(stderr, "Could not release interface\n");
                fprintf(stderr, "Could not release interface\n");
                perror("O/S Err:");
                perror("O/S Err:");
 
 
                libusb_close(m_xula_usb_device);
                libusb_close(m_xula_usb_device);
                libusb_exit(m_usb_context);
                libusb_exit(m_usb_context);
                exit(-1);
                exit(-1);
        }
        }
 
 
        // And then close our device with
        // And then close our device with
        libusb_close(m_xula_usb_device);
        libusb_close(m_xula_usb_device);
 
 
        // And just before exiting, we free our USB context
        // And just before exiting, we free our USB context
        libusb_exit(m_usb_context);
        libusb_exit(m_usb_context);
}
}
 
 
void    USBI::write(char *buf, int len) {
void    USBI::write(char *buf, int len) {
        int     r, actual_length;
        int     r, actual_length;
 
 
        if (len >= USB_PKTLEN) {
        if (len >= USB_PKTLEN) {
                const int       nv = USB_PKTLEN/2-1;
                const int       nv = USB_PKTLEN/2-1;
                for(int pos=0; pos<len; pos+=nv)
                for(int pos=0; pos<len; pos+=nv)
                        write(&buf[pos], (len-pos>nv)?(nv):len-pos);
                        write(&buf[pos], (len-pos>nv)?(nv):len-pos);
        } else {
        } else {
                memset(m_txbuf, 0, len+6);
                memset(m_txbuf, 0, len+6);
                m_txbuf[0] = JTAG_CMD;
                m_txbuf[0] = JTAG_CMD;
                m_txbuf[1] = len * 8;
                m_txbuf[1] = len * 8;
                m_txbuf[2] = 0;
                m_txbuf[2] = 0;
                m_txbuf[3] = 0;
                m_txbuf[3] = 0;
                m_txbuf[4] = 0;
                m_txbuf[4] = 0;
                m_txbuf[5] = PUT_TDI_MASK | GET_TDO_MASK;
                m_txbuf[5] = PUT_TDI_MASK | GET_TDO_MASK;
 
 
                for(int i=0; i<len; i++)
                for(int i=0; i<len; i++)
                        m_txbuf[6+i] = buf[i];
                        m_txbuf[6+i] = buf[i];
                // printf("WRITE::(buf=%*s, %d)\n", len, buf, len);
                // printf("WRITE::(buf=%*s, %d)\n", len, buf, len);
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                        (unsigned char*)m_txbuf, len+6, &actual_length, 0);
                        (unsigned char*)m_txbuf, len+6, &actual_length, 0);
                if ((r!=0)||(actual_length != len+6)) {
                if ((r!=0)||(actual_length != len+6)) {
                        printf("WRITE::(buf, %d) -- ERR\n", len+6);
                        printf("WRITE::(buf, %d) -- ERR\n", len+6);
                        printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                        printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                                actual_length, len+6);
                                actual_length, len+6);
 
 
                        if (r == -7) {
                        if (r == -7) {
                                r = libusb_bulk_transfer(m_xula_usb_device,
                                r = libusb_bulk_transfer(m_xula_usb_device,
                                        XESS_ENDPOINT_OUT,
                                        XESS_ENDPOINT_OUT,
                                        (unsigned char*)m_txbuf, len+6,
                                        (unsigned char*)m_txbuf, len+6,
                                        &actual_length, 2);
                                        &actual_length, 2);
                                if ((r!=0)||(actual_length != len+6)) {
                                if ((r!=0)||(actual_length != len+6)) {
                                        printf("WRITE::(buf, %d) -- ERR\n", len+6);
                                        printf("WRITE::(buf, %d) -- ERR\n", len+6);
                                        printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                                        printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                                                actual_length, len+6);
                                                actual_length, len+6);
                                        perror("O/S Err");
                                        perror("O/S Err");
 
 
                                        exit(-2);
                                        exit(-2);
                                }
                                }
                        } else {
                        } else {
                                perror("O/S Err");
                                perror("O/S Err");
                                exit(-2);
                                exit(-2);
                        }
                        }
                }
                }
 
 
                // Try to read back however many bytes we can
                // Try to read back however many bytes we can
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
                r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
                        (unsigned char*)m_rxbuf, USB_PKTLEN, &actual_length, 20);
                        (unsigned char*)m_rxbuf, USB_PKTLEN, &actual_length, 20);
                if ((r==0)&&(actual_length > 0)) {
                if ((r==0)&&(actual_length > 0)) {
                        push_fifo(m_rxbuf, actual_length);
                        push_fifo(m_rxbuf, actual_length);
                } else {
                } else {
                        printf("Some error took place in receiving\n");
                        printf("Some error took place in receiving\n");
                        perror("O/S Err");
                        perror("O/S Err");
                }
                }
        }
        }
}
}
 
 
int     USBI::read(char *buf, int len) {
int     USBI::read(char *buf, int len) {
        return read(buf, len, 4);
        return read(buf, len, 4);
}
}
 
 
int     USBI::read(char *buf, int len, int timeout_ms) {
int     USBI::read(char *buf, int len, int timeout_ms) {
        int     left = len, nr=0;
        int     left = len, nr=0;
 
 
        // printf("USBI::read(%d) (FIFO is %d-%d)\n", len, m_rend, m_rbeg);
        // printf("USBI::read(%d) (FIFO is %d-%d)\n", len, m_rend, m_rbeg);
        nr = pop_fifo(buf, left);
        nr = pop_fifo(buf, left);
        left -= nr;
        left -= nr;
 
 
        while(left > 0) {
        while(left > 0) {
                raw_read(left, timeout_ms);
                raw_read(left, timeout_ms);
                nr = pop_fifo(&buf[len-left], left);
                nr = pop_fifo(&buf[len-left], left);
                left -= nr;
                left -= nr;
 
 
                // printf("\tWHILE (nr = %d, LEFT = %d, len=%d)\n", nr, left, len);
                // printf("\tWHILE (nr = %d, LEFT = %d, len=%d)\n", nr, left, len);
                if (nr == 0)
                if (nr == 0)
                        break;
                        break;
        }
        }
 
 
        // printf("READ %d characters (%d req, %d left)\n", len-left, len, left);
        // printf("READ %d characters (%d req, %d left)\n", len-left, len, left);
        return len-left;
        return len-left;
}
}
 
 
void    USBI::raw_read(const int clen, int timeout_ms) {
void    USBI::raw_read(const int clen, int timeout_ms) {
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK), actual_length;
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK), actual_length;
        int     len = clen;
        int     len = clen;
        if (len > RCV_BUFMASK-avail)
        if (len > RCV_BUFMASK-avail)
                len = RCV_BUFMASK-avail;
                len = RCV_BUFMASK-avail;
        if (len > 26)
        if (len > 26)
                len = 26;
                len = 26;
 
 
        // printf("USBI::RAW-READ(%d, was %d)\n", len, clen);
        // printf("USBI::RAW-READ(%d, was %d)\n", len, clen);
        memcpy(m_txbuf, REQ_RX_BITS, REQ_RX_LEN);
        memcpy(m_txbuf, REQ_RX_BITS, REQ_RX_LEN);
 
 
 
        // I have chased process hangs to this line, but have no more
 
        // information than that somewhere within libusb_bulk_transfer,
 
        // libusb_handle_events_completed,
 
        // libusb_handle_events_timeout_completed, ?, poll(), there seems
 
        // to be a bug.
 
        //
 
        // I'm not certain if the bug is in the Linux kernel, or in the 
 
        // Xess tools.  I will note that, when a followup attempt is made
 
        // to read from the device, previously unread data may still get dumped
 
        // to it.  Therefore, be careful to clear the device upon starting
 
        // any process.
 
        //
 
        // fprintf(stderr, "[");
        int r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
        int r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_OUT,
                (unsigned char *)m_txbuf, REQ_RX_LEN, &actual_length,
                (unsigned char *)m_txbuf, REQ_RX_LEN, &actual_length,
                timeout_ms);
                timeout_ms);
 
        // fprintf(stderr, "]");
 
 
        if ((r==0)&&(actual_length == REQ_RX_LEN)) {
        if ((r==0)&&(actual_length == REQ_RX_LEN)) {
        } else if (r == -7) {
        } else if (r == -7) {
                // Nothing to read in the timeout provided
                // Nothing to read in the timeout provided
                // We'll have to request this data again ... later
                // We'll have to request this data again ... later
                return;
                return;
        } else {
        } else {
                printf("READ(WRITE,READ-REQ) -- ERR\n");
                printf("READ(WRITE,READ-REQ) -- ERR\n");
                printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                printf("r = %d, actual_length = %d (!= %d requested)\n", r,
                        actual_length, len+6);
                        actual_length, len+6);
                perror("O/S Err");
                perror("O/S Err");
                exit(-2);
                exit(-2);
        }
        }
 
 
        // Try to read back however many bytes we can
        // Try to read back however many bytes we can
        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
        r = libusb_bulk_transfer(m_xula_usb_device, XESS_ENDPOINT_IN,
                (unsigned char *)m_rxbuf, USB_PKTLEN, &actual_length, 0);
                (unsigned char *)m_rxbuf, USB_PKTLEN, &actual_length, 0);
        if ((r==0)&&(actual_length > 0)) {
        if ((r==0)&&(actual_length > 0)) {
                /*
                /*
                printf("RAW-READ() -> %d Read\n", actual_length);
                printf("RAW-READ() -> %d Read\n", actual_length);
                for(int i=0; i<actual_length; i++)
                for(int i=0; i<actual_length; i++)
                        printf("%02x ", m_rxbuf[i] & 0x0ff);
                        printf("%02x ", m_rxbuf[i] & 0x0ff);
                printf("\n");
                printf("\n");
                */
                */
                push_fifo(m_rxbuf, actual_length);
                push_fifo(m_rxbuf, actual_length);
        } else if (r == -7) {
        } else if (r == -7) {
                // Nothing to read in the timeout provided
                // Nothing to read in the timeout provided
                // Return, adding nothing to our FIFO
                // Return, adding nothing to our FIFO
        } else {
        } else {
                printf("Some error took place in receiving\n");
                printf("Some error took place in receiving\n");
                perror("O/S Err");
                perror("O/S Err");
        }
        }
 
 
        // fprintf(stderr, "\tUSBI::RAW-READ() -- COMPLETE (%d avail)\n",
        // fprintf(stderr, "\tUSBI::RAW-READ() -- COMPLETE (%d avail)\n",
                // (m_rbeg-m_rend)&(RCV_BUFMASK));
                // (m_rbeg-m_rend)&(RCV_BUFMASK));
}
}
 
 
void    USBI::flush_read(void) {
void    USBI::flush_read(void) {
        while(poll(4)) {
        while(poll(4)) {
                m_rbeg = m_rend = 0;
                m_rbeg = m_rend = 0;
        }
        }
}
}
 
 
void    USBI::push_fifo(char *buf, int len) {
void    USBI::push_fifo(char *buf, int len) {
        char    last = 0;
        char    last = 0;
        char    *sptr = buf;
        char    *sptr = buf;
 
 
        // printf("Pushing %d items onto FIFO (%d - %d)\n", len, m_rend, m_rbeg);
        // printf("Pushing %d items onto FIFO (%d - %d)\n", len, m_rend, m_rbeg);
        if (m_rbeg != m_rend)
        if (m_rbeg != m_rend)
                last = m_rbuf[m_rend];
                last = m_rbuf[m_rend];
        for(int i=0; i<len; i++) {
        for(int i=0; i<len; i++) {
                char v = *sptr++;
                char v = *sptr++;
                if (((v & 0x80)||((unsigned char)v < 0x10))&&(v == last)) {
                if (((v & 0x80)||((unsigned char)v < 0x10))&&(v == last)) {
                        // printf("\tSkipping: %02x\n", v & 0x0ff);
                        // printf("\tSkipping: %02x\n", v & 0x0ff);
                } else if ((unsigned char)v == 0x0ff) {
                } else if ((unsigned char)v == 0x0ff) {
                } else {
                } else {
                        m_rbuf[m_rbeg] = v;
                        m_rbuf[m_rbeg] = v;
                        m_rbeg = (m_rbeg+1)&(RCV_BUFMASK);
                        m_rbeg = (m_rbeg+1)&(RCV_BUFMASK);
                        // printf("\tPushing: %02x\n", v & 0x0ff);
                        // printf("\tPushing: %02x\n", v & 0x0ff);
                } last = v;
                } last = v;
        }
        }
}
}
 
 
int     USBI::pop_fifo(char *buf, int len) {
int     USBI::pop_fifo(char *buf, int len) {
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK);
        int     avail = (m_rbeg - m_rend)&(RCV_BUFMASK);
        int     left = len;
        int     left = len;
        int     nr = 0;
        int     nr = 0;
 
 
        // printf("Attempting to pop %d items from FIFO (%d - %d)\n",
        // printf("Attempting to pop %d items from FIFO (%d - %d)\n",
        //              len, m_rend, m_rbeg);
        //              len, m_rend, m_rbeg);
        while((avail > 0)&&(left > 0)) {
        while((avail > 0)&&(left > 0)) {
                int ln = RCV_BUFLEN-m_rend;
                int ln = RCV_BUFLEN-m_rend;
                if (ln > left)
                if (ln > left)
                        ln = left;
                        ln = left;
                if (ln > avail)
                if (ln > avail)
                        ln = avail;
                        ln = avail;
                memcpy(&buf[len-left], &m_rbuf[m_rend], ln);
                memcpy(&buf[len-left], &m_rbuf[m_rend], ln);
                left   -= ln;
                left   -= ln;
                avail  -= ln;
                avail  -= ln;
                m_rend  = (m_rend + ln)&(RCV_BUFMASK);
                m_rend  = (m_rend + ln)&(RCV_BUFMASK);
                nr     += ln;
                nr     += ln;
 
 
        //      printf("P:");
        //      printf("P:");
        //      for(int i=0; i<ln; i++)
        //      for(int i=0; i<ln; i++)
        //              printf("%02x ", buf[len-left-ln+i]);
        //              printf("%02x ", buf[len-left-ln+i]);
        } // printf("\n");
        } // printf("\n");
 
 
        /*
        /*
        if (nr > 0)
        if (nr > 0)
                printf("\tPopped %d items, buf[0] = %02x (%d - %d)\n",
                printf("\tPopped %d items, buf[0] = %02x (%d - %d)\n",
                        nr, buf[0], m_rend, m_rbeg);
                        nr, buf[0], m_rend, m_rbeg);
        else
        else
                printf("\tPopped nothing, %d - %d\n", m_rend, m_rbeg);
                printf("\tPopped nothing, %d - %d\n", m_rend, m_rbeg);
        */
        */
 
 
        return nr;
        return nr;
}
}
 
 
bool    USBI::poll(unsigned ms) {
bool    USBI::poll(unsigned ms) {
        int     avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
        int     avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
        bool    r = true;
        bool    r = true;
 
 
        // printf("POLL request\n");
        // printf("POLL request\n");
 
 
        if ((avail < 2)&&((avail<1)||(m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10))) {
        if ((avail < 2)&&((avail<1)||(m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10))) {
                raw_read(4,ms);
                raw_read(4,ms);
                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
                avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
                // printf("%d availabe\n", avail);
                // printf("%d availabe\n", avail);
 
 
                char    v = (m_rbuf[(m_rbeg-1)&(RCV_BUFMASK)]);
                char    v = (m_rbuf[(m_rbeg-1)&(RCV_BUFMASK)]);
                while(((v&0x80)==0)&&((unsigned)v>=0x10)&&(avail < RCV_BUFMASK-32)) {
                while(((v&0x80)==0)&&((unsigned)v>=0x10)&&(avail < RCV_BUFMASK-32)) {
                        raw_read(26,ms);
                        raw_read(26,ms);
                        avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
                        avail = (m_rbeg-m_rend)&(RCV_BUFMASK);
                }
                }
                if (avail < 1)
                if (avail < 1)
                        r = false;
                        r = false;
                else if ((avail==1)&&((m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10)))
                else if ((avail==1)&&((m_rbuf[m_rend]&0x80)||(m_rbuf[m_rend]<0x10)))
                        r = false;
                        r = false;
        }
        }
 
 
        // printf("USBI::poll() -> %s (%d avail)\n", (r)?"true":"false", avail);
        // printf("USBI::poll() -> %s (%d avail)\n", (r)?"true":"false", avail);
        return r;
        return r;
}
}
 
 

powered by: WebSVN 2.1.0

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