LinkedIn YouTube Facebook
Szukaj

Newsletter

Proszę czekać.

Dziękujemy za zgłoszenie!

Wstecz
Artykuły

KwikStik K40: Kinetis i SmartSwitch z OLED

Konfiguracja SPI0

Kontroler wyświetlacza dołączony jest do linii interfejsu SPI0 mikrokontrolera Kinetis (PTA14 – CS0, PTA15 – SCK, PTA16 – DOUT, PTA17 – DIN), aby uruchomić ten interfejs należy:

  • odblokować zegary linii I/O oraz interfejsu SPI0
    SIM->SCGC5 |= (1 << SIM_SCGC5_PORTA_SHIFT);
    SIM->SCGC6 |= (1 << SIM_SCGC6_DSPI0_SHIFT);
  • wybrać funkcje linii I/O
    PORTA->PCR[14] = PORT_PCR_MUX(2);
    PORTA->PCR[15] = PORT_PCR_MUX(2);
    PORTA->PCR[16] = PORT_PCR_MUX(2);
    PORTA->PCR[17] = PORT_PCR_MUX(2);
  • skonfigurować SPI0 wpisując do rejestrów MCR i CTAR0 odpowiednie wartości. W rejestrze MCR (Module Configuration Register) wpisujemy: MSTR = 1 (tryb Master), PCSIS = 1 (podczas bezczynności linia Chip Select ma stan wysoki), DIS_TXF = 1, DIS_RXF = 1: (wyłączamy bufory FIFO wejścia i wyjścia). W rejestrze CTAR0 (Clock and Transfer Attributes Register) wpisujemy: FMSZ = 7 (liczba bitów w  ramce danych pomniejszona o jeden), CPOL = 1 (linia zegarowa podczas bezczynności jest w stanie wysokim), CPHA = 1 (stany linii danych są odczytywane na rosnącym zboczu zegara), wartości bitów PBR, DBR i BR określą częstotliwość interfejsu SPI. Ponieważ w dokumentacji kontrolera znajduje się informacja, że minimalny okres zegara to 150 ns musimy skonfigurować SPI tak, żeby częstotliwość zegara była jak najbliższa wartości (ale nie większa niż):
    1/150 ns = 1/0,00015 s  = 6666,(6) Hz
    Częstotliwość SPI zależy od bitów konfiguracyjnych następująco:
    F = (fsys/PreskalerPBR) * ((1+DBR)/PreskalerBR)
    Przy częstotliwości zegara systemowego 25 MHz (domyślne ustawienie) analizując możliwe wartości bitów dobrym wyborem będzie DBR = 0, PreskalerPBR=2 (bity PBR=0) i PreskalerBR=2 (bity BR=0), wtedy otrzymujemy:
    F = 25 MHz/2 * (1/2) = 25 MHz/4 = 6,250 MHz

Wysyłanie danych realizowane jest przez funkcję:

void SPI0Write(char b, char h)
{
	if (h)
		SPI0->PUSHR = b | SPI_PUSHR_CTAS(0) | SPI_PUSHR_PCS(1);	
	  else
		SPI0->PUSHR = b | SPI_PUSHR_CTAS(0) | SPI_PUSHR_PCS(1) | (1 << SPI_PUSHR_CONT_SHIFT);	
		
    while (! (SPI0->SR & SPI_SR_RFDF_MASK));
    SPI0->POPR;
    SPI0->SR |= SPI_SR_RFDF_MASK;
}

Aby wysłać bajt trzeba go wpisać do rejestru PUSHR jako najmłodsze osiem bitów. Wpisane razem z danymi starsze 16 bitów określa sposób wysłania danych:

  • PCS[5:0] – te bity określają która linia CS będzie w danym transferze, my ustawiamy bit 0 (SPI_PUSHR_PCS(1)), ponieważ korzystamy z linii CS0,
  • CTAS[2:0] – możliwe wartości to 0 i 1, do transmisji wykorzystywane będą ustawienia zawarte odpowiednio w rejestrze CTAR0 lub CTAR1.
  • CONT – jeśli ten bit ma wartość 0 to po zakończeniu transmisji linia CS powróci do stanu jaki przyjmuje podczas bezczynności (w naszym przypadku jedynka). W funkcji SPI0Write bit CONT jest ustawiany w zależności od parametru h.

Następnie w pętli czekamy aż rejestr POPR będzie gotowy do odczytu, potem odczytujemy ten rejestr i kasujemy flagę SPI_SR_RFDF_MASK. Rejest POPR musi zostać odczytany, ponieważ w innym przypadku niemożliwe byłoby wysłanie następnego bajtu.

Obsługa kontrolera wyświetlacza ISC15ANP4

Do obsługi kontrolera wyświetlacza potrzebna jest nam jeszcze jedna linia wyjściowa mikrokontrolera, która sterować będzie wejściem D/C kontrolera (PTE10), w zależności od jej stanu dane przesyłane interfejsem SPI są traktowane jako: instrukcje dla kontrolera (dla D/C = 0) lub dane do wyświetlenia (dla D/C = 1). Przebieg czasowy ramki danych SPI przestawiony jest na rysunku 3.

 

Rys. 3. Przebieg sygnałów interfejsu SPI i linii D/C

Rys. 3. Przebieg sygnałów interfejsu SPI i linii D/C

 

 

Przed użyciem przycisku należy skonfigurować sterownik wyświetlacza, zadanie to wykonywane jest w funkcji ISC15ANP4_Init. Dokumentacja nie opisuje funkcji poszczególnych instrukcji, zawiera tylko dwa zestawy instrukcji konfiguracyjnych, z czego jedna zapewnia wyższą jasność obrazu i 15000 godzin działania, druga – niższą jasność i 30000 godzin działania, ja wykorzystałem tę pierwszą (fragment funkcji ISC15ANP4_Init):

	SPI0Write(0x81, 0); SPI0Write(0x19, 1); // Contras for color A		
	SPI0Write(0x82, 0); SPI0Write(0x14, 1);	// Contras for color B
	SPI0Write(0x83, 0); SPI0Write(0x24, 1);	// Contras for color C
	SPI0Write(0x87, 0); SPI0Write(0x0F, 1);	// Master current control
	SPI0Write(0xA0, 0); SPI0Write(0x70, 1);	// Remap & color depth setting
	SPI0Write(0xA1, 0); SPI0Write(0x00, 1);	// Set display start line
	SPI0Write(0xA2, 0); SPI0Write(0x10, 1);	// Set display offset
	SPI0Write(0xA4, 1); 					// Normal display
	SPI0Write(0xA8, 0); SPI0Write(0x2F, 1);	// Multiplex ratio
	SPI0Write(0xAB, 0); SPI0Write(0x00, 0); SPI0Write(0x12, 0); SPI0Write(0x0C, 0); SPI0Write(0x14, 0); SPI0Write(0x12, 1); //Dim mode setting for color A, B &C
	SPI0Write(0xAD, 0); SPI0Write(0x8E, 1);	// Master configuration
	SPI0Write(0xB0, 0); SPI0Write(0x0B, 1);	// Power save mode
	SPI0Write(0xB1, 0); SPI0Write(0x44, 1);	// Phase 1 and 2 period adjustment
	SPI0Write(0xB3, 0); SPI0Write(0xA0, 1);	// Display clock divider/ oscillator frequency
	SPI0Write(0xB9, 1);						// Enable linear gray scale
	SPI0Write(0xBB, 0); SPI0Write(0x12, 1);	// Pre charge level
	SPI0Write(0xBE, 0); SPI0Write(0x28, 1);	// Set Vcomh
	SPI0Write(0xAF, 1); 					// Display on in normal mode	

Zapis do pamięci obrazu sterownika wyświetlacza polega na wysłaniu danych przez interfejs SPI podczas gdy linia D/C ma stan wysoki. Ponieważ sterownik jest przystosowany do pracy również z większymi wyświetlaczami jego pamięć jest większa niż wymagana dla 3072 pikseli (64×48), umiejscowienie widocznego na wyświetlaczu obrazu w pamięci sterownika widać na rysunku 4.

 

Rys. 4. Widoczny na wyświetlaczu obszar pamięci kontrolera

Rys. 4. Widoczny na wyświetlaczu obszar pamięci kontrolera