Individální projekty MPOA

Mikroprocesory s architekturou ARM

Uživatelské nástroje

Nástroje pro tento web


2016:ft800-driver

Zadání

Navrhněte driver pro grafický řadič FT800 a kompatibilní. Možnosti driveru prakticky demonstrujte. Aplikace bude využívat dotykové ovládání, obsahovat vlastní textový font a umožňovat vykreslování widgetů.

Úvod

Cílem projektu bylo vytvořit C driver pro grafický řadič FT800 (a kompatibilní varianty). Driver by měl umožňovat naplno využívat možnosti chipu. Dále pak vytvořit ukázkovou aplikaci sloužící jako kostru pro další aplikace. Tato aplikace má implementovat všechny potřebné soubory a funkce pro použití vlastních fontů a bitmap. Dále pak má umožňovat změnu barevného schématu a jazyka použitého v aplikaci.

FT800

Driver je určen primárně pro FT800. Tento řadič je specifický tím, že umožňuje tvorbu pokročilých GUI (grafických uživatelských rozhraní) s minimálními nároky na řídící mikrokontrolér. Obvod je připojován pomoci SPI (serial peripherial interface) s rychlostí až 30MHz nebo pomocí i2c (Inter-Integrated Circuit) do rychlosti 3.4MHz. Varianta FT800 umožnuje připojení displejů o rozlišení až 512×512 pixelů, přičemž každá barva je reprezentována 6-ti vodiči. Jde tedy o 18-bitovou hloubku (262144 barev). Obvod dále podporuje připojení rezistivní dotykové vrstvy. Uživateli pak poskytuje nejen souřadnice stlačeného bodu, ale také informaci o objektu na daných souřadnicích. Řadič dále umožňuje generování PWM mono audio signálu a je tedy vhodný i pro složitá GUI. Malé náročnosti pro řídící mikrokontrolér je dosaženo mimo jiné pomocí widgetů, což jsou složitější prvky, jako například tlačítka, posuvníky, hodiny, stavové ukazatele a mnohé další. Uživatelská aplikace může každému vykreslenému prvku nebo objektu přiřadit tag, který slouží jako identifikátor objektu. Následným sledováním tagu může aplikace zjišťovat, zda došlo k dotyku objektu a libovolným způsobem reagovat. Pro vykreslení obrazovky se vytváří DL (Display-list). Pro jeho tvorbu je vymezená paměť velikosti 8192B, do které může mikrokontrolér zapisovat příkazy a následně je nechat vykreslit pomocí dedikovaného registru. Do této paměti může ale zapisovat také grafický koprocesor, který vytvoří widgety. Proto není vhodné do této paměti zapisovat a využívat raději FIFO koprocesoru k vykreslování jednoduchých prvků i widgetů. Tento blok paměti má velikost 4096B a pro jeho obsluhu má řadič dva registry sloužící jako zapisovací a čtecí ukazatel. Zapisovací ukazatel musí po zapsání příkazů inkrementovat aplikace. Naopak čtecí ukazatel obsluhuje grafický koprocesor. Jsou-li si oba ukazatele rovné, znamená to, že všechny příkazy už byly zpracovány a zapsány do DL. FIFO je realizováno jako kruhový zásobník. Pro jednodušší aplikace lze využít některý z dostupných nástrojů umožňující vytvářet aplikace pomocí grafického prostředí nebo použití arduino knihovny. Nicméně ani jedno z těchto řešení se neukázalo pro vývoj aplikací příliš vhodné.

ft800.jpg

Hardware

Driver je psán nezávisle na platformě. Pro použití v libovolné aplikaci je potřeba pouze správně nakonfigurovat soubor FT800 library_cfg.h (makra pro ovládání CS pro SPI, makra pro inicializaci SPI pro dvě různé rychlosti, definice datových typů, optimalizacční proměnné, velikost interního pole pro zpracování řetězců, rozlišení a typ displeje, …). Pro použití pro jiný FTDI řadič je pak potřeba zkontrolovat a případně upravit nebo vyměnit soubor FT800 library.h který obsahuje mimo jiné definice adres registrů a mapování pamětí řadiče.

DRIVER

Struktura driveru

Driver se skládá ze tří souborů. FT800 library.c - hlavní modul FT800 library.h - deklarace funkci hlavního modulu, definice registrů, adresace pamětí řadiče, parametry pro prvky a widgety FT800 library_cfg.h - konfigurace driveru specifická pro danou aplikaci a hardware

Hlavní modul

Modul obsahuje definice funkcí rozdělené do několika sekcí. Funkce pro : - zápis a čtení z registrů (7 funkcí) - tvorbu a řízení DL (3 funkce) - nastavení grafického kontextu (40 funkcí) - funkce pro koprocesor (45 funkcí) - uživatelské funkce (19 funkcí)

První dvě sekce pro grafický kontext a koprocesor kompletně implementují api z dokumentu FT800 Series Programmer Guide, další sekce vznikaly postupně na základě potřeb během vývoje.

Funkce nastavené grafického kontextu

Tyto funkce mohou být použity přímo pro zápis do DL nebo mohou být použity prostřednictvým FIFO koprocesoru (preferovaná varianta). Návratová hodnota je vždy výsledkem logických operací mezi opcodem a parametry. Jednoduchým příkladem může být funkce line_width.

uint32_t line_width(uint16_t width){         //sets width of line primitive in 1/16th pixel precision
      uint32_t temp=0;
      temp=(width)|(0x0E000000);
      return temp;   
}

Funkce pro koprocesor

Tyto funkce zapisují do FIFO koprocesoru, který následně vytváří DL. Veškereé widgety jsou umístěny v této části. Příkladem může být vykreslení tlačítka. Nejdříve je kontrolován staf FIFO, poté následuje opcode a parametry specifické pro daný příkaz (mapříklad souřadnice, rozměry, vypisovaný řetězec,…),nakonec je inkrementován zapisovací ukazatel FIFO (včetně zarovnání na 4B).

void cmd_button(sint16_t x, sint16_t y,sint16_t w, sint16_t h, sint16_t font, uint16_t options,const char *s){        //draws a button
      uint32_t i=0;
      uint32_t read_addr;
      uint32_t write_addr;
      /* Waiting is needed to ensure that the coprocessor buffer does not overflow. BUFFER_RESERVE is used to make the program faster */
      uint8_t wait_condition;
      do{
            read_addr=rd16(REG_CMD_READ);
            write_addr=rd16(REG_CMD_WRITE);
            if(write_addr>=read_addr)
                wait_condition = ((write_addr-read_addr)>BUFFER_RESERVE?1:0);
            else
                wait_condition = ((write_addr+BUFFER_SIZE-read_addr)>BUFFER_RESERVE?1:0);                
      }while(wait_condition); 
          
      wr32(RAM_CMD+(write_addr),0xFFFFFF0D);
      wr16(RAM_CMD+((write_addr+4)&(BUFFER_SIZE-1)),x);
      wr16(RAM_CMD+((write_addr+6)&(BUFFER_SIZE-1)),y);
      wr16(RAM_CMD+((write_addr+8)&(BUFFER_SIZE-1)),w);
      wr16(RAM_CMD+((write_addr+10)&(BUFFER_SIZE-1)),h);
      wr16(RAM_CMD+((write_addr+12)&(BUFFER_SIZE-1)),font);
      wr16(RAM_CMD+((write_addr+14)&(BUFFER_SIZE-1)),options);
      
      while(*(s+i)!=0){
            wr8(RAM_CMD+((write_addr+16+i)&(BUFFER_SIZE-1)),*(s+i));
            i++;
      }
      wr8(RAM_CMD+((write_addr+16+i)&(BUFFER_SIZE-1)),*(s+i));
      i++;  
      wr16(REG_CMD_WRITE,(write_addr+16+i+3)&0xffc);     
}

Uživatelské funkce

Tato sekce se sice dále dělí na několik částí, nicméně obsahem všech jsou funkce, které souvisí s tvorbou GUI a jsou universálně použitelné pro různé projekty jako například : inicializace FT800, inicializace barev, inicializace řetězců, inicializace bitmamp a uživatelských fontů, kalibrace dotykové vrstvy, čtení tagu nebo souřadnic, konverze řetězců, inteligentní zalamování řetězců, počítadlo FPS, a další.

Možnosti aplikací

Driver byl použit již ve více projektech různé složitosti. Všechny aplikace jsou stejně strukturované a je tudíž velmi jednoduché vytvořit novou aplikaci. Postačuje zkopírovat několik souborů a pak už jen vytvářet jednotlivé obrazovky. Kostra nového projektu je tedy daná a je výsledkem postupného vývoje. Poutřebné soubory : - ftf.c,ftf.h,tft_cfg.h - hlavní modul ve kterém se nachází jednotlivé obrazovky - FT800 library.c, FT800 library.h, FT800 library_cfg.h - driver FT800 - tft_global_variables.h - strings.h - soubor s texty - font_data.h - soubor s daty pro font - bitmaps.h - soubor s daty pro bitmapy - tft_types.h - definice konfigurační struktury (jazyk,podsvit,barevné schema, …)

Stavový automat

Aplikace je strukturována jako stavový automat se stavovou proměnnou scr. Jednotlivé obrazovky často přistupují ke stejným datům a většina proměnných je tak pro modul globálních. Během běhu programu je potřeba periodicky provádět některé operace jako například kontrola stavů časovačů nebo čtení tagu. Tyto operace jsou prováděny mezi vykreslením obrazovek z hlavní smyčky, která obrazovky volá. Obrazovky („screeny“) jsou tedy implementovány jako jednorázové vykreslení, ne jako smyčky.

    /* Touch handling */
    ...
    /* Timers handling */
    ...
    /* Screen state machine */
    switch (scr) {                          //screens are not loops (they are called repeatedly)
        case MAIN_SCREEN: //MAIN screan
            main_screen();
            break;
        case SETTINGS_SCREEN: //settings
            settings_screen();            
            break;
        case PASSWORD_SCREEN: //password
            password_screen();            
            break;
        case
           .
           .
           .
    }

Obrazovky (screeny),DL

Každé překreslení obrazovky je reprezentováno vykreslením jednoho displej listu (DL). Každý DL začíná voláním cmd_dlstart, dále pokračuje vykreslováním dalších příkazů s případnými výpočty. Ukončuje ho příkaz cmd(display()) a vykresluje ho cmd_swap(). Driver je koncipován bez vlastního zásobníku, tj. příkazy se posílají do FT800 přímo a je tedy možné mezitím provádět výpočty (např. souřadnic), což by při jednorázovém odeslání zásobníku nebylo možné. Navíc by bylo nutné alokovat 4KB SRAM, což by omezilo použití driveru pro menší mikrokontroléry. Obrazovky jsou vykresleny typicky s 20 až 70 FPS podle jejich složitosti.

Příklad jednoduché obrazovky:

cmd_dlstart();

/* Background gradient */
cmd_gradient_custom(COLOR_GR1);
/* RGB type of color for the next commants */
cmd_set_color(COLOR_STR3,_COLOR_RGB);
/* Print text to the center of the screen */ 
cmd_text(DISP_WIDTH/2,DISP_HEIGHT/2,28,OPT_CENTERX,"Hello World"); 
/* Draw button with tag 2, if it currently touched it is wrawned as flat */
cmd(tag(2)); 
cmd_button(5.5,20, 30, (atag==2)*OPT_FLAT,"Press here");
.
.
.
/* End of DL */
cmd(display());
/* Draw */
cmd_swap();

Fonty, bitmapy

FT800 má integrovány dva druhy fontů v několika velikostech. Pokud aplikace vyžaduje font například s českou diakritikou, je možné si tento font pomocí poskytovaného nástroje pro příkazovou řádku vygenerovat. K tomu je potřeba soubor fontu a textový soubor se znaky, které mají být vytvořeny. Výsledná data lze vložit například jako hlavičkový soubor do kódu. Dále je potřeba font do řadiče nahrát a správně jej inicializovat (custom_font_init). Aby bylo možné font použít, je nejdříve nutné konvertovat řetězce na správné kódování (znaky ve vytvořeném fontu jsou kódovány podle pořadí v textovém souboru před konverzí, kdežto řetězce v kódu jsou dány vývojovým prostředím). K tomu slouží další uživatelské funkce obsahující převod znaků podle kódovací tabulky.

Podobně jako s fonty je možné dedikovaným nástrojem konvertovat bitmapy v různých formátech. Ty je následně potřeba, stejně jako fonty, nahrát do paměti a inicializovat (ardesa,rozměry, handle,formát,..).

Retězce, jazyky

Aby bylo možné měnit jazyk aplikace, obsahuje program vícerozměrné pole s adresami konstantních řetězců. První index určuje text (např. „Nastavení“,„Vytvořit položku“,…), druhý index vybírá jazyk.

Barevná schémata

Podobně jako u řetězců obsahuje aplikace tabulku barev. První index určuje tzv. třídu (tlačítko typu jedna-BUT1, text typu 1 -STR1, bitmapy popředí -BMFG, gradient na pozadí GR11, atd..), druhý index par určuje složku RGB. Pro změnu barevného schématu stačí předat driveru adresu jiné tabulky barev. Jelikož grafický kontext používá tři druhy barev (COLOR_RGB,FGCOLOR,BGCOLOR), byla v ytvořena funkce cmd_set_color, která nastavování zjednodušuje.

Demonstrace funkcí

Následující video demonstruje široké možnosti vytvořeného driveru a možnosti aplikace. Tento konkrétní projekt realizuje nízkonapěťovou část spínacích hodin. Tato komplexní aplikace je postavena na 8-bitovém mikrokontroléru z řady ATXMEGA.

Na následujících snímcích je vidět hardware vytvořený v rámci diplomové práce a ukázková aplikace. Tato zařízení jsou řízena pomocí mikrokontrolérů s jádry ARM (STM - STM32F030CC) realizují vývojové desky pro bezdrátový přenos audio signálu ve standardu WiSA. Jelikož konkrétní aplikace je zatím ve vývoji, byla pro demonstraci pouze přeportována jiná aplikace, která ukazuje, že vytvořená driver je možné použít pro různé platformy.

Závěr

Projekt popisuje vytvořený driver umožňující plné využití grafického řadiče FT800. Software je universálné a může být použit pro libovolnou platformu. Tento řadič spolu s vytvořeným ovladačem umožňuje tvorbu pokročilých GUI při minimálních nárocích na mikrokontrolér. Software byl již využit pro několik profesionálních produktů, na dalších se pracuje a další jsou v plánu (vztaženo k datu vytvoření tohoto dokumentu).

2016/ft800-driver.txt · Poslední úprava: 2017/01/14 12:56 autor: Jeroným Juráň