Вычитка данных из GRAM (ILI9486)

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Всем здравствуйте, не пинайте по голове, есть вопрос.

Я с AVR познакомился 15 декабря, еще много чего не понимаю и Си для меня пока еще тяжеловат.

Дошло ту дело до вычитки данных из GRAM и тут я застрял капитально (с выводом на экран разобрался и это работает хорошо). Если кто то делал вычитку - подскажите, где я ошибся?

Согласно даташиту драйвера, за вычитку отвечает команда 0x2eh.

Перед этим надо выставить координаты области экрана x,y,x1,y1 (типа активной области, с которой работаем, она выставляется прямо в экранных координатах)
Далее нужно вычитать dummy
И в общем читать из памяти, дергая RD ногой.
 
Именно так это и организовано в чьем-то драйвере:
#define read8(dst) { RD_ACTIVE; DELAY7; dst = (PIND & DMASK) | (PINB & BMASK); RD_IDLE; }

где, собственно, RD_ACTIVE это в моем случае ноль на 7-й ноге порта А, а RD_IDLE - единица. Между ними вычитка (в моем случае только PORTB без маски) и макрос DELAY7 (который мне пока что не очень понятен, я его от безнадеги уже просто спер из чужого кода):

#define DELAY7        \
  asm volatile(       \
    "rjmp .+0" "\n\t" \
    "rjmp .+0" "\n\t" \
    "rjmp .+0" "\n\t" \
    "nop"      "\n"   \
    ::);

Собственно мой тестовый код (корявенький, но я уже как только не пробовал), который пытается вычитать область памяти 8х16 с координат x=16, y=0 и тут разместить вычитанные данные по координатам x=320, y=0:

unsigned char block[255];
void ReadGRAM(){
    int a=255;            // счетчик байт

    Lcd_Write_Com(0x2e);        // засылка команды
    LCD_RS_HIGH();            // поднимаю после засылки команды
    LCD_CS_LOW();            // опускаем бит засылки команды
    Address_set(16,0,23,16);    // ставлю экранные координаты для вычитки
    LCD_RS_HIGH();            // поднимаю после установки экранных координат, так надо ))
    DDRB = 0;            // на всякий случай ноги в ноль на PORTB
    LCD_RD_LOW();            // вычитка dummy
    DELAY7;                // скопи-нный макрос (уже от безнадеги)
    LCD_RD_HIGH();            // поднимаю ногу
    while (a>0){             // тут цикл вычитки и набивки массива block[] вычитанными данными
        LCD_RD_LOW();
        DELAY7;
        block[a] = PINB;
        LCD_RD_HIGH();
        a--;
        LCD_RD_LOW();
        DELAY7;
        block[a] = PINB;
        LCD_RD_HIGH();
        a--;
        }
    LCD_CS_HIGH();            // поднимаем бит засылки команды

    DDRB = 255;            // порт В на запись
    Lcd_Write_Com(0x2c);         // дальше весь код полностью рабочий, рисует черный квадрат 8х16, а если без DELAY7 то лазурный
    LCD_RS_HIGH();            // с задержками, что бы смотреть как что рисуется
    LCD_CS_LOW();
    Address_set(320,0,327,16);
    LCD_RS_HIGH();
    a=255;
    while (a>0){
        PORTB = block[a];
        PORTF &= ~(1<<6);
        PORTF |= (1<<6);
        a--;
        PORTB = block[a];
        PORTF &= ~(1<<6);
        PORTF |= (1<<6);
        a--;
        Delay(65000);
        }
    LCD_CS_HIGH();
}

Просто уже и мыслей не осталось, кроме того как с CS я что то не так делаю (вот почему-то на него думаю).

 

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Забыл написать, что экран паралельный, 8-битная шина.

mixail844
Offline
Зарегистрирован: 30.04.2012

Другие команды чтения проходят успешно ? Например 

Read display identification information (04h)

или Read Display Self-Diagnostic Result (0Fh)

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

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

mixail844 пишет:

Другие команды чтения проходят успешно ? Например 

Read display identification information (04h)

или Read Display Self-Diagnostic Result (0Fh)

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

Спасибо что так неравнодушны ))

Точно разведен ) http://forum.amperka.ru/attachments/img_7272-jpg.15378/

Я просто не могу понять как им дрыгнуть так, что бы считалось. В даташите одно:

Но так не работает:

LCD_RD_LOW();
LCD_RD_HIGH();
block[a] = PINB;

в других драйверах код приблизительно такой:

		LCD_RD_LOW();
		Delay(1);
		block[a] = PINB;
		LCD_RD_HIGH();
		Delay(1);

Вся функция вычитки в буфер и заливки буфером:

unsigned char block[255];

void ReadGRAM(){
// READ
	int a=255;
	Address_set(16,0,23,16);
	LCD_RS_HIGH();
	Lcd_Write_Com(0x2e); //read_memory_start
	LCD_RS_HIGH();
	DDRB = 0;
//	PORTB=255; // for test
	LCD_CS_LOW(); 

	LCD_RD_LOW(); // read dummy
	Delay(1);
	LCD_RD_HIGH();
	Delay(1);

	LCD_RD_LOW();
	Delay(1);
	LCD_RD_HIGH();
	Delay(1); // end read dummy


	while (a>0){
		LCD_RD_LOW();
		Delay(1);
		block[a] = PINB;
		LCD_RD_HIGH();
		Delay(1);
		a--;
		}

// WRITE	
	DDRB = 255;
	Lcd_Write_Com(0x2c); //write_memory_start
	LCD_RS_HIGH();
	LCD_CS_LOW();
	Address_set(320,0,327,16);
	LCD_RS_HIGH();
	a=255;
	while (a>0){
		PORTB = block[a];
		PORTF &= ~(1<<6); //WR LOW
		PORTF |= (1<<6); //WR HIGH
		a--;
		Delay(6500); // Delay for test
		}
	LCD_CS_HIGH();
	
}

И у меня на третий день уже мысли кончились почти ))

 
3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

не, либо я читать не могу вообще, либо там не читается в принципе ((( вычитал dummy, вычитал первый параметр и он ноль, хотя должен быть ManufacturerID  

Справа черный квадрат - это должна была продублироваться буква s из слова Test (координаты 16,0) а там нули в итоге (0х00,0x00)...

Экран врядли глючит, поменял на другой - такая же картина Малевича. Скорее глючу я, не верится, что китайцы разведя RD ногу на плате, вырезали ее программно из оборота )) Например если поубирать Delay(1) из процесса - квадрат становится зеленым. Если поставить значение 1000-3000 то можно нахвататься помех и получить разноцветную кашу. 

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019
Есть одна мысль, но нужно экспертно ее оценить.
 
Смотрите, что надумалось:
1. у Atmega32u4 (Iskra Neo) на ноге 5в, эти 5в идут в экран по шине данных и шине управления.
2. в экране стоят две трехвольтовые микрухи LVC245A (на шину управления и на шину данных), что преобразуют 5в > 3.3в
3. это позволяет нормально писать в экран (заливать его данными по шине), так как 5в с микроконтроллера преобразуются LVC245A в нужные ему 3.3в и он прекрасно понимает и 1 и 0.
4. но попытка прочитать шину когда она с экрана получает только 3.3в (возможно и меньше)....
 
Возможно ли то, что микроконтроллер просто не может определить когда на шине 1 возникает? Поэтому я и читаю стабильно нули...
 
Сколько там на шине - я сегодня вечером измерю.
3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Вы были почти правы ))

 
микруха LVC245A дохлая. отдает 0,07в на ноги шины. При этом исправно получает с другой стороны положенные 0,7-3,3в (low/high). То есть конкретно этот китайский экран в принципе не выставляет данные на шине и МК оттуда читать просто нечего. Поэтому у меня и нули читаются из видеопамяти. До микрухи все в порядке, после - нули. Разобрался на 100%. Но мне не радостно ни разу.
Feofan
Offline
Зарегистрирован: 28.05.2017

На ноге /OE 0 или 1? И на DIR?

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Feofan пишет:

На ноге /OE 0 или 1?

На ОЕ 0,07в, наверное это ничего ))

на Vcc 3,3

На ногах со стороны экрана 0,07в-3,3в, я там задержку поставил при развороте шины (RD = 0, задержка, чтение, RD  =1, задержка) и так в цикле. Со стороны шины по всем восьми ногам 0в-0,07в. 

На DIR - 0в-5в

сейчас еще все промерил - на некоторых ногах в сторону шины таки есть 3,3в а на некоторых аж 5 вольт на HIGH, а на некоторых 0,07в на high и 0 на low

Feofan
Offline
Зарегистрирован: 28.05.2017

DIR определяет направление передачи, низкий на /OE - передача разрешена. На выходах должно что-то быть. Быть может действительно неисправна.

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Feofan пишет:

DIR определяет направление передачи, низкий на /OE - передача разрешена. На выходах должно что-то быть. Быть может действительно неисправна.

Вот что странно - на двух идентичных экранах одно и то же. Невозможно ничего вычитать из видеопамяти. Может они тупо отбраковку на али толкают? ))

Feofan
Offline
Зарегистрирован: 28.05.2017

Если правильно понимаю, то на /OE постоянно низкий, а на DIR телепается высокий/низкий?

От LVC245A в сторону МК микросхем более нет?

Логический анализатор есть?

3ABX03
3ABX03 аватар
Offline
Зарегистрирован: 18.01.2019

Feofan пишет:

Если правильно понимаю, то на /OE постоянно низкий, а на DIR телепается высокий/низкий?

Верно. На OE 0,07в постоянно, на DIR 0в-5в согласно задержкам в цикле  

Цитата:
От LVC245A в сторону МК микросхем более нет?

Нет, прямые дорожки к штырям.

Цитата:
Логический анализатор есть?

К сожалению нету. 

С другой стороны меня тут мысль посетила, если на некоторых ногах есть 3,3в в сторону МК, а на некоторых даже 5в возникает - то черного квадрата у меня быть не должно. То есть если я вычитываю положем 10110011 с шины (два раза на пиксель) то он однозначно черным не будет. 

Feofan
Offline
Зарегистрирован: 28.05.2017

Я бы попробовал поставить преобразователь уровня, между МК и дисплеем. Что-то типа такого:

https://ru.aliexpress.com/item/I2C-IIC-8-Channel-Logic-Level-Converter-Module-Bi-Directional-Module-For-Arduino-Step-Up-3/32816690842.html