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

Subversion Repositories ftdi_wb_bridge

[/] [ftdi_wb_bridge/] [trunk/] [sw/] [ftdi_hw.c] - Rev 2

Compare with Previous | Blame | View Log

#include <stdio.h>
#include <ftdi.h>
 
#include "ftdi_hw.h"
 
//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------
#define CMD_NOP        0x0
#define CMD_WR         0x1
#define CMD_RD         0x2
#define CMD_GP_WR      0x3
#define CMD_GP_RD      0x4
 
#define MAX_TX_SIZE    2048
#define HDR_SIZE       6
 
#define FTDI_PID       0x0403
#define FTDI_VID       0x6010
 
//-----------------------------------------------------------------
// Locals:
//-----------------------------------------------------------------
static struct ftdi_context *_handle;
 
//-----------------------------------------------------------------
// ftdi_hw_init:
//-----------------------------------------------------------------
int ftdi_hw_init(int interface)
{
    int status;
 
    _handle = ftdi_new();
    if (!_handle)
        return -1;
 
    // Open channel
    ftdi_set_interface(_handle, interface ? INTERFACE_B : INTERFACE_A);
    status = ftdi_usb_open(_handle, FTDI_PID, FTDI_VID);
    if (status != 0)
    {
        ftdi_free(_handle);
        _handle = NULL;
        return -1;
    }
 
    // Reset FTDI
    status = ftdi_usb_reset(_handle);
    if (status != 0)
    {
        ftdi_usb_close(_handle);
        ftdi_free(_handle);
        _handle = NULL;
        return -1;
    }
 
    // Flush buffers
    status = ftdi_usb_purge_buffers(_handle);
    if (status != 0)
    {
        ftdi_usb_close(_handle);
        ftdi_free(_handle);
        _handle = NULL;
        return -1;
    }
 
    // Set transfer mode
    status = ftdi_set_bitmode(_handle, 0xFF, BITMODE_RESET);
    if (status != 0)
    {
        ftdi_usb_close(_handle);
        ftdi_free(_handle);
        _handle = NULL;
        return -1;
    }
 
    return 0;
}
//-----------------------------------------------------------------
// ftdi_hw_close:
//-----------------------------------------------------------------
int ftdi_hw_close(void)
{
    if (_handle)
    {
        ftdi_usb_close(_handle);
        ftdi_free(_handle);
        _handle = NULL;
    }
 
    return 0;
}
//-----------------------------------------------------------------
// ftdi_hw_mem_write:
//-----------------------------------------------------------------
int ftdi_hw_mem_write(uint32_t addr, uint8_t *data, int length)
{
    int i;
    int sent = 0;
    int size = length;
    int res;
    uint8_t buffer[MAX_TX_SIZE + HDR_SIZE];
    uint8_t *p;
 
    while (sent < length)
    {
        size = (length - sent);
        if (size > MAX_TX_SIZE)
            size = MAX_TX_SIZE;
 
        // Build packet header
        p = buffer;
        *p++ = (((size >> 8) & 0xF) << 4) | CMD_WR;
        *p++ = (size & 0xFF);
 
        *p++ = (addr >> 24);
        *p++ = (addr >> 16);
        *p++ = (addr >> 8);
        *p++ = (addr >> 0);        
 
        // Fill packet payload
        for (i=0;i<size;i++)
            *p++ = *data++;
 
        // Write request + data to FTDI device
        res = ftdi_write_data(_handle, buffer, (size + HDR_SIZE));
        if (res != (size + HDR_SIZE))
        {
            fprintf(stderr, "ftdi_hw_mem_write: Failed to send\n");
            return -1;
        }        
 
        sent += size;
        addr += size;
    }
 
    return sent;
}
//-----------------------------------------------------------------
// ftdi_hw_mem_read:
//-----------------------------------------------------------------
int ftdi_hw_mem_read(uint32_t addr, uint8_t *data, int length)
{
    int i;
    int received = 0;
    int size = length;
    int remain;
    int res;
    uint8_t buffer[HDR_SIZE];
    uint8_t *p;
 
    while (received < length)
    {
        size = (length - received);
        if (size > MAX_TX_SIZE)
            size = MAX_TX_SIZE;
 
        // Round up to nearest 4 byte multiple
        size = (size + 3) & ~3;
 
        // Build packet header
        p = buffer;
        *p++ = (((size >> 8) & 0xF) << 4) | CMD_RD;
        *p++ = (size & 0xFF);
 
        *p++ = (addr >> 24);
        *p++ = (addr >> 16);
        *p++ = (addr >> 8);
        *p++ = (addr >> 0);
 
        // Write request to FTDI device
        res = ftdi_write_data(_handle, buffer, HDR_SIZE);
        if (res != HDR_SIZE)
        {
            fprintf(stderr, "ftdi_hw_mem_read: Failed to send request\n");
            return -1;
        }
 
        remain = size;
        do
        {
            res = ftdi_read_data(_handle, data, remain);
            if (res < 0)
            {
                fprintf(stderr, "ftdi_hw_mem_read: Failed to read data\n");
                return -1;
            }
 
            remain -= res;
            data += res;
        }
        while (remain > 0);
 
        received += size;
        addr     += size;
    }
 
    return received;
}
//-----------------------------------------------------------------
// ftdi_hw_mem_write_word:
//-----------------------------------------------------------------
int ftdi_hw_mem_write_word(uint32_t addr, uint32_t data)
{
    uint8_t buffer[4];
 
    buffer[3] = (data >> 24);
    buffer[2] = (data >> 16);
    buffer[1] = (data >> 8);
    buffer[0] = (data >> 0);
 
    return ftdi_hw_mem_write(addr, buffer, 4);
}
//-----------------------------------------------------------------
// ftdi_hw_mem_read_word:
//-----------------------------------------------------------------
int ftdi_hw_mem_read_word(uint32_t addr, uint32_t *data)
{
    uint8_t buffer[4];
 
    int res = ftdi_hw_mem_read(addr, buffer, 4);
    if (res > 0)
    {
        (*data) = ((uint32_t)buffer[3]) << 24;
        (*data)|= ((uint32_t)buffer[2]) << 16;
        (*data)|= ((uint32_t)buffer[1]) << 8;
        (*data)|= ((uint32_t)buffer[0]) << 0;
    }
    return res;
}
//-----------------------------------------------------------------
// ftdi_hw_gpio_write:
//-----------------------------------------------------------------
int ftdi_hw_gpio_write(uint8_t value)
{
    uint8_t buffer[2] = { CMD_GP_WR, value };
 
    // Write request to FTDI device
    int res = ftdi_write_data(_handle, buffer, sizeof(buffer));
    if (res != sizeof(buffer))
    {
        fprintf(stderr, "ftdi_hw_mem_write: Failed to send\n");
        return -1;
    }
 
    return 0;
}
//-----------------------------------------------------------------
// ftdi_hw_gpio_read:
//-----------------------------------------------------------------
int ftdi_hw_gpio_read(uint8_t *value)
{
    // Write request to FTDI device
    uint8_t request = CMD_GP_RD;
    int res = ftdi_write_data(_handle, &request, 1);
    if (res != 1)
    {
        fprintf(stderr, "ftdi_hw_mem_write: Failed to send\n");
        return -1;
    }
 
    // Poll for response
    do
    {
        res = ftdi_read_data(_handle, value, 1);
        if (res < 0)
        {
            fprintf(stderr, "ftdi_hw_mem_read: Failed to read data\n");
            return -1;
        }
    }
    while (res != 1);
 
    return 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.