Всем привет, походу выявил аппаратный баг с SPI шиной на Arduino TFT LCD Screen. Предыстория. Баловался arduino wi-fi шилдом и понадобился небольшой цветной экран выводить данные, выбрал вышеуказанный. Купил на днях. Выяснилось, что при подключении обоих шилдов, wi-fi категорически не поднимался - ардуинка не видела шилд при инициализации (WiFi.status() = WL_NO_SHIELD). Пример кода (тупо взято с примеров и объединено): Код (Text): // include the necessary libraries #include <SPI.h> #include <SD.h> #include <TFT.h> // Arduino LCD library #include <WiFi.h> // pin definition for the Uno #define sd_cs 5 #define lcd_cs 6 #define dc 9 #define rst 8 TFT TFTscreen = TFT(lcd_cs, dc, rst); // wi-fi def #define wifi_ss 10 #define wifi_sd_ss 4 char ssid[] = "*****"; // your network SSID (name) char pass[] = "*******"; // your network password int status = WL_IDLE_STATUS; // server def WiFiServer server(25); // this variable represents the image to be drawn on screen PImage logo; void setup() { // initialize the GLCD and show a message // asking the user to open the serial line TFTscreen.begin(); TFTscreen.background(255, 255, 255); TFTscreen.stroke(0, 0, 255); TFTscreen.println(); TFTscreen.println(F("Arduino TFT Bitmap Example")); TFTscreen.stroke(0, 0, 0); TFTscreen.println(F("Open serial monitor")); TFTscreen.println(F("to run the sketch")); delay (5000); // initialize the serial port: it will be used to // print some diagnostic info Serial.begin(9600); while (!Serial) { // wait for serial line to be ready } // clear the GLCD screen before starting TFTscreen.background(255, 255, 255); // try to access the SD card. If that fails (e.g. // no card present), the setup process will stop. Serial.print(F("Initializing SD card...")); if (!SD.begin(sd_cs)) { Serial.println(F("failed!")); return; } Serial.println(F("OK!")); // initialize and clear the GLCD screen TFTscreen.begin(); TFTscreen.background(255, 255, 255); // now that the SD card can be access, try to load the // image file. logo = TFTscreen.loadImage("arduino.bmp"); if (!logo.isValid()) { Serial.println(F("error while loading arduino.bmp")); } Serial.println("Attempting to connect to WPA network..."); Serial.print("SSID: "); Serial.println(ssid); if (WiFi.status() == WL_NO_SHIELD) { // don't continue: Serial.println("Couldn't find a wifi-shield"); while(true); } // attempt to connect to Wifi network: while ( status != WL_CONNECTED) { status = WiFi.begin(ssid, pass); // wait 5 seconds for connection: delay(5000); } server.begin(); Serial.print("Connected to wifi. My address:"); IPAddress myAddress = WiFi.localIP(); Serial.println(myAddress); } void loop() { // don't do anything if the image wasn't loaded correctly. if (logo.isValid() == false) { return; } Serial.println(F("drawing image")); // get a random location where to draw the image. // To avoid the image to be draw outside the screen, // take into account the image size. int x = random(TFTscreen.width() - logo.width()); int y = random(TFTscreen.height() - logo.height()); // draw the image to the screen TFTscreen.image(logo, x, y); // wait a little bit before drawing again delay(1500); } По отдельности девайсы работают нормально. Погуглил тему - ничего похожего не нашел, запостил тему на официальном форуме ардуино. За пару дней никто не отозвался. В общем грусть пичалька (сколько хорошего пива можно было купать за те деньги)... Решил поэкспериментировать с физическим отключением от ардуино портов дисплея. Вот тут и началось все самое интересное . При отсоединении порта MISO дисплея от ардуино все оживало - дисплей показывает, wi-fi живет и здравствует (при этом встроенный в tft sd работать не будет, т.к. нечем данные передавать). Как говорится WTF???? Решил вкурить схему Arduino TFT LCD Screen (тут). Смотрим как наши желтолицие итальянские собратья по разуму накосячили сделали порт MISO. Немного лирики в теорию по шине SPI - поскольку к шине SPI может подключаться несколько девайсов у каждого из них есть порт SS(CS) - выбора устройства. Когда на нем логическая единица то девайс должен перевести свой порт на шине MISO в неактивное состояние, дабы остальные могли ей пользоваться. Так вот, возвращаясь к нашим баранам, Arduino TFT LCD Screen физически этого делать не может в текущем релизе схемы. Смотрим на схему, находим IC3 - 74LVC1G125DCK - это буфер для совместимости 3,3 V логики и 5V логики дабы все работало. Вход буфера (2 нога) подключен к шине MISOB картридера, выход (4 нога) на шину MISO платы. А вот 1 нога чипа брошена на землю! Вкуриваем даташит под данному чипу и читаем на простом аглицком языке - де данная нога используется для перевода вывода буфера в неактивное состояние при наличие на ней логической 1. А у нас на ней всегда логический 0. Т.е. MISO порт ВСЕГДА АКТИВЕН не взирая на состояние порта SS картридера. А раз так то будет 100% конфликт с другими устройствами которые захотят использовать шину MISO. Что собственно и произошло в моем случае. По логике вещей 1 ногу чипа нужно вешать на шину "SD_CSB" по схеме. Тогда все должно быть хорошо. Подводя итог как юзать сей кривой девайс: 1. Если у вас в проекте только одно SPI устройство - данный дисплей и вы не планируете добавлять еще SPI девайсов, то можно не париться и подключать его как обычно по мануалу. 2. Если у вас в проекте более одного SPI девайса - тогда два варианта: 2.1 Забить на наличие картридера в дисплее и не подключать MISO порт на нем. Все остальное будет цвести и пахнуть . 2.2 Взять в руки паяльник и исправить косяк на плате дисплея. Тоже будет все работать, включая картридер на дисплее . P.S. извиняюсь за длиннопост. Всем бобра . P.S.S пойду сочинять bug report на arduino.cc
Не совсем... туда по идее нужно вкорячить логику "2И", чтобы было /MISO_EN=/SD_CSB and /LCD_CSB. (активный уровень низкий, поэтому выражение эквивалентно MISO_EN=SD_CSB or LCD_CSB) К сожалению, у логики SN74LVC1G08 нет третьего состояния выхода, хотя распиновка и совпадает со 125-м буфером, просто заменить чип не выйдет. Нда... знатный косяк у них вышел.
Да косяк тот еще. С необходимость делать MISO_EN=SD_CSB or LCD_CSB TFT не согласен, по следующей причине - для SPI шины TFT и SD разные устройства - они должны независимо друг от друга работать и соответственно освобождать MISO. Но поскольку TFT не использует MISO то нужно исправить только то, что я выше в описал.