Rst7 5 19 апреля, 2011 Опубликовано 19 апреля, 2011 · Жалоба Сделал, по Вашему совету. Разве я вам такое насоветовал? Вот причесанный и компилирующийся код: #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); } } Листинг: 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 и длительность нуля огласите пожалуйста. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 19 апреля, 2011 Опубликовано 19 апреля, 2011 (изменено) · Жалоба Разве я вам такое насоветовал? Вот причесанный и компилирующийся код: Листинг: Но оптимально еще заменить вторую проверку на задержку. Какие точно у Вас параметры строба пикселей? Длительность 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; } Листинг: 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 } Изменено 19 апреля, 2011 пользователем IgorKossak [codebox] !!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 19 апреля, 2011 Опубликовано 19 апреля, 2011 · Жалоба Я его пробовал, он почему-то хуже работает. Может с иаром проблема. Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 19 апреля, 2011 Опубликовано 19 апреля, 2011 · Жалоба Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных. Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 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); } } //---------------------------------------------------------------- Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 19 апреля, 2011 Опубликовано 19 апреля, 2011 · Жалоба Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 28. Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №31. Я уже собачку скушал на оптимизации алгоритмов. Ага. Особенно доставляет FlagReady. Просто плакать хочется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №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, но проконсультировавшись со специалистом и проделав пару практических задачь делаю вывод, что это не особо поможет. Буду другой камушик изучать. Спасибо за помощь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать. Ну только ради Вас: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба Ну только ради Вас: Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас). Пожалуйста: YACD511SBDBC___DataSheet__Ver_0.0_.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца. Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде: while(hsync) { *d++=v; } Ну и естественно, нопами добить частоту чтения то частоты выдачи. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца. Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде: while(hsync) { *d++=v; } Ну и естественно, нопами добить частоту чтения то частоты выдачи. Как вариант, но я планирую в дальнейшем менять динамически частоту PCLK. Правда не очень симпатишный вариант. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 20 апреля, 2011 Опубликовано 20 апреля, 2011 · Жалоба он же стабильный и кратный частоте проца. Это если тактирование от проца и идет. Тогда да. Если нет, то должно быть некое подобие ФАПЧ. Реализуется довольно просто, типа такого: do { v=*port; if (!(v&PCLK_MASK)) __delay_cycles(2); *d++=v; delay_cycles(....); } while(v&HSYNC_MASK); Делать это надо на асме, тогда код будет примерно таким: 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МГц. но я планирую в дальнейшем менять динамически частоту PCLK. Сделайте себе несколько читалок, запиленных под разные скорости PCLK. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Zigrund 0 21 апреля, 2011 Опубликовано 21 апреля, 2011 (изменено) · Жалоба . 1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить? 2) Я не очень знаком с асмом LPC, точнее я на нём ещё вообще не разу не писал. помогите пожалуйста с ним. 3) Это понятно. Хотя, если честно, мне такая идея не очень нравится. А если камеру поменять, а если ещё что-нибудь? Получается устройство очень жёстко привязоно к этой камере. Гораздо лучше, когда точно тактируются фронты. Изменено 21 апреля, 2011 пользователем IgorKossak Избыточное цитирование Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Rst7 5 21 апреля, 2011 Опубликовано 21 апреля, 2011 · Жалоба 1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить? Это пример. Нету в ARM'овской версии IAR'а __delay_cycles. Писать надо на асме. Хотя можно и на Си, результат тот же - вместо перехода используется LDREQ - он тоже весит либо 1, либо 3 такта. __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; } Результат: \ 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. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться