ВНИМАНИЕ! На форуме начался конкурс - астрофотография месяца - ИЮЛЬ!
0 Пользователей и 2 Гостей просматривают эту тему.
Если фифо кипариса забито данными и он не может их отправить в хост из за занятости USB - он запрашивает от трансмиттера->секвенсора приостановку потока. Учтен ли этот момент, и если да, то каким образом? Не получается ли так, что у кипариса случился запор, а трансмиттер продолжает пихать данные.
FTF5066C_1 timegen ( // тактирование матрицы на частоте 1 МГц dalsa1.xsvf//FTF5066C_2 timegen ( // тактирование матрицы на частоте 2 МГц dalsa2.xsvf//FTF5066C_4 timegen ( // тактирование матрицы на частоте 4 МГц dalsa4.xsvf//FTF5066C_8 timegen ( // тактирование матрицы на частоте 8 МГц dalsa8.xsvf.clock(c48), //Clock 48 MHz .data_gain(reg8), //<===== усиление АЦП задаётся в хосте .data_offset(reg9), //<===== смещение данных АЦП задаётся в хосте .data_msb(out_byte_DS18B20[7:0]),//<===== значение тока Пельтье .data_lsb(data_lsb), //<===== значение тока Пельтье .CR_IN(reg1[0]),//перед открытием затвора и началом накопления заряда очищаем матрицу импульсом CR .power_MAX618(reg1[1]), //<== подача питания на MAX618 00000010 .integration(reg1[2]), //<== накопление пикселей 00000100 .transport(reg1[3]), //<== перенос заряда в хост 00001000
//команда сброса и активации пересылки значения термосенсора 10 20 40 byte = 0x70; status = flWriteChannel(handle, 1000, 0x01, 1 , &byte, &error); byte = 0x00; status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); //flSleep(100);//==== перед открытием затвора и началом накопления заряда разряжаем матрицу импульсом CR ===== byte = 0x01;//00000001 status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); flSleep(500);//========= ПОДАЧА ПИТАНИЯ НА MAX618 ===============================================byte = 0x02;//00000010 status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); flSleep(100);//========= УСТАНОВКА 8 ВОЛЬТ, РЕЖИМ НАКОПЛЕНИЯ ЗАРЯДОВ =======================================byte = 0x06;//00000110 0x04 & 0x02 status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); //======================= УПРАВЛЯЕМ ЗАТВОРОМ =======================================byte = 0x86;//10000110 0x80 & 0x04 & 0x02 // затвор открыть status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); flSleep(100); flSleep(exposition_time); // задаём время экспозиции next_time = 0; //========= ЗАТВОР ЗАКРЫТ,ПЕРЕКЛЮЧЕНИЕ НА 11 ВОЛЬТ И СЧИТЫВАНИЕ ДАННЫХ =====================================byte=0x0A;//00001010 0x08 & 0x02 status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error);////========= ЗАПИСЬ В БУФЕР НЕПРЕРЫВНЫМ ПОТОКОМ ===================================== // if(flReadChannel(handle, 1000, 0x00, ccd, ccd_buf, &error)!=0)//проверка flReadChannel(handle, 1000, 0x00, ccd, ccd_buf, &error);//без проверки // запись циклом, но выглядит хуже, какая-то рванина//for(p = 0; p <= image_lines; p++) flReadChannel(handle, 1000, 0x00, image_pixs*2, &ccd_buf[p*image_pixs*2], &error);//без проверки//========= СТОП ПОСЫЛКА НА СЧИТЫВАНИЕ ДАННЫХ ======================================byte=0x00; //00000000 отключается всё status = flWriteChannel(handle, 1000, 0x01, 1, &byte, &error); anf_kadr = pixel * Size_Wert_Line ; //удвоенное кол-во пикселей одной строки х номер строки (0 - 2600)//=============== обрезка верхнего края кадра ======================================for(p = 0; p <= anf_kadr; p++) { if(ccd_buf[p] == 0x01) { if(ccd_buf[p+1] == 0x02) { if(ccd_buf[p+2] == 0x00) { if(ccd_buf[p+3] == 0x01) { line=0; break;} } } } }//=================================================================================== line = 0; //============== переписывание буфера ===============================================for(p = anf_kadr; p <= ccd; p++) { if(ccd_buf[p] == 0x01) { if(ccd_buf[p+1] == 0x02) { if(ccd_buf[(p+9)] != 0x00) { if(ccd_buf[(p+10)] != 0x00) { ccd += pixel; line-=1;// } } else memmove(&buf_out[pixel * line++], &ccd_buf[p + offset_raw], pixel);// } } }//========================================================================================================================== fwrite(buf_out, sizeof(unsigned char), write_raw, fp); //записываем данные в файл. последовательная запись flSleep(pause_time); //задаём время паузы между экспозициями fclose(fp); //закрываем созданный файл next_file=1; //разрешаем преобразование raw2tiff.exe//========================================================================================================================== Temp_Ist = peltier_current_temp(Current_Peltier); //возвращает истинное значение Тemp.Пельтье//==========================================================================================================================}while (--number_of_file != 0);//считаем , пока не кончатся
Опишите мне понятным мне языком, какие сигналы связывают ПЛИС и кипарис между собой - аппаратно(!) и как они описаны в декларации(?) сигналов трансмиттера в проекте ПЛИС. Мне припоминается что у кипариса вроде как есть какие-то разрешающие/запрещающие сигналы для источника данных.Т.е. если у кипариса запор, он выставляет трансмиттеру сигнал запрета передачи данных, пока фифо не освободится в хост. Этот сигнал должен безусловно и немедленно останавливать секвенсор, в какой бы стадии тот не был.
input wire fx2GotRoom_in, // asserted (active-high) when FX2 has room for more data from usЕсли я правильно понял - это оно. Высокий уровень, пока в фифо FX2го есть место для новых данных. Низкий - когда фифо переполнен и не может принимать новые данные.Вам надо сделать так, чтобы низкий уровень этого сигнала немедленно приостанавливал работу секвенсора.
я понял, щас помолюсь, принесу кота в жертву и попытаюсь сделать это самостоятельно. но это будет долго......
ну тут понадобится хороший пахарь. возможно когда-нибудь он обязательно отыщется, я даже думаю, что обязательно отыщется. а какие преимущества это собственно нам даст?
Сигнал Room можно пока отложить в сторону, но не исключено, что он еще может понадобиться, когда придет время отлаживать устройство на загруженной USB шине.Нельзя-ли посмотреть прогон в симуляторе сигналов ADCCLK и вот этого:output wire fx2Write_outЕсли этот сигнал в эмуляторе статичен, то тогда нужно его смотреть осциллографом на камере в момент считывания.
Нельзя-ли посмотреть прогон в симуляторе сигналов ADCCLK и вот этого:output wire fx2Write_outЕсли этот сигнал в эмуляторе статичен, то тогда нужно его смотреть осциллографом на камере в момент считывания.
Цифровой ДКВ вместо аналогового:1. Перевести АЦП в режим SHA, когда он измеряет сигнал отн. offsеt'a.2. Вывод OFFSET закоротить на землю, установив верхом на керамический кондер резистор нулевик. Возможно, стОит поставить вместо нуля резистор с подобранным сопротивлением, чтобы шунтируя внутреннюю цепочку формирования offset'а добиться такой величины смещения, чтобы оно было несколько ниже уровня насыщения ПЗС.3. Перепахать секвенсор:Сигнал CDSCLK1 убрать.Секвенсор прокручивает циклограмму, пока на выходе ПЗС не появляется опорный уровень черного. Далее секвенсор останавливает циклограмму ПЗС, и тактирует АЦП согласно Fig6 даташита, но только аналоговый сигнал на входе в этот момент не меняется - т.е. АЦП проводит многоточечный замер уровня черного для данного пикселя. Думаю, 2-4 замера вполне достаточно, ибо скорость АЦП ограничена. В трансмиттере полученные с АЦП данные суммируются в достаточно просторном регистре, чтобы не произошло переполнение.Далее, результат суммирования делится на количество замеров, а если замеров 2 или 4 - то тупо отбрасывается один или два младших разряда.Далее, секвенсор проворачивается, пока на выходе ПЗС появляется уровень полезного.Далее секвенсор опять тактирует АЦП, для многоточечного замера уровня полезного. В трансмиттере так-же результаты замеров суммируются и делятся.Далее, трансмиттер из усредненного уровня черного вычитает усредненный уровень белого, и выдает разность в качестве результата оцифровки пикселя, а секвенсор крутит шарманку до следующего раза.Наилучший вариант - если настройками GAIN/OFFSET АЦП получится захватить уровень черного/полезного (в режиме SHA!) не потеряв участка шкалы, и не переделывая цепь смещения АЦП - тогда переход между цифровым и аналоговым ДКВ можно будет осуществлять чисто программно, например реализовать в качестве опции "сверхмедленного прецизионного чтения".
ЦитатаНельзя-ли посмотреть прогон в симуляторе сигналов ADCCLK и вот этого:output wire fx2Write_outтам на нём узкие отриц. импульсы с частотой 1 МГц. Этот сигнал спартан гонит в кипресс .другими словами , там тот же ADCCLK ,только инвертированный
Нельзя-ли посмотреть прогон в симуляторе сигналов ADCCLK и вот этого:output wire fx2Write_out
Я так понимаю, что fx2Wo и ADCCLK формируются внутри ПЛИС, из глобального клока...Выложите пожалуйста кусок кода, где _оба этих сигнала формируются.
- Путь ADCH/L от пинов АЦП до пинов кипариса.
- Разрядность шины данных между кипарисом и ПЛИС.
- Ссылка на учебник "VHDL для чайников за 1 день", желательно чтобы побольше картинок и поменьше текста.
Цитатаoutput wire fx2Write_outтам на нём узкие отриц. импульсы с частотой 1 МГц. Этот сигнал спартан гонит в кипресс .другими словами , там тот же ADCCLK ,только инвертированный
output wire fx2Write_out
Ссылку на проект связи спартана с фх2 не дадите? Чтение авторского описания проекта может помочь.
Судя по "тот же ADCCLK", этот сигнал является стробом записи данных в EР FIFO FX2го. Но тогда не понятно, почему он "тот-же", когда по идее должен быть с частотой, в два раза выше чем ADCCLK? Обычно стробы записи управляют фифо таким образом, чтобы данные с шины, защелкивались в фифо по переднему или заднему фронту строба. Если только не применяется DDR, где данные защелкиваются по обеим фронтам строба. Вы не упустили из виду момент, что АЦП по факту DDR, а кипарис (если я не путаю) - не DDR?
fx2Write_out должен быть с частотой, в два раза выше чем ADCCLK