|
|
  |
Какую максимальную частоту можно считать с портов контроллера?, LPC2478 |
|
|
|
Apr 19 2011, 10:56
|

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

|
QUOTE Сделал, по Вашему совету. Разве я вам такое насоветовал? Вот причесанный и компилирующийся код: CODE #define VIDEOPORT FIOPIN
__ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) { unsigned int v; unsigned char *d=dest; while((*port)&(1<<9)); //Ждем начала строки do { while(!((v=*port)&(1<<8))); //Ждем пикселя *d++=v; //Сохраняем while((v=*port)&(1<<8)); //Ждем конца строба пикселя, оптимальнее заменить на просто достаточную задержку } while(!(v&(1<<9))); //Пока не закончилась строка return d-dest; }
extern void PrintPixCount(unsigned int); extern unsigned char BmpBuff[];
void CameraTest(void) { unsigned int PixelCount; __disable_interrupt(); while(1) { while(!(VIDEOPORT&(1<<9))); //А вдруг начало в середине строки PixelCount=GetScanLine(BmpBuff,&VIDEOPORT); PrintPixCount(PixelCount); } } Листинг: CODE 187 #define VIDEOPORT FIOPIN 188
\ In section .textrw, align 4, keep-with-next 189 __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) 190 { 191 unsigned int v; 192 unsigned char *d=dest; \ GetScanLine: \ 00000000 0020A0E1 MOV R2,R0 193 while((*port)&(1<<9)); //Ждем начала строки \ ??GetScanLine_0: \ 00000004 003091E5 LDR R3,[R1, #+0] \ 00000008 800F13E3 TST R3,#0x200 \ 0000000C FCFFFF1A BNE ??GetScanLine_0 194 do 195 { 196 while(!((v=*port)&(1<<8))); //Ждем пикселя \ ??GetScanLine_1: \ 00000010 003091E5 LDR R3,[R1, #+0] \ 00000014 400F13E3 TST R3,#0x100 \ 00000018 FCFFFF0A BEQ ??GetScanLine_1 197 *d++=v; //Сохраняем \ 0000001C 0130C2E4 STRB R3,[R2], #+1 198 while((v=*port)&(1<<8)); //Ждем конца строба пикселя, оптимальнее заменить на просто достаточную задержку \ ??GetScanLine_2: \ 00000020 003091E5 LDR R3,[R1, #+0] \ 00000024 400F13E3 TST R3,#0x100 \ 00000028 FCFFFF1A BNE ??GetScanLine_2 199 } 200 while(!(v&(1<<9))); //Пока не закончилась строка \ 0000002C 800F13E3 TST R3,#0x200 \ 00000030 F6FFFF0A BEQ ??GetScanLine_1 201 return d-dest; \ 00000034 000042E0 SUB R0,R2,R0 \ 00000038 1EFF2FE1 BX LR ;; return 202 } 203 204 extern void PrintPixCount(unsigned int); 205 extern unsigned char BmpBuff[]; 206
\ In section .text, align 4, keep-with-next 207 void CameraTest(void) 208 { \ CameraTest: \ 00000000 30402DE9 PUSH {R4,R5,LR} \ 00000004 04D04DE2 SUB SP,SP,#+4 209 unsigned int PixelCount; 210 __disable_interrupt(); \ 00000008 00000FE1 MRS R0,CPSR \ 0000000C C00080E3 ORR R0,R0,#0xC0 \ 00000010 00F021E1 MSR CPSR_c,R0 \ 00000014 24509FE5 LDR R5,??CameraTest_0 ;; BmpBuff \ 00000018 AF41E0E3 MVN R4,#-1073741781 \ 0000001C FF4DC4E3 BIC R4,R4,#0x3FC0 211 while(1) 212 { 213 while(!(VIDEOPORT&(1<<9))); //А вдруг начало в середине строки \ ??CameraTest_1: \ 00000020 000094E5 LDR R0,[R4, #+0] \ 00000024 800F10E3 TST R0,#0x200 \ 00000028 FCFFFF0A BEQ ??CameraTest_1 214 PixelCount=GetScanLine(BmpBuff,&VIDEOPORT); \ 0000002C 0410A0E1 MOV R1,R4 \ 00000030 0500A0E1 MOV R0,R5 \ 00000034 ........ BL GetScanLine 215 PrintPixCount(PixelCount); \ 00000038 ........ BL PrintPixCount \ 0000003C F7FFFFEA B ??CameraTest_1 \ ??CameraTest_0: \ 00000040 ........ DC32 BmpBuff \ 00000044 REQUIRE _A_FIOPIN 216 } 217 }
Но оптимально еще заменить вторую проверку на задержку. Какие точно у Вас параметры строба пикселей? Длительность 1 и длительность нуля огласите пожалуйста.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 19 2011, 11:21
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 19 2011, 16:56)  Разве я вам такое насоветовал?
Вот причесанный и компилирующийся код:
Листинг:
Но оптимально еще заменить вторую проверку на задержку. Какие точно у Вас параметры строба пикселей? Длительность 1 и длительность нуля огласите пожалуйста. Я его пробовал, он почему-то хуже работает. Может с иаром проблема. Вот моя версия, почти тоже всё самое, но работатет быстрее: Код void CameraTest(BYTE *BmpBuff) { unsigned char v; BYTE *d = BmpBuff; BYTE str1[40]; DWORD PixelCount = 0; bool FlagReady = false; pInt32U REG = (pInt32U)0x3FFFC056; //àäðåññ FIO2PIN2 __disable_interrupt(); m4: if((*REG & 0x40) == 0x0) { PixelCount = 0x0; goto m3; } goto m4; m3: if((*REG & 0x40)) goto m1; goto m3; m1: v = *REG; if((v & 0x40) == 0x0) goto m2; if((v & 0x80)) { if(FlagReady) { //*BmpBuff++ = v; PixelCount ++; FlagReady = false; } } else FlagReady = true; goto m1; m2: //PixelCount = BmpBuff - d; //BmpBuff = d; sprintf((char*)str1,"%u",PixelCount); lcd_put_str(10, 28, str1, 0x00FFFFFF,0); goto m4; } Листинг: CODE void CameraTest(BYTE *BmpBuff) 92 { \ CameraTest: \ 00000000 F0432DE9 PUSH {R4-R9,LR} \ 00000004 2CD04DE2 SUB SP,SP,#+44 \ 00000008 0040B0E1 MOVS R4,R0 93 unsigned char v; 94 BYTE *d = BmpBuff; \ 0000000C 0460B0E1 MOVS R6,R4 95 BYTE str1[40]; 96 DWORD PixelCount = 0; \ 00000010 0000A0E3 MOV R0,#+0 \ 00000014 0070B0E1 MOVS R7,R0 97 bool FlagReady = false; \ 00000018 0000A0E3 MOV R0,#+0 \ 0000001C 0080B0E1 MOVS R8,R0 98 pInt32U REG = (pInt32U)0x3FFFC056; //àäðåññ FIO2PIN2 \ 00000020 A701E0E3 MVN R0,#-1073741783 \ 00000024 FE0DC0E3 BIC R0,R0,#0x3F80 \ 00000028 0090B0E1 MOVS R9,R0 99 __disable_interrupt(); \ 0000002C 00000FE1 MRS R0,CPSR \ 00000030 C00080E3 ORR R0,R0,#0xC0 \ 00000034 00F021E1 MSR CPSR_c,R0 100 m4: if((*REG & 0x40) == 0x0) \ ??CameraTest_0: \ 00000038 0000D9E5 LDRB R0,[R9, #+0] \ 0000003C 400010E3 TST R0,#0x40 \ 00000040 0200001A BNE ??CameraTest_1 101 { 102 PixelCount = 0x0; \ 00000044 0000A0E3 MOV R0,#+0 \ 00000048 0070B0E1 MOVS R7,R0 103 goto m3; \ 0000004C 000000EA B ??CameraTest_2 104 } 105 goto m4; \ ??CameraTest_1: \ 00000050 F8FFFFEA B ??CameraTest_0 106 m3: if((*REG & 0x40)) goto m1; \ ??CameraTest_2: \ 00000054 0000D9E5 LDRB R0,[R9, #+0] \ 00000058 400010E3 TST R0,#0x40 \ 0000005C 0000001A BNE ??CameraTest_3 107 goto m3; \ ??CameraTest_4: \ 00000060 FBFFFFEA B ??CameraTest_2 108 m1: v = *REG; \ ??CameraTest_3: \ 00000064 000099E5 LDR R0,[R9, #+0] \ 00000068 0050B0E1 MOVS R5,R0 109 if((v & 0x40) == 0x0) goto m2; \ 0000006C 400015E3 TST R5,#0x40 \ 00000070 0B00001A BNE ??CameraTest_5 110 if((v & 0x80)) 111 { 112 if(FlagReady) 113 { 114 //*BmpBuff++ = v; 115 PixelCount ++; 116 FlagReady = false; 117 } 118 } 119 else FlagReady = true; 120 goto m1; 121 m2: //PixelCount = BmpBuff - d; 122 //BmpBuff = d; 123 sprintf((char*)str1,"%u",PixelCount); \ 00000074 0720B0E1 MOVS R2,R7 \ 00000078 ........ ADR R1,??DataTable3 ;; 0x25, 0x75, 0x00, 0x00 \ 0000007C 04008DE2 ADD R0,SP,#+4 \ 00000080 ........ BL sprintf 124 lcd_put_str(10, 28, str1, 0x00FFFFFF,0); \ 00000084 0000A0E3 MOV R0,#+0 \ 00000088 00008DE5 STR R0,[SP, #+0] \ 0000008C FF34E0E3 MVN R3,#-16777216 \ 00000090 04208DE2 ADD R2,SP,#+4 \ 00000094 1C10A0E3 MOV R1,#+28 \ 00000098 0A00A0E3 MOV R0,#+10 \ 0000009C ........ BL _Z11lcd_put_strttPhjj 125 goto m4; \ 000000A0 E4FFFFEA B ??CameraTest_0 \ ??CameraTest_5: \ 000000A4 800015E3 TST R5,#0x80 \ 000000A8 0600000A BEQ ??CameraTest_6 \ 000000AC FF8018E2 ANDS R8,R8,#0xFF ;; Zero extend \ 000000B0 000058E3 CMP R8,#+0 \ 000000B4 0500000A BEQ ??CameraTest_7 \ 000000B8 017097E2 ADDS R7,R7,#+1 \ 000000BC 0000A0E3 MOV R0,#+0 \ 000000C0 0080B0E1 MOVS R8,R0 \ 000000C4 010000EA B ??CameraTest_7 \ ??CameraTest_6: \ 000000C8 0100A0E3 MOV R0,#+1 \ 000000CC 0080B0E1 MOVS R8,R0 \ ??CameraTest_7: \ 000000D0 E3FFFFEA B ??CameraTest_3 126 }
Сообщение отредактировал IgorKossak - Apr 19 2011, 11:22
Причина редактирования: [codebox] !!!
|
|
|
|
|
Apr 19 2011, 12:04
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 19 2011, 17:26)  Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных. Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 28. Когда я пишу все эти while работает хуже. Я уже собачку скушал на оптимизации алгоритмов. Но тут я ничего не понимаю, Ващ код нормальный, у меня изначально почти такой же был, но он работает хуже. Может в чём-то ещё проблема??? Вот ещё версия, работает также: Код //---------------------------------------------------------------- void CameraTest(BYTE *BmpBuff) { unsigned char v; BYTE *d = BmpBuff; BYTE str1[40]; DWORD PixelCount = 0; bool FlagReady = false; pInt32U REG = (pInt32U)0x3FFFC056; //FIO2PIN2 __disable_interrupt(); while(1) { while((*REG & 0x40)); PixelCount = 0x0; while((*REG & 0x40) == 0x00); while(1) { v = *REG; if((v & 0x40) == 0x0) break; if((v & 0x80)) { if(FlagReady) { //*BmpBuff++ = v; PixelCount ++; FlagReady = false; } } else FlagReady = true; } sprintf((char*)str1,"%u",PixelCount); lcd_put_str(10, 28, str1, 0x00FFFFFF,0); } } //----------------------------------------------------------------
|
|
|
|
|
Apr 19 2011, 12:57
|

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

|
QUOTE Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 28. Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №31. QUOTE Я уже собачку скушал на оптимизации алгоритмов. Ага. Особенно доставляет FlagReady. Просто плакать хочется.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 20 2011, 04:57
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 19 2011, 18:57)  Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №31.
Ага. Особенно доставляет FlagReady. Просто плакать хочется. Доведя немного до ума Ваш код, внеся незначительные коррективы: Код //---------------------------------------------------------------- __ramfunc unsigned int GetScanLine(BYTE *dest, unsigned long volatile *port) { unsigned int v; BYTE *d = dest; while(!((*port) & 0x400000)); do { while(!((v=*port) & 0x800000)); *d++=v; while(((v=*port) & 0x800000)); } while((v & 0x400000)); return d - dest; }
void CameraTestNew(unsigned char *BmpBuff) { BYTE str1[40]; __disable_interrupt(); unsigned int PixelCount = 0; __disable_interrupt(); while(1) { while((FIO2PIN & 0x400000)); // PixelCount=GetScanLine(BmpBuff,&FIO2PIN); sprintf((char*)str1,"%u",PixelCount); lcd_put_str(10, 28, str1, 0x00FFFFFF,0); } } //---------------------------------------------------------------- Смею заметить, что Ваш код также не успевает сохранять как и моя версия. Переменная FlagReady позваляет использовать только один цикл, как видете, но как говорить на вкус и цвет товарища нет. Вообщем Ваш код не помог. Можно сделать DMA, но проконсультировавшись со специалистом и проделав пару практических задачь делаю вывод, что это не особо поможет. Буду другой камушик изучать. Спасибо за помощь.
|
|
|
|
|
Apr 20 2011, 08:48
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 20 2011, 13:58)  Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать. Ну только ради Вас:
Эскизы прикрепленных изображений
|
|
|
|
|
Apr 20 2011, 10:50
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 20 2011, 16:25)  Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас). Пожалуйста:
|
|
|
|
|
Apr 20 2011, 11:23
|
Местный
  
Группа: Свой
Сообщений: 252
Регистрация: 9-10-08
Из: Московская обл.
Пользователь №: 40 797

|
А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца. Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде: Код while(hsync) { *d++=v; } Ну и естественно, нопами добить частоту чтения то частоты выдачи.
|
|
|
|
|
Apr 20 2011, 12:07
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Flexz @ Apr 20 2011, 17:23)  А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца. Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде: Код while(hsync) { *d++=v; } Ну и естественно, нопами добить частоту чтения то частоты выдачи. Как вариант, но я планирую в дальнейшем менять динамически частоту PCLK. Правда не очень симпатишный вариант.
|
|
|
|
|
Apr 20 2011, 12:27
|

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

|
QUOTE он же стабильный и кратный частоте проца. Это если тактирование от проца и идет. Тогда да. Если нет, то должно быть некое подобие ФАПЧ. Реализуется довольно просто, типа такого: CODE do { v=*port; if (!(v&PCLK_MASK)) __delay_cycles(2); *d++=v; delay_cycles(....); } while(v&HSYNC_MASK); Делать это надо на асме, тогда код будет примерно таким: CODE LOOP: LDR R2,[R0] TST R2,PCLK_MASK BEQ DELAY2 ; Если 0, то выполнить переход - 3 такта, если не 0 - не выполнять переход, 1 такт. DELAY2: STRB R2,[R1],1! ; Или как он там пишется, не помню .... ; Тут при необходимости доп. задержка TST R2,HSYNC_MASK BNE LOOP Итого - 3+1+(1 или 3, в среднем 2)+2+1+3=12 тактов. При тактовой частоте 72МГц можно съесть данные со скоростью 72/12=6МГц. QUOTE но я планирую в дальнейшем менять динамически частоту PCLK. Сделайте себе несколько читалок, запиленных под разные скорости PCLK.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Apr 21 2011, 05:57
|
Частый гость
 
Группа: Участник
Сообщений: 184
Регистрация: 11-09-08
Пользователь №: 40 121

|
Цитата(Rst7 @ Apr 20 2011, 18:27)  . 1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить? 2) Я не очень знаком с асмом LPC, точнее я на нём ещё вообще не разу не писал. помогите пожалуйста с ним. 3) Это понятно. Хотя, если честно, мне такая идея не очень нравится. А если камеру поменять, а если ещё что-нибудь? Получается устройство очень жёстко привязоно к этой камере. Гораздо лучше, когда точно тактируются фронты.
Сообщение отредактировал IgorKossak - Apr 21 2011, 07:34
Причина редактирования: Избыточное цитирование
|
|
|
|
|
Apr 21 2011, 08:09
|

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

|
QUOTE 1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить? Это пример. Нету в ARM'овской версии IAR'а __delay_cycles. Писать надо на асме. Хотя можно и на Си, результат тот же - вместо перехода используется LDREQ - он тоже весит либо 1, либо 3 такта. CODE __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) { unsigned int v; unsigned char *d=dest; while(!((*port) & 0x400000)); //Æäåì íà÷àëà ñòðîêè do { v=*port; *d++=v; if (!(v&0x800000)) {v=*port;} //Тут можно навставлять нужное количество __no_operation(); ... __no_operation(); } while(v & 0x400000); //Ïîêà íå çàêîí÷èëàñü ñòðîêà return d-dest; } Результат: CODE \ In section .textrw, align 4, keep-with-next 189 __ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned long volatile *port) 190 { 191 unsigned int v; 192 unsigned char *d=dest; \ GetScanLine: \ 00000000 0020A0E1 MOV R2,R0 193 while(!((*port) & 0x400000)); //Æäåì íà÷àëà ñòðîêè \ ??GetScanLine_0: \ 00000004 003091E5 LDR R3,[R1, #+0] \ 00000008 400813E3 TST R3,#0x400000 \ 0000000C FCFFFF0A BEQ ??GetScanLine_0 194 do 195 { 196 v=*port; \ ??GetScanLine_1: \ 00000010 003091E5 LDR R3,[R1, #+0] 197 *d++=v; \ 00000014 0130C2E4 STRB R3,[R2], #+1 198 if (!(v&0x800000)) {v=*port;} \ 00000018 800813E3 TST R3,#0x800000 \ 0000001C 00309105 LDREQ R3,[R1, #+0] 199 } 200 while(v & 0x400000); //Ïîêà íå çàêîí÷èëàñü ñòðîêà \ 00000020 400813E3 TST R3,#0x400000 \ 00000024 F9FFFF1A BNE ??GetScanLine_1 201 return d-dest; \ 00000028 000042E0 SUB R0,R2,R0 \ 0000002C 1EFF2FE1 BX LR ;; return 202 }
Кстати... А I2S есть у Вас в выбранном камне? Если да, то используйте его, он быстрый в Slave-mode.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|