-
-
Save goganchic/b88c85b0ea652e66a320 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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