* Examples / LCD: Refactored LCD code from an example
This commit is contained in:
parent
f1f2f31b5e
commit
59d3143be5
|
@ -0,0 +1,202 @@
|
|||
with Ada.Unchecked_Conversion;
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
|
||||
with Board.SPI.IO;
|
||||
use Board;
|
||||
|
||||
package body Board.LCD.IO is
|
||||
procedure Initialize_SPI is
|
||||
begin
|
||||
-- First initialize SPI to communicate onboard controller
|
||||
SPI_RCC_EN := True;
|
||||
SPI_RCC_RST := True;
|
||||
SPI_RCC_RST := False;
|
||||
|
||||
declare
|
||||
R : STM32.SPI.Control_Register_1 := SPI_Module.CR1;
|
||||
begin
|
||||
R.BR := STM32.SPI.PCLK_DIV_16;
|
||||
R.CPHA := STM32.SPI.Late_Clock;
|
||||
R.CPOL := STM32.SPI.Positive_Clock;
|
||||
R.DFF := STM32.SPI.Frame_8_Bit;
|
||||
R.LSBFIRST := False;
|
||||
R.SSM := True;
|
||||
R.SSI := True;
|
||||
R.MSTR := STM32.SPI.Master;
|
||||
R.SPE := True;
|
||||
R.RXONLY := False;
|
||||
R.BIDIMODE := STM32.SPI.Unidirectional;
|
||||
R.BIDIOE := True;
|
||||
R.CRCEN := False;
|
||||
R.CRCNEXT := False;
|
||||
|
||||
SPI_Module.CR1 := R;
|
||||
end;
|
||||
|
||||
declare
|
||||
R : STM32.SPI.Control_Register_2 := SPI_Module.CR2;
|
||||
begin
|
||||
R.FRF := STM32.SPI.Motorola_Mode;
|
||||
SPI_Module.CR2 := R;
|
||||
end;
|
||||
|
||||
-- Enabling pins
|
||||
RCC.AHB1ENR (Index.GPIOC) := True;
|
||||
RCC.AHB1ENR (Index.GPIOD) := True;
|
||||
RCC.AHB1ENR (Index.GPIOF) := True;
|
||||
|
||||
CSX.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
CSX.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
CSX.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
CSX.Set (True);
|
||||
|
||||
DCX.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
DCX.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
DCX.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
DCX.Set (True);
|
||||
|
||||
SCL_Port.AFR (SCL_Bit) := STM32.GPIO.Alternate_Functions.SPI5;
|
||||
SCL.Set_MODER (STM32.GPIO.Alternate_Mode);
|
||||
SCL.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
SCL.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
SCL.Set_PUPDR (STM32.GPIO.Pull_Up);
|
||||
|
||||
SDA_Port.AFR (SDA_Bit) := STM32.GPIO.Alternate_Functions.SPI5;
|
||||
SDA.Set_MODER (STM32.GPIO.Alternate_Mode);
|
||||
SDA.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
SDA.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
SDA.Set_PUPDR (STM32.GPIO.Pull_Up);
|
||||
end;
|
||||
|
||||
procedure Enter is
|
||||
begin
|
||||
CSX.Set (False);
|
||||
end;
|
||||
|
||||
procedure Leave is
|
||||
begin
|
||||
CSX.Set (True);
|
||||
end;
|
||||
|
||||
procedure Command (Command : ILI9341.Command) is
|
||||
function To_Unsigned_8 is new Ada.Unchecked_Conversion (ILI9341.Command, Interfaces.Unsigned_8);
|
||||
begin
|
||||
DCX.Set(False);
|
||||
SPI.IO.Transmit (LCD.SPI_Module, To_Unsigned_8 (Command));
|
||||
end;
|
||||
|
||||
procedure Command (Command : ILI9341.Command; Data_1 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
IO.Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI.IO.Transmit (LCD.SPI_Module, Data_1);
|
||||
end;
|
||||
|
||||
procedure Data (Data : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
DCX.Set (True);
|
||||
SPI.IO.Transmit (LCD.SPI_Module, Data);
|
||||
end;
|
||||
|
||||
procedure Data (Data : Unsigned_8_Array) is
|
||||
begin
|
||||
DCX.Set (True);
|
||||
for D of Data loop
|
||||
SPI.IO.Transmit (LCD.SPI_Module, D);
|
||||
end loop;
|
||||
end;
|
||||
|
||||
procedure Command (Command : ILI9341.Command; Data : Unsigned_8_Array) is
|
||||
begin
|
||||
IO.Command (Command);
|
||||
IO.Data (Data);
|
||||
end;
|
||||
|
||||
procedure Initialize_Controller is
|
||||
Now : Time := Clock;
|
||||
begin
|
||||
Enter;
|
||||
|
||||
-- Initialization procedure per
|
||||
-- https://github.com/mongoose-os-libs/ili9341-spi
|
||||
-- released under Apache licence
|
||||
|
||||
Command (ILI9341.SWRESET);
|
||||
Now := Clock + Milliseconds (5);
|
||||
delay until Now;
|
||||
|
||||
Command (ILI9341.Power_Control_A, (16#39#, 16#2C#, 16#00#, 16#34#, 16#02#));
|
||||
-- Vcore = 1.6, DDVDH = 5.6 (default)
|
||||
Command (ILI9341.Power_Control_B, (16#00#, 16#C1#, 16#30#));
|
||||
-- PCEQ = 1, DRV_ena = 0, Power_Control = 0, DRV_vml = 0, DRV_vmh = 0, DC_ena = 1
|
||||
--Command (ILI9341.Undocumented_EF, 16#03#, 16#80#, 16#02#);
|
||||
Command (ILI9341.Driver_Timing_Control_A, (16#85#, 16#00#, 16#78#));
|
||||
-- NOW = 1, EQ = 0, CR = 0, precharge = 2unit
|
||||
Command (ILI9341.Driver_Timing_Control_B, (16#00#, 16#00#));
|
||||
-- T1 = 0, T2 = 0, T3 = 0, T3 = 0
|
||||
Command (ILI9341.Power_On_Sequence_Control, (16#64#, 16#03#, 16#12#, 16#81#));
|
||||
-- CP1 = 1frame, CP23 = 3frame, En_vcl = 1st, En_ddvdh = 4th, En_vgh = 2nd, En_vgl = 3rd, DDVDH = En
|
||||
Command (ILI9341.Pump_Ratio_Control, (16#20#));
|
||||
-- DDVDH = 2xVCI
|
||||
Command (ILI9341.PWCTRL1, (16#23#));
|
||||
-- GVDD level = 4.45 V
|
||||
Command (ILI9341.PWCTRL2, (16#10#));
|
||||
-- VGH = VCIx7, VGL = VCIx4
|
||||
Command (ILI9341.VMCTRL1, (16#3E#, 16#28#));
|
||||
-- VCOMH = 4.250, VCOML = -1.500
|
||||
Command (ILI9341.VMCTRL2, (16#86#));
|
||||
-- nVM = 1, VCOMH = VMH - 58
|
||||
Command (ILI9341.MADCTL, (16#48#));
|
||||
-- MY = 0, MX = 1, MV = 0, ML = 0, BGR = 1, MH = 0
|
||||
Command (ILI9341.PIXSET, (16#66#));
|
||||
-- RGB = 18bpp, MCU = 18bpp
|
||||
Command (ILI9341.DINVOFF);
|
||||
Command (ILI9341.FRMCTR1, (16#00#, 16#13#));
|
||||
-- DivA = fosc, RTNA = 19 clocks
|
||||
Command (ILI9341.DISCTRL, (16#08#, 16#82#, 16#27#, 16#00#));
|
||||
-- PTG Intervalscan, PT = V63/V0/VCOMH/L, REV = White, ISC = 5 fr, GS = G1>G320,W, NL = 320, Fosc = DOTCLK/2
|
||||
Command (ILI9341.PTLAR, (16#00#, 16#00#, 16#01#, 16#3F#));
|
||||
-- SR = 0, ER = 319
|
||||
Command (ILI9341.Enable_3G, (16#02#));
|
||||
-- 3G = disable
|
||||
Command (ILI9341.GAMSET, (16#01#));
|
||||
-- Curve = G2.2
|
||||
Command (ILI9341.PGAMCTRL, (16#0F#, 16#31#, 16#2B#, 16#0C#, 16#0E#,
|
||||
16#08#, 16#4E#, 16#F1#, 16#37#, 16#07#, 16#10#, 16#03#, 16#0E#, 16#09#, 16#00#));
|
||||
Command (ILI9341.NGAMCTRL, (16#00#, 16#0E#, 16#14#, 16#03#, 16#11#,
|
||||
16#07#, 16#31#, 16#C1#, 16#48#, 16#08#, 16#0F#, 16#0C#, 16#31#, 16#36#, 16#0F#));
|
||||
Now := Clock + Milliseconds (120);
|
||||
delay until Now;
|
||||
Command (ILI9341.SLPOUT);
|
||||
Command (ILI9341.DISPON);
|
||||
|
||||
LCD.IO.Leave;
|
||||
end Initialize_Controller;
|
||||
|
||||
procedure Plot_24 (X, Y, R, G, B: Integer) is
|
||||
begin
|
||||
-- Draw a pixel;
|
||||
Enter;
|
||||
|
||||
Command (ILI9341.CASET, (
|
||||
Interfaces.Unsigned_8 (X / 256),
|
||||
Interfaces.Unsigned_8 (X mod 256),
|
||||
Interfaces.Unsigned_8 ((X + 1) / 256),
|
||||
Interfaces.Unsigned_8 ((X + 1) mod 256)));
|
||||
Command (ILI9341.PASET, (
|
||||
Interfaces.Unsigned_8 (Y / 256),
|
||||
Interfaces.Unsigned_8 (Y mod 256),
|
||||
Interfaces.Unsigned_8 ((Y + 1) / 256),
|
||||
Interfaces.Unsigned_8 ((Y + 1) mod 256)));
|
||||
Command (ILI9341.RAMWR, (
|
||||
Interfaces.Unsigned_8 (G),
|
||||
Interfaces.Unsigned_8 (B),
|
||||
Interfaces.Unsigned_8 (R)));
|
||||
|
||||
Leave;
|
||||
end;
|
||||
begin
|
||||
Initialize_SPI;
|
||||
Initialize_Controller;
|
||||
|
||||
end Board.LCD.IO;
|
|
@ -0,0 +1,34 @@
|
|||
with Interfaces;
|
||||
with STM32.GPIO.Ports; use STM32.GPIO.Ports;
|
||||
with ILI9341;
|
||||
|
||||
package Board.LCD.IO is
|
||||
package CSX is new GPIO_Port_Boolean (LCD.CSX_Port, LCD.CSX_Bit);
|
||||
package DCX is new GPIO_Port_Boolean (LCD.DCX_Port, LCD.DCX_Bit);
|
||||
package SCL is new GPIO_Port_Boolean (LCD.SCL_Port, LCD.SCL_Bit);
|
||||
package SDA is new GPIO_Port_Boolean (LCD.SDA_Port, LCD.SDA_Bit);
|
||||
|
||||
procedure Initialize_SPI;
|
||||
|
||||
procedure Enter;
|
||||
|
||||
procedure Leave;
|
||||
|
||||
procedure Command (Command : ILI9341.Command);
|
||||
|
||||
-- These LCD_Command's are for convenience
|
||||
procedure Command (Command : ILI9341.Command; Data_1 : Interfaces.Unsigned_8);
|
||||
|
||||
procedure Data (Data : Interfaces.Unsigned_8);
|
||||
|
||||
type Unsigned_8_Array is array (Integer range <>) of Interfaces.Unsigned_8;
|
||||
|
||||
procedure Data (Data : Unsigned_8_Array);
|
||||
|
||||
procedure Command (Command : ILI9341.Command; Data : Unsigned_8_Array);
|
||||
|
||||
procedure Initialize_Controller;
|
||||
|
||||
procedure Plot_24 (X, Y, R, G, B: Integer);
|
||||
|
||||
end Board.LCD.IO;
|
|
@ -0,0 +1,22 @@
|
|||
with STM32.SPI;
|
||||
package Board.LCD is
|
||||
CSX_Port : GPIO_Registers renames GPIOC;
|
||||
CSX_Bit : constant Port_Bit_Number := 2;
|
||||
|
||||
DCX_Port : GPIO_Registers renames GPIOD;
|
||||
DCX_Bit : constant Port_Bit_Number := 13;
|
||||
|
||||
TE_Port : GPIO_Registers renames GPIOD;
|
||||
TE_Bit : constant Port_Bit_Number := 11;
|
||||
|
||||
SCL_Port : GPIO_Registers renames GPIOF;
|
||||
SCL_Bit : constant Port_Bit_Number := 7;
|
||||
|
||||
SDA_Port : GPIO_Registers renames GPIOF;
|
||||
SDA_Bit : constant Port_Bit_Number := 9;
|
||||
|
||||
SPI_Module : STM32.SPI.SPI_Registers renames SPI5;
|
||||
|
||||
SPI_RCC_EN : Boolean renames RCC.APB2ENR (Index.SPI5);
|
||||
SPI_RCC_RST : Boolean renames RCC.APB2RSTR (Index.SPI5);
|
||||
end Board.LCD;
|
|
@ -0,0 +1,2 @@
|
|||
package Board.SPI is
|
||||
end;
|
|
@ -1,6 +1,5 @@
|
|||
with STM32.RCC; use STM32.RCC;
|
||||
with STM32.GPIO; use STM32.GPIO;
|
||||
with STM32.SPI;
|
||||
with Chip.Units; use Chip.Units;
|
||||
|
||||
package Board is
|
||||
|
@ -20,25 +19,6 @@ package Board is
|
|||
|
||||
LED_2_RCC_EN : Boolean renames RCC.AHB1ENR(Index.GPIOG);
|
||||
|
||||
-- LCD
|
||||
|
||||
LCD_CSX_Port : GPIO_Registers renames GPIOC;
|
||||
LCD_CSX_Bit : constant Port_Bit_Number := 2;
|
||||
|
||||
LCD_DCX_Port : GPIO_Registers renames GPIOD;
|
||||
LCD_DCX_Bit : constant Port_Bit_Number := 13;
|
||||
|
||||
LCD_TE_Port : GPIO_Registers renames GPIOD;
|
||||
LCD_TE_Bit : constant Port_Bit_Number := 11;
|
||||
|
||||
LCD_SCL_Port : GPIO_Registers renames GPIOF;
|
||||
LCD_SCL_Bit : constant Port_Bit_Number := 7;
|
||||
|
||||
LCD_SDA_Port : GPIO_Registers renames GPIOF;
|
||||
LCD_SDA_Bit : constant Port_Bit_Number := 9;
|
||||
|
||||
LCD_SPI_Module : STM32.SPI.SPI_Registers renames SPI5;
|
||||
|
||||
-- More internals
|
||||
|
||||
APB2_Frequency : constant := 90_000_000; -- Set by board support
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package body Board.SPI.IO is
|
||||
|
||||
procedure Transmit_Receive (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_16;
|
||||
Input : out Interfaces.Unsigned_16)
|
||||
is
|
||||
begin
|
||||
while not Unit.SR.TXE loop
|
||||
null;
|
||||
end loop;
|
||||
|
||||
Unit.DR := Output;
|
||||
|
||||
if Unit.SR.BSY then
|
||||
null;
|
||||
end if;
|
||||
|
||||
while not Unit.SR.RXNE loop
|
||||
null;
|
||||
end loop;
|
||||
|
||||
if Unit.SR.RXNE then
|
||||
Input := Unit.DR;
|
||||
end if;
|
||||
end;
|
||||
|
||||
procedure Transmit (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_16)
|
||||
is
|
||||
pragma Warnings (Off, "variable ""X"" is assigned but never read");
|
||||
X : Interfaces.Unsigned_16;
|
||||
pragma Warnings (On, "variable ""X"" is assigned but never read");
|
||||
begin
|
||||
Transmit_Receive (Unit, Output, X);
|
||||
end;
|
||||
|
||||
procedure Transmit_Receive (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_8;
|
||||
Input : out Interfaces.Unsigned_8)
|
||||
is
|
||||
X : Interfaces.Unsigned_16;
|
||||
begin
|
||||
Transmit_Receive (Unit, Interfaces.Unsigned_16 (Output), X);
|
||||
Input := Interfaces.Unsigned_8 (X);
|
||||
end;
|
||||
|
||||
procedure Transmit (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_8)
|
||||
is
|
||||
pragma Warnings (Off, "variable ""X"" is assigned but never read");
|
||||
X : Interfaces.Unsigned_16;
|
||||
pragma Warnings (On, "variable ""X"" is assigned but never read");
|
||||
begin
|
||||
Transmit_Receive (Unit, Interfaces.Unsigned_16 (Output), X);
|
||||
end;
|
||||
|
||||
end Board.SPI.IO;
|
|
@ -0,0 +1,21 @@
|
|||
with Interfaces;
|
||||
with STM32.SPI;
|
||||
package Board.SPI.IO is
|
||||
procedure Transmit_Receive (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_16;
|
||||
Input : out Interfaces.Unsigned_16);
|
||||
|
||||
procedure Transmit (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_16);
|
||||
|
||||
procedure Transmit_Receive (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_8;
|
||||
Input : out Interfaces.Unsigned_8);
|
||||
|
||||
procedure Transmit (
|
||||
Unit : in out STM32.SPI.SPI_Registers;
|
||||
Output : Interfaces.Unsigned_8);
|
||||
end Board.SPI.IO;
|
|
@ -1,345 +0,0 @@
|
|||
with Interfaces;
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
with Ada.Unchecked_Conversion;
|
||||
with Chip.Units; use Chip.Units;
|
||||
with Board.UART.IO; use Board;
|
||||
with ILI9341;
|
||||
|
||||
with STM32.RCC; use STM32.RCC;
|
||||
with STM32.SPI;
|
||||
with STM32.GPIO.Ports; use STM32.GPIO.Ports;
|
||||
|
||||
procedure LCD is
|
||||
package LED is new GPIO_Port_Boolean(LED_Port, LED_Bit);
|
||||
|
||||
package LED_2 is new GPIO_Port_Boolean(LED_2_Port, LED_2_Bit);
|
||||
|
||||
|
||||
package CSX is new GPIO_Port_Boolean (LCD_CSX_Port, LCD_CSX_Bit);
|
||||
package DCX is new GPIO_Port_Boolean (LCD_DCX_Port, LCD_DCX_Bit);
|
||||
package SCL is new GPIO_Port_Boolean (LCD_SCL_Port, LCD_SCL_Bit);
|
||||
package SDA is new GPIO_Port_Boolean (LCD_SDA_Port, LCD_SDA_Bit);
|
||||
|
||||
procedure SPI_Transmit (Data : Interfaces.Unsigned_16) is
|
||||
pragma Warnings (Off, "variable ""X"" is assigned but never read");
|
||||
X: Interfaces.Unsigned_16;
|
||||
pragma Warnings (On, "variable ""X"" is assigned but never read");
|
||||
begin
|
||||
--LED.Set(LED_On);
|
||||
|
||||
while not LCD_SPI_Module.SR.TXE loop
|
||||
null;
|
||||
end loop;
|
||||
|
||||
LED_2.Set (LED_2_On);
|
||||
|
||||
LCD_SPI_Module.DR := Data;
|
||||
|
||||
if LCD_SPI_Module.SR.BSY then
|
||||
null;
|
||||
end if;
|
||||
|
||||
while not LCD_SPI_Module.SR.RXNE loop
|
||||
null;
|
||||
end loop;
|
||||
|
||||
--LED.Set(not LED_On);
|
||||
LED_2.Set (not LED_2_On);
|
||||
|
||||
if LCD_SPI_Module.SR.RXNE then
|
||||
X := LCD_SPI_Module.DR;
|
||||
--UART.IO.Transmit ("Rcv: " & Interfaces.Unsigned_16'Image (X) & ASCII.CR & ASCII.LF);
|
||||
end if;
|
||||
|
||||
end;
|
||||
|
||||
procedure SPI_Transmit (Data : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
SPI_Transmit (Interfaces.Unsigned_16 (Data));
|
||||
end;
|
||||
|
||||
procedure LCD_Command (Command : ILI9341.Command) is
|
||||
function To_Unsigned_8 is new Ada.Unchecked_Conversion (ILI9341.Command, Interfaces.Unsigned_8);
|
||||
begin
|
||||
DCX.Set(False);
|
||||
SPI_Transmit (To_Unsigned_8 (Command));
|
||||
end;
|
||||
|
||||
-- These LCD_Command's are for convenience
|
||||
procedure LCD_Command (Command : ILI9341.Command; Data_1 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
LCD_Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data_1);
|
||||
end;
|
||||
|
||||
procedure LCD_Command (Command : ILI9341.Command; Data_1, Data_2 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
LCD_Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data_1);
|
||||
SPI_Transmit (Data_2);
|
||||
end;
|
||||
|
||||
procedure LCD_Command (Command : ILI9341.Command; Data_1, Data_2, Data_3 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
LCD_Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data_1);
|
||||
SPI_Transmit (Data_2);
|
||||
SPI_Transmit (Data_3);
|
||||
end;
|
||||
|
||||
procedure LCD_Command (Command : ILI9341.Command; Data_1, Data_2, Data_3, Data_4 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
LCD_Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data_1);
|
||||
SPI_Transmit (Data_2);
|
||||
SPI_Transmit (Data_3);
|
||||
SPI_Transmit (Data_4);
|
||||
end;
|
||||
|
||||
procedure LCD_Command (Command : ILI9341.Command; Data_1, Data_2, Data_3, Data_4, Data_5 : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
LCD_Command (Command);
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data_1);
|
||||
SPI_Transmit (Data_2);
|
||||
SPI_Transmit (Data_3);
|
||||
SPI_Transmit (Data_4);
|
||||
SPI_Transmit (Data_5);
|
||||
end;
|
||||
|
||||
procedure LCD_Data (Data : Interfaces.Unsigned_8) is
|
||||
begin
|
||||
DCX.Set (True);
|
||||
SPI_Transmit (Data);
|
||||
end;
|
||||
|
||||
|
||||
type Unsigned_8_Array is array (Integer range <>) of Interfaces.Unsigned_8;
|
||||
|
||||
procedure LCD_Data (Data : Unsigned_8_Array) is
|
||||
begin
|
||||
DCX.Set (True);
|
||||
for D of Data loop
|
||||
SPI_Transmit (D);
|
||||
end loop;
|
||||
end;
|
||||
|
||||
procedure Plot (X, Y, R, G, B: Integer) is
|
||||
begin
|
||||
-- Draw a pixel;
|
||||
CSX.Set (False);
|
||||
|
||||
LCD_Command (ILI9341.CASET,
|
||||
Interfaces.Unsigned_8 (X / 256),
|
||||
Interfaces.Unsigned_8 (X mod 256),
|
||||
Interfaces.Unsigned_8 ((X + 1) / 256),
|
||||
Interfaces.Unsigned_8 ((X + 1) mod 256));
|
||||
LCD_Command (ILI9341.PASET,
|
||||
Interfaces.Unsigned_8 (Y / 256),
|
||||
Interfaces.Unsigned_8 (Y mod 256),
|
||||
Interfaces.Unsigned_8 ((Y + 1) / 256),
|
||||
Interfaces.Unsigned_8 ((Y + 1) mod 256));
|
||||
LCD_Command (ILI9341.RAMWR,
|
||||
Interfaces.Unsigned_8 (G),
|
||||
Interfaces.Unsigned_8 (B),
|
||||
Interfaces.Unsigned_8 (R));
|
||||
|
||||
CSX.Set (True);
|
||||
end;
|
||||
|
||||
Period : constant Time_Span := Milliseconds(2000);
|
||||
Now : Time := Clock;
|
||||
|
||||
--X, Y : Integer := 0;
|
||||
--Colour : Integer := 0;
|
||||
|
||||
Scale : Float := 1.0/60.0;
|
||||
CRe, CIm : Float;
|
||||
ZRe, ZIm, T : Float;
|
||||
N : Integer;
|
||||
begin
|
||||
-- First initialize SPI to communicate onboard controller
|
||||
RCC.APB2ENR (Index.SPI5) := True;
|
||||
RCC.APB2RSTR (Index.SPI5) := True;
|
||||
RCC.APB2RSTR (Index.SPI5) := False;
|
||||
|
||||
UART.IO.Transmit (Boolean'Image (LCD_SPI_Module.CR1.SPE) & ASCII.CR & ASCII.LF);
|
||||
|
||||
declare
|
||||
R : STM32.SPI.Control_Register_1 := LCD_SPI_Module.CR1;
|
||||
begin
|
||||
R.BR := STM32.SPI.PCLK_DIV_16;
|
||||
R.CPHA := STM32.SPI.Late_Clock;
|
||||
R.CPOL := STM32.SPI.Positive_Clock;
|
||||
R.DFF := STM32.SPI.Frame_8_Bit;
|
||||
R.LSBFIRST := False;
|
||||
R.SSM := True;
|
||||
R.SSI := True;
|
||||
R.MSTR := STM32.SPI.Master;
|
||||
R.SPE := True;
|
||||
R.RXONLY := False;
|
||||
R.BIDIMODE := STM32.SPI.Unidirectional;
|
||||
R.BIDIOE := True;
|
||||
R.CRCEN := False;
|
||||
R.CRCNEXT := False;
|
||||
|
||||
LCD_SPI_Module.CR1 := R;
|
||||
end;
|
||||
|
||||
declare
|
||||
R : STM32.SPI.Control_Register_2 := LCD_SPI_Module.CR2;
|
||||
begin
|
||||
R.FRF := STM32.SPI.Motorola_Mode;
|
||||
LCD_SPI_Module.CR2 := R;
|
||||
end;
|
||||
|
||||
-- Enabling pins
|
||||
RCC.AHB1ENR (Index.GPIOC) := True;
|
||||
RCC.AHB1ENR (Index.GPIOD) := True;
|
||||
RCC.AHB1ENR (Index.GPIOF) := True;
|
||||
|
||||
CSX.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
CSX.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
CSX.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
CSX.Set (True);
|
||||
|
||||
DCX.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
DCX.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
DCX.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
DCX.Set (True);
|
||||
|
||||
LCD_SCL_Port.AFR (LCD_SCL_Bit) := STM32.GPIO.Alternate_Functions.SPI5;
|
||||
SCL.Set_MODER (STM32.GPIO.Alternate_Mode);
|
||||
SCL.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
SCL.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
SCL.Set_PUPDR (STM32.GPIO.Pull_Up);
|
||||
|
||||
LCD_SDA_Port.AFR (LCD_SDA_Bit) := STM32.GPIO.Alternate_Functions.SPI5;
|
||||
SDA.Set_MODER (STM32.GPIO.Alternate_Mode);
|
||||
SDA.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
SDA.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
SDA.Set_PUPDR (STM32.GPIO.Pull_Up);
|
||||
|
||||
-- LED to see what's happen
|
||||
LED_RCC_EN := True;
|
||||
|
||||
LED.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
LED.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
LED.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
LED.Set_PUPDR (STM32.GPIO.No_Pull);
|
||||
|
||||
LED.Set (not LED_On);
|
||||
|
||||
LED_2_RCC_EN := True;
|
||||
|
||||
LED_2.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
LED_2.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
LED_2.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
LED_2.Set_PUPDR (STM32.GPIO.No_Pull);
|
||||
|
||||
LED_2.Set (not LED_2_On);
|
||||
|
||||
UART.IO.Transmit (Boolean'Image (LCD_SPI_Module.CR1.SPE) & ASCII.CR & ASCII.LF);
|
||||
UART.IO.Transmit (STM32.GPIO.Alternate_Function'Image (LCD_SCL_Port.AFR (LCD_SCL_Bit)) & ASCII.CR & ASCII.LF);
|
||||
|
||||
-- Trying to transmit
|
||||
|
||||
CSX.Set (False);
|
||||
|
||||
-- Initialization procedure per
|
||||
-- https://github.com/mongoose-os-libs/ili9341-spi
|
||||
-- released under Apache licence
|
||||
|
||||
LCD_Command (ILI9341.SWRESET);
|
||||
Now := Clock + Milliseconds (5);
|
||||
delay until Now;
|
||||
LCD_Command (ILI9341.Power_Control_A, 16#39#, 16#2C#, 16#00#, 16#34#, 16#02#);
|
||||
-- Vcore = 1.6, DDVDH = 5.6 (default)
|
||||
LCD_Command (ILI9341.Power_Control_B, 16#00#, 16#C1#, 16#30#);
|
||||
-- PCEQ = 1, DRV_ena = 0, Power_Control = 0, DRV_vml = 0, DRV_vmh = 0, DC_ena = 1
|
||||
--LCD_Command (ILI9341.Undocumented_EF, 16#03#, 16#80#, 16#02#);
|
||||
LCD_Command (ILI9341.Driver_Timing_Control_A, 16#85#, 16#00#, 16#78#);
|
||||
-- NOW = 1, EQ = 0, CR = 0, precharge = 2unit
|
||||
LCD_Command (ILI9341.Driver_Timing_Control_B, 16#00#, 16#00#);
|
||||
-- T1 = 0, T2 = 0, T3 = 0, T3 = 0
|
||||
LCD_Command (ILI9341.Power_On_Sequence_Control, 16#64#, 16#03#, 16#12#, 16#81#);
|
||||
-- CP1 = 1frame, CP23 = 3frame, En_vcl = 1st, En_ddvdh = 4th, En_vgh = 2nd, En_vgl = 3rd, DDVDH = En
|
||||
LCD_Command (ILI9341.Pump_Ratio_Control, 16#20#);
|
||||
-- DDVDH = 2xVCI
|
||||
LCD_Command (ILI9341.PWCTRL1, 16#23#);
|
||||
-- GVDD level = 4.45 V
|
||||
LCD_Command (ILI9341.PWCTRL2, 16#10#);
|
||||
-- VGH = VCIx7, VGL = VCIx4
|
||||
LCD_Command (ILI9341.VMCTRL1, 16#3E#, 16#28#);
|
||||
-- VCOMH = 4.250, VCOML = -1.500
|
||||
LCD_Command (ILI9341.VMCTRL2, 16#86#);
|
||||
-- nVM = 1, VCOMH = VMH - 58
|
||||
LCD_Command (ILI9341.MADCTL, 16#48#);
|
||||
-- MY = 0, MX = 1, MV = 0, ML = 0, BGR = 1, MH = 0
|
||||
LCD_Command (ILI9341.PIXSET, 16#66#);
|
||||
-- RGB = 18bpp, MCU = 18bpp
|
||||
LCD_Command (ILI9341.DINVOFF);
|
||||
LCD_Command (ILI9341.FRMCTR1, 16#00#, 16#13#);
|
||||
-- DivA = fosc, RTNA = 19 clocks
|
||||
LCD_Command (ILI9341.DISCTRL, 16#08#, 16#82#, 16#27#, 16#00#);
|
||||
-- PTG Intervalscan, PT = V63/V0/VCOMH/L, REV = White, ISC = 5 fr, GS = G1>G320,W, NL = 320, Fosc = DOTCLK/2
|
||||
LCD_Command (ILI9341.PTLAR, 16#00#, 16#00#, 16#01#, 16#3F#);
|
||||
-- SR = 0, ER = 319
|
||||
LCD_Command (ILI9341.Enable_3G, 16#02#);
|
||||
-- 3G = disable
|
||||
LCD_Command (ILI9341.GAMSET, 16#01#);
|
||||
-- Curve = G2.2
|
||||
LCD_Command (ILI9341.PGAMCTRL);
|
||||
LCD_Data (Unsigned_8_Array'(16#0F#, 16#31#, 16#2B#, 16#0C#,
|
||||
16#0E#, 16#08#, 16#4E#, 16#F1#, 16#37#, 16#07#, 16#10#,
|
||||
16#03#, 16#0E#, 16#09#, 16#00#));
|
||||
LCD_Command (ILI9341.NGAMCTRL);
|
||||
LCD_Data (Unsigned_8_Array'(16#00#, 16#0E#, 16#14#, 16#03#,
|
||||
16#11#, 16#07#, 16#31#, 16#C1#, 16#48#, 16#08#, 16#0F#,
|
||||
16#0C#, 16#31#, 16#36#, 16#0F#));
|
||||
Now := Clock + Milliseconds (120);
|
||||
delay until Now;
|
||||
LCD_Command (ILI9341.SLPOUT);
|
||||
LCD_Command (ILI9341.DISPON);
|
||||
|
||||
CSX.Set (True);
|
||||
|
||||
|
||||
loop
|
||||
|
||||
for Y in Integer range 0 .. 319 loop
|
||||
for X in Integer range 0 .. 239 loop
|
||||
CRe := Float(- Y + 160) * Scale - 1.403;
|
||||
CIm := Float(X - 120) * Scale;
|
||||
N := 0;
|
||||
ZRe := CRe;
|
||||
ZIm := CIm;
|
||||
while ZRe * ZRe + ZIm * ZIm < 4.0 and N < 256 loop
|
||||
T := ZRe * ZRe - ZIm * ZIm + CRe;
|
||||
ZIm := 2.0 * ZRe * ZIm + CIm;
|
||||
ZRe := T;
|
||||
N := N + 1;
|
||||
end loop;
|
||||
if N = 256 then
|
||||
Plot (X, Y, 0, 0, 0);
|
||||
else
|
||||
Plot (X, Y, 255 - N, N, 255 - N);
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
Scale := Scale * 0.63;
|
||||
|
||||
Now := Clock + Period;
|
||||
delay until Now;
|
||||
|
||||
--LED.Set (not LED_On);
|
||||
|
||||
end loop;
|
||||
|
||||
|
||||
end LCD;
|
|
@ -1,5 +1,5 @@
|
|||
# Here's a example project name
|
||||
X = lcd
|
||||
X = spi_lcd
|
||||
|
||||
# Supported board list
|
||||
BOARDS = 429disco
|
|
@ -0,0 +1,80 @@
|
|||
with Interfaces;
|
||||
with Ada.Real_Time; use Ada.Real_Time;
|
||||
with Chip.Units; use Chip.Units;
|
||||
with Board.LCD.IO;
|
||||
use Board;
|
||||
with ILI9341;
|
||||
|
||||
with STM32.RCC; use STM32.RCC;
|
||||
with STM32.SPI;
|
||||
with STM32.GPIO.Ports; use STM32.GPIO.Ports;
|
||||
|
||||
procedure SPI_LCD is
|
||||
package LED is new GPIO_Port_Boolean(LED_Port, LED_Bit);
|
||||
|
||||
package LED_2 is new GPIO_Port_Boolean(LED_2_Port, LED_2_Bit);
|
||||
|
||||
Period : constant Time_Span := Milliseconds(2000);
|
||||
Now : Time := Clock;
|
||||
|
||||
--X, Y : Integer := 0;
|
||||
--Colour : Integer := 0;
|
||||
|
||||
Scale : Float := 1.0/60.0;
|
||||
CRe, CIm : Float;
|
||||
ZRe, ZIm, T : Float;
|
||||
N : Integer;
|
||||
begin
|
||||
-- LED to see what's happen
|
||||
LED_RCC_EN := True;
|
||||
|
||||
LED.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
LED.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
LED.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
LED.Set_PUPDR (STM32.GPIO.No_Pull);
|
||||
|
||||
LED.Set (not LED_On);
|
||||
|
||||
LED_2_RCC_EN := True;
|
||||
|
||||
LED_2.Set_MODER (STM32.GPIO.Output_Mode);
|
||||
LED_2.Set_OTYPER (STM32.GPIO.Push_Pull_Type);
|
||||
LED_2.Set_OSPEEDR (STM32.GPIO.Very_High_Speed);
|
||||
LED_2.Set_PUPDR (STM32.GPIO.No_Pull);
|
||||
|
||||
LED_2.Set (not LED_2_On);
|
||||
|
||||
loop
|
||||
|
||||
for Y in Integer range 0 .. 319 loop
|
||||
for X in Integer range 0 .. 239 loop
|
||||
CRe := Float(- Y + 160) * Scale - 1.403;
|
||||
CIm := Float(X - 120) * Scale;
|
||||
N := 0;
|
||||
ZRe := CRe;
|
||||
ZIm := CIm;
|
||||
while ZRe * ZRe + ZIm * ZIm < 4.0 and N < 256 loop
|
||||
T := ZRe * ZRe - ZIm * ZIm + CRe;
|
||||
ZIm := 2.0 * ZRe * ZIm + CIm;
|
||||
ZRe := T;
|
||||
N := N + 1;
|
||||
end loop;
|
||||
if N = 256 then
|
||||
LCD.IO.Plot_24 (X, Y, 0, 0, 0);
|
||||
else
|
||||
LCD.IO.Plot_24 (X, Y, 255 - N, N, 255 - N);
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
Scale := Scale * 0.63;
|
||||
|
||||
Now := Clock + Period;
|
||||
delay until Now;
|
||||
|
||||
--LED.Set (not LED_On);
|
||||
|
||||
end loop;
|
||||
|
||||
|
||||
end SPI_LCD;
|
|
@ -1,8 +1,8 @@
|
|||
with "../../stm32f4_library.gpr";
|
||||
|
||||
project LCD_429disco is
|
||||
project SPI_LCD_429disco is
|
||||
for Languages use("Ada");
|
||||
for Main use("lcd.adb");
|
||||
for Main use("spi_lcd.adb");
|
||||
for Object_Dir use "objects/429disco";
|
||||
for Target use "arm-eabi";
|
||||
for Runtime("Ada") use "ravenscar-sfp-stm32f429disco";
|
||||
|
@ -22,4 +22,4 @@ project LCD_429disco is
|
|||
for Connection_Tool use "st-util";
|
||||
end IDE;
|
||||
|
||||
end LCD_429disco;
|
||||
end SPI_LCD_429disco;
|
|
@ -290,7 +290,7 @@ package STM32.SPI is
|
|||
pragma Volatile_Full_Access (I2SCFGR);
|
||||
I2SPR : I2S_Prescaler_Register;
|
||||
pragma Volatile_Full_Access (I2SPR);
|
||||
end record;
|
||||
end record with Volatile;
|
||||
for SPI_Registers use record
|
||||
CR1 at 16#00# range 0 .. 15;
|
||||
CR2 at 16#04# range 0 .. 15;
|
||||
|
|
Loading…
Reference in New Issue