Zigrund 0 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба Накатал кодик: __ramfunc unsigned int GetScanLineTest(BYTE *dest, unsigned long volatile *port) { unsigned int v; BYTE *d = dest; while(!((*port) & HSYNC_MASK)); //Ждем начала строки do { v = *port; if((v & PCLK_MASK)) { __no_operation(); //__no_operation(); while((v & HSYNC_MASK)) { *d++ = v; v = *port; /*__no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation();*/ __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); } } } while((v & HSYNC_MASK)); return d - dest; } Оцените, пожалуйста. 2,25MHz считал, но всё равно этот медот мне ужасно не нравится. Прям душа не лежит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба Оцените, пожалуйста. Ересь какая-то. У Вас чем камера тактируется? Процессором? Или совершенно отдельной частотой? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба Ересь какая-то. У Вас чем камера тактируется? Процессором? Или совершенно отдельной частотой? Отдельно. А что нельзя, в начале один раз затактировать, а дальше задержками считать всю строку? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба А что нельзя, в начале один раз затактировать, а дальше задержками считать всю строку? Нельзя, если генератор отдельный. Нужен ФАПЧ. Посмотрите внимательно на последний код, который я Вам написал - там это реализовано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба Нельзя, если генератор отдельный. Нужен ФАПЧ. Посмотрите внимательно на последний код, который я Вам написал - там это реализовано. Это должно быть так!? __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) { unsigned int v; unsigned char *d=dest; while(!((*port) & HSYNC_MASK)); do { v = *port; if (!(v & PCLK_MASK)) { __no_operation(); //пол периода __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); v = *port; } *d++ = v; __no_operation(); //период __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); } while((v & HSYNC_MASK)); return d - dest; } Я не знаком с I2S. Как он может мне помочь? Мне кто-то его уже советовал. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба Это должно быть так!? Уберите вот эти __no_operation, которые отмечены комментарием "пол периода". Там только это if (!(v & PCLK_MASK)) v = *port; должно остаться. Сей код будет занимать по времени или 1 или три такта, в зависимости от попадания на фронт сигнала. И будет держать фазу (и, как следствие, компенсировать разбег частот) в общем зачете. Как он может мне помочь? Это некое подобие SPI. Почитайте usermanual на процессор, там же все написано. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Уберите вот эти __no_operation, которые отмечены комментарием "пол периода". Там только это if (!(v & PCLK_MASK)) v = *port; должно остаться. Сей код будет занимать по времени или 1 или три такта, в зависимости от попадания на фронт сигнала. И будет держать фазу (и, как следствие, компенсировать разбег частот) в общем зачете. Это некое подобие SPI. Почитайте usermanual на процессор, там же все написано. Убрал всё лишнее, только почему-то колличество считанных пикселей всегда нестабильное. Оно вроде как кружиться у нужного числа, так сказть маткматического ожидания, с какой-то дисперсией. Что нет так? Я это понял, что подобие SPI. The I2S bus specification defines a 3-wire serial bus Тут вроде как написано, что это трёх проводная последовательная шмна. Как она должна мне помочь? Просветите пожалуйста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Что нет так? Ну надо точно засинхронизироваться с началом PCLK, видимо как-то так: while(!((*port) & HSYNC_MASK)); while (!((*port) & PCLK_MASK)); do { v = *port; ... Рекомендую вместо __no_operation() добавить дергание какой-либо ножкой порта и посмотреть, в какие моменты времени происходит считывание. Благо, сейчас там у Вас очень много nop'ов. Тут вроде как написано, что это трёх проводная последовательная шмна. Как она должна мне помочь? Просветите пожалуйста. Черт... Пардон... У Вас же шина параллельная. Да, конечно, не поможет, это я загнался :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Ну надо точно засинхронизироваться с началом PCLK, видимо как-то так: Рекомендую вместо __no_operation() добавить дергание какой-либо ножкой порта и посмотреть, в какие моменты времени происходит считывание. Благо, сейчас там у Вас очень много nop'ов. Черт... Пардон... У Вас же шина параллельная. Да, конечно, не поможет, это я загнался :( Вот результат моего творчества: __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) { unsigned int v; unsigned char *d = dest; while(!((*port) & HSYNC_MASK)); while(!((*port) & PCLK_MASK)); do { v = *port; *d++ = v; if (!(v & PCLK_MASK)) { v = *port; } FIO2SET |= 1 << 10; __no_operation(); __no_operation(); FIO2CLR |= 1 << 10; __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); __no_operation(); } while((v & HSYNC_MASK)); return d - dest; } 1,125 MHz Поднимает на ура и железно. Возникла другая проблема вот в этом месте: *d++ = v; Когда в функцию передаёшь указатель на внутреннею память, тоесть просто создаёшь BYTE buff[500]; Всё нормально, *d++ = v эта команда выполняется с постоянное число тактов. А когда передаёшь на внешнюю память, то вот это *d++ = v; каманда исполняется за разное число тактов. Проверил точно предложенным Вами способом. В чём проблема. Может как-то не так настроена внешняя память??? Из - за этого сбивается вся синхронизация и поэтому получается такой своего рода случайный процесс. ))) Помогите пожалуйста и как правильно объявлять массив во внешней памяти? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба 1,125 MHz Поднимает на ура и железно. Это еще не предел. В пределе - 6МГц (ибо 12 тактов минимум) Возникла другая проблема Немудрено. Внешняя память наверняка работает на более низкой частоте чем ядро и посему процессор должен ждать начала нового цикла внешней памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Это еще не предел. В пределе - 6МГц (ибо 12 тактов минимум) Немудрено. Внешняя память наверняка работает на более низкой частоте чем ядро и посему процессор должен ждать начала нового цикла внешней памяти. 6 всё равно маловато, надо 9 ) А что делать? Ведь одна строка занимает 400 байт, при этом их 150. Это самый худшиф вариант,а надо 3200 байт, на 1200 строк. Ну или ходя бы 1600 байт на 600 строк.Тоесть однозначно около 1 MB. Можно построчно запихивать, а потом капировать, но это как-то не выход. Что подскажите. может что понастраивать надо? Вот мой кусочек настройки внешней памяти: //#define USE_32_BIT_DATABUS #define SDRAM_BASE_ADDR 0xA0000000 void initEMC(void) { volatile unsigned int i, dummy = dummy; // SCS &= ~0x00000002; // SCS |= 0x00000002; EMCCONTROL = 0x00000001; PCONP |= 0x00000800; /* Turn on EMC PCLK */ FIO2DIR &= ~(1 << 12); /* make P2.12 pin as input */ FIO2MASK &= ~(1 << 12); PINSEL4 = 0x50000000; #ifdef USE_32_BIT_DATABUS PINSEL5 = 0x55010115; PINSEL7 = 0x55555555; #else // x PINSEL5 = 0x05000555; #endif PINSEL6 = 0x55555555; PINSEL8 = 0x55555555; PINSEL9 = 0x50555555; //all registers... #ifdef USE_32_BIT_DATABUS EMCDYNAMICRP = 1; EMCDYNAMICRAS = 3; EMCDYNAMICSREX = 5; EMCDYNAMICAPR = 1; EMCDYNAMICDAL = 5; EMCDYNAMICWR = 1; EMCDYNAMICRC = 5; EMCDYNAMICRFC = 5; EMCDYNAMICXSR = 5; EMCDYNAMICRRD = 1; EMCDYNAMICMRD = 1; EMCDINAMICRDCFG = 1; // EMCDYNAMICRASCAS0 = 0x00000202; // EMCDYNAMICCFG0 = 0x00005480; #else EMCDYNAMICRP = 2; EMCDYNAMICRAS = 3; EMCDYNAMICSREX = 7; EMCDYNAMICAPR = 2; EMCDYNAMICDAL = 5; EMCDYNAMICWR = 1; EMCDYNAMICRC = 5; EMCDYNAMICRFC = 5; EMCDYNAMICXSR = 7; EMCDYNAMICRRD = 1; EMCDYNAMICMRD = 2; EMCDINAMICRDCFG = 1; // EMCDYNAMICRASCAS0 = 0x00000303; // EMCDYNAMICCFG0 = 0x00000680; #endif //wait 100mS delay(100000); //Send command: NOP EMCDINAMICCTRL = 0x00000183; //wait 200mS delay(200000); //Send command: PRECHARGE-ALL, shortest possible refresh period EMCDINAMICCTRL = 0x00000103; EMCDINAMICRFR = 0x00000002; //wait 128 ABH clock cycles for(i=0; i<0x40; i++) asm ("nop"); //Set correct refresh period EMCDINAMICRFR = 28; //Send command: MODE EMCDINAMICCTRL = 0x00000083; //Set mode register in SDRAM #ifdef USE_32_BIT_DATABUS dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x22 << 11))); #else dummy = *((volatile unsigned int*)(SDRAM_BASE_ADDR | (0x33 << 12))); #endif //Send command: NORMAL EMCDINAMICCTRL = 0x00000000; //Enable buffer EMCDYNAMICCFG0 |= 0x00080000; //initial system delay delay(1000); EMCSTATICWAITWEN0 = 0x2; EMCSTATICWAITOEN0 = 0x2; EMCSTATICWAITRD0 = 0x1f; EMCSTATICWAITPG0 = 0x1f; EMCSTATICWAITWR0 = 0x1f; EMCSTATICWAITTURN0 = 0xf; EMCSTATICCNFG0 = 0x00000081; delay(2000); /* for NAND FLASH */ EMCSTATICCNFG1 = 0x00000080; EMCSTATICWAITWEN1 = 0x2; EMCSTATICWAITOEN1 = 0x2; EMCSTATICWAITRD1 = 0x1F; EMCSTATICWAITPG1 = 0x1F; EMCSTATICWAITWR1 = 0x1F; EMCSTATICWAITTURN1 = 0xF; delay(2000); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба 6 всё равно маловато, надо 9 ) Вы бы определились, а? А то все началось с этого: Самый быстрый строб, ко которому надо записывать эти 8bit меняется с частотой 4,5 МегаГерца. Можно построчно запихивать, а потом капировать, но это как-то не выход. Это, кстати, хороший и правильный выход. Надо оценить, успеет или нет за время обратного хода. Ну, грубо говоря, практически чуть больше, чем пол-такта на байт скорость правильного memcpy (это если внешняя память без задержек, 32 бита и SDRAM-контроллер поддерживает burst-запись), тогда 400*0.5 примерно равно 200 тактов, это, грубо говоря, 3мкс. Походу вполне, насколько я понимаю. Что подскажите. может что понастраивать надо? Ничего Вы там особо не понастраиваете. SDRAM довольно хитрозадая вещь. У меня под рукой нет мануала на Ваш проц, гляньте разве что, какая скорость CLK на SDRAM установленна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Вы бы определились, а? А то все началось с этого: Это, кстати, хороший и правильный выход. Надо оценить, успеет или нет за время обратного хода. Ну, грубо говоря, практически чуть больше, чем пол-такта на байт скорость правильного memcpy (это если внешняя память без задержек, 32 бита и SDRAM-контроллер поддерживает burst-запись), тогда 400*0.5 примерно равно 200 тактов, это, грубо говоря, 3мкс. Походу вполне, насколько я понимаю. Ничего Вы там особо не понастраиваете. SDRAM довольно хитрозадая вещь. У меня под рукой нет мануала на Ваш проц, гляньте разве что, какая скорость CLK на SDRAM установленна. 4.5 это нормальный результат. В идеале надо 9. У меня память подключена по 16 бит. А правильный memcpy это какой??? Вы имеете ввиду вот эти вод регистры? PCLKSEL0 =0x55595555; PCLKSEL1 =0x55555555; Тут всё по максимому, кроме RTC. Прилогаю usermanual: user.manual.lpc24xx.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба 4.5 это нормальный результат. В идеале надо 9. Можно и 9. На асме и с считыванием кратно 3м байтам. SECTION `.textrw`:CODE:NOROOT(2) SECTION_TYPE SHT_PROGBITS, SHF_WRITE | SHF_EXECINSTR ARM // 189 __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) // 190 { // 191 unsigned int v; // 192 unsigned char *d=dest; GetScanLine: MOV R2,R0 // 193 while(!((*port) & 0x400000)); ??GetScanLine_0: LDR R3,[R1, #+0] TST R3,#0x400000 BEQ ??GetScanLine_0 // 194 while(!((*port) & 0x800000)); ??GetScanLine_1: LDR R3,[R1, #+0] TST R3,#0x800000 BEQ ??GetScanLine_1 // 195 do // 196 { // 197 v=*port; ??GetScanLine_2: LDR R3,[R1, #+0] // 198 *d++=v; STRB R3,[R2], #+1 // 199 if (!(v&0x800000)) {v=*port;} TST R3,#0x800000 LDREQ R3,[R1, #+0] // 200 v=*port; LDR R3,[R1, #+0] // 201 *d++=v; STRB R3,[R2], #+1 TST R3,#0x400000 // 203 __no_operation(); Nop // 204 __no_operation(); Nop // 205 v=*port; LDR R3,[R1, #+0] // 206 *d++=v; STRB R3,[R2], #+1 // 207 } // 208 while(v & 0x400000); BNE ??GetScanLine_2 // 209 return d-dest; SUB R0,R2,R0 BX LR ;; return // 210 } Смысл в том, что в одном цикле считывается три байта и доп. действия распределены так - на первом байте - ФАПЧ, на втором - проверка конца строки, на третьем - собственно цикл. Обратите внимание, что собственно чтение с порта выполняется всегда на точке, кратной 8ми тактам, т.е. 72/8=9МГц. А правильный memcpy это какой??? Который не по байту копирует, а пачками слов через LDM/STM. У меня память подключена по 16 бит. Ну уже хуже. Прилогаю usermanual: Ну и? Вам еще и начальные настройки разжевывать? Учить азам ремесла? Уж извините, молодой человек, но Вам уже все на блюдечке принесли. Дальше - за деньги, или включайте собственный мозг, учите матчасть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 22 апреля, 2011 Опубликовано 22 апреля, 2011 · Жалоба Можно и 9. На асме и с считыванием кратно 3м байтам. Смысл в том, что в одном цикле считывается три байта и доп. действия распределены так - на первом байте - ФАПЧ, на втором - проверка конца строки, на третьем - собственно цикл. Обратите внимание, что собственно чтение с порта выполняется всегда на точке, кратной 8ми тактам, т.е. 72/8=9МГц. Который не по байту копирует, а пачками слов через LDM/STM. Ну уже хуже. Ну и? Вам еще и начальные настройки разжевывать? Учить азам ремесла? Уж извините, молодой человек, но Вам уже все на блюдечке принесли. Дальше - за деньги, или включайте собственный мозг, учите матчасть. Понятно, буду выжимать мксимум, но я ещё дождусь другой контроллер с готовым интерфейсом. Тоесть его писать самому? Его нет в библиотеках, как на билдере? Если честно, то я на армах всего 3-ю неделю пишу, но разжёвывать не надо, я его на всякий случай выложил, раз вы сказали его нет под рукой. Никогда ничего не покупал, всё сам, так что лучше вариант второй, с мозгом который))) За помощь спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться