Skip to content

Commit

Permalink
Add some test SW for verifying FTDI Async interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ultraembedded committed May 31, 2015
1 parent 5974f43 commit f9560f6
Show file tree
Hide file tree
Showing 4 changed files with 473 additions and 0 deletions.
275 changes: 275 additions & 0 deletions ftdi_async_bridge/sw/ftdi_hw.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,275 @@
#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;
}
26 changes: 26 additions & 0 deletions ftdi_async_bridge/sw/ftdi_hw.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef _FTDI_HW_H_
#define _FTDI_HW_H_

#include <stdint.h>

//-----------------------------------------------------------------
// Defines:
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// Prototypes:
//-----------------------------------------------------------------
int ftdi_hw_init(int interface);
int ftdi_hw_close(void);

// Memory Access
int ftdi_hw_mem_write(uint32_t addr, uint8_t *data, int length);
int ftdi_hw_mem_read(uint32_t addr, uint8_t *data, int length);
int ftdi_hw_mem_write_word(uint32_t addr, uint32_t data);
int ftdi_hw_mem_read_word(uint32_t addr, uint32_t *data);

// GPIO
int ftdi_hw_gpio_write(uint8_t value);
int ftdi_hw_gpio_read(uint8_t *value);

#endif
31 changes: 31 additions & 0 deletions ftdi_async_bridge/sw/makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
###############################################################################
## Makefile
###############################################################################

# Target
TARGET ?= test

# Options
CFLAGS = -g
LDFLAGS =
LIBS = -lftdi

# Source Files
OBJ = ftdi_hw.o $(TARGET).o

###############################################################################
# Rules
###############################################################################
all: $(TARGET)

clean:
-rm *.o $(TARGET)

%.o : %.c
gcc -c $(CFLAGS) $< -o $@

%.o : %.cpp
g++ -c $(CFLAGS) $< -o $@

$(TARGET): $(OBJ)
g++ $(LDFLAGS) $(OBJ) $(LIBS) -o $@
Loading

0 comments on commit f9560f6

Please sign in to comment.