Обладатели шилда с выводом управляющих пинов на 38 контактный разъем. предлагаю попрбововать следующие действия. В тексте скетча дефайним ноги RS, CS итд.
#define LCD_CS 40 // Chip Select goes to digit 40
#define LCD_CD 38 // Command/Data goes to digit 38
#define LCD_WR 39 // LCD Write goes to digit 39
#define LCD_RD A0 // LCD Read goes to Analog 0
#define LCD_RESET 41 // Can alternately just connect to Arduino's reset pin№
Так как пин RD не выведен на разъем переопределять его бесполезно.
Далее принудительно определяем идентификатор контроллера, инициализируем и пишем, например команду заливки экрана цветом.
Используем библиотеку Adafruit С новым pin_magic.h. Надеюсь что Data порт находится на пинах порта PORTA PA0 - PA7, иначе придется еще думать о редактировании выводов порта Data. Ссылки на библиотеку и файл pin_magic в предыдущих постах. Инклюдить pin_magic надо в файле Adafruit_TFTLCD.ccp. коммментируем строки
#if defined __AVR_ATmega328P__
#include "pin_magic_UNO.h"
#endif
#if defined __AVR_ATmega2560__
#include "pin_magic_MEGA.h"
#endif
Уважаемые коллеги. Подскажите какие пины дёргать, чтобы подключить micro SD карту? Сборки по 1кОм запаял кое-как. Экран работает, но хочу подключить через шлейф и развести датчики на макетной плате, т. к. нужны остальные порты.
Если у кого есть распиновка, то скиньте, пожалуйста.
Как совместить sd_in, sd_out и пины miso, mosi? Какие требования к картам? У меня 16 Гб и форматированная в FAT32.
Плата такая, но изображение не моё (из поста 402):
В общем как подключить через шлейф SD карту на этом шилде?
Varg, когда перепаивал себе резисторные сборки, то были места на них с коротким замыканием (паяльник с жалом как сама сборка + сорвал пару дорожек без опыта пайки таких элементов). При загрузке скетча тоже экран делился на две неравные части, только показвал в одной части белое поле, а другая немного другого белого оттенка. Если у вас такая же ситуация, то может где-то непропай или коротит. У меня было 2-3 места корочения.
И у меня такой на на фотках выше дисплей, с таким же поведением.
Программа LCD_ID_Reader выдала
Initializing LCD...
Reading ID...0x0404
Так это "новое слово" в китайской технике. В отзывах на алиэкспресс пишут различные строки инициализации. У меня получается только 2 варианта: или как на предыдущих фотках или белый экран. Похоже китайцы распродав одну партию дисплеев, покупают другую один-в-один похожую, но с другим контроллером. Или в гараже на красную печатную плату лепят новый экран.
По поводу резисторных сборок - все проверил, все работает. Предполагаю, китайцы начали ставить некие аналоги R61581, под которые нужно править стандартную библиотеку... Написал продавцу об этой проблеме, он выслал дистрибутив ардуины первой версии и какую-то модифицированную UTFT. Но с ней только белый экран получается..
"Чтобы использовать этот экран с библиотекой UTFT нужно выбрать драйвер ILI9486. " Вы этот вариант пробовали? Человек же пишет, что там стоит не R61581. А китайцам фиолетово заморачиваться, с соответствием, один раз написанного и реальным товаром, который они в данный момент продают. В этой теме несколько раз описаны случаи, что даже после списывания с китайцем, китаец присылает совсем другой товар. Не хотите рисковать, для этого есть адафруит и им подобные, дороже в разы, но и косяков с разносортицей не будет. Что купите, то и получите.
Прислал и мне китаец пример для ардуины. Цвета стали лучше, но всё равно только полэкрана правильно отображает и символы не читаемы. Может у кого заработает.
Покупать шилды без выведенного сигнала RD, это жопа. Без этого вывода не жизнь. Ни тебе сигнатуру чипа определить, ни тебе нормально с регистрами поработать. Вообщем кастрированные чипы сплошной гемр!!!
Да, все варианты перепробовал, результат либо белый экран, либо то что на фото выше. Конкретно с ILI9486 имеем белый экран и несколько чуть заметных разноцветных линий. По поводу фирмовых модулей согласен. До этого покупал пару китайских - все было в порядке. От одного пришлось отказаться потому как он для UNO, памяти не хватило. Другой тоже для меги, но работал с простейшей библиотекой, для моих целей ее было не достаточно.
naturalist
Попробовал Ваши библиотеки, результат тот же, только ориентация дисплея изменилась на вертикальную.
Повнимательней изучил изображение выложенные вами. Обратил внимание, что все надписи зеркальны. Сталкнулся с таким когда по ошибке инициализировал ili9327 как ili9341 была примерно такаяже бодяга, может там установлен ili9327?. Если бы был выведен пин RD на разъем, решить проблемму былобы проще. Я вообще покупаю дисплеи с тачем и сам делаю шилды, так мне проще и я точно знаю что и куда подключать и как инициализировать.
Вскрытие показало: экран имеет шлейф с 39 пинами. При прозвонке линий 38-42 от разъема меги до щлейфа стоят резисторные сборки.
№ на MEGA/резисторная сборка/№ шлейфе дисплея
38 / RP3 pin4 / 34
39 / RP7 pin1 / 33
40 / RP3 pin3 / 35
41 / RP7 pin2 / 12
42 / RP3 pin2 / а дальше дорожи нет и не было.
Нет выхода на шлейф у ножек меги 22(DB8), 27 (DB13), 36(DB1), 43.
Как в этой теме обсуждалось RD на шилд не выведен. По надписи на шлейфе (там ноль в названии) )легко находится море предложений о продаже. И даже известен телефон - Banghua BOWAY U1 waveguide 9105, Banghua u1 Hedy H702 / T700 waveguide 9105.
Меня посетила почти крамольная мысль, а может этот шилд надо подключать через переходную плату. Посмотрите распиновку, тогда не совсем понятно зачем согласующие резисторы.
начните с простого, прозвоните как выводы дисплея доходят через 10к резисторы на разъем. мож где затерялись или на рядом идущие замкнули. точность питания дисплея +3,30в на его шлейфе. Это всё вы ранее проверяли?Если какие выводы затерялись, то заведите их.
потом уже копаться серьезней. вывод RD похоже на 32pin дисплея, но лучше погуглить tft lcd 39pin и глянуть картинки, можно и с 37pin подсмотреть аналогии. Через резистор 10к закинуть на вывод ардуинки (возможно он подключён на 3,3в - разорвать эту цепь). . Т.к. дисплей скорее всего активирован на 16бит, в любом случае можно написать простенький скетч дерганья управляющими пинами и вывода ID дисплея в сериал порт . ибо чем считываете у адафруита - в основном это для 8 бит, вот и получаете повторение типа 0404. и глянуть пдф возможных претендентов, ибо не у всех ID храниться в нулевом регистре. У R61509V явно по нулевому адресу 00h , а в несколько дерганий RD у ILI9488 и ILI9486 " device code " по D3h адресу, у ILI9327 по EFh адресу , у R61581 - по BFh. Читалка ID от адафруита это не панацея, она заточена распознать их шилды, а не все подряд, и в основном только по адресу 00h. Если есть время , можете написать универсальную, для большинства контроллеров дисплеев на мегу.
п.с. 2пин дисплея похож на IM.. для перевода его в режим 8/16 бит или 18бит. Схемы шилдов вроде тут уже давались. разрисуйте как у вас. можно еще на taobao.com поискать похожие шилды, там продавцы иногда приводят распиновку дисплеев , схемы шилдов и простенькие тесты с инициализациями.
Прозвонил все дорожки от резисторных сборок. Извиняюсь - ввёл в заюлуждение, недосмотрел. Все 16 проводов шины данных меги имеют подключение к дисплею и в последовательном по старшинству бит порядке. Нет продолжения у 42(rd) и 43. Открыл вчера на али диспут на полную стоимость экрана, сегодня продавец согласился.
Есть альтернативный вариант подбору библиотек к дисплею. Купить дисплей/модуль/устройство с известным и не модифицируемым каждый год экраном. Лежит у меня видео-дисплей - 4.3 inch car rear monitor. Замечательно подходит для домофона. Картинки есть в статье http://www.eevblog.com/forum/reviews/mini-teardown-5%27-hd-800x480px-car.... В самом экране стоит чип OTA5180A с 40пиновым разъемом и RGB интерфейсом (3х8=24 линии). К нему подключена плата видеодекодера на AMT630. Цена с доставкой от 13 зеленых. Схема стабильная и нет причин её совершенствовать. Бывают и готовые ардуино модули с этим же дисплеем и контроллером ssd1963 на плате, но стоят от 20.
Готовых решений я в интернете не нашел.
Ничего не мешает использовать библиотеку TV out. Доработать. Через переходник подключить мегу к экрану напрямую. Если взять 3 линии, то будет 8 цветов. Вполне достаточно для простых применений.
Вопрос - потянет ли мега? На экран надо постоянно подавать сигнал CLK и саму картинку с частотой 1 МГц.
Так же интересует, какой удобный ( в плане работы с ним библиотека, подключение и сами команды и вывод картинки)дисплей с тач - скрином и без тач скрина, размером не менее 3,2 дюйма, и что бы он мог работать и с ардуино УНО и с Адуино 2560? Или дисплей который я нашёл в ссылке это самый оптимальный и можно как я понимаю его и без тача использовать и с тачем?
Работать будет. Только При повороте изображения надо учитывать смещение в 80 пикселей. Контроллер расчитан на работу с экраном 480х320 и нет возможности изменить резрешение на уровне железа. Я подобный запускал. Да и с поключением тача повозиться пришлось, перекинуть ноги в программе. А так прилично работает. Что касается библиотеки, то они по сути все взаимозаменяемы. Основным критерием является дамп инициализации и описание протокола обмена с индикатором. Берем любую библиотеку, даташит по контроллеру, описываем протоколл обмена, используя переменные передаваемые в функции библиотеки и вперед. Я так перенес с AVR на ARM библиотеку Adafruit и UTouch, скрестил их и получил набор функций необходимых для моего проекта. Понимая как работает контроллер TFT можно и свои функции добавлять.
При развороте, это вертикально если его использовать или горизонтально? Во вторых есть ли какой - нить дисплей что бы и с ардуиной 2560, и с УНО можно было работать без смещения пикселей? И такой кто - то использовал:
http://forum.cxem.net/index.php?showtopic=151543&hl= Как он вообще, на вид программируется как сенсорная панель промышленного контроллера Сименс, я так думаю и на УНО он пойдёт и на 2560, вот только где его купить не могу найти что - то.
Работать будет. Только При повороте изображения надо учитывать смещение в 80 пикселей. Контроллер расчитан на работу с экраном 480х320 и нет возможности изменить резрешение на уровне железа.....
Да тож одно решение такое было.
1й способ здесь описал, в файле setxy библиотеки UTFT добавил к координате +32 (дисплей был на 400 точек, а контроллер на 432точки)
2м способом для другого контроллера помогло установка в регистрах размеров матрицы и переворачивание.
3м способом для третьего вида контроллера в самом скетче, в функциях UTFT просто к координате дописывал +80. а так что только не делал. и разрешение менял (были спец регистры в контроллере для выбора под разные матрицы, и зеркалировал и переворачивал - нифига, в других контроллерах помагало, здесь нет. видимо матрицу развели не под этот контроллер. решилось тож именно только +80.)
После запуска обнаружилось зеркальное отображение, для победы пришлось заменить содержание файла initlcd.h в папке C:\Documents and Settings\.........\Мои документы\Arduino\libraries\UTFT\tft_drivers\ili9481
Тест провести можете используя функцию millis(). Важно понимать что скорость отрисовк будет одинакова для всего ряда контроллеров + конкретное разрешение, т.к. эта скорость обусловлена скоростью обработки алгоритма процессором AVR, а не быстродействием контроллера индикатора. Чем боьше разрешение, а следовательно количество пикселей, тем дольше отрисовка фрейма (экрана). К сожилению все библиотеки пиксельные, для ардуино не встречал векторных.
Ваш модуль наверное с ибея. Есть там продавец robothome. А изготовитель модуля: shanYan. И на одной из фоток на ибее на плате прилеплена бирка "9486". Хотя китайцы они такие выдумщики ...
UTouch работает обсолютно нормально. Я даже переделал ее для работы с stm32. Без калибровки работает даже на разрешении 480х320, правда остаются поля по 10 - 25 пикселей по бордюру.
Подключил к ARDUINO MEGA2560 напрямую, по следующей схеме:
..........
Напрямую такой шилд нельзя подключать, там не видать ни резисторов 10ком , ни преобразователей уровней. На эти контроллеры при питании 3,3в нельзя подавать мощные логические уровни выше 3,3в , а у меги они 5в.
максимальное критичное напряжение по питанию для этого контроллера 4,6в, но лучше не доводить его до этого. Питание должно быть не выше 3,3в и уровни управляющих сигналов 3,3в (если через резисторы, то лишнее оседает на них, благодаря внутренним диодам в контроллере, которые лишнее напряжение ограничивают на его питание.
13.2. DC Characteristics
Parameter Symbol Condition Min. Typ. Max.
Analog Power Supply Voltage VCI Analog Operation Voltage 2.5 2.8 3.3 V
I/O pin Power Supply Voltage IOVCC I/O pin Operation Voltage 1.65 2.8 3.3 V
Logic High level input voltage VIH IOVCC = 1.65V ~ 3.3V 0.7*IOVCC - IOVCC V ........
Вот засада, для работы TFT с динамическими изображениями надо использовать или панель без контролера, или проц ГГЦа этак на 1,5 - 2. Иначе видно лаги, неуспевает записать в ОЗУ TFT проц фрэйм. Есть правда еще идея использовать SDRAM -> DMA -> TFT. может выйграю пару мгновений у электронов ;-)
Все просто и красиво, но не работает. Функции вызываю - ничего не происходит.
2. В даташите на ili9488 расписаны функции чтения/записи неких CTRL Display value, там речь идет и о Backlight Control.
Что написано - как бы понимаю, как этим воспользоваться - совсем не понимаю.
3. На avrfreaks.net нашел файлы, где расписывается управление подсветкой
/**
* \file
*
* \brief ILI9488 Display Controller Component Driver
*
* Copyright (c) 2012-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#ifndef ILI9488_H_INCLUDED
#define ILI9488_H_INCLUDED
#include <ioport.h>
#include <compiler.h>
/* Controller and interface configuration file */
#include "conf_ili9488.h"
#if defined(CONF_ILI9488_USART_SPI)
# include <usart_spi.h>
#elif defined(CONF_ILI9488_SPI)
# include <spi_master.h>
#elif defined(CONF_ILI9488_EBI)
# include <smc.h>
# include <pmc.h>
#else
# error "Interface not supported by the component driver"
#endif
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup ili9488_group ILI9488 Display Controller Component Driver
*
* See \ref common_ili9488_qs
*
* This is the low level component driver for the ILI9488 display controller.
* It provides basic functions for initializing, writing and reading the
* controller. In addition to hardware control and use of the LCD controller
* internal functions.
*
* \warning This component driver is not reentrant and can not be used in
* interrupt service routines without extra care.
*
* Before writing data to the display call \ref ili9488_init() which will set up
* the physical interface and the display. A configuration file conf_ili9488.h
* is needed to define which interface to use, pin connections and communication
* speed.
*
* An example conf_ili9488.h file for the XMEGA could look like:
* \code
* #define CONF_ILI9488_USART_SPI &USARTC0
* #define CONF_ILI9488_CLOCK_SPEED 8000000UL
*
* #define CONF_ILI9488_CS_PIN IOPORT_CREATE_PIN(PORTC, 5)
* #define CONF_ILI9488_DC_PIN IOPORT_CREATE_PIN(PORTC, 4)
* #define CONF_ILI9488_BACKLIGHT_PIN IOPORT_CREATE_PIN(PORTA, 5)
* #define CONF_ILI9488_RESET_PIN IOPORT_CREATE_PIN(PORTA, 7)
* \endcode
*
* \section dependencies Dependencies
* This component driver depends on the following modules:
* - \ref gpio_group for IO port control.
* - \ref sysclk_group for clock speed and functions.
* - \ref usart_spi_group or \ref spi_group for communication with the
* controller.
* @{
*/
/** This macro generates a 16-bit native color for the display from a
* 24-bit RGB value.
*/
#define ILI9488_COLOR(r, g, b)\
Swap16((((uint16_t)b) >> 3) |\
((((uint16_t)g) << 3) & 0x07E0) |\
((((uint16_t)r) << 8) & 0xf800))
/** Type define for an integer type large enough to store a pixel color. */
typedef uint16_t ili9488_color_t;
/** Type define for an integer type large enough to store a pixel coordinate.
*/
typedef int16_t ili9488_coord_t;
/**
* \name Display orientation flags
* @{
*/
/** Bit mask for flipping X for ili9488_set_orientation() */
#define ILI9488_FLIP_X 1
/** Bit mask for flipping Y for ili9488_set_orientation() */
#define ILI9488_FLIP_Y 2
/** Bit mask for swapping X and Y for ili9488_set_orientation() */
#define ILI9488_SWITCH_XY 4
/** @} */
/** Height of display using default orientation */
#define ILI9488_DEFAULT_HEIGHT 320
/** Width of display using default orientation */
#define ILI9488_DEFAULT_WIDTH 480
/** Height of display using swapped X/Y orientation */
#define ILI9488_SWITCH_XY_HEIGHT 480
/** Width of display using swapped X/Y orientation */
#define ILI9488_SWITCH_XY_WIDTH 320
/**
* \name Controller primitive graphical functions
* @{
*/
ili9488_color_t ili9488_read_gram(void);
void ili9488_write_gram(ili9488_color_t color);
void ili9488_set_top_left_limit(ili9488_coord_t x, ili9488_coord_t y);
void ili9488_set_bottom_right_limit(ili9488_coord_t x, ili9488_coord_t y);
void ili9488_set_limits(ili9488_coord_t start_x, ili9488_coord_t start_y,
ili9488_coord_t end_x, ili9488_coord_t end_y);
void ili9488_set_orientation(uint8_t flags);
void ili9488_copy_pixels_to_screen(const ili9488_color_t *pixels,
uint32_t count);
#if XMEGA
void ili9488_copy_progmem_pixels_to_screen(
ili9488_color_t PROGMEM_PTR_T pixels, uint32_t count);
#endif
void ili9488_copy_pixels_from_screen(ili9488_color_t *pixels, uint32_t count);
void ili9488_duplicate_pixel(const ili9488_color_t color, uint32_t count);
/** @} */
/**
* \name Controller and display initialization and management
* @{
*/
void ili9488_init(void);
/**
* \brief Function to turn on the display back light
*
* Use this function to simply set the pin controlling the back light high to
* turn on the back light.
*
* \note It is up to the user application if other means of controlling this pin
* should be used, e.g. a PWM signal to be able to dim the display.
*/
static inline void ili9488_backlight_on(void)
{
ioport_set_pin_level(CONF_ILI9488_BACKLIGHT_PIN, true);
}
/**
* \brief Function to turn off the display back light
*
* Use this function to simply set the pin controlling the back light low to
* turn off the back light.
*/
static inline void ili9488_backlight_off(void)
{
ioport_set_pin_level(CONF_ILI9488_BACKLIGHT_PIN, false);
}
/** @} */
/** @} */
/**
* \page common_ili9488_qs Quick Start Guide for the ILI9488 Display Controller Component Driver
*
* This is the quick start guide for the \ref ili9488_group, with step-by-step
* instructions on how to configure and use the component driver for specific
* use cases.
*
* The section described below can be compiled into e.g. the main application
* loop or any other function that will need to interface non-volatile memory.
*
* \section common_ili9488_qs_basic Basic usage of the ILI9488 component driver
* This section will present one use cases of the ILI9488 component driver. It
* will first turn on the backlight and then fill the screen with a solid
* color.
*
* \section common_ili9488_qs_basic_case Use case 1: Fill Screen Color
*
* The ILI9488 component driver contains a basic backlight control as well as
* functions to draw pixels of various colors within a given pixel boundary.
* This use case will turn on the backlight and fill the entire display with a
* single color.
*
* \section common_ili9488_qs_basic_case_prereq Prerequisites
* The conf_ili9488.h configuration file must be present in your application,
* and should be set to use the correct SPI interface of your chosen
* microcontroller.
*
* Your application should configure the display SPI, reset, command/data and
* backlight pins as appropriate. If you are using the maXTouch Xplained Pro
* kit this can be achieved by defining:
* \code
* #define CONF_BOARD_MAXTOUCH_XPLAINED_PRO
* \endcode
* in your conf_board.h header file.
*
* \section common_ili9488_qs_basic_case_setup Setup
*
* \subsection common_ili9488_qs_basic_case_setup_steps Code
* \code
* ili9488_init();
* ili9488_backlight_on();
* \endcode
*
* \subsection common_ili9488_qs_basic_case_setup_workflow Workflow
* -# First, we must initialize the display so that it is correctly configured
* and ready to receive commands:
* \code
* ili9488_init();
* \endcode
* -# Next, the display backlight is enabled, turning it on:
* \code
* ili9488_backlight_on();
* \endcode
*
* \section common_ili9488_qs_basic_case_example_code Example code
*
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(240, 320);
*
* ili9488_duplicate_pixel(ILI9488_COLOR(255, 0, 0), 240UL * 320UL);
* \endcode
*
* \subsection common_ili9488_qs_basic_case_workflow Workflow
*
* -# First the screen drawing limits are set to start from the upper-left
* pixel coordinate, and end at the lower right screen boundary:
* - \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(240, 320);
* \endcode
* \note If both the top-left and bottom-right limits are to be set at the
* same time, it is faster to call \ref ili9488_set_limits() instead.
* -# Next, the display is filled with 240*320 (the screen's pixel dimensions)
* pixels of the same RGB color of (255, 0, 0), a bright red.
* - \code
* ili9488_duplicate_pixel(ILI9488_COLOR(255, 0, 0), 240UL * 320UL);
* \endcode
* \note You must encode the RGB color value to use in the display's native
* pixel color format using the \ref ILI9488_COLOR() macro.
*/
#ifdef __cplusplus
}
#endif
#endif /* ILI9488_H_INCLUDED */
и
/**
* \file
*
* \brief ILI9488 display controller component driver
*
* Copyright (c) 2012-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of Atmel may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* \asf_license_stop
*
*/
#include "conf_ili9488.h"
#include "ili9488.h"
#include "ili9488_regs.h"
#include <sysclk.h>
#include <ioport.h>
#include <delay.h>
#if (SAM3S || SAM3N || SAM4S)
# include <pdc.h>
#elif UC3
# include <pdca.h>
#endif
#if (SAM3S || SAM3N || SAM4S) && defined(CONF_ILI9488_SPI)
# define ILI9488_DMA_ENABLED
# define ILI9488_DMA_CHUNK_SIZE 16
#elif UC3 && defined(CONF_ILI9488_PDCA_CHANNEL)
# define ILI9488_DMA_ENABLED
# define ILI9488_DMA_CHUNK_SIZE 16
#endif
#ifndef CONF_ILI9488_EBI
/**
* \internal
* \brief Helper function to select the CS of the controller on the bus
*/
__always_inline static void ili9488_select_chip(void)
{
ioport_set_pin_level(CONF_ILI9488_CS_PIN, false);
}
/**
* \internal
* \brief Helper function to de-select the CS of the controller on the bus
*/
__always_inline static void ili9488_deselect_chip(void)
{
ioport_set_pin_level(CONF_ILI9488_CS_PIN, true);
}
/**
* \internal
* \brief Helper function to select command byte transmission mode
*/
__always_inline static void ili9488_select_command_mode(void)
{
ioport_set_pin_level(CONF_ILI9488_DC_PIN, false);
}
/**
* \internal
* \brief Helper function to select data byte transmission mode
*/
__always_inline static void ili9488_select_data_mode(void)
{
ioport_set_pin_level(CONF_ILI9488_DC_PIN, true);
}
/**
* \internal
* \brief Helper function to wait for the last send operation to complete
*/
__always_inline static void ili9488_wait_for_send_done(void)
{
#if defined(CONF_ILI9488_USART_SPI)
# if XMEGA
while (!usart_tx_is_complete(CONF_ILI9488_USART_SPI)) {
/* Do nothing */
}
usart_clear_tx_complete(CONF_ILI9488_USART_SPI);
# else
/* Wait for TX to complete */
while (!usart_spi_is_tx_empty(CONF_ILI9488_USART_SPI)) {
/* Do nothing */
}
# endif
#elif defined(CONF_ILI9488_SPI)
/* Wait for TX to complete */
while (!spi_is_tx_empty(CONF_ILI9488_SPI)) {
/* Do nothing */
}
#endif
}
/**
* \internal
* \brief Helper function to send a byte over an arbitrary interface
*
* This function is used to hide what interface is used by the component
* driver, e.g. the component driver does not need to know if USART in SPI
* mode is used or the native SPI module.
*
* \param data The byte to be transfered
*/
__always_inline static void ili9488_send_byte(uint8_t data)
{
#if defined(CONF_ILI9488_USART_SPI)
# if XMEGA
while (!usart_data_register_is_empty(CONF_ILI9488_USART_SPI)) {
/* Do nothing */
}
irqflags_t flags = cpu_irq_save();
usart_clear_tx_complete(CONF_ILI9488_USART_SPI);
usart_put(CONF_ILI9488_USART_SPI, data);
cpu_irq_restore(flags);
# else
usart_spi_write_single(CONF_ILI9488_USART_SPI, data);
# endif
#elif defined(CONF_ILI9488_SPI)
/* Wait for any previously running send data */
ili9488_wait_for_send_done();
spi_write_single(CONF_ILI9488_SPI, data);
#endif
}
/**
* \internal
* \brief Helper function to read a byte from an arbitrary interface
*
* This function is used to hide what interface is used by the component
* driver, e.g. the component driver does not need to know if USART in SPI
* mode is used or the native SPI module.
*
* \retval uint8_t Byte of data read from the display controller
*/
__always_inline static uint8_t ili9488_read_byte(void)
{
uint8_t data;
#if defined(CONF_ILI9488_USART_SPI)
# if XMEGA
/* Workaround for clearing the RXCIF for XMEGA */
usart_rx_enable(CONF_ILI9488_USART_SPI);
usart_put(CONF_ILI9488_USART_SPI, 0xFF);
while (!usart_rx_is_complete(CONF_ILI9488_USART_SPI)) {
/* Do nothing */
}
data = usart_get(CONF_ILI9488_USART_SPI);
/* Workaround for clearing the RXCIF for XMEGA */
usart_rx_disable(CONF_ILI9488_USART_SPI);
# else
usart_spi_read_single(CONF_ILI9488_USART_SPI, &data);
# endif
#elif defined(CONF_ILI9488_SPI)
spi_write_single(CONF_ILI9488_SPI, 0xFF);
ili9488_wait_for_send_done();
/* Wait for RX to complete */
while (!spi_is_rx_full(CONF_ILI9488_SPI)) {
/* Do nothing */
}
spi_read_single(CONF_ILI9488_SPI, &data);
#endif
return data;
}
/**
* \internal
* \brief Sends a command to the controller, and prepares for parameter transfer
*
* Helper function to use for sending a command to the controller.
*
* \note After the command is sent, the display remains selected.
*
* \param command The command to send
*/
static void ili9488_send_command(uint8_t command)
{
ili9488_select_command_mode();
ili9488_select_chip();
ili9488_send_byte(command);
ili9488_wait_for_send_done();
ili9488_select_data_mode();
}
#else
volatile uint8_t *cmd_addr = (uint8_t *) (CONF_ILI9488_EBI_CMD_ADDRESS);
volatile uint8_t *data_addr = (uint8_t *) (CONF_ILI9488_EBI_DATA_ADDRESS);
#define ili9488_select_chip()
#define ili9488_deselect_chip()
#define ili9488_select_command_mode()
#define ili9488_select_data_mode()
#define ili9488_wait_for_send_done()
__always_inline static void ili9488_send_byte(uint8_t data) {
*data_addr = data;
}
__always_inline static uint8_t ili9488_read_byte(void) {
return *data_addr;
}
static void ili9488_send_command(uint8_t command) {
*cmd_addr = command;
}
#endif
static ili9488_coord_t limit_start_x, limit_start_y;
static ili9488_coord_t limit_end_x, limit_end_y;
/**
* \internal
* \brief Helper function to send the drawing limits (boundaries) to the display
*
* This function is used to send the currently set upper-left and lower-right
* drawing limits to the display, as set through the various limit functions.
*
* \param send_end_limits True to also send the lower-right drawing limits
*/
static void ili9488_send_draw_limits(const bool send_end_limits)
{
ili9488_send_command(ILI9488_CMD_COLUMN_ADDRESS_SET);
ili9488_send_byte(limit_start_x >> 8);
ili9488_send_byte(limit_start_x & 0xFF);
if (send_end_limits) {
ili9488_send_byte(limit_end_x >> 8);
ili9488_send_byte(limit_end_x & 0xFF);
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
ili9488_send_command(ILI9488_CMD_PAGE_ADDRESS_SET);
ili9488_send_byte(limit_start_y >> 8);
ili9488_send_byte(limit_start_y & 0xFF);
if (send_end_limits) {
ili9488_send_byte(limit_end_y >> 8);
ili9488_send_byte(limit_end_y & 0xFF);
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
}
/**
* \brief Set the display top left drawing limit
*
* Use this function to set the top left limit of the drawing limit box.
*
* \param x The x coordinate of the top left corner
* \param y The y coordinate of the top left corner
*/
void ili9488_set_top_left_limit(ili9488_coord_t x, ili9488_coord_t y)
{
limit_start_x = x;
limit_start_y = y;
ili9488_send_draw_limits(false);
}
/**
* \brief Set the display bottom right drawing limit
*
* Use this function to set the bottom right corner of the drawing limit box.
*
* \param x The x coordinate of the bottom right corner
* \param y The y coordinate of the bottom right corner
*/
void ili9488_set_bottom_right_limit(ili9488_coord_t x, ili9488_coord_t y)
{
limit_end_x = x;
limit_end_y = y;
ili9488_send_draw_limits(true);
}
/**
* \brief Set the full display drawing limits
*
* Use this function to set the full drawing limit box.
*
* \param start_x The x coordinate of the top left corner
* \param start_y The y coordinate of the top left corner
* \param end_x The x coordinate of the bottom right corner
* \param end_y The y coordinate of the bottom right corner
*/
void ili9488_set_limits(ili9488_coord_t start_x, ili9488_coord_t start_y,
ili9488_coord_t end_x, ili9488_coord_t end_y)
{
limit_start_x = start_x;
limit_start_y = start_y;
limit_end_x = end_x;
limit_end_y = end_y;
ili9488_send_draw_limits(true);
}
/**
* \brief Read a single color from the graphical memory
*
* Use this function to read a color from the graphical memory of the
* controller.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \retval ili9488_color_t The read color pixel
*/
ili9488_color_t ili9488_read_gram(void)
{
uint8_t red, green, blue;
ili9488_send_command(ILI9488_CMD_MEMORY_READ);
/* No interesting data in the first byte, hence read and discard */
red = ili9488_read_byte();
red = ili9488_read_byte();
green = ili9488_read_byte();
blue = ili9488_read_byte();
ili9488_deselect_chip();
return ILI9488_COLOR(red, green, blue);
}
/**
* \brief Write the graphical memory with a single color pixel
*
* Use this function to write a single color pixel to the controller memory.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \param color The color pixel to write to the screen
*/
void ili9488_write_gram(ili9488_color_t color)
{
/* Only 16-bit color supported */
Assert(sizeof(color) == 2);
ili9488_send_command(ILI9488_CMD_MEMORY_WRITE);
ili9488_send_byte(color);
ili9488_send_byte(color >> 8);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
}
/**
* \brief Copy pixels from SRAM to the screen
*
* Used to copy a large quantitative of data to the screen in one go.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \param pixels Pointer to the pixel data
* \param count Number of pixels to copy to the screen
*/
void ili9488_copy_pixels_to_screen(const ili9488_color_t *pixels, uint32_t count)
{
const ili9488_color_t *pixel = pixels;
/* Sanity check to make sure that the pixel count is not zero */
Assert(count > 0);
ili9488_send_command(ILI9488_CMD_MEMORY_WRITE);
#if defined(ILI9488_DMA_ENABLED)
ili9488_color_t chunk_buf[ILI9488_DMA_CHUNK_SIZE];
uint32_t chunk_len;
# if SAM
Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9488_SPI);
pdc_packet_t spi_pdc_data;
pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN);
spi_pdc_data.ul_addr = (uint32_t)chunk_buf;
# elif UC3
pdca_set_transfer_size(CONF_ILI9488_PDCA_CHANNEL,
PDCA_TRANSFER_SIZE_BYTE);
pdca_set_peripheral_select(CONF_ILI9488_PDCA_CHANNEL,
CONF_ILI9488_PDCA_PID);
# endif
while (count)
{
/* We need to copy out the data to send in chunks into RAM, as the PDC
* does not allow FLASH->Peripheral transfers */
chunk_len = min(ILI9488_DMA_CHUNK_SIZE, count);
/* Wait for pending transfer to complete */
ili9488_wait_for_send_done();
for (uint32_t i = 0; i < chunk_len; i++) {
chunk_buf[i] = le16_to_cpu(pixel[i]);
}
# if SAM
spi_pdc_data.ul_size = (uint32_t)sizeof(ili9488_color_t) * chunk_len;
pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data);
# elif UC3
pdca_reload_channel(CONF_ILI9488_PDCA_CHANNEL, chunk_buf,
(uint32_t)sizeof(ili9488_color_t) * chunk_len);
pdca_enable(CONF_ILI9488_PDCA_CHANNEL);
# endif
pixel += chunk_len;
count -= chunk_len;
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
# if SAM
pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN);
# elif UC3
pdca_disable(CONF_ILI9488_PDCA_CHANNEL);
# endif
#else
while (count--) {
ili9488_send_byte(*pixel);
ili9488_send_byte(*pixel >> 8);
pixel++;
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
#endif
}
#if XMEGA
/**
* \brief Copy pixels from progmem to the screen
*
* This function can be used to copy data from program memory (flash) to the
* display.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \param pixels Pointer to the progmem data
* \param count Number of pixels to write
*/
void ili9488_copy_progmem_pixels_to_screen(
ili9488_color_t PROGMEM_PTR_T pixels, uint32_t count)
{
ili9488_color_t color;
/* Sanity check to make sure that the pixel count is not zero */
Assert(count > 0);
ili9488_send_command(ILI9488_CMD_MEMORY_WRITE);
while (count--) {
color = PROGMEM_READ_WORD(pixels);
ili9488_send_byte(color);
ili9488_send_byte(color >> 8);
pixels++;
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
}
#endif
/**
* \brief Set a given number of pixels to the same color
*
* Use this function to write a certain number of pixels to the same color
* within a set limit.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \param color The color to write to the display
* \param count The number of pixels to write with this color
*/
void ili9488_duplicate_pixel(const ili9488_color_t color, uint32_t count)
{
/* Sanity check to make sure that the pixel count is not zero */
Assert(count > 0);
ili9488_send_command(ILI9488_CMD_MEMORY_WRITE);
#if defined(ILI9488_DMA_ENABLED)
ili9488_color_t chunk_buf[ILI9488_DMA_CHUNK_SIZE];
uint32_t chunk_len;
# if SAM
Pdc *SPI_DMA = spi_get_pdc_base(CONF_ILI9488_SPI);
pdc_packet_t spi_pdc_data;
pdc_enable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN);
spi_pdc_data.ul_addr = (uint32_t)chunk_buf;
# elif UC3
pdca_set_transfer_size(CONF_ILI9488_PDCA_CHANNEL,
PDCA_TRANSFER_SIZE_BYTE);
pdca_set_peripheral_select(CONF_ILI9488_PDCA_CHANNEL,
CONF_ILI9488_PDCA_PID);
# endif
for (uint32_t i = 0; i < ILI9488_DMA_CHUNK_SIZE; i++) {
chunk_buf[i] = le16_to_cpu(color);
}
while (count)
{
chunk_len = min(ILI9488_DMA_CHUNK_SIZE, count);
ili9488_wait_for_send_done();
# if SAM
spi_pdc_data.ul_size = (uint32_t)sizeof(ili9488_color_t) * chunk_len;
pdc_tx_init(SPI_DMA, NULL, &spi_pdc_data);
# elif UC3
pdca_reload_channel(CONF_ILI9488_PDCA_CHANNEL, chunk_buf,
(uint32_t)sizeof(ili9488_color_t) * chunk_len);
pdca_enable(CONF_ILI9488_PDCA_CHANNEL);
# endif
count -= chunk_len;
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
# if SAM
pdc_disable_transfer(SPI_DMA, PERIPH_PTCR_TXTEN);
# elif UC3
pdca_disable(CONF_ILI9488_PDCA_CHANNEL);
# endif
#else
while (count--) {
ili9488_send_byte(color);
ili9488_send_byte(color >> 8);
}
ili9488_wait_for_send_done();
ili9488_deselect_chip();
#endif
}
/**
* \brief Copy pixels from the screen to a pixel buffer
*
* Use this function to copy pixels from the display to an internal SRAM buffer.
*
* Limits have to be set prior to calling this function, e.g.:
* \code
* ili9488_set_top_left_limit(0, 0);
* ili9488_set_bottom_right_limit(320, 240);
* ...
* \endcode
*
* \param pixels Pointer to the pixel buffer to read to
* \param count Number of pixels to read
*/
void ili9488_copy_pixels_from_screen(ili9488_color_t *pixels, uint32_t count)
{
uint8_t red, green, blue;
/* Sanity check to make sure that the pixel count is not zero */
Assert(count > 0);
ili9488_send_command(ILI9488_CMD_MEMORY_READ);
/* No interesting data in the first byte, hence read and discard */
red = ili9488_read_byte();
while (count--) {
red = ili9488_read_byte();
green = ili9488_read_byte();
blue = ili9488_read_byte();
*pixels = ILI9488_COLOR(red, green, blue);
pixels++;
}
ili9488_deselect_chip();
}
/**
* \internal
* \brief Initialize the hardware interface to the controller
*
* This will initialize the module used for communication with the controller.
* Currently supported interfaces by this component driver are the SPI
* interface through either the SPI module in master mode or the USART in
* Master SPI mode. Configuration must be done in the associated
* conf_ili9488.h file.
*/
static void ili9488_interface_init(void)
{
#if defined(CONF_ILI9488_USART_SPI) || defined(CONF_ILI9488_SPI)
spi_flags_t spi_flags = SPI_MODE_0;
board_spi_select_id_t spi_select_id = 0;
#elif defined(CONF_ILI9488_EBI)
#else
#error Interface for ILI9488 has not been selected or interface not\
supported, please configure component driver using the conf_ili9488.h\
file!
#endif
#if defined(CONF_ILI9488_USART_SPI)
struct usart_spi_device device = {
.id = 0,
};
usart_spi_init(CONF_ILI9488_USART_SPI);
usart_spi_setup_device(CONF_ILI9488_USART_SPI, &device, spi_flags,
CONF_ILI9488_CLOCK_SPEED, spi_select_id);
#elif defined(CONF_ILI9488_SPI)
struct spi_device device = {
.id = 0,
};
spi_master_init(CONF_ILI9488_SPI);
spi_master_setup_device(CONF_ILI9488_SPI, &device, spi_flags,
CONF_ILI9488_CLOCK_SPEED, spi_select_id);
spi_enable(CONF_ILI9488_SPI);
# if UC3
spi_set_chipselect(CONF_ILI9488_SPI, ~(1 << 0));
# if defined(ILI9488_DMA_ENABLED)
sysclk_enable_peripheral_clock(&AVR32_PDCA);
# endif
# endif
/* Send one dummy byte for the spi_is_tx_ok() to work as expected */
spi_write_single(CONF_ILI9488_SPI, 0);
#else
pmc_enable_periph_clk(ID_SMC);
/* The timing is based on a 120 MHz clock and the configuration is the
* fastest speed that the display can do in parallel mode.
*/
smc_set_setup_timing(SMC, CONF_ILI9488_EBI_CS,
SMC_SETUP_NWE_SETUP(1)
| SMC_SETUP_NCS_WR_SETUP(0)
| SMC_SETUP_NRD_SETUP(1)
| SMC_SETUP_NCS_RD_SETUP(0));
smc_set_pulse_timing(SMC, CONF_ILI9488_EBI_CS,
SMC_PULSE_NWE_PULSE(2)
| SMC_PULSE_NCS_WR_PULSE(4)
| SMC_PULSE_NRD_PULSE(43)
| SMC_PULSE_NCS_RD_PULSE(54));
smc_set_cycle_timing(SMC, CONF_ILI9488_EBI_CS,
SMC_CYCLE_NWE_CYCLE(5)
| SMC_CYCLE_NRD_CYCLE(55));
smc_set_mode(SMC, CONF_ILI9488_EBI_CS, SMC_MODE_READ_MODE | SMC_MODE_WRITE_MODE);
#endif
}
/**
* \internal
* \brief Initialize all the display registers
*
* This function will set up all the internal registers according the the
* manufacturer's description.
*/
static void ili9488_controller_init_registers(void)
{
// PGAMCTRL - Positive Gamma Control
ili9488_send_command(ILI9488_CMD_POSITIVE_GAMMA_CTRL);
ili9488_send_byte(0x00);
ili9488_send_byte(0x07);
ili9488_send_byte(0x0f);
ili9488_send_byte(0x0D);
ili9488_send_byte(0x1B);
ili9488_send_byte(0x0A);
ili9488_send_byte(0x3c);
ili9488_send_byte(0x78);
ili9488_send_byte(0x4A);
ili9488_send_byte(0x07);
ili9488_send_byte(0x0E);
ili9488_send_byte(0x09);
ili9488_send_byte(0x1B);
ili9488_send_byte(0x1e);
ili9488_send_byte(0x0f);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// NGAMCTRL - Negative Gamma Control
ili9488_send_command(ILI9488_CMD_NEGATIVE_GAMMA_CTRL);
ili9488_send_byte(0x00);
ili9488_send_byte(0x22);
ili9488_send_byte(0x24);
ili9488_send_byte(0x06);
ili9488_send_byte(0x12);
ili9488_send_byte(0x07);
ili9488_send_byte(0x36);
ili9488_send_byte(0x47);
ili9488_send_byte(0x47);
ili9488_send_byte(0x06);
ili9488_send_byte(0x0a);
ili9488_send_byte(0x07);
ili9488_send_byte(0x30);
ili9488_send_byte(0x37);
ili9488_send_byte(0x0f);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Power Control 1
ili9488_send_command(ILI9488_CMD_POWER_CONTROL_1);
ili9488_send_byte(0x10);
ili9488_send_byte(0x10);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Power Control 2
ili9488_send_command(ILI9488_CMD_POWER_CONTROL_2);
ili9488_send_byte(0x41);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// VCOM Control
ili9488_send_command(ILI9488_CMD_VCOM_CONTROL_1);
ili9488_send_byte(0x00);
ili9488_send_byte(0x22);
ili9488_send_byte(0x80);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Memory Access Control
ili9488_send_command(ILI9488_CMD_MEMORY_ACCESS_CONTROL);
ili9488_send_byte(0x68);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
//Interface Mode Control
// Set up used SPI lines and RGB interface
ili9488_send_command(ILI9488_CMD_INTERFACE_MODE_CONTROL);
ili9488_send_byte(0x00);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
//Frame rate 70HZ
ili9488_send_command(ILI9488_CMD_FRAME_RATE_CONTROL_NORMAL);
ili9488_send_byte(0xB0);
ili9488_send_byte(0x11);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Display Inversion
ili9488_send_command(ILI9488_CMD_DISPLAY_INVERSION_CONTROL);
ili9488_send_byte(0x02);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Entry Set Mode
ili9488_send_command(ILI9488_CMD_ENTRY_MODE_SET);
ili9488_send_byte(0xC6);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
#ifndef CONF_ILI9488_SPI
// Interface Pixel Format
ili9488_send_command(ILI9488_CMD_INTERFACE_PIXEL_FORMAT);
ili9488_send_byte(0x55);// DPI: 16bpp DBI: 16bpp
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Set Image Function
// enable 24 bit data bus
ili9488_send_command(ILI9488_CMD_SET_IMAGE_FUNCTION);
ili9488_send_byte(0x01);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
#else
// Interface Pixel Format
ili9488_send_command(ILI9488_CMD_INTERFACE_PIXEL_FORMAT);
ili9488_send_byte(0x51);// DPI: 16bpp DBI: 16bpp
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Set Image Function
ili9488_send_command(ILI9488_CMD_SET_IMAGE_FUNCTION);
ili9488_send_byte(0x00);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
#endif
// Adjustment Control 3
// fixed settings and DSI packet setup
ili9488_send_command(ILI9488_CMD_ADJUST_CONTROL_3);
ili9488_send_byte(0xA9);
ili9488_send_byte(0x51);
ili9488_send_byte(0x2C);
ili9488_send_byte(0x82);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
// Set Interface Mode
ili9488_send_command(ILI9488_CMD_DISPLAY_FUNCTION_CONTROL);
ili9488_send_byte(0x00);// RGB or other interface
ili9488_send_byte(0x22);
ili9488_send_byte(0x3B);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
ili9488_set_orientation(0);
ili9488_set_limits(0, 0, ILI9488_DEFAULT_WIDTH,
ILI9488_DEFAULT_HEIGHT);
}
/**
* \internal
* \brief Send display commands to exit standby mode
*
* This function is used to exit the display standby mode, which is the default
* mode after a reset signal to the display.
*/
static void ili9488_exit_standby(void)
{
ili9488_send_command(ILI9488_CMD_SLEEP_OUT);
ili9488_deselect_chip();
delay_ms(150);
ili9488_send_command(ILI9488_CMD_DISPLAY_ON);
ili9488_deselect_chip();
}
/**
* \internal
* \brief Reset the display using the digital control interface
*
* Controls the reset pin of the display controller to reset the display.
*/
static void ili9488_reset_display(void)
{
ioport_set_pin_level(CONF_ILI9488_RESET_PIN, true);
delay_ms(10);
ioport_set_pin_level(CONF_ILI9488_RESET_PIN, false);
delay_ms(10);
ioport_set_pin_level(CONF_ILI9488_RESET_PIN, true);
delay_ms(150);
}
/**
* \brief Initialize the controller
*
* Used to initialize the ILI9488 display controller by setting up the hardware
* interface, and setting up the controller according to the manufacturer's
* description. It also set up the screen orientation to the default state
* (portrait).
*/
void ili9488_init(void)
{
/* Initialize the communication interface */
ili9488_interface_init();
/* Reset the display */
ili9488_reset_display();
/* Write all the controller registers with correct values */
ili9488_controller_init_registers();
/* Send commands to exit standby mode */
ili9488_exit_standby();
}
/**
* \brief Sets the orientation of the display data
*
* Configures the display for a given orientation, including mirroring and/or
* screen rotation.
*
* \param flags Orientation flags to use, see \ref ILI9488_FLIP_X, \ref ILI9488_FLIP_Y
* and \ref ILI9488_SWITCH_XY.
*/
void ili9488_set_orientation(uint8_t flags)
{
/* Flip X/Y and reverse X orientation and set BGR mode*/
uint8_t madctl = 0x68;
/* Pretend the display is in landscape mode by default to match other display drivers */
//flags ^= ILI9488_SWITCH_XY | ILI9488_FLIP_X;
if (flags & ILI9488_FLIP_X) {
madctl &= ~(1 << 6);
}
if (flags & ILI9488_FLIP_Y) {
madctl |= 1 << 7;
}
if (flags & ILI9488_SWITCH_XY) {
madctl &= ~(1 << 5);
}
ili9488_send_command(ILI9488_CMD_MEMORY_ACCESS_CONTROL);
ili9488_send_byte(madctl);
ili9488_wait_for_send_done();
ili9488_deselect_chip();
}
Опять же, как этим воспользоваться - совсем не понимаю.
Самому интересно)
кому интересно видео по TFT3.5 + MEGA2560 + Shild
https://www.youtube.com/watch?v=Ypn7hTenzsQ&list=PLEa82m3Qi7r_BRhTdlp0Ug...
файл проги с коментариями на С/С++ на файлообменике под индикатор который на видео
https://drive.google.com/drive/folders/0Bw5oxFI4bKDAa3lMUkxHcTZ3WTQ
Так как пин RD не выведен на разъем переопределять его бесполезно.
Далее принудительно определяем идентификатор контроллера, инициализируем и пишем, например команду заливки экрана цветом.
Используем библиотеку Adafruit С новым pin_magic.h. Надеюсь что Data порт находится на пинах порта PORTA PA0 - PA7, иначе придется еще думать о редактировании выводов порта Data. Ссылки на библиотеку и файл pin_magic в предыдущих постах. Инклюдить pin_magic надо в файле Adafruit_TFTLCD.ccp. коммментируем строки
И пишем
Уважаемые коллеги. Подскажите какие пины дёргать, чтобы подключить micro SD карту? Сборки по 1кОм запаял кое-как. Экран работает, но хочу подключить через шлейф и развести датчики на макетной плате, т. к. нужны остальные порты.
Если у кого есть распиновка, то скиньте, пожалуйста.
Как совместить sd_in, sd_out и пины miso, mosi? Какие требования к картам? У меня 16 Гб и форматированная в FAT32.
Плата такая, но изображение не моё (из поста 402):
В общем как подключить через шлейф SD карту на этом шилде?
Подскажите пожалуйста, в чем может заключаться проблема. Подключаю вот такой модуль http://ru.aliexpress.com/item/Free-shipping-LCD-module-TFT-3-5-inch-TFT-LCD-screen-for-Arduino-MEGA-2560-R3/1874970050.html к arduino mega, выбираю соответствующий пример для него 480х320 на стандартной библиотеке UTFT, строка инициализации UTFT myGLCD(R61581,38,39,40,41); На экране отображается следующее:
В чем может быть проблема? Модифицированные библиотеки с этой ветки перепробовал - не помогло.
Varg, когда перепаивал себе резисторные сборки, то были места на них с коротким замыканием (паяльник с жалом как сама сборка + сорвал пару дорожек без опыта пайки таких элементов). При загрузке скетча тоже экран делился на две неравные части, только показвал в одной части белое поле, а другая немного другого белого оттенка. Если у вас такая же ситуация, то может где-то непропай или коротит. У меня было 2-3 места корочения.
Varg
по вашей же ссылке, человек пишет, в отзывах,что контроллер дисплея совсем не тот который заявлен китайцем, и который вы пытаетесь инициализировать.
Таже проблема, брал вот такой комплект http://www.aliexpress.com/snapshot/6925325075.html
только пришел дисплей не 3.95, а 3.5 дюймов.
Если заменить в файле инициализации строки
LCD_Write_COM(0x36);
LCD_Write_DATA(0x0A);
на
LCD_Write_COM(0x36);
LCD_Write_DATA(0x2A);
а если взять инициализацию которую предлагает китаец по Вашей ссылке то получаются другие цвета:
Второй день кувыркаюсь.
И у меня такой на на фотках выше дисплей, с таким же поведением.
Программа LCD_ID_Reader выдала
Initializing LCD...
Reading ID...0x0404
Так это "новое слово" в китайской технике. В отзывах на алиэкспресс пишут различные строки инициализации. У меня получается только 2 варианта: или как на предыдущих фотках или белый экран. Похоже китайцы распродав одну партию дисплеев, покупают другую один-в-один похожую, но с другим контроллером. Или в гараже на красную печатную плату лепят новый экран.
По поводу резисторных сборок - все проверил, все работает. Предполагаю, китайцы начали ставить некие аналоги R61581, под которые нужно править стандартную библиотеку... Написал продавцу об этой проблеме, он выслал дистрибутив ардуины первой версии и какую-то модифицированную UTFT. Но с ней только белый экран получается..
"Чтобы использовать этот экран с библиотекой UTFT нужно выбрать драйвер ILI9486. " Вы этот вариант пробовали? Человек же пишет, что там стоит не R61581. А китайцам фиолетово заморачиваться, с соответствием, один раз написанного и реальным товаром, который они в данный момент продают. В этой теме несколько раз описаны случаи, что даже после списывания с китайцем, китаец присылает совсем другой товар. Не хотите рисковать, для этого есть адафруит и им подобные, дороже в разы, но и косяков с разносортицей не будет. Что купите, то и получите.
Прислал и мне китаец пример для ардуины. Цвета стали лучше, но всё равно только полэкрана правильно отображает и символы не читаемы. Может у кого заработает.
https://yadi.sk/d/BJOxAXBmjn2MX
В архиве запускать единственный пример из библиотеки UTFT.
Спасибо нашел был невнимателен, образец загрузился тач тоже заработал, теперь ковыряю CD пишет ошибку видимо дело в размере (4Гб)
Покупать шилды без выведенного сигнала RD, это жопа. Без этого вывода не жизнь. Ни тебе сигнатуру чипа определить, ни тебе нормально с регистрами поработать. Вообщем кастрированные чипы сплошной гемр!!!
Вы читали заголовок зип файла. Судя по названию там идет речь о работе с шилдом 16 бит.
URkA
Да, все варианты перепробовал, результат либо белый экран, либо то что на фото выше. Конкретно с ILI9486 имеем белый экран и несколько чуть заметных разноцветных линий. По поводу фирмовых модулей согласен. До этого покупал пару китайских - все было в порядке. От одного пришлось отказаться потому как он для UNO, памяти не хватило. Другой тоже для меги, но работал с простейшей библиотекой, для моих целей ее было не достаточно.
naturalist
Попробовал Ваши библиотеки, результат тот же, только ориентация дисплея изменилась на вертикальную.
Повнимательней изучил изображение выложенные вами. Обратил внимание, что все надписи зеркальны. Сталкнулся с таким когда по ошибке инициализировал ili9327 как ili9341 была примерно такаяже бодяга, может там установлен ili9327?. Если бы был выведен пин RD на разъем, решить проблемму былобы проще. Я вообще покупаю дисплеи с тачем и сам делаю шилды, так мне проще и я точно знаю что и куда подключать и как инициализировать.
Моя плата похожа, но не такая как в этой теме.
Вскрытие показало: экран имеет шлейф с 39 пинами. При прозвонке линий 38-42 от разъема меги до щлейфа стоят резисторные сборки.
№ на MEGA/резисторная сборка/№ шлейфе дисплея
38 / RP3 pin4 / 34
39 / RP7 pin1 / 33
40 / RP3 pin3 / 35
41 / RP7 pin2 / 12
42 / RP3 pin2 / а дальше дорожи нет и не было.
Нет выхода на шлейф у ножек меги 22(DB8), 27 (DB13), 36(DB1), 43.
Как в этой теме обсуждалось RD на шилд не выведен. По надписи на шлейфе (там ноль в названии) )легко находится море предложений о продаже. И даже известен телефон - Banghua BOWAY U1 waveguide 9105, Banghua u1 Hedy H702 / T700 waveguide 9105.
Посоветуйте, куда дальше копать.
Меня посетила почти крамольная мысль, а может этот шилд надо подключать через переходную плату. Посмотрите распиновку, тогда не совсем понятно зачем согласующие резисторы.
начните с простого, прозвоните как выводы дисплея доходят через 10к резисторы на разъем. мож где затерялись или на рядом идущие замкнули. точность питания дисплея +3,30в на его шлейфе. Это всё вы ранее проверяли?Если какие выводы затерялись, то заведите их.
потом уже копаться серьезней. вывод RD похоже на 32pin дисплея, но лучше погуглить tft lcd 39pin и глянуть картинки, можно и с 37pin подсмотреть аналогии. Через резистор 10к закинуть на вывод ардуинки (возможно он подключён на 3,3в - разорвать эту цепь). . Т.к. дисплей скорее всего активирован на 16бит, в любом случае можно написать простенький скетч дерганья управляющими пинами и вывода ID дисплея в сериал порт . ибо чем считываете у адафруита - в основном это для 8 бит, вот и получаете повторение типа 0404. и глянуть пдф возможных претендентов, ибо не у всех ID храниться в нулевом регистре. У R61509V явно по нулевому адресу 00h , а в несколько дерганий RD у ILI9488 и ILI9486 " device code " по D3h адресу, у ILI9327 по EFh адресу , у R61581 - по BFh. Читалка ID от адафруита это не панацея, она заточена распознать их шилды, а не все подряд, и в основном только по адресу 00h. Если есть время , можете написать универсальную, для большинства контроллеров дисплеев на мегу.
п.с. 2пин дисплея похож на IM.. для перевода его в режим 8/16 бит или 18бит. Схемы шилдов вроде тут уже давались. разрисуйте как у вас. можно еще на taobao.com поискать похожие шилды, там продавцы иногда приводят распиновку дисплеев , схемы шилдов и простенькие тесты с инициализациями.
Прозвонил все дорожки от резисторных сборок. Извиняюсь - ввёл в заюлуждение, недосмотрел. Все 16 проводов шины данных меги имеют подключение к дисплею и в последовательном по старшинству бит порядке. Нет продолжения у 42(rd) и 43. Открыл вчера на али диспут на полную стоимость экрана, сегодня продавец согласился.
Есть альтернативный вариант подбору библиотек к дисплею. Купить дисплей/модуль/устройство с известным и не модифицируемым каждый год экраном. Лежит у меня видео-дисплей - 4.3 inch car rear monitor. Замечательно подходит для домофона. Картинки есть в статье http://www.eevblog.com/forum/reviews/mini-teardown-5%27-hd-800x480px-car.... В самом экране стоит чип OTA5180A с 40пиновым разъемом и RGB интерфейсом (3х8=24 линии). К нему подключена плата видеодекодера на AMT630. Цена с доставкой от 13 зеленых. Схема стабильная и нет причин её совершенствовать. Бывают и готовые ардуино модули с этим же дисплеем и контроллером ssd1963 на плате, но стоят от 20.
Готовых решений я в интернете не нашел.
Ничего не мешает использовать библиотеку TV out. Доработать. Через переходник подключить мегу к экрану напрямую. Если взять 3 линии, то будет 8 цветов. Вполне достаточно для простых применений.
Вопрос - потянет ли мега? На экран надо постоянно подавать сигнал CLK и саму картинку с частотой 1 МГц.
А такой дисплей подойдёт для Ардуино 2560? http://uamper.com/3.6-%D0%B4%D1%8E%D0%B9%D0%BC%D1%96%D0%B2-TFT-Touch-LCD-Arduino?tag=Arduino
Так же интересует, какой удобный ( в плане работы с ним библиотека, подключение и сами команды и вывод картинки)дисплей с тач - скрином и без тач скрина, размером не менее 3,2 дюйма, и что бы он мог работать и с ардуино УНО и с Адуино 2560? Или дисплей который я нашёл в ссылке это самый оптимальный и можно как я понимаю его и без тача использовать и с тачем?
Работать будет. Только При повороте изображения надо учитывать смещение в 80 пикселей. Контроллер расчитан на работу с экраном 480х320 и нет возможности изменить резрешение на уровне железа. Я подобный запускал. Да и с поключением тача повозиться пришлось, перекинуть ноги в программе. А так прилично работает. Что касается библиотеки, то они по сути все взаимозаменяемы. Основным критерием является дамп инициализации и описание протокола обмена с индикатором. Берем любую библиотеку, даташит по контроллеру, описываем протоколл обмена, используя переменные передаваемые в функции библиотеки и вперед. Я так перенес с AVR на ARM библиотеку Adafruit и UTouch, скрестил их и получил набор функций необходимых для моего проекта. Понимая как работает контроллер TFT можно и свои функции добавлять.
При развороте, это вертикально если его использовать или горизонтально? Во вторых есть ли какой - нить дисплей что бы и с ардуиной 2560, и с УНО можно было работать без смещения пикселей? И такой кто - то использовал:
http://forum.cxem.net/index.php?showtopic=151543&hl= Как он вообще, на вид программируется как сенсорная панель промышленного контроллера Сименс, я так думаю и на УНО он пойдёт и на 2560, вот только где его купить не могу найти что - то.
..
Работать будет. Только При повороте изображения надо учитывать смещение в 80 пикселей. Контроллер расчитан на работу с экраном 480х320 и нет возможности изменить резрешение на уровне железа.....
Да тож одно решение такое было.
1й способ здесь описал, в файле setxy библиотеки UTFT добавил к координате +32 (дисплей был на 400 точек, а контроллер на 432точки)
2м способом для другого контроллера помогло установка в регистрах размеров матрицы и переворачивание.
3м способом для третьего вида контроллера в самом скетче, в функциях UTFT просто к координате дописывал +80. а так что только не делал. и разрешение менял (были спец регистры в контроллере для выбора под разные матрицы, и зеркалировал и переворачивал - нифига, в других контроллерах помагало, здесь нет. видимо матрицу развели не под этот контроллер. решилось тож именно только +80.)
Мои пять копеек...
TFT модуль 3.5" с тач скрином, маркировка: QQ:895838470 TFT MODULE V7.0 изготовитель: shanuan, разрешение: 480X320, шина данных: 16 бит, драйвер дисплея: ILI9481.
Подключил к ARDUINO MEGA2560 напрямую, по следующей схеме:
PIN TFT
PIN 23 BL - подсветка, у меня работает от 3,3В.
PIN 32 FCS -не задействован.
Разъемы TFT подключены к ARDUINO MEGA 2560 напрямую, для подключения использовался 34-х контактный разъем от старого флоппи диска с родным шлейфом.
Подключал с использованием библиотеки UTFT ver 2.81.
Строки инициализации:
Initialize display:
UTFT myGLCD(ILI9481,38,39,40,41);
Initialize touchscreen:
UTouch myTouch( 46, 47, 42, 43, 44);
После запуска обнаружилось зеркальное отображение, для победы пришлось заменить содержание файла initlcd.h в папке C:\Documents and Settings\.........\Мои документы\Arduino\libraries\UTFT\tft_drivers\ili9481
на
В результате получил достаточно быстрый дисплей с рабочим тачскрином.
Кто ни будь может дать ссылку на способы проверки скорости отрисовки дисплея, хотелось бы оттестировать и выдать полную информацию для сравнения?
Тест провести можете используя функцию millis(). Важно понимать что скорость отрисовк будет одинакова для всего ряда контроллеров + конкретное разрешение, т.к. эта скорость обусловлена скоростью обработки алгоритма процессором AVR, а не быстродействием контроллера индикатора. Чем боьше разрешение, а следовательно количество пикселей, тем дольше отрисовка фрейма (экрана). К сожилению все библиотеки пиксельные, для ардуино не встречал векторных.
Здравствуйте!
Помогите пожалуйста опознать "зверя" и подобрать дравйвер, чтобы работал и тач.
Купил давно на волне энтузиазма. Сейчас 2я волна пошла, хочу использовать ))
Заранее спасибо!
99% что поедет как ILI9327.
спасибо! а где взять библ-ки для tft и touch?
UTFT гуглите
vis22
Ваш модуль наверное с ибея. Есть там продавец robothome. А изготовитель модуля: shanYan. И на одной из фоток на ибее на плате прилеплена бирка "9486". Хотя китайцы они такие выдумщики ...
по высоте норм, по ширине мало, где-то четверть еще не хватает
Чаво?
Чаво?
установил этот тип экрана в строку инициализации, избражение есть, но по ширине не на весь экран.
запускаю тестовый проект из биб-ки УТФТ.
запускайте тестовый 400х240
с изображением все ок, а как тач заставить работать?
открыл пример тач_калибровка, провел, забил полученные значения, затем открыл пример тач_баттоны.
не работает, т.е. работает, но криво, давлю по краям экрана, тогда пишет цифры
надо при калибровке правильно выставить ориентацию дисплея
UTouch работает обсолютно нормально. Я даже переделал ее для работы с stm32. Без калибровки работает даже на разрешении 480х320, правда остаются поля по 10 - 25 пикселей по бордюру.
Ориентацию выставлял по всякому, что не так делаю?
naturalist
Покупал на ebay, продавец robothome.
В тексте объявления о продаже был указано The controller: ILI9481.
Утилита LCD_ID_Reader также показала его, наверное отпределение контроллера моего экземпляра правильное.
Сегодня попробовал указать в строке инициализации ILI9486 - получил белый экран.
Короче, заказал уновский дисплей на 9488 с подписанной распиновкой, буду его мучить)
Мои пять копеек...
TFT модуль 3.5" с тач скрином, маркировка: QQ:895838470 TFT MODULE V7.0 изготовитель: shanuan, разрешение: 480X320, шина данных: 16 бит, драйвер дисплея: ILI9481.
Подключил к ARDUINO MEGA2560 напрямую, по следующей схеме:
..........
Напрямую такой шилд нельзя подключать, там не видать ни резисторов 10ком , ни преобразователей уровней. На эти контроллеры при питании 3,3в нельзя подавать мощные логические уровни выше 3,3в , а у меги они 5в.
Yarik.Yar, смело можешь использовать скачанную у меня библиотеку.
Вот засада, для работы TFT с динамическими изображениями надо использовать или панель без контролера, или проц ГГЦа этак на 1,5 - 2. Иначе видно лаги, неуспевает записать в ОЗУ TFT проц фрэйм. Есть правда еще идея использовать SDRAM -> DMA -> TFT. может выйграю пару мгновений у электронов ;-)
STM можно нехило разогнать, насколько я знаю...у F4 до 168МГц вроде (ВРОДЕ!) без разгона...ты же их мучаешь?)
Удачи в изысканиях)
slider пишет:
Напрямую такой шилд нельзя подключать...... к 5-и волтовой Mege.
Провел эксперимент: для пробы подключил один из сигналов, а именно «WR» через резистор 10 кОм –получил белый экран.
Заменил резистор подстроечным на 50 кОм и регулировал от 0-до max- получил следующие результаты:
-по достижению 1,2 кОм появились первые артефакты на изображении;
-по достижению 4,5 кОм – белый экран, при этом амплитуда уровня сигнала снизилась до 4,2В.
Вернул схему в исходное состояние и поставил на обкатку, на настоящее время шилд отработал 78 часов. Полет нормальный.
Задам-ка я свой вопрос в этой теме..
Суть вопроса : имеется LCD Display Module TFT 3.95 inch на контроллере ili9488, вот такой
Читать тач, писать/рисовать на нем я уже умею, нет проблем. А вот научиться программно управлять подсветкой - ну никак ((.
Поиски решения дали следующее:
1. В библиотеку добавить две функции, void lcdoff(); и void lcdon();
и
Опять же, как этим воспользоваться - совсем не понимаю.
Понимающие, помогите пожалуйста.