|
|
  |
Какую максимальную частоту можно считать с портов контроллера?, LPC2478 |
|
|
|
Apr 21 2011, 08:46
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Накатал кодик: Код __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 считал, но всё равно этот медот мне ужасно не нравится. Прям душа не лежит.
|
|
|
|
|
Apr 21 2011, 10:12
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 21 2011, 16:09)  Ересь какая-то. У Вас чем камера тактируется? Процессором? Или совершенно отдельной частотой? Отдельно. А что нельзя, в начале один раз затактировать, а дальше задержками считать всю строку?
|
|
|
|
|
Apr 21 2011, 11:27
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 21 2011, 16:15)  Нельзя, если генератор отдельный. Нужен ФАПЧ. Посмотрите внимательно на последний код, который я Вам написал - там это реализовано. Это должно быть так!? Код __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. Как он может мне помочь? Мне кто-то его уже советовал.
|
|
|
|
|
Apr 21 2011, 11:53
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE Это должно быть так!? Уберите вот эти __no_operation, которые отмечены комментарием "пол периода". Там только это CODE if (!(v & PCLK_MASK)) v = *port; должно остаться. Сей код будет занимать по времени или 1 или три такта, в зависимости от попадания на фронт сигнала. И будет держать фазу (и, как следствие, компенсировать разбег частот) в общем зачете. QUOTE Как он может мне помочь? Это некое подобие SPI. Почитайте usermanual на процессор, там же все написано.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 22 2011, 04:58
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 21 2011, 17:53)  Уберите вот эти __no_operation, которые отмечены комментарием "пол периода". Там только это Код if (!(v & PCLK_MASK)) v = *port; должно остаться. Сей код будет занимать по времени или 1 или три такта, в зависимости от попадания на фронт сигнала. И будет держать фазу (и, как следствие, компенсировать разбег частот) в общем зачете. Это некое подобие SPI. Почитайте usermanual на процессор, там же все написано. Убрал всё лишнее, только почему-то колличество считанных пикселей всегда нестабильное. Оно вроде как кружиться у нужного числа, так сказть маткматического ожидания, с какой-то дисперсией. Что нет так? Я это понял, что подобие SPI. The I2S bus specification defines a 3-wire serial bus Тут вроде как написано, что это трёх проводная последовательная шмна. Как она должна мне помочь? Просветите пожалуйста.
|
|
|
|
|
Apr 22 2011, 06:44
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE Что нет так? Ну надо точно засинхронизироваться с началом PCLK, видимо как-то так: CODE while(!((*port) & HSYNC_MASK)); while (!((*port) & PCLK_MASK)); do { v = *port; ... Рекомендую вместо __no_operation() добавить дергание какой-либо ножкой порта и посмотреть, в какие моменты времени происходит считывание. Благо, сейчас там у Вас очень много nop'ов. QUOTE Тут вроде как написано, что это трёх проводная последовательная шмна. Как она должна мне помочь? Просветите пожалуйста. Черт... Пардон... У Вас же шина параллельная. Да, конечно, не поможет, это я загнался
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 22 2011, 08:28
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 22 2011, 12:44)  Ну надо точно засинхронизироваться с началом 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; каманда исполняется за разное число тактов. Проверил точно предложенным Вами способом. В чём проблема. Может как-то не так настроена внешняя память??? Из - за этого сбивается вся синхронизация и поэтому получается такой своего рода случайный процесс. ))) Помогите пожалуйста и как правильно объявлять массив во внешней памяти?
|
|
|
|
|
Apr 22 2011, 08:50
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE 1,125 MHz Поднимает на ура и железно. Это еще не предел. В пределе - 6МГц (ибо 12 тактов минимум) QUOTE Возникла другая проблема Немудрено. Внешняя память наверняка работает на более низкой частоте чем ядро и посему процессор должен ждать начала нового цикла внешней памяти.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 22 2011, 08:58
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 22 2011, 14:50)  Это еще не предел. В пределе - 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);
}
|
|
|
|
|
Apr 22 2011, 09:11
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE 6 всё равно маловато, надо 9 ) Вы бы определились, а? А то все началось с этого: QUOTE Самый быстрый строб, ко которому надо записывать эти 8bit меняется с частотой 4,5 МегаГерца. QUOTE Можно построчно запихивать, а потом капировать, но это как-то не выход. Это, кстати, хороший и правильный выход. Надо оценить, успеет или нет за время обратного хода. Ну, грубо говоря, практически чуть больше, чем пол-такта на байт скорость правильного memcpy (это если внешняя память без задержек, 32 бита и SDRAM-контроллер поддерживает burst-запись), тогда 400*0.5 примерно равно 200 тактов, это, грубо говоря, 3мкс. Походу вполне, насколько я понимаю. QUOTE Что подскажите. может что понастраивать надо? Ничего Вы там особо не понастраиваете. SDRAM довольно хитрозадая вещь. У меня под рукой нет мануала на Ваш проц, гляньте разве что, какая скорость CLK на SDRAM установленна.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 22 2011, 09:34
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 22 2011, 15:11)  Вы бы определились, а? А то все началось с этого:
Это, кстати, хороший и правильный выход. Надо оценить, успеет или нет за время обратного хода. Ну, грубо говоря, практически чуть больше, чем пол-такта на байт скорость правильного memcpy (это если внешняя память без задержек, 32 бита и SDRAM-контроллер поддерживает burst-запись), тогда 400*0.5 примерно равно 200 тактов, это, грубо говоря, 3мкс. Походу вполне, насколько я понимаю.
Ничего Вы там особо не понастраиваете. SDRAM довольно хитрозадая вещь. У меня под рукой нет мануала на Ваш проц, гляньте разве что, какая скорость CLK на SDRAM установленна. 4.5 это нормальный результат. В идеале надо 9. У меня память подключена по 16 бит. А правильный memcpy это какой??? Вы имеете ввиду вот эти вод регистры? PCLKSEL0 =0x55595555; PCLKSEL1 =0x55555555; Тут всё по максимому, кроме RTC. Прилогаю usermanual:
|
|
|
|
|
Apr 22 2011, 09:53
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
QUOTE 4.5 это нормальный результат. В идеале надо 9. Можно и 9. На асме и с считыванием кратно 3м байтам. CODE 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МГц. QUOTE А правильный memcpy это какой??? Который не по байту копирует, а пачками слов через LDM/STM. QUOTE У меня память подключена по 16 бит. Ну уже хуже. QUOTE Прилогаю usermanual: Ну и? Вам еще и начальные настройки разжевывать? Учить азам ремесла? Уж извините, молодой человек, но Вам уже все на блюдечке принесли. Дальше - за деньги, или включайте собственный мозг, учите матчасть.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 22 2011, 10:12
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 22 2011, 15:53)  Можно и 9. На асме и с считыванием кратно 3м байтам.
Смысл в том, что в одном цикле считывается три байта и доп. действия распределены так - на первом байте - ФАПЧ, на втором - проверка конца строки, на третьем - собственно цикл. Обратите внимание, что собственно чтение с порта выполняется всегда на точке, кратной 8ми тактам, т.е. 72/8=9МГц.
Который не по байту копирует, а пачками слов через LDM/STM.
Ну уже хуже.
Ну и? Вам еще и начальные настройки разжевывать? Учить азам ремесла? Уж извините, молодой человек, но Вам уже все на блюдечке принесли. Дальше - за деньги, или включайте собственный мозг, учите матчасть. Понятно, буду выжимать мксимум, но я ещё дождусь другой контроллер с готовым интерфейсом. Тоесть его писать самому? Его нет в библиотеках, как на билдере? Если честно, то я на армах всего 3-ю неделю пишу, но разжёвывать не надо, я его на всякий случай выложил, раз вы сказали его нет под рукой. Никогда ничего не покупал, всё сам, так что лучше вариант второй, с мозгом который))) За помощь спасибо.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|