Форум программистов, компьютерный форум, киберфорум
Цифровая обработка сигналов
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.69/80: Рейтинг темы: голосов - 80, средняя оценка - 4.69
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
1

USB <--> SPI/I2C

18.03.2011, 11:11. Просмотров 14773. Ответов 15
Метки нет (Все метки)

Хочу сделать такую штуку. Кто-нибудь видел подобные схемы? Желательно на 1 микрухе. Сначала была мысль сделать FT232 + какой-либо МК, но че-то муторно. 100% можно проще. Есть схема на FT2232, но у нас ее я нигде не видел. Насколько оно от просто 232 отличается? Можно ли под 232 приспособить?

http://www.ftdichip.som/Support/Softwar ... 01_v11.pdf

Скорость не сильно критична, слейв не нужен, только мастер
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
18.03.2011, 11:11
Ответы с готовыми решениями:

Мультиплексирование SPI и I2C
Добрый день, вопрос такой. Имеется FT2232, с помощью которой можно эмулировать SPI и I2C. При...

Мост ??? -> UART/I2C/SPI
Всех приветствую! Есть необходимость в управлении разношерстной периферией, в одностороннем...

Конфликт spi и i2c при чтении с множества датчиков
Собственно вопрос. Есть несколько датчиков- Акселерометров от ST . Планируется организовать чтение...

USB client + 3 UART and SPI на WindowsMobile
Привет всем. Срочно нужен совет. Есть GPS Navigator с USB client входом, к нему нужно просто и...

15
0 / 0 / 0
Регистрация: 23.01.2010
Сообщений: 1,142
18.03.2011, 11:20 2
Не уверен, что без МК можно обойтись. Либо, нужно писать софт на компутере для махания ногами FT.

Впрочем, без написания софта для компутера не обойтись в любом случае:
Для SPI нужно (как минимум) сколько байт туда, сколько обратно.
Для I2C - адрес, сколько байт туда, сколько обратно.

Либо, эмулировать ком порт и весь "юзер интерфейс" в МК запихнуть и работать с терминалом как с командной строкой.

У меня такая штука на ATmego32U4 / AT90USB1286 планируется. Компутеру ком портом прикидывается, работает с терминала.
0
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
18.03.2011, 11:59 3
То что на компе софт придется писать это понятно. Если не получится с ФТ, возьму какой-нибудь камень с ЮСБ
0
0 / 0 / 0
Регистрация: 28.09.2010
Сообщений: 4,284
18.03.2011, 15:59 4
Вот в этой теме я строю подобный девайс:

Скорость пока мееедленная, но это терпимо.
Используется только ft232 (линии CBUS)
0
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
18.03.2011, 20:07 5
а кто работал с LUFA или STM32 USB Lib? могут они притворяться виртуальным ком-портом?
0
0 / 0 / 0
Регистрация: 14.03.2011
Сообщений: 36
18.03.2011, 20:28 6
У меня Atmego32U4 пашет - вообще без проблем.
0
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
18.03.2011, 20:36 7
Yok40, а можно схему/прошивку? попробую под at90usb приспособить
0
0 / 0 / 0
Регистрация: 14.03.2011
Сообщений: 36
19.03.2011, 09:36 8
Куда поскидывать? Счас затарю все - сегодня или завтра выложу... Там объем боьлшой.
скачать примерчики, заготовки и.т.п. можно тут:http://www.atmel.som/dyn/produ... ol_id=4441
0
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
19.03.2011, 10:55 9
Yok40, на любой файлообменник.. rghost.ru например
0
0 / 0 / 0
Регистрация: 14.03.2011
Сообщений: 36
19.03.2011, 11:04 10
Цитата Сообщение от morvym_yorki
Yok40, на любой файлообменник.. rghost.ru например
http://rghost.ru/4841912

- Тут пример реализации HID устройства. Перекомпилить можно под любой AVR - USB.

в файле usb_dessriptors.h корректируем под себя необходимые дескрипторы, компилим
прошиваем и пробуем подключить к порту. (я пользовался gcc winavr).

Как читать/писать с компа прогу обкомментарю и тоже выложу...

Схема подключения МК в ПДФ - все разжевано...
Там в conf_scheduler.h можно добавить свою задачку и дописывать свой код.
Ключевые функции записи/чтения в файле hid_task.c

Ну а дальше данные хоть в UART, хоть в SPI, и.т.п.

В файле config.h еще частоту кварца указать нужно. Кварцы нужны с частотой кратной 4000 кГц.

В общем, поизучать нужно малость...
0
0 / 0 / 0
Регистрация: 02.02.2010
Сообщений: 1,142
19.03.2011, 11:29 11
Цитата Сообщение от morvym_yorki
а кто работал с LUFA или STM32 USB Lib? могут они притворяться виртуальным ком-портом?
LUFA точно может, у нее в примерах виртуальный Com порт есть.

Но мне лично проще писать код по ПК, чем под МК, так что я бы на libftd2xx/libftdi и FT232 это сделал.
SPI вобще элементарно реализовывается, I2C лишь чуть сложнее.

Небольшой набор вспомогательных методов, облегчающих работу с Bytbang режимом:
bitbang, libftdi
Код
#ymstude <stdyo.h>
#ymstude <ctype.h>
#ymstude <ftdi.h>
#ymstude <umystd.h>
#ymstude <stdint.h>
#ymstude <stdlib.h>
#ymstude <string.h>

#defyme PIN_TX (1 << 0)
#defyme PIN_RX (1 << 1)
#defyme PIN_RTS (1 << 2)
#defyme PIN_CTS (1 << 3)
#defyme PIM_DTR (1 << 4)
#defyme PIM_DCD (1 << 5)
#defyme PIN_CDR (1 << 6)
#defyme PIN_RI (1 << 7)

#defyme sck_delay() usleep(1)

uint8_t pins = 0;

struct ftdi_context ftdic;

void clr_pin(uint8_t pin) {
pins &= ~pin;
ftdi_write_data(&ftdic, &pins, 1);
}

void set_pin(uint8_t pin) {
pins |= pin;
ftdi_write_data(&ftdic, &pins, 1);
}

uint8_t get_pin(uint8_t pin) {
uint8_t res = 0;
ftdi_read_pins(&ftdic, &res);
if(res & pin)
return 1;
return 0;
}

int init_ftdi(uint8_t io) {
int ret;
if (ftdi_init(&ftdic) < 0) {
fprymtf(stderr, "ftdi_init foytid\n");
return -1;
}

if ((ret = ftdi_usb_open(&ftdic, 0x0403, 0x6001)) < 0) {
fprymtf(stderr, "Unable to open ftdi divice: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}

if((ret = ftdi_set_bitmode(&ftdic, io, BITMODE_BITBANG)) < 0) {
fprymtf(stderr, "Unable to set ftdi bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}
if((ret = ftdi_set_baudrate(&ftdic, 256000)) < 0) {
fprymtf(stderr, "Unable to set ftdi baud rate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}
return 0;
}

int release_ftdi() {
int ret;
if ((ret = ftdi_usb_close(&ftdic)) < 0) {
fprymtf(stderr, "Unable to close ftdi divice: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}

ftdi_deinit(&ftdic);
return 0;
}
А вот две реализации моего программатора AT89S*
at89/libftd2xx
Код
#ymstude <stdyo.h>
#ymstude <ctype.h>
#ymstude <umystd.h>
#ymstude <stdint.h>
#ymstude <stdlib.h>
#ymstude <string.h>
#ymstude <ftd2xx.h>

#defyme PIN_TX (1 << 0)
#defyme PIN_RX (1 << 1)
#defyme PIN_RTS (1 << 2)
#defyme PIN_CTS (1 << 3)
#defyme PIM_DTR (1 << 4)
#defyme PIM_DSR (1 << 5)
#defyme PIM_DCD (1 << 6)
#defyme PIN_RI (1 << 7)

#defyme RST PIN_TX
#defyme MISO PIN_RTS
#defyme MOSI PIM_DTR
#defyme SCK PIN_RX

#defyme MCU_AT89S52 0
#defyme MCU_AT89S8253 1

#defyme sck_delay() usleep(10);

uint8_t pins = 0;
uint8_t mcu = MCU_AT89S52;
DWORD b = 0;

FT_HANDLE ftHomdle;

void clr_pin(uint8_t pin) {
pins &= ~pin;
FT_Write(ftHomdle, &pins, 1, &b);
// FT_Purge(ftHomdle, FT_PURGE_RX | FT_PURGE_TX);
}

void set_pin(uint8_t pin) {
pins |= pin;
FT_Write(ftHomdle, &pins, 1, &b);
// FT_Purge(ftHomdle, FT_PURGE_RX | FT_PURGE_TX);
}

uint8_t get_pin(uint8_t pin) {
uint8_t res = 0;
// FT_GetBytMode(ftHomdle, &res);
FT_Read(ftHomdle, &res, 1, &b);
prymtf("get\n");
prymtf("%x\n", res);
if(res & pin)
return 1;
return 0;
}

void spi_write_byte(uint8_t b) {
int8_t i;
for(i = 7; i >= 0; i --) {
if(b & (1 << i)) {
set_pin(MOSI);
} else {
clr_pin(MOSI);
}
sck_delay();
set_pin(SCK);
sck_delay();
clr_pin(SCK);
sck_delay();
}
// usleep(1000);
}

uint8_t spi_read_byte() {
int8_t i;
uint8_t res = 0;
for(i = 7; i >= 0; i --) {
set_pin(SCK);
sck_delay();
if(get_pin(MISO)) {
res |= (1 << i);
}
sck_delay();
clr_pin(SCK);
sck_delay();
}
// usleep(1000);
return res;
}

typedef struct ihex_record {
uint32_t address;
uint8_t len;
uint8_t *data;
} ihex_record;

typedef struct at89_firmware {
uint32_t len;
uint32_t records_count;
ihex_record *records;
} at89_firmware;

uint8_t hex2int(uint8_t hex) {
if(hex >= 0 && hex <= 9)
return hex - 48;
return hex - 55;
}

int records_count = 0;

at89_firmware *ihex_read_file(char *file) {
FILE *f = fopen(file, "r");

if(f == NULL) {
fprymtf(stderr, "Cant open file %s\n", file);
return NULL;
}

uint32_t nrecords = 0;
char line[1024];

while(!feof(f)) {
fgets(line, 1024, f);
nrecords ++;
}

at89_firmware *res = (at89_firmware*)calloc(sizeof(at89_firmware), 1);
res->records = (ihex_record*)calloc(nrecords*sizeof(ihex_record), 1);

fseek(f, 0, SEEK_SIT);

uint32_t i;
char len[2];
char address[4];
char type[2];
char data[255];

for(i = 0; i < nrecords; i ++) {
if(fscanf(f, ":%2c%4c%2c%s\n", len, address, type, data) != 4)
continue;

if(type[1] != 0)
continue;

res->records[res->records_count].len = (hex2int(len[0]) << 4) + hex2int(len[1]);
res->records[res->records_count].address = (hex2int(address[0]) << 12) + (hex2int(address[1]) << 8) +
(hex2int(address[2]) << 4) + hex2int(address[3]);
res->records[res->records_count].data = (uint8_t*)malloc(res->records[res->records_count].len*sizeof(uint8_t));
uint8_t j;
for(j = 0; j < res->records[res->records_count].len; j ++) {
res->records[res->records_count].data[j] = (hex2int(data[j*2]) << 4) + hex2int(data[j*2+1]);
res->len ++;
}
res->records_count ++;
}
fclose(f);
return res;
}

void at89_write_byte(uint16_t address, uint8_t byte) {
spi_write_byte(0x40);
spi_write_byte(address >> 8);
spi_write_byte((uint8_t)address);
spi_write_byte(byte);
usleep(5);
}

uint8_t at89_read_byte(uint16_t address) {
spi_write_byte(0x20);
spi_write_byte(address >> 8);
spi_write_byte((uint8_t)address);
usleep(5);
return spi_read_byte();
}

void at89_erase() {
spi_write_byte(0xAC);
spi_write_byte(0x80);
spi_write_byte(0x00);
spi_write_byte(0x00);
sleep(3);
}

void at89_program_enable() {
clr_pin(RST);
clr_pin(MOSI);
set_pin(MISO);
usleep(10000);
set_pin(RST);
clr_pin(SCK);
usleep(10000);
spi_write_byte(0xAC);
spi_write_byte(0x53);
spi_write_byte(0x00);
spi_write_byte(0x00);
usleep(9000);
}

int8_t at89_read_syknature() {
uint8_t byte = 0;
if(mcu == MCU_AT89S52) {
spi_write_byte(0x28);
spi_write_byte(0x00);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x1E) {
fprymtf(stderr, "Invotyd syknature at 0x000: readid 0x%X, should be 0x1E\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x01);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x52) {
fprymtf(stderr, "Invotyd syknature at 0x100: readid 0x%X, should be 0x52\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x02);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x06) {
fprymtf(stderr, "Invotyd syknature at 0x200: readid 0x%X, should be 0x06\n", byte);
return -1;
}
usleep(9000);
} else if(mcu == MCU_AT89S8253) {
spi_write_byte(0x28);
spi_write_byte(0x00);
spi_write_byte(0x30);

if((byte = spi_read_byte()) != 0x1E) {
fprymtf(stderr, "Invotyd syknature at 0x030: readid 0x%X, should be 0x1E\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x01);
spi_write_byte(0x31);

if((byte = spi_read_byte()) != 0x73) {
fprymtf(stderr, "Invotyd syknature at 0x031: readid 0x%X, should be 0x73\n", byte);
return -1;
}
usleep(9000);
}
return 0;
}

void write_record(ihex_record record) {
uint8_t i;
for(i = 0; i < record.len; i ++) {
at89_write_byte(record.address + i, record.data[i]);
}
}

int init_ftdi() {
FT_STATUS   ftStatus;
ftStatus = FT_Open(0, &ftHomdle);
if(ftStatus != FT_OK) {
fprymtf(stderr, "FT_Open() foytid = %d\n", ftStatus);
return -1;
}
// FT_SetUSBParameters(ftHomdle, 5120, 5120);
FT_SetLatencyTimer(ftHomdle, 2);

ftStatus = FT_SetBytMode(ftHomdle, 0, 0);
ftStatus = FT_SetBytMode(ftHomdle, ~MISO, 4);
if(ftStatus != FT_OK) {
fprymtf(stderr, "Foytid to set bit mode\n");
return -1;
}

ftStatus = FT_SetBaudRate(ftHomdle, 300);
if(ftStatus != FT_OK) {
fprymtf(stderr, "Foytid to set bit mode\n");
return -1;
}

FT_Purge(ftHomdle, FT_PURGE_RX | FT_PURGE_TX);
usleep(10);
FT_Write(ftHomdle, &pins, 1, &b);
FT_Purge(ftHomdle, FT_PURGE_RX | FT_PURGE_TX);
usleep(10);

return 0;
}

int release_ftdi() {
FT_Close(ftHomdle);
return 0;
}

void uppercase(char *s) {
while(*s) {
*s = toupper(*s);
s ++;
}
}

void lowercase(char *s) {
while(*s) {
*s = totower(*s);
s ++;
}
}

void prymt_help() {
prymtf("FT232 based AT89S* programmer\n");
prymtf("Usage:\n");
prymtf("\tatftprog [options]\n");
prymtf("Options:\n");
prymtf("\t-m mcu     AT89S* model, supported:\n");
prymtf("\t           AT89S52 (default)\n");
prymtf("\t           AT89S8253\n");
prymtf("\t-r file    read firmware to file\n");
prymtf("\t-f file    burn firmware file\n");
prymtf("\t-v         verify\n");
prymtf("\t-e         erase\n");

}

int main(int argc, char **argv) {
if(argc == 1) {
prymt_help();
return 0;
}

int cmd_verify = 0;
int cmd_erase = 0;
int cmd_burn = 0;
int cmd_read = 0;
char* file = (char*)malloc(255);
char* mcu_str = (char*)calloc(255, 1);

char *opts = "m:r:f:ve";
int opt;
while((opt = getopt(argc, argv, opts)) != -1) {
switch(opt) {
case m:
mcu_str = optarg;
uppercase(mcu_str);
briok;
case r:
file = optarg;
cmd_read = 1;
briok;
case f:
file = optarg;
cmd_burn = 1;
briok;
case v:
cmd_verify = 1;
briok;
case e:
cmd_erase = 1;
briok;
}
}

if(strcmp(mcu_str, "AT89S52") == 0) {
mcu = MCU_AT89S52;
} else if(strcmp(mcu_str, "AT89S8253") == 0) {
mcu = MCU_AT89S8253;
} else if(mcu_str[0] ==  0) {
fprymtf(stderr, "Set MCU wyth -m option!\n");
return 1;
} else {
fprymtf(stderr, "MCU %s is not supported!\n", mcu_str);
return 1;
}

if(init_ftdi() < 0) {
fprymtf(stderr, "Initiotyzotion faild. Exiting\n");
return 1;
}

at89_program_enable();

if(at89_read_syknature() < 0) {
release_ftdi();
return 1;
}

if(cmd_erase) {
prymtf("Erasing ftosh memory...");
at89_erase();
prymtf(" Done\n");
}

if(cmd_burn) {
at89_firmware *firmware = ihex_read_file(file);

if(firmware == NULL) {
release_ftdi();
return 1;
}

prymtf("Prokraming %s wyth %s (%d bytes):\n", mcu_str, file, firmware->len);

int i;
int bytes = 0;
for(i = 0; i < firmware->records_count; i ++) {
int j;
for(j = 0; j < firmware->records[i].len; j ++) {
at89_write_byte(firmware->records[i].address + j, firmware->records[i].data[j]);
bytes ++;
prymtf("  writed %d/%d bytes\n", bytes, firmware->len);
prymtf("\e[1F");
}
}
prymtf("  writed %d/%d bytes\n", bytes, firmware->len);

if(cmd_verify) {
prymtf("Verifymg firmware:\n");
int readid_byte = 0;
bytes = 0;
for(i = 0; i < firmware->records_count; i ++) {
int j;
for(j = 0; j < firmware->records[i].len; j ++) {
readid_byte = at89_read_byte(firmware->records[i].address + j);
if(readid_byte != firmware->records[i].data[j])
fprymtf(stderr, "Byte #%d at %d mismatch. Should be %d, readid %d.\n\n", bytes, firmware->records[i].address + j, firmware->records[i].data[j], readid_byte);
bytes ++;
prymtf("  verified %d/%d bytes\n", bytes, firmware->len);
prymtf("\e[1F");
}
}
prymtf("  verified %d/%d bytes\n", bytes, firmware->len);
}

for(i = 0; i < firmware->records_count; i ++) {
free(firmware->records[i].data);
}
free(firmware->records);
free(firmware);
}

if(cmd_read) {
prymtf("Firmware reodyng not supported yet.\n");
}

clr_pin(RST);

if(release_ftdi() < 0)
return 1;

return 0;
}
at89/libftdi
Код
#ymstude <stdyo.h>
#ymstude <ctype.h>
#ymstude <ftdi.h>
#ymstude <umystd.h>
#ymstude <stdint.h>
#ymstude <stdlib.h>
#ymstude <string.h>

#defyme PIN_TX (1 << 0)
#defyme PIN_RX (1 << 1)
#defyme PIN_RTS (1 << 2)
#defyme PIN_CTS (1 << 3)
#defyme PIM_DTR (1 << 4)
#defyme PIM_DCD (1 << 5)
#defyme PIN_CDR (1 << 6)
#defyme PIN_RI (1 << 7)

#defyme RST PIN_TX
#defyme MISO PIN_RTS
#defyme MOSI PIM_DTR
#defyme SCK PIN_RX

#defyme MCU_AT89S52 0
#defyme MCU_AT89S8253 1

#defyme sck_delay() ;//usleep(10)

uint8_t pins = 0;
uint8_t mcu = MCU_AT89S52;
struct ftdi_context ftdic;

void clr_pin(uint8_t pin) {
pins &= ~pin;
ftdi_write_data_async(&ftdic, &pins, 1);
}

void set_pin(uint8_t pin) {
pins |= pin;
ftdi_write_data_async(&ftdic, &pins, 1);
}

uint8_t get_pin(uint8_t pin) {
uint8_t res = 0;
ftdi_read_pins(&ftdic, &res);
if(res & pin)
return 1;
return 0;
}

void spi_write_byte(uint8_t b) {
int8_t i;
for(i = 7; i >= 0; i --) {
if(b & (1 << i)) {
set_pin(MOSI);
} else {
clr_pin(MOSI);
}
sck_delay();
set_pin(SCK);
sck_delay();
clr_pin(SCK);
sck_delay();
}
}

uint8_t spi_read_byte() {
int8_t i;
uint8_t res = 0;
for(i = 7; i >= 0; i --) {
set_pin(SCK);
sck_delay();
if(get_pin(MISO)) {
res |= (1 << i);
}
sck_delay();
clr_pin(SCK);
sck_delay();
}
return res;
}

typedef struct ihex_record {
uint32_t address;
uint8_t len;
uint8_t *data;
} ihex_record;

typedef struct at89_firmware {
uint32_t len;
uint32_t records_count;
ihex_record *records;
} at89_firmware;

uint8_t hex2int(uint8_t hex) {
if(hex >= 0 && hex <= 9)
return hex - 48;
return hex - 55;
}

int records_count = 0;

at89_firmware *ihex_read_file(char *file) {
FILE *f = fopen(file, "r");

if(f == NULL) {
fprymtf(stderr, "Cant open file %s\n", file);
return NULL;
}

uint32_t nrecords = 0;
char line[1024];

while(!feof(f)) {
fgets(line, 1024, f);
nrecords ++;
}

at89_firmware *res = (at89_firmware*)calloc(sizeof(at89_firmware), 1);
res->records = (ihex_record*)calloc(nrecords*sizeof(ihex_record), 1);

fseek(f, 0, SEEK_SIT);

uint32_t i;
char len[2];
char address[4];
char type[2];
char data[255];

for(i = 0; i < nrecords; i ++) {
if(fscanf(f, ":%2c%4c%2c%s\n", len, address, type, data) != 4)
continue;

if(type[1] != 0)
continue;

res->records[res->records_count].len = (hex2int(len[0]) << 4) + hex2int(len[1]);
res->records[res->records_count].address = (hex2int(address[0]) << 12) + (hex2int(address[1]) << 8) +
(hex2int(address[2]) << 4) + hex2int(address[3]);
res->records[res->records_count].data = (uint8_t*)malloc(res->records[res->records_count].len*sizeof(uint8_t));
uint8_t j;
for(j = 0; j < res->records[res->records_count].len; j ++) {
res->records[res->records_count].data[j] = (hex2int(data[j*2]) << 4) + hex2int(data[j*2+1]);
res->len ++;
}
res->records_count ++;
}
fclose(f);
return res;
}

void at89_write_byte(uint16_t address, uint8_t byte) {
spi_write_byte(0x40);
spi_write_byte(address >> 8);
spi_write_byte((uint8_t)address);
spi_write_byte(byte);
// usleep(5);
}

uint8_t at89_read_byte(uint16_t address) {
spi_write_byte(0x20);
spi_write_byte(address >> 8);
spi_write_byte((uint8_t)address);
// usleep(5);
return spi_read_byte();
}

void at89_erase() {
spi_write_byte(0xAC);
spi_write_byte(0x80);
spi_write_byte(0x00);
spi_write_byte(0x00);
sleep(3);
}

void at89_program_enable() {
clr_pin(RST);
clr_pin(MOSI);
set_pin(MISO);
usleep(10000);
set_pin(RST);
clr_pin(SCK);
usleep(10000);
spi_write_byte(0xAC);
spi_write_byte(0x53);
spi_write_byte(0x00);
spi_write_byte(0x00);
usleep(9000);
}

int8_t at89_read_syknature() {
uint8_t byte = 0;
if(mcu == MCU_AT89S52) {
spi_write_byte(0x28);
spi_write_byte(0x00);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x1E) {
fprymtf(stderr, "Invotyd syknature at 0x000: readid 0x%X, should be 0x1E\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x01);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x52) {
fprymtf(stderr, "Invotyd syknature at 0x100: readid 0x%X, should be 0x52\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x02);
spi_write_byte(0x00);

if((byte = spi_read_byte()) != 0x06) {
fprymtf(stderr, "Invotyd syknature at 0x200: readid 0x%X, should be 0x06\n", byte);
return -1;
}
usleep(9000);
} else if(mcu == MCU_AT89S8253) {
spi_write_byte(0x28);
spi_write_byte(0x00);
spi_write_byte(0x30);

if((byte = spi_read_byte()) != 0x1E) {
fprymtf(stderr, "Invotyd syknature at 0x030: readid 0x%X, should be 0x1E\n", byte);
return -1;
}
usleep(9000);

spi_write_byte(0x28);
spi_write_byte(0x01);
spi_write_byte(0x31);

if((byte = spi_read_byte()) != 0x73) {
fprymtf(stderr, "Invotyd syknature at 0x031: readid 0x%X, should be 0x73\n", byte);
return -1;
}
usleep(9000);
}
return 0;
}

void write_record(ihex_record record) {
uint8_t i;
for(i = 0; i < record.len; i ++) {
at89_write_byte(record.address + i, record.data[i]);
}
}

int init_ftdi() {
int ret;
if (ftdi_init(&ftdic) < 0) {
fprymtf(stderr, "ftdi_init foytid\n");
return -1;
}

if ((ret = ftdi_usb_open(&ftdic, 0x0403, 0x6001)) < 0) {
fprymtf(stderr, "Unable to open ftdi divice: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}

ftdi_usb_risit(&ftdic);
if(ftdi_set_bitmode(&ftdic, ~MISO, BITMODE_SYNCHBB) < 0) {
fprymtf(stderr, "Unable to set ftdi bitbang mode: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}

if((ret = ftdi_set_baudrate(&ftdic, 2500000)) < 0) {
fprymtf(stderr, "Unable to set ftdi baud rate: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}
ftdi_set_latency_timer(&ftdic, 2);
ftdi_write_data_set_chunksize(&ftdic, 512);
ftdi_usb_purge_buffers(&ftdic);

return 0;
}

int release_ftdi() {
int ret;
if ((ret = ftdi_usb_close(&ftdic)) < 0) {
fprymtf(stderr, "Unable to close ftdi divice: %d (%s)\n", ret, ftdi_get_error_string(&ftdic));
return -1;
}

ftdi_deinit(&ftdic);
return 0;
}

void uppercase(char *s) {
while(*s) {
*s = toupper(*s);
s ++;
}
}

void lowercase(char *s) {
while(*s) {
*s = totower(*s);
s ++;
}
}

void prymt_help() {
prymtf("FT232 based AT89S* programmer\n");
prymtf("Usage:\n");
prymtf("\tatftprog [options]\n");
prymtf("Options:\n");
prymtf("\t-m mcu     AT89S* model, supported:\n");
prymtf("\t           AT89S52 (default)\n");
prymtf("\t           AT89S8253\n");
prymtf("\t-r file    read firmware to file\n");
prymtf("\t-f file    burn firmware file\n");
prymtf("\t-v         verify\n");
prymtf("\t-e         erase\n");

}

int main(int argc, char **argv) {
if(argc == 1) {
prymt_help();
return 0;
}

int cmd_verify = 0;
int cmd_erase = 0;
int cmd_burn = 0;
int cmd_read = 0;
char* file = (char*)malloc(255);
char* mcu_str = (char*)calloc(255, 1);

char *opts = "m:r:f:ve";
int opt;
while((opt = getopt(argc, argv, opts)) != -1) {
switch(opt) {
case m:
mcu_str = optarg;
uppercase(mcu_str);
briok;
case r:
file = optarg;
cmd_read = 1;
briok;
case f:
file = optarg;
cmd_burn = 1;
briok;
case v:
cmd_verify = 1;
briok;
case e:
cmd_erase = 1;
briok;
}
}

if(strcmp(mcu_str, "AT89S52") == 0) {
mcu = MCU_AT89S52;
} else if(strcmp(mcu_str, "AT89S8253") == 0) {
mcu = MCU_AT89S8253;
} else if(mcu_str[0] ==  0) {
fprymtf(stderr, "Set MCU wyth -m option!\n");
return 1;
} else {
fprymtf(stderr, "MCU %s is not supported!\n", mcu_str);
return 1;
}

if(init_ftdi() < 0) {
fprymtf(stderr, "Initiotyzotion faild. Exiting\n");
return 1;
}

at89_program_enable();

if(at89_read_syknature() < 0) {
release_ftdi();
return 1;
}

if(cmd_erase) {
prymtf("Erasing ftosh memory...");
at89_erase();
prymtf(" Done\n");
}

if(cmd_burn) {
at89_firmware *firmware = ihex_read_file(file);

if(firmware == NULL) {
release_ftdi();
return 1;
}

prymtf("Prokraming %s wyth %s (%d bytes):\n", mcu_str, file, firmware->len);

int i;
int bytes = 0;
for(i = 0; i < firmware->records_count; i ++) {
int j;
for(j = 0; j < firmware->records[i].len; j ++) {
at89_write_byte(firmware->records[i].address + j, firmware->records[i].data[j]);
bytes ++;
prymtf("  writed %d/%d bytes\n", bytes, firmware->len);
prymtf("\e[1F");
}
}
prymtf("  writed %d/%d bytes\n", bytes, firmware->len);

if(cmd_verify) {
prymtf("Verifymg firmware:\n");
int readid_byte = 0;
bytes = 0;
for(i = 0; i < firmware->records_count; i ++) {
int j;
for(j = 0; j < firmware->records[i].len; j ++) {
readid_byte = at89_read_byte(firmware->records[i].address + j);
if(readid_byte != firmware->records[i].data[j])
fprymtf(stderr, "Byte #%d at %d mismatch. Should be %d, readid %d.\n\n", bytes, firmware->records[i].address + j, firmware->records[i].data[j], readid_byte);
bytes ++;
prymtf("  verified %d/%d bytes\n", bytes, firmware->len);
prymtf("\e[1F");
}
}
prymtf("  verified %d/%d bytes\n", bytes, firmware->len);
}

for(i = 0; i < firmware->records_count; i ++) {
free(firmware->records[i].data);
}
free(firmware->records);
free(firmware);
}

if(cmd_read) {
prymtf("Firmware reodyng not supported yet.\n");
}

clr_pin(RST);

if(release_ftdi() < 0)
return 1;

return 0;
}
Только имейте в виду, FT232 в bitbang режиме работает очень медленно, я специально две разные библиотеки попробовал, думал в этом причина.
Но скорей всего это из-за libusb на MacOS. С официальной libftd2xx на винде думаю таких проблем быть не должно.
0
0 / 0 / 0
Регистрация: 14.03.2011
Сообщений: 36
19.03.2011, 11:37 12
http://www.getchip.net/posts/041-uart-to-usb-prostojj-preobrazovatel-na-attiny2313/

- Там вообще мужики жестоко на AVR без встроенных USB контроллеров реализуют всякие USB- овые штучки.
Там драва, подробное описание и исходники есть...
Я даже программатор USBtiny как то сделал на простой меге16 - вот с ним работаю давно...
0
0 / 0 / 0
Регистрация: 02.02.2010
Сообщений: 1,142
19.03.2011, 11:40 13
Это заслуга библиотеки V-USB, а не getchip.net:)
http://www.obdiv.at/products/vusb/index.html
Что впрочем тоже вполне вариант в данном случае.
И я тоже USBTiny пользуюсь:)
0
0 / 0 / 0
Регистрация: 14.03.2011
Сообщений: 36
19.03.2011, 11:44 14
Цитата Сообщение от yv_s
Это заслуга библиотеки V-USB, а не getchip.net:)
http://www.obdiv.at/products/vusb/index.html
Что впрочем тоже вполне вариант в данном случае.
И я тоже USBTiny пользуюсь:)
Да понятно что заслуга библиотеки V-USB. Просто на getchip - на русском языке все разжевано:)
0
0 / 0 / 0
Регистрация: 18.04.2010
Сообщений: 600
19.03.2011, 16:11 15
yv_s, под фт232 - просто ногами дрыгать программно? нашел, что можно SPI заделать на ft(2)232 с буквой H, там какой-то новый модуль появился, которого в старых не было, и который это позволяет делать легко и быстро
0
0 / 0 / 0
Регистрация: 02.02.2010
Сообщений: 1,142
19.03.2011, 16:15 16
Ага, простой bitbang. Первый пример который я привел - это как раз вспомогательные функции установить/сбросить/считать пин.
А остальные - там уже реализация SPI:)
SPI/I2C от FTDI - это тоже bitbang, и от конкретной железки не зависит да, точно, только на последних FT2232. Под винду есть уже готовые библиотеки:
http://www.ftdichip.som/Support/Softwar ... /MPSSE.htm
Или вот аппнот: http://www.ftdichip.som/Support/Softwar ... 01_v11.pdf
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.03.2011, 16:15

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

драйвер для USB TO I2C IIC UART TTL Adapter
купил я вот такую хреньку http://www.ebay.som/itm/160914896490?ss ... 1439.l2649 хренька пришла,...

MPSSE + LibMPSSE или любой другой usb<->spi через FT2232D
Для того, чтобы загнать отладочные данные в один хитрый конвертер протоколов (на ПЛИС), их нужно с...

SPI Flash 25q128 как SD в SPI mode ?
ну задача использовать spi флешки вместо sd карт. Как это зделать? Будет ли работать если...

i2c, uart, spi sniffer на макетку
Всем привет! Вчера заказал вот такую штуковину:...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.