Перейти к содержанию
    

Какую максимальную частоту можно считать с портов контроллера?

Сделал, по Вашему совету.

 

Разве я вам такое насоветовал?

 

Вот причесанный и компилирующийся код:

 

#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 и длительность нуля огласите пожалуйста.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Разве я вам такое насоветовал?

 

Вот причесанный и компилирующийся код:

 

 

 

Листинг:

 

 

Но оптимально еще заменить вторую проверку на задержку. Какие точно у Вас параметры строба пикселей? Длительность 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			  }

Изменено пользователем IgorKossak
[codebox] !!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я его пробовал, он почему-то хуже работает.

Может с иаром проблема.

 

Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных.

 

Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 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);
    }   
  }
//----------------------------------------------------------------

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 28.

 

Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №31.

 

Я уже собачку скушал на оптимизации алгоритмов.

 

Ага. Особенно доставляет FlagReady. Просто плакать хочется.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, только данные не сохраняет. Во-вторых, более-менее готовый код приведен в посте №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, но проконсультировавшись со специалистом и проделав пару практических задачь делаю вывод, что это не особо поможет.

Буду другой камушик изучать.

Спасибо за помощь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать.

 

Ну только ради Вас:

 

post-40121-1303289296_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну только ради Вас:

 

Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас).

 

Пожалуйста:

YACD511SBDBC___DataSheet__Ver_0.0_.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца.

Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде:

while(hsync)
{
*d++=v;
}

Ну и естественно, нопами добить частоту чтения то частоты выдачи.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца.

Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде:

while(hsync)
{
*d++=v;
}

Ну и естественно, нопами добить частоту чтения то частоты выдачи.

 

Как вариант, но я планирую в дальнейшем менять динамически частоту PCLK.

Правда не очень симпатишный вариант.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

он же стабильный и кратный частоте проца.

 

Это если тактирование от проца и идет. Тогда да. Если нет, то должно быть некое подобие ФАПЧ. Реализуется довольно просто, типа такого:

 

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

.

 

1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить?

2) Я не очень знаком с асмом LPC, точнее я на нём ещё вообще не разу не писал. помогите пожалуйста с ним.

3) Это понятно.

 

Хотя, если честно, мне такая идея не очень нравится.

А если камеру поменять, а если ещё что-нибудь? Получается устройство очень жёстко привязоно к этой камере.

Гораздо лучше, когда точно тактируются фронты.

Изменено пользователем IgorKossak
Избыточное цитирование

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...