Skip to content

Instantly share code, notes, and snippets.

@goganchic
Created March 31, 2014 19:58
Show Gist options
  • Save goganchic/b88c85b0ea652e66a320 to your computer and use it in GitHub Desktop.
Save goganchic/b88c85b0ea652e66a320 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ftdi.h>
#define PIN_BUFF 3
#define PIN_MOSI 6
#define PIN_MISO 4
#define PIN_SCK 2
#define PIN_RESET 5
#define CMD_RESULT_OK 0
#define CMD_RESULT_EXIT 1
#define CMD_RESULT_UNKNOWN 2
#define BAUDRATE 600
#define FT245R_CYCLES 2
#define SET_BITS_0(x,pinbit,level) (((x) & ~(pinbit)) | ((level) << (pinbit)))
#define GET_BITS_0(x,pinbit) ((x) & (1 << (pinbit)))
typedef struct ftdi_context * pftdi;
unsigned char cur_state;
void debug(const char *fmt, ...)
{
va_list arglist;
va_start(arglist, fmt);
vfprintf(stderr, fmt, arglist);
va_end(arglist);
}
unsigned char *char2bin_str(unsigned char a, unsigned char *buffer) {
int i;
buffer[8] = 0;
for (i = 7; i >= 0; i--) {
buffer[i] = (a & 1) + '0';
a >>= 1;
}
return buffer;
}
pftdi open_ft232rl()
{
pftdi ftdi;
int f;
unsigned char mode = ~(1 << PIN_MISO);
unsigned char mode_str[9];
unsigned char tmp_buf[4096];
if ((ftdi = ftdi_new()) == 0)
{
debug("ftdi_new failed\n");
return NULL;
}
f = ftdi_usb_open(ftdi, 0x0403, 0x6001);
if (f != 0)
{
debug("unable to open ftdi device: %d (%s)\n", f, ftdi_get_error_string(ftdi));
return NULL;
}
ftdi_set_baudrate(ftdi, BAUDRATE);
ftdi_set_bitmode(ftdi, mode, BITMODE_SYNCBB);
ftdi_write_data(ftdi, &cur_state, 1);
ftdi_read_data(ftdi, tmp_buf, sizeof(tmp_buf));
return ftdi;
}
void close_ft232rl(pftdi ftdi)
{
ftdi_disable_bitbang(ftdi);
ftdi_usb_close(ftdi);
ftdi_free(ftdi);
}
void set_pin(pftdi ftdi, unsigned char pin, unsigned char val)
{
unsigned char tmp_buf;
if (val)
cur_state |= (1 << pin);
else
cur_state &= ~(1 << pin);
ftdi_write_data(ftdi, &cur_state, 1);
ftdi_read_data(ftdi, &tmp_buf, 1);
}
static inline int set_data(unsigned char *buf, unsigned char data) {
int j;
int buf_pos = 0;
unsigned char bit = 0x80;
for (j=0; j<8; j++) {
cur_state = SET_BITS_0(cur_state, PIN_MOSI, data & bit);
cur_state = SET_BITS_0(cur_state, PIN_SCK, 0);
buf[buf_pos] = cur_state;
buf_pos++;
cur_state = SET_BITS_0(cur_state, PIN_SCK, 1);
buf[buf_pos] = cur_state;
buf_pos++;
bit >>= 1;
}
return buf_pos;
}
static inline unsigned char extract_data(unsigned char *buf, int offset) {
int j;
int buf_pos = 1;
unsigned char bit = 0x80;
unsigned char r = 0;
buf += offset * (8 * FT245R_CYCLES);
for (j=0; j<8; j++) {
if (GET_BITS_0(buf[buf_pos], PIN_MISO)) {
r |= bit;
}
buf_pos += FT245R_CYCLES;
bit >>= 1;
}
return r;
}
void avr_cmd(pftdi ftdi, unsigned char *cmd, unsigned char *out)
{
int i;
unsigned char tmp_buf;
unsigned char buf[64];
for (i = 0; i < 4; ++i) {
set_data(buf + i, cmd[i]);
}
ftdi_write_data(ftdi, buf, 64);
ftdi_read_data(ftdi, buf, 64);
out[0] = extract_data(buf, 0);
out[1] = extract_data(buf, 1);
out[2] = extract_data(buf, 2);
out[3] = extract_data(buf, 3);
}
void start_prog(pftdi ftdi)
{
unsigned char in_buf[4];
unsigned char ares[4];
unsigned char buf_str[9];
set_pin(ftdi, PIN_BUFF, 1);
set_pin(ftdi, PIN_RESET, 0);
set_pin(ftdi, PIN_SCK, 0);
set_pin(ftdi, PIN_BUFF, 0);
set_pin(ftdi, PIN_RESET, 1);
usleep(50);
set_pin(ftdi, PIN_RESET, 0);
usleep(50);
in_buf[0] = 0b10101100;
in_buf[1] = 0b01010011;
in_buf[2] = 0;
in_buf[3] = 0;
avr_cmd(ftdi, in_buf, ares);
debug("result:");
debug(" %s", char2bin_str(ares[0], buf_str));
debug(" %s", char2bin_str(ares[1], buf_str));
debug(" %s", char2bin_str(ares[2], buf_str));
debug(" %s\n", char2bin_str(ares[3], buf_str));
debug("Read from buffer %d bytes\n", ftdi_read_data(ftdi, buf_str, sizeof(buf_str)));
}
int main(int argc, char **argv)
{
unsigned char acmd[4];
unsigned char ares[4];
pftdi ftdi;
cur_state = 0xff;
ftdi = open_ft232rl();
if (!ftdi) {
debug("can not open device\n");
return 1;
}
start_prog(ftdi);
close_ft232rl(ftdi);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment