Hello, Alexander! You wrote to All on Wed, 5 Aug 2009 17:38:21 +0000 (UTC):
AT> Просьба откликнуться тем, кто работал с этой заразой через FIFO.
AT> Именно FIFO а не RS232 или SPI !!!!
В первых ревизиях фирмваре оно вообще не работало.
AT> проскальзывает, что он все время стоит в "0", пере записю пдывается в AT> "1", потом опускается снова в "0" (это момент стрбирования) и в нем и AT> остается. Т.е. пр чтении, получется оба сигнала "0", что для всех AT> нормальных шин всегда было запрещенным состоянием, но FDTI повидимому AT> стандарты - не указ.
Hикто не обещал стандартную шину.
AT> Посему вопрос - а как же все-таки надо?
В пассивном состоянии RD# = 1, WR = 0.
AT> Дело в том.что работает и так и так, но поскольку я наьблюдают всякие AT> разные глюки, то хотелось бы хоть тут быть в чем-то уверенным.
AT> 2) По поводу сигнала WR_EN# - написано только что писать можно если он AT> "0". Hо у меня получается, что когда пишу масив, он вдруг выскакивает в AT> "1" и там и остается. AT> Вроде победилось это принудительным вычитыванием их чипа в этот момент, AT> но иногда все же такие происходит, а почему- непонятно.
Бага знакомая, но как оно лечилось уже не помню. Либо подбором задержек (не допускать переполнения фифо) либо сменой фирмваре.
AT> 3) Hигде ничео не написано про временные задержки между командами AT> монитора, а все аппликухи - в основном расписывают как с ним общаться AT> из терминала по RS232, ручками набирая команды. Понятно. что в таком AT> режиме вопрос о времени между командами не стоит :) AT> Hо, мне пока приходится давать вот такие задержки (речь идет о записи AT> файла на USB-брелок):
AT> SendCmd(OpenFile, filename); AT> SendCmd(Write, lentgh); AT> Delay (200ms); AT> for (i=0;i<length;i++) SendByte(data); // data -пока просто константа AT> Delay(500ms); AT> SendCmd(CloseFile); AT> Delay(3sec);
Ответы читаешь? Что-то я не помню, чтобы я делал какие-то задержки в коде. Смотри в конце письма.
AT> Самое интересное, что если задержки уменьшить в 10 раз - то один раз AT> эта последовательност команд проходит, а иногда даже второй, а потом AT> зависает из-за WR_EN=1 и тут уже семь бед - один ресет :(
AT> С задержками - писал файлы от 5 байт до 50мб, пиковая скорость (с AT> учетом выполнения цикла на 8мгц msp430) - примерно 130-140 байт/сек, AT> (без учета цикла, т.е. если в нем писать несколько байт подряд - AT> скорость около 270 байт/сек), но периодически возникают задержки до AT> 10мс.
Таки оно работало существенно быстрее.
WBR, AVB
#define nRD LATEbits.LATE1 #define WR LATEbits.LATE0
#define vncReset TRISAbits.TRISA4
#define VNC_BUFFER_SIZE 32
static uint8_t vnc_buffer[VNC_BUFFER_SIZE]; static uint8_t vnc_state;
enum { // VNC_RESETCOMPLETE, VNC_NODISK, VNC_WAITPROMPT, VNC_IDLE };
uint8_t FlashReady(void) { return (vnc_state == (uint8_t)VNC_IDLE) ? 1 : 0; }
void vnc_ResetComplete(void) { vncReset = 1; // release reset vnc_state = VNC_RESETCOMPLETE; // change state }
void vnc_Reset(void) { vncReset = 0; // force reset to zero systimer_set(VNC_TIMER, 200, vnc_ResetComplete); // set timer to initiate reset sequence }
void vnc_Init(void) { TRISD = 0xFF; // all pins to input // nRD = 1; // RD# inactive WR = 0; // WR inactive // TRISEbits.TRISE0 = 0; // output TRISEbits.TRISE1 = 0; // output // TRISAbits.TRISA1 = 1; // input TRISAbits.TRISA2 = 1; // input TRISAbits.TRISA4 = 0; // output // vnc_Reset(); // reset the Vinculum }
void vnc_proc(void) { switch (vnc_state) { case VNC_RESETCOMPLETE: vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read empty string from VNC1L vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read version number of VNC1L firmware vnc_state = VNC_NODISK; break; // case VNC_NODISK: vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status message if (!_strcmp(vnc_buffer, "Device Detected P2\x0D")) // check disk presence { systimer_set(VNC_TIMER, sec(60UL), vnc_Reset); // set timeout for checking for updates vnc_state = VNC_WAITPROMPT; return; } break; // case VNC_WAITPROMPT: systimer_cancel(VNC_TIMER); vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status message if (!_strcmp(vnc_buffer, "No Disk\x0D")) // check disk presence { vnc_state = VNC_NODISK; return; } if (!_strcmp(vnc_buffer, "D:\\>\x0D")) // prompt available { vnc_state = VNC_IDLE; return; } systimer_set(VNC_TIMER, 100, vnc_Reset); // set timeout for next message break; // case VNC_IDLE: vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status message if (!_strcmp(vnc_buffer, "Device Removed P2\x0D") || !_strcmp(vnc_buffer, "No Disk\x0D")) // check disk presence { vnc_state = VNC_NODISK; return; } if (!_strcmp(vnc_buffer, "D:\\>\x0D")) // prompt available { vnc_state = VNC_IDLE; return; } // vnc_Reset(); // unexpected message received break; // default: // unknown state vnc_Reset(); } }
uint8_t vnc_gets(uint8_t *buffer, uint8_t buffer_size) { uint8_t data_size;
if (nRXF) return 0; // no data in FIFO // for (data_size = buffer_size - 1; data_size--; ) { while (nRXF); // wait for the RXF# // nRD = 0; // activate RD# *buffer = PORTD; // read PORTD nRD = 1; // deactivate RD# // if (*buffer++ == 0x0Du) break; } *buffer = 0; // append string with zero // return buffer_size - data_size - 1; // returns number of characters actualy read }
uint8_t vnc_fputs(const rom char *filename, uint8_t *str) { uint8_t *ptr;
if (vnc_state != (uint8_t)VNC_IDLE) return 0; // _strcpy_r(_strcpy_r(_strcpy_r(vnc_buffer, "OPW "), filename), "\x0D"); if (!vnc_puts(vnc_buffer)) { vnc_Reset(); return 0; } while (nRXF); // wait for replay vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status str if (_strcmp(vnc_buffer, "D:\\>\x0D")) // prompt available { vnc_Reset(); return 0; } // ptr = _strcpy_r(vnc_buffer, "WRF "); *ptr++ = 0; *ptr++ = 0; *ptr++ = 0; *ptr++ = (_strlen(str)); *ptr++ = '0x0D'; if (!vnc_puts(vnc_buffer)) { vnc_Reset(); return 0; } if (!vnc_write(str, _strlen(str))) { vnc_Reset(); return 0; } while (nRXF); // wait for replay vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status str if (_strcmp(vnc_buffer, "D:\\>\x0D")) // prompt available { vnc_Reset(); return 0; } // _strcpy_r(_strcpy_r(_strcpy_r(vnc_buffer, "CLF "), filename), "\x0D"); if (!vnc_puts(vnc_buffer)) { vnc_Reset(); return 0; } while (nRXF); // wait for replay vnc_gets(vnc_buffer, VNC_BUFFER_SIZE); // read status str if (_strcmp(vnc_buffer, "D:\\>\x0D")) // prompt available { vnc_Reset(); return 0; } }
uint8_t vnc_puts(uint8_t *buffer) { uint8_t data_size = 0;
if (nTXE) return 0; // FIFO not ready // do { LATD = *buffer++; while (nTXE); // wait for TXE# // WR = 1; TRISD = 0; // force all pins to output WR = 0; // deactivate WR TRISD = 0xFF; // force all pins to input data_size++; // } while (LATD != 0x0Du); // return data_size; // returns number of actually writen characters }
uint8_t vnc_write(uint8_t *buffer, uint8_t size) { if (nTXE) return 0; // FIFO not ready // do { LATD = *buffer++; while (nTXE); // wait for TXE# // WR = 1; TRISD = 0; // force all pins to output WR = 0; // deactivate WR TRISD = 0xFF; // force all pins to input // } while (--size); // return 1; }