|
|
- -- raspilcd, a simple tool to display bmp pictures & text on a ST7565 LCD
- -- Copyright (C) 2014 Torsten Meissner
- --
- -- This program is free software: you can redistribute it and/or modify
- -- it under the terms of the GNU General Public License as published by
- -- the Free Software Foundation, either version 3 of the License, or
- -- (at your option) any later version.
- --
- -- This program is distributed in the hope that it will be useful,
- -- but WITHOUT ANY WARRANTY; without even the implied warranty of
- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- -- GNU General Public License for more details.
- --
- -- You should have received a copy of the GNU General Public License
- -- along with this program. If not, see http://www.gnu.org/licenses/.
-
-
-
- with Interfaces;
- use Interfaces;
- with Interfaces.C;
- use Interfaces.C;
- with Interfaces.C.extensions;
- use Interfaces.C.extensions;
- with bcm2835_h;
- use bcm2835_h;
- with Ada.Text_IO;
- use Ada.Text_IO;
-
-
-
- package body st7565lcd is
-
-
- procedure io_init is
- begin
- bcm2835_gpio_fsel(pin => LCD_CS, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
- bcm2835_gpio_fsel(pin => LCD_RST, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
- bcm2835_gpio_fsel(pin => LCD_A0, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
- bcm2835_gpio_fsel(pin => LCD_CLK, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
- bcm2835_gpio_fsel(pin => LCD_SI, mode => unsigned_char(BCM2835_GPIO_FSEL_OUTP));
- end io_init;
-
-
- procedure lcd_init is
- begin
- -- reset
- bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
- bcm2835_delayMicroseconds(unsigned_long_long(1));
- bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(LOW));
- bcm2835_delayMicroseconds(unsigned_long_long(1));
- bcm2835_gpio_write(pin => LCD_RST, on => unsigned_char(HIGH));
- bcm2835_delayMicroseconds(unsigned_long_long(1));
- -- init routine
- for index in lcd_init_data'range loop
- lcd_transfer_data(value => lcd_init_data(index), si => false);
- end loop;
- lcd_clear;
- end lcd_init;
-
-
- -- display strings on the lcd at a given position
- -- data is a string with any allowed range
- -- for strings not beginning at 0 we have to decrement the index
- -- variable for xpos by the value of the range begin, so we get
- -- for xpos a range from (xpos + 0 .. xpos + number of char in string)
- procedure lcd_ascii57_string (xpos : natural; ypos : natural; data : string) is
- begin
- for index in data'range loop
- lcd_ascii57(xpos => xpos + (index - data'first) * 6, ypos => ypos, data => character'val(character'pos(data(index))));
- end loop;
- end lcd_ascii57_string;
-
-
- procedure lcd_ascii57 (xpos : natural; ypos : natural; data : character) is
- begin
- lcd_set_page(page => ypos, column => xpos);
- -- write one 5x7 char
- for index in 0..4 loop
- lcd_transfer_data(value => font_5x7(character'pos(data))(index), si => true);
- end loop;
- -- one free column between chars
- lcd_transfer_data(value => 16#00#, si => true);
- end lcd_ascii57;
-
-
- procedure lcd_picture (xpos : natural; ypos: natural; picture : t_lcd_array) is
- begin
- for outdex in 0..7 loop
- lcd_set_page(page => ypos + outdex, column => xpos);
- for index in (128 * outdex) .. (128 * (outdex + 1) - 1) loop
- lcd_transfer_data(value => picture(index), si => true);
- end loop;
- end loop;
- end lcd_picture;
-
-
- procedure lcd_clear is
- begin
- bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
- for outdex in 0..7 loop
- lcd_set_page(page => outdex, column => 0);
- for index in 0..128 loop
- lcd_transfer_data(value => 16#00#, si => true);
- end loop;
- end loop;
- bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
- end lcd_clear;
-
-
- procedure lcd_transfer_data (value : byte; si : boolean) is
- begin
- bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(LOW));
- bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
- if si then
- bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(HIGH));
- else
- bcm2835_gpio_write(pin => LCD_A0, on => unsigned_char(LOW));
- end if;
- lcd_byte(value);
- bcm2835_gpio_write(pin => LCD_CS, on => unsigned_char(HIGH));
- end lcd_transfer_data;
-
-
- procedure lcd_set_page (page : natural; column : natural) is
- lsb : byte := byte(column + 1) and 16#0f#;
- msb : byte := byte(column + 1) and 16#f0#;
- page_int : byte := byte(page) or 16#b0#;
- begin
- msb := Shift_Right(msb, 4);
- msb := msb or 16#10#;
- lcd_transfer_data(value => page_int, si => false);
- lcd_transfer_data(value => msb, si => false);
- lcd_transfer_data(value => lsb, si => false);
- null;
- end lcd_set_page;
-
-
- procedure lcd_byte (data : byte) is
- data_int : byte := data;
- begin
- for index in 0..7 loop
- bcm2835_delayMicroseconds(unsigned_long_long(1));
- bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(LOW));
- if (data_int and 16#80#) = 16#80# then
- bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(HIGH));
- else
- bcm2835_gpio_write(pin => LCD_SI, on => unsigned_char(LOW));
- end if;
- data_int := Shift_Left(data_int, 1);
- bcm2835_delayMicroseconds(unsigned_long_long(1));
- bcm2835_gpio_write(pin => LCD_CLK, on => unsigned_char(HIGH));
- end loop;
- end lcd_byte;
-
-
- function bmp_to_lcd (bmp_picture : t_bmp_picture) return t_lcd_array is
- lcd : t_lcd_array := (others => 16#00#);
- logic : byte;
- begin
- for aussen in 0 .. 7 loop
- logic := 16#01#;
- for outdex in 0 .. 7 loop
- for index in 0 .. 127 loop
- if ((bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.red)) or
- bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.green)) or
- bmp_picture.data(aussen * 1024 + outdex * 128 + index)(which_byte(bmp_picture.mask.blue))) < 16#88#) then
- lcd(aussen * 128 + index) := lcd(aussen * 128 + index) or logic;
- end if;
- end loop;
- logic := Shift_Left(logic, 1);
- end loop;
- end loop;
- return lcd;
- end bmp_to_lcd;
-
-
- function which_byte (data : dword) return integer is
- begin
- case data is
- when 16#000000FF# =>
- return 0;
- when 16#0000FF00# =>
- return 1;
- when 16#00FF0000# =>
- return 2;
- when 16#FF000000# =>
- return 3;
- when others =>
- raise mask_exception;
- end case;
- end which_byte;
-
-
- -- read_bmp : read a bmp file in t_bmp_picture record
- procedure read_bmp (file : in Ada.Streams.Stream_IO.File_Type;
- file_access : access Ada.Streams.Root_Stream_Type'Class;
- bmp_picture : in out t_bmp_picture) is
- begin
- -- read header
- t_bmp_header'Read(file_access, bmp_picture.header);
- -- check for valid header
- if (abs bmp_picture.header.biHeight /= 64 or bmp_picture.header.biWidth /= 128 or
- (bmp_picture.header.biCompression /= 0 and bmp_picture.header.biCompression /= 3) or
- bmp_picture.header.biBitCount /= 32) then
- raise bmp_exception;
- end if;
- -- get color map if existing
- if bmp_picture.header.biCompression = 3 then
- t_color_mask'Read(file_access, bmp_picture.mask);
- end if;
- -- read in image data
- if bmp_picture.header.biHeight < 0 then
- -- top-down pixel matrix
- for index in bmp_picture.data'range loop
- if not Ada.Streams.Stream_IO.End_Of_File(file) then
- t_byte_array'Read(file_access, bmp_picture.data(index));
- end if;
- end loop;
- else
- -- bottom-top pixel matrix
- for row in reverse 0 .. 63 loop
- for column in 0 .. 127 loop
- if not Ada.Streams.Stream_IO.End_Of_File(file) then
- t_byte_array'Read(file_access, bmp_picture.data(row * 128 + column));
- end if;
- end loop;
- end loop;
- end if;
- end read_bmp;
-
-
- end st7565lcd;
|