Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Какую максимальную частоту можно считать с портов контроллера?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
Prinz
Использую контроллер LPC2478.
Перефирия на частоте 72МГц.
Подскажите пожалуйста какую максимальную частоту можно считать этим контроллером с его портов?
И как будет быстрее в прерывании по изменении порта или в лмнлвнлм цикле?
Как правильно настроить ИАР для этого?
Поделитесь Ваши опытом пожалуйста. Самостоятельно у меня получилось считать только до 1 MHz. И то с натягом.
Заранее спасибо.
scifi
Для точного захвата внешних сигналов следует использовать аппаратные таймеры с функцией capture или counter. GPIO для этого плохо подходит.
Prinz
Цитата(scifi @ Apr 15 2011, 17:30) *
Для точного захвата внешних сигналов следует использовать аппаратные таймеры с функцией capture или counter. GPIO для этого плохо подходит.


Я немного не понял, как это сделать.
Поясню свой вопрос. Имеется 8bit шина данных и три строба. Самый быстрый строб, ко которому надо записывать эти 8bit меняется с частотой 4,5 МегаГерца. Можно понизить до 2,25, но лучше не надо.
И как это делается, привидите примерчик пожалуйста.

Я это никогда не пользовал, поэтому не очень представляю, как параллельную шину считать.
kovigor
Цитата(Prinz @ Apr 15 2011, 14:37) *
И как это делается, привидите примерчик пожалуйста.


Боюсь, что никак. Слишком быстро. Или же без всякого таймера в цикле ждать фронтов строба и захватывать данные на шине, и то я ничего не обещаю. Я бы CPLD поставил или обычный регистр ...
Rst7
Строб заводите на ножку прерывания. Режим для этого прерывания используете FIQ. Прямо на ассемблере пишете код прерывания (из трех команд - чтение из порта, запись с автоинкрементом), помятуя, что в FIQ есть банкирование регистров и, следовательно, можно не сохранять регистры (некоторые, в общем за подробностями в мануал по ARM).

Кстати, в том же мане есть такой раздельчик - "Примеры кода". Там есть такой "Soft-DMA", именно через FIQ. В общем, может и успеть.
Prinz
Цитата(kovigor @ Apr 15 2011, 18:02) *
Боюсь, что никак. Слишком быстро. Или же без всякого таймера в цикле ждать фронтов строба и захватывать данные на шине, и то я ничего не обещаю. Я бы CPLD поставил или обычный регистр ...


Плис не нужен, надо на контроллере.
Сейчас буду пробовать на asm цикл писать. А команды асемблера для этого контроллера где можно глянуть?

Цитата(Rst7 @ Apr 16 2011, 21:12) *
Строб заводите на ножку прерывания. Режим для этого прерывания используете FIQ. Прямо на ассемблере пишете код прерывания (из трех команд - чтение из порта, запись с автоинкрементом), помятуя, что в FIQ есть банкирование регистров и, следовательно, можно не сохранять регистры (некоторые, в общем за подробностями в мануал по ARM).

Кстати, в том же мане есть такой раздельчик - "Примеры кода". Там есть такой "Soft-DMA", именно через FIQ. В общем, может и успеть.


Про FIQ, тоже думал.
А где в мане этот раздельчик?
А можно примерчик на асемблере, если не сложно, а то на арм написания программ на асме у меня ещё не было.
Prinz
Был бы рад краткому курсу по asm LPC )

Код
void CameraTest(void)
  {

    BYTE str1[40];
  
  SCS |= 0x1;
  FIO0DIR_bit.P0_22 = 0;
  #define HSYNC FIO0PIN_bit.P0_22
  FIO2DIR_bit.P2_22 = 0;
  #define PCLK  FIO2PIN_bit.P2_22
  DWORD PixelCount = 0;
  bool FlagReady = false;
  
  while(1)
  {
    while(HSYNC == 1);
    PixelCount = 0;
    while(HSYNC == 0);
    while(1)
    {
      if(HSYNC == 0) break;
      if(PCLK  == 1)
      {
        if(FlagReady)
        {
          //BmpBuff[PixelCount] = 0x56;
            PixelCount ++;
            FlagReady = false;
        }
      }
      else FlagReady = true;
    }
    sprintf((char*)str1,"%u",PixelCount);
    lcd_put_str(10, 28, str1, 0x00FFFFFF,0);    
  }
  }

Вот этотим кусочком я пытаюсь сосчитать стробы.
Подскажите, как он на asm выглядеь будет?
kovigor
Цитата(Prinz @ Apr 18 2011, 10:36) *
Вот этотим кусочком я пытаюсь сосчитать стробы.
Подскажите, как он на asm выглядеь будет?


А вы посмотрите файл листинга и узнаете. От себя добавлю, что ваша идея почти наверняка обречена на неудачу. 4.5МГц - это явно очень быстро. А современные компиляторы генерируют ну почти оптимальный код, и чтобы сделать лучше, программируя на ассемблере, придется серьезно потрудиться ...
Prinz
Цитата(kovigor @ Apr 18 2011, 13:52) *
А вы посмотрите файл листинга и узнаете. От себя добавлю, что ваша идея почти наверняка обречена на неудачу. 4.5МГц - это явно очень быстро. А современные компиляторы генерируют ну почти оптимальный код, и чтобы сделать лучше, программируя на ассемблере, придется серьезно потрудиться ...



CODE
59 void CameraTest(void)
60 {
\ CameraTest:
\ 00000000 30402DE9 PUSH {R4,R5,LR}
\ 00000004 2CD04DE2 SUB SP,SP,#+44
61
62 BYTE str1[40];
63
64 SCS |= 0x1;
\ 00000008 ........ LDR R0,??DataTable1 ;; 0xe01fc1a0
\ 0000000C 000090E5 LDR R0,[R0, #+0]
\ 00000010 010090E3 ORRS R0,R0,#0x1
\ 00000014 ........ LDR R1,??DataTable1 ;; 0xe01fc1a0
\ 00000018 000081E5 STR R0,[R1, #+0]
65 FIO0DIR_bit.P0_22 = 0;
\ 0000001C FF05A0E3 MOV R0,#+1069547520
\ 00000020 FF0980E3 ORR R0,R0,#0x3FC000
\ 00000024 000090E5 LDR R0,[R0, #+0]
\ 00000028 4008D0E3 BICS R0,R0,#0x400000
\ 0000002C FF15A0E3 MOV R1,#+1069547520
\ 00000030 FF1981E3 ORR R1,R1,#0x3FC000
\ 00000034 000081E5 STR R0,[R1, #+0]
66 #define HSYNC FIO0PIN_bit.P0_22
67 FIO2DIR_bit.P2_22 = 0;
\ 00000038 FF01E0E3 MVN R0,#-1073741761
\ 0000003C FE0DC0E3 BIC R0,R0,#0x3F80
\ 00000040 000090E5 LDR R0,[R0, #+0]
\ 00000044 4008D0E3 BICS R0,R0,#0x400000
\ 00000048 FF11E0E3 MVN R1,#-1073741761
\ 0000004C FE1DC1E3 BIC R1,R1,#0x3F80
\ 00000050 000081E5 STR R0,[R1, #+0]
68 #define PCLK FIO2PIN_bit.P2_22
69 DWORD PixelCount = 0;
\ 00000054 0000A0E3 MOV R0,#+0
\ 00000058 0040B0E1 MOVS R4,R0
70 bool FlagReady = false;
\ 0000005C 0000A0E3 MOV R0,#+0
\ 00000060 0050B0E1 MOVS R5,R0
71
72 while(1)
73 {
74 while(HSYNC == 1);
\ ??CameraTest_0:
\ ??CameraTest_1:
\ 00000064 AF01E0E3 MVN R0,#-1073741781
\ 00000068 FF0DC0E3 BIC R0,R0,#0x3FC0
\ 0000006C 000090E5 LDR R0,[R0, #+0]
\ 00000070 400810E2 ANDS R0,R0,#0x400000
\ 00000074 200BB0E1 LSRS R0,R0,#+22
\ 00000078 010050E3 CMP R0,#+1
\ 0000007C F8FFFF0A BEQ ??CameraTest_1
75 PixelCount = 0;
\ 00000080 0000A0E3 MOV R0,#+0
\ 00000084 0040B0E1 MOVS R4,R0
76 while(HSYNC == 0);
\ ??CameraTest_2:
\ 00000088 AF01E0E3 MVN R0,#-1073741781
\ 0000008C FF0DC0E3 BIC R0,R0,#0x3FC0
\ 00000090 000090E5 LDR R0,[R0, #+0]
\ 00000094 400810E2 ANDS R0,R0,#0x400000
\ 00000098 200BB0E1 LSRS R0,R0,#+22
\ 0000009C 000050E3 CMP R0,#+0
\ 000000A0 F8FFFF0A BEQ ??CameraTest_2
77 while(1)
78 {
79 if(HSYNC == 0) break;
\ ??CameraTest_3:
\ 000000A4 AF01E0E3 MVN R0,#-1073741781
\ 000000A8 FF0DC0E3 BIC R0,R0,#0x3FC0
\ 000000AC 000090E5 LDR R0,[R0, #+0]
\ 000000B0 400810E2 ANDS R0,R0,#0x400000
\ 000000B4 200BB0E1 LSRS R0,R0,#+22
\ 000000B8 000050E3 CMP R0,#+0
\ 000000BC 0B00001A BNE ??CameraTest_4
80 if(PCLK == 1)
81 {
82 if(FlagReady)
83 {
84 //BmpBuff[PixelCount] = 0x56;
85 PixelCount ++;
86 FlagReady = false;
87 }
88 }
89 else FlagReady = true;
90 }
91 sprintf((char*)str1,"%u",PixelCount);
\ 000000C0 0420B0E1 MOVS R2,R4
\ 000000C4 ........ ADR R1,??DataTable0 ;; 0x25, 0x75, 0x00, 0x00
\ 000000C8 04008DE2 ADD R0,SP,#+4
\ 000000CC ........ BL sprintf
92 lcd_put_str(10, 28, str1, 0x00FFFFFF,0);
\ 000000D0 0000A0E3 MOV R0,#+0
\ 000000D4 00008DE5 STR R0,[SP, #+0]
\ 000000D8 FF34E0E3 MVN R3,#-16777216
\ 000000DC 04208DE2 ADD R2,SP,#+4
\ 000000E0 1C10A0E3 MOV R1,#+28
\ 000000E4 0A00A0E3 MOV R0,#+10
\ 000000E8 ........ BL _Z11lcd_put_strttPhjj
\ 000000EC DCFFFFEA B ??CameraTest_0
\ ??CameraTest_4:
\ 000000F0 AF01E0E3 MVN R0,#-1073741781
\ 000000F4 FE0DC0E3 BIC R0,R0,#0x3F80
\ 000000F8 000090E5 LDR R0,[R0, #+0]
\ 000000FC 400810E2 ANDS R0,R0,#0x400000
\ 00000100 200BB0E1 LSRS R0,R0,#+22
\ 00000104 010050E3 CMP R0,#+1
\ 00000108 0600001A BNE ??CameraTest_5
\ 0000010C FF5015E2 ANDS R5,R5,#0xFF ;; Zero extend
\ 00000110 000055E3 CMP R5,#+0
\ 00000114 E2FFFF0A BEQ ??CameraTest_3
\ 00000118 014094E2 ADDS R4,R4,#+1
\ 0000011C 0000A0E3 MOV R0,#+0
\ 00000120 0050B0E1 MOVS R5,R0
\ 00000124 DEFFFFEA B ??CameraTest_3
\ ??CameraTest_5:
\ 00000128 0100A0E3 MOV R0,#+1
\ 0000012C 0050B0E1 MOVS R5,R0
\ 00000130 DBFFFFEA B ??CameraTest_3
\ 00000134 REQUIRE _A_SCS
\ 00000134 REQUIRE _A_FIO0DIR
\ 00000134 REQUIRE _A_FIO0PIN
\ 00000134 REQUIRE _A_FIO2DIR
\ 00000134 REQUIRE _A_FIO2PIN
93 }
94 }


Может вы своим провессиональным взглядом, что подскажите??? Где, что надо умотать, чтобы шустрее работало.
У меня даже 1 мегагерц сейчас пиксели пропускаются.
kovigor
Цитата(Prinz @ Apr 18 2011, 11:04) *
Может вы своим провессиональным взглядом, что подскажите??? Где, что надо умотать, чтобы шустрее работало.
У меня даже 1 мегагерц сейчас пиксели пропускаются.


А вы попробуйте сначала сделать вообще без прерывания (для проверки). Запретите все прерывания и просто в цикле ждите фронтов синхроимпульсов или того, что у вас там вместо них, и по этим фронтам читайте ваши данные. Успеете ? Ну, тогда и с прерываниями можно потягаться. Нет ? Тогда и пробовать нечего ...
Слесарь
Я при тактовой частоте 24 мГц PIC контроллера, устойчиво, с программной фильтрацией промежуточного пограничного состояние аналогового сигнала, считываю с порта частоту до 200 кГц. А так вообще, думаю что 1мкс импульс регистрировал бы портом без проблем.
Prinz
Цитата(kovigor @ Apr 18 2011, 14:17) *
А вы попробуйте сначала сделать вообще без прерывания (для проверки). Запретите все прерывания и просто в цикле ждите фронтов синхроимпульсов или того, что у вас там вместо них, и по этим фронтам читайте ваши данные. Успеете ? Ну, тогда и с прерываниями можно потягаться. Нет ? Тогда и пробовать нечего ...


Так я перед вызовам функции так и делаю:


__disable_interrupt();
CameraTest();

Это я Вам привёл мой код, который я сейчас тестирую.
Так, что все прерывания запрещены. (

Цитата(Слесарь @ Apr 18 2011, 14:18) *
Я при тактовой частоте 24 мГц PIC контроллера, устойчиво, с программной фильтрацией промежуточного пограничного состояние аналогового сигнала, считываю с порта частоту до 200 кГц. А так вообще, думаю что 1мкс импульс регистрировал бы портом без проблем.

Мне надо 4,5MHz.
Слесарь
Цитата(Prinz @ Apr 18 2011, 12:35) *
Мне надо 4,5MHz.

Тогда надо использовать встроенный специальный счетчик, если он есть в МК
Prinz
Цитата(Слесарь @ Apr 18 2011, 14:36) *
Тогда надо использовать встроенный специальный счетчик, если он есть в МК


По стробу надо считывать данные ещё 8 bit.
Я не верю, что контроллер на частоте 72 MHz, не может счиать каки-то хилых 5 MHz.
Может есть какой способ?
Слесарь
проблема может статься в задержке распространения сигнала по проводникам. плавное нарастание сигнала на порту и соответсвенно неправильная фиксация сигнала. необходимо как-то прикинуть скорость нарастания сигнала при тактовой частоте 5 мГц и длине проводников.
Prinz
Цитата(Слесарь @ Apr 18 2011, 14:58) *
проблема может статься в задержке распространения сигнала по проводникам. плавное нарастание сигнала на порту и соответсвенно неправильная фиксация сигнала. необходимо как-то прикинуть скорость нарастания сигнала при тактовой частоте 5 мГц и длине проводников.


Фронты наблюдаю на осцилографе, всё красиво. Никаких завалов нет.
Слесарь
У тебя есть осцилограф 05.gif

Если бы у меня был осцилограф, я бы попробывал программно сгенерировать максимальную частоту на порту контроллера. Чтоб шла красиво. От этого, чисто по слесарски, прикинул бы максимально возможную частоту которую смог бы этим портом надежно фиксировать. Просто разделить частоту генерации на десять, вот и будет частота фиксации
Prinz
Цитата(Слесарь @ Apr 18 2011, 15:21) *
У тебя есть осцилограф 05.gif

Если бы у меня был осцилограф, я бы попробывал программно сгенерировать максимальную частоту на порту контроллера. Чтоб шла красиво. От этого, чисто по слесарски, прикинул бы максимально возможную частоту которую смог бы этим портом надежно фиксировать. Просто разделить частоту генерации на десять, вот и будет частота фиксации



Я так делал. Делал следующее.

while(1)
{
FIO2SET_bit.P2_22 = 1;
FIO2CLR_bit.P2_22 = 1;
}

И получилось всего 1 MHz. И это с 72 MHz?
Такой навороченны кантроллер. Я тут очти всё запустил, а считать частоту не могу. (

Я ещё так забодяжил, тоже не помогло.

Код
  void CameraTest(void)
  {

    BYTE str1[40];
    DWORD PixelCount = 0;
    bool FlagReady = false;
    
      while(1)
      {
    m4: if(HSYNC == 0)
        {
          PixelCount = 0;
          goto m3;
        }
        goto m4;
    m3: if(HSYNC) goto m1;
        goto m3;
    m1: if(HSYNC == 0) goto m2;  
        if(PCLK)
        {
          if(FlagReady)
          {
            //BmpBuff[PixelCount] = 0x56;
              PixelCount ++;
              FlagReady = false;
          }
        }
        else FlagReady = true;
        goto m1;
    m2: sprintf((char*)str1,"%u",PixelCount);
        lcd_put_str(10, 28, str1, 0x00FFFFFF,0);    
      }
    }
Слесарь
Цитата(Prinz @ Apr 18 2011, 13:28) *
Я так делал. Делал следующее.

while(1)
{
FIO2SET_bit.P2_22 = 1;
FIO2CLR_bit.P2_22 = 1;
}

И получилось всего 1 MHz. И это с 72 MHz?
Такой навороченны кантроллер. Я тут очти всё запустил, а считать частоту не могу. (

Маловато, при учете что требуется 4 ... 8 тактов для грязной генерации на порту контроллера. Может все дело в конфигурации проца? Как там настроен умножитель частоты тактового генератора? Ведь кварц у тебя значительно меньшей частоты?
Prinz
Цитата(Слесарь @ Apr 18 2011, 15:47) *
Маловато, при учете что требуется 4 ... 8 тактов для грязной генерации на порту контроллера. Может все дело в конфигурации проца? Как там настроен умножитель частоты тактового генератора? Ведь кварц у тебя значительно меньшей частоты?


Да вроде всё верно.
Вот мой код:
Код
void InitClock(void)
{
    MAMCR_bit.MODECTRL = 0;
  MAMTIM_bit.CYCLES  = 3;   // FCLK > 40 MHz
  MAMCR_bit.MODECTRL = 2;
  // 1. Init OSC
  SCS_bit.OSCRANGE = 0;
  SCS_bit.OSCEN = 1;
  // 2.  Wait for OSC ready
  while(!SCS_bit.OSCSTAT);
  // 3. Disconnect PLL
  PLLCON_bit.PLLC = 0;
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // 4. Disable PLL
  PLLCON_bit.PLLE = 0;
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // 5. Select source clock for PLL
  CLKSRCSEL_bit.CLKSRC = 1; // Selects the main oscillator as a PLL clock source.
  // 6. Set PLL settings 288 MHz
  PLLCFG_bit.MSEL = 24-1;
  PLLCFG_bit.NSEL = 2-1;
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // 7. Enable PLL
  PLLCON_bit.PLLE = 1;
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // 8. Wait for the PLL to achieve lock
  while(!PLLSTAT_bit.PLOCK);
  // 9. Set clk divider settings
  CCLKCFG   = 4-1;            // 1/4 Fpll - 72 MHz
  USBCLKCFG = 6-1;            // 1/6 Fpll - 48 MHz
  PCLKSEL0 =0x55595555;     // òàéìåð 0 72ÌÃö
  PCLKSEL1 =0x55555555;
  // 10. Connect the PLL
  PLLCON_bit.PLLC = 1;
  PLLFEED = 0xAA;
  PLLFEED = 0x55;
  // stop all Peripherals' clocks
  PCONP = 0xFFFFFFFF;
}
Prinz
Коллеги, кто ещё что посоветует?
Прерывание счиатете делать бессмыслено, если так в цикле считаьт не могу?
Как - то даже стыдно за этот контроллер, 72 Mhz, а даже 1,1 поднять не может. Мега точно бы 1,1 подняла, а мне надо 4,5.
Не понимаю, или я, или лыжи, или контроллер? )
ViKo
Цитата(Слесарь @ Apr 18 2011, 12:21) *
Если бы у меня был осцилограф, я бы попробывал программно сгенерировать максимальную частоту на порту контроллера. Чтоб шла красиво. От этого, чисто по слесарски, прикинул бы максимально возможную частоту которую смог бы этим портом надежно фиксировать. Просто разделить частоту генерации на десять, вот и будет частота фиксации

У меня был... я сгенерировал...
http://electronix.ru/forum/index.php?showt...st&p=913156
можем прикинуть... раз 500000 в секунду словить можно рассчитывать.
Процессор, правда, другой, но вряд ли на большее стоит надеяться.
Prinz
Цитата(ViKo @ Apr 18 2011, 17:07) *
У меня был... я сгенерировал...
http://electronix.ru/forum/index.php?showt...st&p=913156
можем прикинуть... раз 500000 в секунду словить можно рассчитывать.
Процессор, правда, другой, но вряд ли на большее стоит надеяться.


Вы имеете ввиду, что максимум 500 kHz считать можно?
scifi
Цитата(Prinz @ Apr 18 2011, 12:46) *
Я не верю, что контроллер на частоте 72 MHz, не может счиать каки-то хилых 5 MHz.

Лучше поверьте. Известно, что GPIO - это тормоз.
ViKo
Цитата(scifi @ Apr 18 2011, 14:16) *
Лучше поверьте. Известно, что GPIO - это тормоз.

Наверное, дело не в GPIO, а в архитектуре и системе команд ARM. Напрямую ни к чему во всем громадном адресном пространстве не обратиться, все посредством косвенной адресации через регистры. Сначала загрузить адрес, потом по этому адресу прочитать, потом что-нибудь сделать, потом записать обратно. И так со всеми переменными, кроме локальных, которые удастся поместить в регистры.
Prinz
Цитата(ViKo @ Apr 18 2011, 17:33) *
Наверное, дело не в GPIO, а в архитектуре и системе команд ARM. Напрямую ни к чему во всем громадном адресном пространстве не обратиться, все посредством косвенной адресации через регистры. Сначала загрузить адрес, потом по этому адресу прочитать, потом что-нибудь сделать, потом записать обратно. И так со всеми переменными, кроме локальных, которые удастся поместить в регистры.

Я тоже заметил по листингу, что уж через чур много команда на асемблере. По опыту написания программ на PIC, я бы 10 командами уложился, а там и куча целая.
А какой выход? Или это гиблое дело. У меня ещё имеется кортекс с максимальной рабочей частотой 120 мегагерц. Может на нём попробывать?
ViKo
Цитата(Prinz @ Apr 18 2011, 14:38) *
А какой выход? Или это гиблое дело. У меня ещё имеется кортекс с максимальной рабочей частотой 120 мегагерц. Может на нём попробывать?

нет выхода sad.gif
Можете на 120MHz Cortex, будет быстрее, как понимаете, раза в 1.5 - 2.
Еще шину замените на 16-битовую, читайте за один раз два байта.
Rst7
Во-первых, я не помню, но посмотрите, есть ли в Вашем камне Fast-GPIO. Если есть, то будет лучше. Если нет, то имейте в виду что:

1. Доступ к GPIO весит 7 тактов через APB. Значит надо минимизировать количество обращений. Оптимально сделать так, чтобы стробы и данные были в одном порту - например данные на битах 0-7, PCLK на бите 8, HSYNC на бите 9. Плюс выполнять код из ОЗУ. Тогда выглядеть это должно так:

CODE
__ramfunc unsigned int GetScanLine(unsigned char *dest, unsigned int *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;
}


void CameraTest(void)
  {

.....
  while(1)
  {
    while(!(FIO2PIN&(1<<9))); //А вдруг начало в середине строки
    PixelCount=GetScanLine(BmpBuff,&FIO2PIN);
    sprintf((char*)str1,"%u",PixelCount);
    lcd_put_str(10, 28, str1, 0x00FFFFFF,0);    
  }



О, написал, и увидел, что у Вас и так Fast-GPIO. Проверьте точные частоты ядра и периферии, ибо чтение для Fast-GPIO весит 3 такта, запись 2.

PS И посмотрите на результат компиляции, будете вполне довольны, как на асме, не хуже.
Prinz
Цитата(Rst7 @ Apr 18 2011, 18:10) *
Во-первых, я не помню, но посмотрите, есть ли в Вашем камне Fast-GPIO. Если есть, то будет лучше. Если нет, то имейте в виду что:

1. Доступ к GPIO весит 7 тактов через APB. Значит надо минимизировать количество обращений. Оптимально сделать так, чтобы стробы и данные были в одном порту - например данные на битах 0-7, PCLK на бите 8, HSYNC на бите 9. Плюс выполнять код из ОЗУ. Тогда выглядеть это должно так:




О, написал, и увидел, что у Вас и так Fast-GPIO. Проверьте точные частоты ядра и периферии, ибо чтение для Fast-GPIO весит 3 такта, запись 2.

PS И посмотрите на результат компиляции, будете вполне довольны, как на асме, не хуже.


Сделал, по Вашему совету. Все стробы считал, но записываь во внешнюю память уже не получается, не успевает:
Вот мой последний оптимизированный код:

Код
void CameraTest(BYTE *BmpBuff)
  {
    unsigned char v;
    __disable_interrupt();
    BYTE str1[40];
    DWORD PixelCount = 0;
    bool FlagReady = false;
    m4: if(HSYNC == 0x0)
        {
          PixelCount = 0x0;
          goto m3;
        }
        goto m4;
    m3: if(HSYNC) goto m1;
        goto m3;
    m1: v = FIO2PIN2;
        if((v & 0x40) == 0x0) goto m2;  
        if((v & 0x80))
        {
          if(FlagReady)
          {
              //BmpBuff[PixelCount] = 0x56;
              PixelCount ++;
              //for(char i = 0;;);
              FlagReady = false;
          }
        }
        else FlagReady = true;
        goto m1;
    m2: sprintf((char*)str1,"%u",PixelCount);
        lcd_put_str(10, 28, str1, 0x00FFFFFF,0);    
        goto m4;
    }

Но это всего 1,1 МГц. А надо 4,5.
Как я понял, надо искать другой контроллер. sad.gif
Prinz
Код
void CameraTest(BYTE *BmpBuff)
     92            {
   \                     CameraTest:
   \   00000000   F0402DE9           PUSH     {R4-R7,LR}
   \   00000004   2CD04DE2           SUB      SP,SP,#+44
   \   00000008   0040B0E1           MOVS     R4,R0
     93              unsigned char v;
     94              __disable_interrupt();
   \   0000000C   00000FE1           MRS      R0,CPSR
   \   00000010   C00080E3           ORR      R0,R0,#0xC0
   \   00000014   00F021E1           MSR      CPSR_c,R0
     95              BYTE str1[40];
     96              DWORD PixelCount = 0;
   \   00000018   0000A0E3           MOV      R0,#+0
   \   0000001C   0060B0E1           MOVS     R6,R0
     97              bool FlagReady = false;
   \   00000020   0000A0E3           MOV      R0,#+0
   \   00000024   0070B0E1           MOVS     R7,R0
     98              m4: if(HSYNC == 0x0)
   \                     ??CameraTest_0:
   \   00000028   AF01E0E3           MVN      R0,#-1073741781
   \   0000002C   FE0DC0E3           BIC      R0,R0,#0x3F80
   \   00000030   0200D0E5           LDRB     R0,[R0, #+2]
   \   00000034   400010E3           TST      R0,#0x40
   \   00000038   0200001A           BNE      ??CameraTest_1
     99                  {
    100                    PixelCount = 0x0;
   \   0000003C   0000A0E3           MOV      R0,#+0
   \   00000040   0060B0E1           MOVS     R6,R0
    101                    goto m3;
   \   00000044   000000EA           B        ??CameraTest_2
    102                  }
    103                  goto m4;
   \                     ??CameraTest_1:
   \   00000048   F6FFFFEA           B        ??CameraTest_0
    104              m3: if(HSYNC) goto m1;
   \                     ??CameraTest_2:
   \   0000004C   AF01E0E3           MVN      R0,#-1073741781
   \   00000050   FE0DC0E3           BIC      R0,R0,#0x3F80
   \   00000054   0200D0E5           LDRB     R0,[R0, #+2]
   \   00000058   400010E3           TST      R0,#0x40
   \   0000005C   0000001A           BNE      ??CameraTest_3
    105                  goto m3;
   \                     ??CameraTest_4:
   \   00000060   F9FFFFEA           B        ??CameraTest_2
    106              m1: v = FIO2PIN2;
   \                     ??CameraTest_3:
   \   00000064   AF01E0E3           MVN      R0,#-1073741781
   \   00000068   FE0DC0E3           BIC      R0,R0,#0x3F80
   \   0000006C   0200D0E5           LDRB     R0,[R0, #+2]
   \   00000070   0050B0E1           MOVS     R5,R0
    107                  if((v & 0x40) == 0x0) goto m2;  
   \   00000074   400015E3           TST      R5,#0x40
   \   00000078   0B00001A           BNE      ??CameraTest_5
    108                  if((v & 0x80))
    109                  {
    110                    if(FlagReady)
    111                    {
    112                        //BmpBuff[PixelCount] = 0x56;
    113                        PixelCount ++;
    114                        //for(char i = 0;;);
    115                        FlagReady = false;
    116                    }
    117                  }
    118                  else FlagReady = true;
    119                  goto m1;
    120              m2: sprintf((char*)str1,"%u",PixelCount);
   \   0000007C   0620B0E1           MOVS     R2,R6
   \   00000080   ........           ADR      R1,??DataTable3 ;; 0x25, 0x75, 0x00, 0x00
   \   00000084   04008DE2           ADD      R0,SP,#+4
   \   00000088   ........           BL       sprintf
    121                  lcd_put_str(10, 28, str1, 0x00FFFFFF,0);    
   \   0000008C   0000A0E3           MOV      R0,#+0
   \   00000090   00008DE5           STR      R0,[SP, #+0]
   \   00000094   FF34E0E3           MVN      R3,#-16777216
   \   00000098   04208DE2           ADD      R2,SP,#+4
   \   0000009C   1C10A0E3           MOV      R1,#+28
   \   000000A0   0A00A0E3           MOV      R0,#+10
   \   000000A4   ........           BL       _Z11lcd_put_strttPhjj
    122                  goto m4;
   \   000000A8   DEFFFFEA           B        ??CameraTest_0
   \                     ??CameraTest_5:
   \   000000AC   800015E3           TST      R5,#0x80
   \   000000B0   0600000A           BEQ      ??CameraTest_6
   \   000000B4   FF7017E2           ANDS     R7,R7,#0xFF     ;; Zero extend
   \   000000B8   000057E3           CMP      R7,#+0
   \   000000BC   0500000A           BEQ      ??CameraTest_7
   \   000000C0   016096E2           ADDS     R6,R6,#+1
   \   000000C4   0000A0E3           MOV      R0,#+0
   \   000000C8   0070B0E1           MOVS     R7,R0
   \   000000CC   010000EA           B        ??CameraTest_7
   \                     ??CameraTest_6:
   \   000000D0   0100A0E3           MOV      R0,#+1
   \   000000D4   0070B0E1           MOVS     R7,R0
   \                     ??CameraTest_7:
   \   000000D8   E1FFFFEA           B        ??CameraTest_3
   \   000000DC                      REQUIRE _A_FIO2PIN
    123              }
Rst7
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 и длительность нуля огласите пожалуйста.
Prinz
Цитата(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 }
Rst7
QUOTE
Я его пробовал, он почему-то хуже работает.
Может с иаром проблема.


Покажите пожалуйста, какой код Вы пробовали. Ибо Ваш код - ересь полная. И еще раз спрашиваю - огласите точные параметры стробов данных.
Prinz
Цитата(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);
    }  
  }
//----------------------------------------------------------------
Rst7
QUOTE
Я бы не писал это ересь, если бы она не работала ровно в два раза быстрее Вашего, который вы мне привели в ссобщении 28.


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

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


Ага. Особенно доставляет FlagReady. Просто плакать хочется.
Prinz
Цитата(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, но проконсультировавшись со специалистом и проделав пару практических задачь делаю вывод, что это не особо поможет.
Буду другой камушик изучать.
Спасибо за помощь.
Rst7
Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать.
Prinz
Цитата(Rst7 @ Apr 20 2011, 13:58) *
Вы бы все-таки огласили параметры тактового сигнала, а? Тогда можно построить читалку, которая наверняка будет успевать.


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

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


Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас).
Prinz
Цитата(Rst7 @ Apr 20 2011, 16:25) *
Это я и так понимаю. А временные параметры? Прикрепите для простоты даташит на Вашу камеру (или что там у Вас).


Пожалуйста:
Flexz
А обязательно по PCLK синхронизироваться каждый раз? он же стабильный и кратный частоте проца.
Достаточно один раз поймать фронт HSYNC и молотить данные с порта пока они не кончатся, что-то вроде:
Код
while(hsync)
{
*d++=v;
}

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

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


Как вариант, но я планирую в дальнейшем менять динамически частоту PCLK.
Правда не очень симпатишный вариант.
Rst7
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.
Prinz
Цитата(Rst7 @ Apr 20 2011, 18:27) *
.


1) Что-то мой иар не знает __delay_cycles для этого контроллера. Хотя я точно применял эту функцию для avr много раз. Что-то надо подключить?
2) Я не очень знаком с асмом LPC, точнее я на нём ещё вообще не разу не писал. помогите пожалуйста с ним.
3) Это понятно.

Хотя, если честно, мне такая идея не очень нравится.
А если камеру поменять, а если ещё что-нибудь? Получается устройство очень жёстко привязоно к этой камере.
Гораздо лучше, когда точно тактируются фронты.
Rst7
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.
Prinz
Накатал кодик:

Код
__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
QUOTE
Оцените, пожалуйста.


Ересь какая-то. У Вас чем камера тактируется? Процессором? Или совершенно отдельной частотой?
Prinz
Цитата(Rst7 @ Apr 21 2011, 16:09) *
Ересь какая-то. У Вас чем камера тактируется? Процессором? Или совершенно отдельной частотой?


Отдельно. А что нельзя, в начале один раз затактировать, а дальше задержками считать всю строку?
Rst7
QUOTE
А что нельзя, в начале один раз затактировать, а дальше задержками считать всю строку?


Нельзя, если генератор отдельный. Нужен ФАПЧ. Посмотрите внимательно на последний код, который я Вам написал - там это реализовано.
Prinz
Цитата(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.
Как он может мне помочь?
Мне кто-то его уже советовал.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.