Например TDA7294

 Форум РадиоКот • Просмотр темы - Выкроить 4 такта в коде прерывания надо
Форум РадиоКот
Здесь можно немножко помяукать :)



Текущее время: Вт апр 24, 2018 23:43:11



Часовой пояс: UTC + 3 часа [ Летнее время ]


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 10 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 13:36:08 
Встал на лапы
Аватар пользователя

Карма: 2
Зарегистрирован: Сб июл 18, 2009 22:38:43
Сообщений: 84
Рейтинг сообщения: 0
Продолжаю мучить http://www.vga-avr.narod.ru/main_rus.html
В проекте есть прерывание, в котором выполняется горизонтальная и вертикальная синхронизации, а также настройки указателей отрисовки.
Прерывание это нормировано по тактам, даже в ветвлениях if-ов нопами выровнено время выполнения. Я не знаю зачем автор так сделал, но если добавить хоть 1 nop в любое место, то вся синхронизация падает.
Проблема в том, что автор использует для выдачи сигналов синхронизации команды PORTD = 4; и PORTD = 0;
Что, естественно, приводит к невозможности использовать порт D для чего бы то ни было ещё.
Вторая проблема - PORTD = 4 на самом деле означает не только установку третьего бита, но и сброс второго. Третий бит это вертикальная синхронизация, второй - горизонтальная. И происходить эта операция должна одновременно.

Я пробовал менять на
PORTD |= (1<<3);
PORTD &= ~(1<<2);
Но всё тут же падает и из-за не одновременности вывода сигналов, и из-за возросшего времени выполнения.
Не помогает также и замена на ассемблерные cbi/sbi.

Единственный вариант, который мне видится, это

char temp;
temp = PORTD;
temp |= (1<<3);
temp &= ~(1<<2);
PORTD = temp;

Но даже
char temp;
temp = PORTD;
Уже приводит к искажению картинки из-за увеличившегося времени выполнения прерывания.

В общем, с этим надо что-то делать :(

Вот текст прерывания:
Код:
//Global definitions for VGA render
#define vga_field_line_count 525 //standart VGA quantity lines
#define vga_symbols_per_row 20   //symbols quantity per horizontal
#define vga_row_count 20         //symbols quantity per vertical
#define vga_symbol_height 24    //rendered symbol height
#define TIMER_LIMIT 0xC3         //set count, One VGA line 31.77us

//All VGA sincronize made here..
SIGNAL(SIG_OVERFLOW0) {

 TCNT0 = TIMER_LIMIT; //reload counter value   0xC3  //set count, One VGA line 31.77us
      //******Syncronization Handler********

         //Count number of lines
         if (++linecount == vga_field_line_count) {
            linecount = 0;
            //clear pointers for render display buffer
            raw_render = 0;
            y_line_render = 0;
         }

// Вертикальный и горизонтальный синхроимпульсы должны быть одновременно, поэтому дёргать битами порта раздельно по cbi/sbi не получится.
// кроме того, тело прерывания крайне чувствительно ко времени исполнения, и добавление любой команды сбивает синхронизацию.

         //Make Vsync length 2 VGA lines
         if ((linecount == 10 )||(linecount == 11 )) {
            //Make here vertical syncronization & HSYNC syncro level on
            PORTD = 0; //vsync_on
         } else    {
            //.. & HSYNC syncro level on
            PORTD = 4;// vsync_off
               
         
         }
      
         video_enable_flg = true;


         if (linecount < 45) {
            video_enable_flg = false;
               //Add to avoid flickering at top display
               NOP; // 15 nops
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               
         }  else  {
             //Forming current string for rendering
             if (++y_line_render == vga_symbol_height) {
              raw_render++;
              y_line_render = 0;
             } else {
               NOP; // 8 nops
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
             }
      
         }
      
         hsync_off; //HSYNC syncro level off sbi(PORTD,3)
      
      //******Syncronization Handler********
}


Ассемблер:

Код:
//All VGA sincronize made here..
SIGNAL(SIG_OVERFLOW0) {
     de4:   1f 92          push   r1
     de6:   0f 92          push   r0
     de8:   0f b6          in   r0, 0x3f   ; 63
     dea:   0f 92          push   r0
     dec:   11 24          eor   r1, r1
     dee:   2f 93          push   r18
     df0:   8f 93          push   r24
     df2:   9f 93          push   r25
//unsigned char port_buffer;

 TCNT0 = TIMER_LIMIT; //reload counter value
     df4:   83 ec          ldi   r24, 0xC3   ; 195
     df6:   82 bf          out   0x32, r24   ; 50
      //******Syncronization Handler********

         //Count number of lines
         if (++linecount == vga_field_line_count) {
     df8:   80 91 77 00    lds   r24, 0x0077
     dfc:   90 91 78 00    lds   r25, 0x0078
     e00:   01 96          adiw   r24, 0x01   ; 1
     e02:   90 93 78 00    sts   0x0078, r25
     e06:   80 93 77 00    sts   0x0077, r24
     e0a:   80 91 77 00    lds   r24, 0x0077
     e0e:   90 91 78 00    lds   r25, 0x0078
     e12:   8d 50          subi   r24, 0x0D   ; 13
     e14:   92 40          sbci   r25, 0x02   ; 2
     e16:   41 f4          brne   .+16        ; 0xe28 <__vector_11+0x44>
            linecount = 0;
     e18:   10 92 78 00    sts   0x0078, r1
     e1c:   10 92 77 00    sts   0x0077, r1
            //clear pointers for render display buffer
            raw_render = 0;
     e20:   10 92 73 03    sts   0x0373, r1
            y_line_render = 0;
     e24:   10 92 79 00    sts   0x0079, r1
// Вертикальный и горизонтальный синхроимпульсы должны быть одновременно, поэтому дёргать битами порта раздельно по cbi/sbi не получится.
// кроме того, тело прерывания крайне чувствительно ко времени исполнения, и добавление любой команды сбивает синхронизацию.
// я не смог победить этот глюк и использовал костыль с промежуточной переменной.

         //Make Vsync length 2 VGA lines
         if ((linecount == 10 )||(linecount == 11 )) {
     e28:   80 91 77 00    lds   r24, 0x0077
     e2c:   90 91 78 00    lds   r25, 0x0078
     e30:   0a 97          sbiw   r24, 0x0a   ; 10
     e32:   31 f0          breq   .+12        ; 0xe40 <__vector_11+0x5c>
     e34:   80 91 77 00    lds   r24, 0x0077
     e38:   90 91 78 00    lds   r25, 0x0078
     e3c:   0b 97          sbiw   r24, 0x0b   ; 11
     e3e:   11 f4          brne   .+4         ; 0xe44 <__vector_11+0x60>
            //Make here vertical syncronization & HSYNC syncro level on
            PORTD = 0; //vsync_on
     e40:   12 ba          out   0x12, r1   ; 18
     e42:   02 c0          rjmp   .+4         ; 0xe48 <__vector_11+0x64>
         } else    {
            //.. & HSYNC syncro level on
            PORTD = 4;// (PORTD | 0x04); //vsync_off
     e44:   84 e0          ldi   r24, 0x04   ; 4
     e46:   82 bb          out   0x12, r24   ; 18
               
         
         }
      
         video_enable_flg = true;
     e48:   81 e0          ldi   r24, 0x01   ; 1
     e4a:   80 93 74 03    sts   0x0374, r24


         if (linecount < 45) {
     e4e:   80 91 77 00    lds   r24, 0x0077
     e52:   90 91 78 00    lds   r25, 0x0078
     e56:   8d 97          sbiw   r24, 0x2d   ; 45
     e58:   90 f4          brcc   .+36        ; 0xe7e <__vector_11+0x9a>
            video_enable_flg = false;
     e5a:   10 92 74 03    sts   0x0374, r1
   ...
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
               NOP;
     e7a:   00 00          nop
     e7c:   19 c0          rjmp   .+50        ; 0xeb0 <__vector_11+0xcc>
               
         }  else  {
             //Forming current string for rendering
             if (++y_line_render == vga_symbol_height) {
     e7e:   80 91 79 00    lds   r24, 0x0079
     e82:   8f 5f          subi   r24, 0xFF   ; 255
     e84:   80 93 79 00    sts   0x0079, r24
     e88:   80 91 79 00    lds   r24, 0x0079
     e8c:   88 31          cpi   r24, 0x18   ; 24
     e8e:   41 f4          brne   .+16        ; 0xea0 <__vector_11+0xbc>
              raw_render++;
     e90:   80 91 73 03    lds   r24, 0x0373
     e94:   8f 5f          subi   r24, 0xFF   ; 255
     e96:   80 93 73 03    sts   0x0373, r24
              y_line_render = 0;
     e9a:   10 92 79 00    sts   0x0079, r1
     e9e:   08 c0          rjmp   .+16        ; 0xeb0 <__vector_11+0xcc>
   ...
               NOP;
             }
      
         }
      
         hsync_off; //HSYNC syncro level off sbi(PORTD,3)
     eb0:   93 9a          sbi   0x12, 3   ; 18
      
      //******Syncronization Handler********

}
     eb2:   9f 91          pop   r25
     eb4:   8f 91          pop   r24
     eb6:   2f 91          pop   r18
     eb8:   0f 90          pop   r0
     eba:   0f be          out   0x3f, r0   ; 63
     ebc:   0f 90          pop   r0
     ebe:   1f 90          pop   r1
     ec0:   18 95          reti

00000ec2 <display_Mega>:


Последний раз редактировалось Dikoy Ср апр 04, 2018 14:03:27, всего редактировалось 1 раз.

Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 2 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 13:54:12 
Говорящий с текстолитом
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1690
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
попробуй буфер - заполняешь его раньше (возможно много раньше, даже может в прошлой итерации прерывания, после всех кодов) а здесь только пуляй его в порт

_________________
Не пойму то ли это киберпанк, то ли на столе банальный срач...


Вернуться наверх
 Профиль  
 
JLCPCB Prototype, Бесплатная доставка первого заказа + $2 на прототип ПП!

Крупнейший производитель печатных плат в Китае, 290,000+ заказчиков, 8,000+ он-лайн заказов в день.

Цена за 10 плат: $2 за 2-х слойную, $15 за 4-х слойную, $74 за 6-ти слойную.

LCSC Parts: Экономия до 50%, большой выбор компонентов в наличии, отправка заказа в день оплаты.

Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 14:11:02 
Встал на лапы
Аватар пользователя

Карма: 2
Зарегистрирован: Сб июл 18, 2009 22:38:43
Сообщений: 84
Рейтинг сообщения: 0
Так было бы место где заполнять...
Я уже думал, что if (linecount < 45) с его нопами можно использовать для
if ((linecount == 10 )||(linecount == 11 )) {
//Make here vertical syncronization & HSYNC syncro level on
PORTD = 0; //vsync_on
} else {
//.. & HSYNC syncro level on
PORTD = 4;// vsync_off

Ибо 10 и 11 меньше 45... Но ещё не опробовал.


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 14:49:24 
Говорящий с текстолитом
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1690
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
эту часть
Код:
//Make Vsync length 2 VGA lines
         if ((linecount == 10 )||(linecount == 11 )) {
            //Make here vertical syncronization & HSYNC syncro level on
            PORTD = 0; //vsync_on
         } else    {
            //.. & HSYNC syncro level on
            PORTD = 4;// vsync_off
               
         
         }
написать так
Код:
//Make Vsync length 2 VGA lines
        PORTD = tempD;
        if ((linecount == 9 )||(linecount == 10 )) {
            //Make here vertical syncronization & HSYNC syncro level on
            tempD = 0; //vsync_on
         } else    {
            //.. & HSYNC syncro level on
            tempD = 4;// vsync_off
               
         
         }


Добавлено after 31 minute 24 seconds:
может прокатит, а может и нет...

_________________
Не пойму то ли это киберпанк, то ли на столе банальный срач...


Вернуться наверх
 Профиль  
 

Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 15:42:19 
Модератор
Аватар пользователя

Карма: 68
Зарегистрирован: Пт мар 19, 2010 00:09:57
Сообщений: 3749
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Цитата:
И происходить эта операция должна одновременно.
Про "одновременно" можно подробнее ?
А если бит, который нужно сбросить "одновременно" с установкой другого, уже до этого момента сброшен ? Это уже считается неодновременность ? И уже, априори, будет какой-то там глюк (не вникал в подробности) ? Или как ?

_________________
Я мненью вашему вращенье придавал, а осью был - мой детородный орган.


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 17:13:28 
Говорящий с текстолитом
Аватар пользователя

Карма: 13
Зарегистрирован: Пт ноя 11, 2016 06:48:09
Сообщений: 1690
Откуда: край интернета... самый край :(
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
я так понял - в середине экрана стрка кончается - приходит импульс строчной синхронизации, а кадровой как небыло, так и нет, а когда меняется кадр приходят обе, но одна из них инверсная, поэтому вариант с и/или не прокатит как и побитовые операции.
как вариант - либо внешняя обвязка либо внутренняя подстановочная маска, к стати - это мысль! вместо 4 или 0 вписывать туда темп,или даже темп4 и темп0 нужные для синхронизации биты которых не трогать в основной программе, а остальные - в любом месте (не в прерывании) менять на своё усмотрение, правда с портом они будут синхронизироваться вместе с развёрткой, но, на них можно возложить задачу, позволяющую такое обращение.

_________________
Не пойму то ли это киберпанк, то ли на столе банальный срач...


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 18:22:57 
Друг Кота
Аватар пользователя

Карма: 76
Зарегистрирован: Вт мар 16, 2010 23:02:27
Сообщений: 7472
Откуда: ДОНЕЦК (ЮГО-ВОСТОК ua/DPR)
Рейтинг сообщения: 0
Можно попробовать таблично под ассемблером отработать - тот алгоритм, что я для программной ШИМ-манипуляции под WS2812 сделал.
С использованием команд косвенных переходов/вызовов подпрограмм (ICALL/IJMP) сразу по входу в прерывание.
А у каждой комбинации "база + смещение", находящейся в Z на момент прихода вызова прерывания указан адрес соответствующего фрагмента к исполнению.
У Си еще собственно загрузка/сброс стека, которую компилятор добавит (согласно своего разумения) - это может быть и весьма большой кусманчик кода (PUSH/POP)...


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 18:41:59 
Модератор
Аватар пользователя

Карма: 68
Зарегистрирован: Пт мар 19, 2010 00:09:57
Сообщений: 3749
Откуда: Планета Земля
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Продолжаю мучить http://www.vga-avr.narod.ru/main_rus.html
Это шутка какая то ?
По ссылке :
Изображение
Жму "Отмена" и опачки :
Изображение

:twisted:

_________________
Я мненью вашему вращенье придавал, а осью был - мой детородный орган.


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Ср апр 04, 2018 19:17:59 
Первый раз сказал Мяу!

Карма: 3
Зарегистрирован: Пт мар 07, 2014 19:37:20
Сообщений: 22
Откуда: Пермь
Рейтинг сообщения: 0
Hsync я формировал таймером в режиме ШИМ, сразу и импульс на выводе есть. Перед синхроимпульсом процессор надо укладывать спать, что бы не было дрожания изображения.


Вернуться наверх
 Профиль  
 
Не в сети
 Заголовок сообщения: Re: Выкроить 4 такта в коде прерывания надо
СообщениеДобавлено: Пт апр 06, 2018 02:52:03 
Встал на лапы
Аватар пользователя

Карма: 2
Зарегистрирован: Сб июл 18, 2009 22:38:43
Сообщений: 84
Рейтинг сообщения: 3
Победил, подробности тут https://electronix.ru/forum/index.php?s ... &p=1554994
Требования к одновременности оказались не таким жёсткими, а вот такты считать пришлось, да...

Добавлено after 4 minutes 15 seconds:
Кстати, оттуда же, я этого не знал:

"Может Вам пригодится...
Для многих АВРок есть возможность тоглить (инвертировать) состояние GPIO путём записи в регистр PINx." https://electronix.ru/forum/index.php?s ... &p=1555011

Добавлено after 2 minutes 13 seconds:
Жму "Отмена" и опачки :


Изображение


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 10 ] 



Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y