LinkedIn YouTube Facebook
Szukaj

Wstecz
Artykuły

Aris Edge S3A3 – nakładka z wyświetlaczem TFT Aris Edge LCD

Aplikacja demonstracyjna pracuje pod kontrolą systemu RTOS. Aby obsłużyć wyświetlacz, a w zasadzie interfejs użytkownika zbudowany w oparciu o wyświetlacz i panel dotykowy, zdefiniowano w konfiguratorze Synergy Configuration programu e2studio wątek GUI Thread – rysunek 7.

Rysunek 7. Dodanie wątku GUI Thread

Teraz trzeba dodać do stosu wątku framework SPI. Po jego dodaniu pojawi się różowy prostokąt z prośbą o dodanie sterownika SPI. Mamy do wyboru interfejs SCI pracujący jako SPI, lub RSPI. Wyprowadzenia modułu Aris Edge umożliwiają tylko użycie interfejsu SCI i dlatego wybieramy r_sci_spi. Dodanie frameworka i wybór interfejsu SPI został pokazany na rysunku 8.

Rysunek 8. Dodawanie frameworka SPI oraz dodanie drivera r_sci_spi

Konfigurator doda automatycznie wszystkie potrzebne moduły niższego poziomu – rysunek 9.

Rysunek 9. Konfiguracja frameworka SPI z automatycznie dodanymi modułami niższych poziomów

Moduły oznaczone paskiem szarym działają samodzielnie, a oznaczone paskiem niebieskim są współdzielone i mogą być w projekcie dodane tylko raz.

W module frameworka g_sf_spi_lcd konfigurujemy parametry pracy interfejsu SPI:

  • Fazę zegara LCD_SCLK i jego polaryzację, kiedy moduł nie jest wybrany (stan IDLE)
  • Linię portu, która pełni funkcję sygnału wyboru LCD_CS – w naszym przypadku jest to linia P411
  • Aktywny poziom linii LCD_CS

Współdzielony moduł g_st_spi_bus0 nie wymaga konfiguracji. W module drivera obsługującego moduł komunikacyjny SCI skonfigurowanego do pracy jako SPI konfigurujemy:

  • Kanał (nr 1)
  • Tryb pracy Master
  • Dosuniecie bitów (MSB)
  • Prędkość transmisji

Można tu również zmienić priorytety przerwań zgłaszanych przez interfejs SCI.

Te konfiguracje dostarczają narzędzi do obsługi interfejsu SPI. Można teraz interfejs wykorzystać do komunikacji ze sterownikiem wyświetlacza. Biblioteka SSP nie wspiera bezpośrednio specjalizowanych sterowników wyświetlaczy i należy odpowiednie funkcje napisać samemu lub skorzystać z gotowych rozwiązań. W projekcie programu demonstracyjnego firmy Reloc można znaleźć pliki z gotowymi driverami mogącymi pracować pod kontrolą RTOS. Żeby sterowanie wyświetlacza było możliwe, trzeba zacząć od procedur wysyłania przez SPI do sterownika komend i danych obrazu. Na listingu 1 pokazano przykładową procedurę zapisywania danych do rejestru sterownika wyświetlacza.

static ssp_err_t SF_ILI9225_WriteReg( sf_ili9225_ctrl_t * const p_ctrl,
                                      uint8_t reg_addr,
                                      uint16_t reg_value )
{
    ssp_err_t status;
    
    /* najpierw wysyłamy kod komendy z argumentu reg_addr*/
    
       /*linia sterująca LED_CD w stanie niskim*/
  	g_ioport.p_api->pinWrite(p_ctrl->cmd_pin, IOPORT_LEVEL_LOW);
       /*wysyłamy przez SPI kod komendy*/
status = p_ctrl->spi->p_api->write(p_ctrl->spi->p_ctrl, &reg_addr, SF_ILI9225_CMD_REG_LEN, SPI_BIT_WIDTH_8_BITS, TX_WAIT_FOREVER);
/*linia sterująca LED_CD w stanie wysokim */
    g_ioport.p_api->pinWrite(p_ctrl->cmd_pin, IOPORT_LEVEL_HIGH);
	/*czy wysłanie komendy zakończone powodzeniem?*/
    if (SSP_SUCCESS == status)
    {
        /* wysyłanie danych do zaadresowanego rejestru */
        uint8_t tmp_buf[SF_ILI9225_DATA_LEN];
        tmp_buf[0] = (uint8_t) (reg_value >> 8);
        tmp_buf[1] = (uint8_t) (reg_value & 0xFF);
        status = p_ctrl->spi->p_api->write(p_ctrl->spi->p_ctrl, &tmp_buf[0], SF_ILI9225_DATA_LEN, SPI_BIT_WIDTH_8_BITS, TX_WAIT_FOREVER);
    }
    return status;
}

Listing 1. Funkcja wysyłania danych do rejestru sterownika wyświetlacza

Sterownik musi być zainicjalizowany z parametrami właściwymi dla użytej matrycy TFT. Dane konfiguracyjne (inicjalizacyjne) zostały zapisane w tablicy pokazanej na listingu 2. W celu dokładnej analizy należy je skonfrontować z dokładnym opisem rejestrów sterujących użytego sterownika.

static const sf_ili9225_cmd init_cmd_list[] =
{
    /* Initial Sequence */
    { SF_ILI9225_REG_DRIVER_OUTPUT_CONTROL,         0x001C },       // NL (528*220 dots) (Screen orientation depending on configuration)
    { SF_ILI9225_REG_LCD_AC_DRIVING_CONTROL,        0x0100 },       // 1 Line Inversion
    { SF_ILI9225_REG_ENTRY_MODE,                    0x1030 },       // GRAM update direction
    { SF_ILI9225_REG_BLANK_PERIOD_CONTROL_1,        0x0808 },       // Back Porch = 8 lines, Front Porch = 8 lines
    { SF_ILI9225_REG_INTERFACE_CONTROL,             0x0001 },       // RGB 16bit
    { SF_ILI9225_REG_OSCILLATION_CONTROL,           0x0801 },       // Refresh Rate 71 Hz
    { SF_ILI9225_REG_RAM_ADDRESS_SET_1,             0x0000 },       // Initial RAM address
    { SF_ILI9225_REG_RAM_ADDRESS_SET_2,             0x0000 },       // Initial RAM address
    /* Power On Sequence */
    { SF_ILI9225_DELAY,                             50     },
    { SF_ILI9225_REG_POWER_CONTROL_1,               0x0A00 },       // Gamma amplification to default
    { SF_ILI9225_REG_POWER_CONTROL_2,               0x103B },       // VCI1 at 2.76 V
    { SF_ILI9225_DELAY,                             50     },
    { SF_ILI9225_REG_POWER_CONTROL_3,               0x3121 },       // VGH = 5x VCI1, VGL = -4x VC1, StepUp1= 1/2 Fosc, StepUp2= 1/16 Fosc, StepUp3= 1/8 Fosc
    { SF_ILI9225_REG_POWER_CONTROL_4,               0x0066 },       // GVDD = Vreg1out = 4.5 V
    { SF_ILI9225_REG_POWER_CONTROL_5,               0x3660 },       // VCOML = GVDD * 0.6985, VCOMH = GVDD * 1.014
    /* Set GRAM area */
    { SF_ILI9225_REG_GATE_SCAN_CONTROL,             0x0000 },       // Start from G1
    { SF_ILI9225_REG_VERTICAL_SCROLL_CONTROL_1,     0x00DB },       // End from 219
    { SF_ILI9225_REG_VERTICAL_SCROLL_CONTROL_2,     0x0000 },       // Start from 0
    { SF_ILI9225_REG_VERTICAL_SCROLL_CONTROL_3,     0x0000 },       // Step
    { SF_ILI9225_REG_PARTIAL_DRIVING_POSITION_1,    0x00DB },       // End from 219
    { SF_ILI9225_REG_PARTIAL_DRIVING_POSITION_2,    0x0000 },       // Start from 0
    { SF_ILI9225_REG_HORIZONTAL_WINDOW_ADDRESS_1,   0x00AF },       // End from 175
    { SF_ILI9225_REG_HORIZONTAL_WINDOW_ADDRESS_2,   0x0000 },       // Start from 0
    { SF_ILI9225_REG_VERTICAL_WINDOW_ADDRESS_1,     0x00DB },       // End from 219
    { SF_ILI9225_REG_VERTICAL_WINDOW_ADDRESS_2,     0x0000 },       // Start from 0
    /* Adjust Gamma Curve */
    { SF_ILI9225_REG_GAMMA_CONTROL_1,               0x0400 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_2,               0x080B },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_3,               0x0E0C },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_4,               0x0103 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_5,               0x0C0E },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_6,               0x0B08 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_7,               0x0004 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_8,               0x0301 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_9,               0x0E00 },       // Gamma
    { SF_ILI9225_REG_GAMMA_CONTROL_10,              0x000E },       // Gamma
    /* Turn on display */
    { SF_ILI9225_DELAY,                             50     },
    { SF_ILI9225_REG_DISPLAY_CONTROL_1,             0x1017 },       // Activate display
};

Listing 2. Definicja wartości inicjalizacyjnych sterownika wyświetlacza

Zgodnie z zasadami tworzenia modułów współpracujących z modułami biblioteki SSP napisano funkcję SF_ILI9225_Open(), która wykonuje:

  • inicjowanie struktury p_ctrl wartościami konfiguracyjnymi
  • zainicjowanie interfejsu SPI
  • wyzerowanie sprzętowe sterownika wyświetlacza
  • wysłanie do sterownika sekwencji komend inicjujących jego pracę

Funkcja SF_ILI9225_Open() została pokazana na listingu 3.

ssp_err_t SF_ILI9225_Open ( sf_ili9225_ctrl_t * const p_ctrl,
                            sf_ili9225_cfg_t const * const p_cfg )
{
    ssp_err_t status;
    uint16_t rotation_cfg;
    /* inicjowanie p_ctrl */
    p_ctrl->cmd_pin = p_cfg->cmd_pin;
    p_ctrl->reset_pin = p_cfg->reset_pin;
    p_ctrl->spi = p_cfg->spi;
    p_ctrl->x_size = p_cfg->x_size;
    p_ctrl->y_size = p_cfg->y_size;
    p_ctrl->byte_per_pixel = p_cfg->byte_per_pixel;

	/* określenie orientacji wyświetlacza*/
    
    switch( p_cfg->rotation_angle )
    {
        case 0  :   rotation_cfg = SF_ILI9225_REG_DRIVER_OUTPUT_CONTROL_ROTATION_0;     break;
        case 180:   rotation_cfg = SF_ILI9225_REG_DRIVER_OUTPUT_CONTROL_ROTATION_180;   break;
        default :   SF_ILI9225_ASSERT( SSP_ERR_INVALID_ARGUMENT );                      break;
    }
    
    status = p_ctrl->spi->p_api->open(p_ctrl->spi->p_ctrl, p_ctrl->spi->p_cfg);
    
    g_ioport.p_api->pinWrite(p_ctrl->reset_pin, IOPORT_LEVEL_HIGH);
    g_ioport.p_api->pinWrite(p_ctrl->cmd_pin, IOPORT_LEVEL_HIGH);
    
    if (SSP_SUCCESS == status)
    {
        uint32_t i;
        
        /* sprzętowe zerowanie sterownika*/
        tx_thread_sleep(CONV_MS_TO_TICK(1));
        g_ioport.p_api->pinWrite(p_ctrl->reset_pin, IOPORT_LEVEL_LOW);
        tx_thread_sleep(CONV_MS_TO_TICK(10));
        g_ioport.p_api->pinWrite(p_ctrl->reset_pin, IOPORT_LEVEL_HIGH);
        tx_thread_sleep(CONV_MS_TO_TICK(50));
        
        status = p_ctrl->spi->p_api->lock( p_ctrl->spi->p_ctrl );
        /* wysłanie do sterownika wyświetlacza sekwencji inicjującej*/
        if( status == SSP_SUCCESS )
        {
            for( i=0 ; i<(sizeof(init_cmd_list)/sizeof(sf_ili9225_cmd)) ; i++ )
            {
                if( init_cmd_list[i].command == SF_ILI9225_DELAY )
                {
                    /* Sleep command */
                    tx_thread_sleep(CONV_MS_TO_TICK(init_cmd_list[i].data));
                }
                else if ( init_cmd_list[i].command == SF_ILI9225_REG_DRIVER_OUTPUT_CONTROL )
                {
                    /* Add orientation configuration */
                    status = SF_ILI9225_WriteReg( p_ctrl, init_cmd_list[i].command, (init_cmd_list[i].data | rotation_cfg) );
                    if(SSP_SUCCESS != status)
                    {
                        break;
                    }
                }
                else
                {
                    /* Normal command */
status = SF_ILI9225_WriteReg( p_ctrl, init_cmd_list[i].command, init_cmd_list[i].data );
                    if(SSP_SUCCESS != status)
                    {
                        break;
                    }
                }
            }
            
            p_ctrl->spi->p_api->unlock( p_ctrl->spi->p_ctrl );
        }
    }
    
    if (SSP_SUCCESS == status)
    {
        p_ctrl->open = SF_ILI9225_INSTANCE_OPEN;
    }
    
    return status;
}

Listing 3. Funkcja inicjalizacji sterownika wyświetlacza

Firma Arrow Electronics przygotowała 10 zestawów, w skład których wchodzą Aris Edge S3A3 oraz nakładka z ekranem LCD Aris Edge LCD. Będą one nagrodami w konkursie, w którym pytania oparte będą na treści artykułów o zestawie. Zadania konkursowe ogłoszone zostaną na początku września. Serdecznie zapraszamy do udziału już teraz!
Absolwent Wydziału Elektroniki Politechniki Wrocławskiej, współpracownik miesięcznika Elektronika Praktyczna, autor książek o mikrokontrolerach Microchip i wyświetlaczach graficznych, wydanych nakładem Wydawnictwa BTC. Zawodowo zajmuje się projektowaniem zaawansowanych systemów mikroprocesorowych.