1
0
mirror of https://github.com/Klagarge/Cursor.git synced 2024-11-30 12:43:28 +00:00
Cursor/Libs/Lcd/hdl/lcdCharacterEncoder_RTL.vhd
2021-11-24 10:50:51 +01:00

214 lines
7.6 KiB
VHDL

library Common;
use Common.CommonLib.all;
ARCHITECTURE Encoder OF lcdCharacterEncoder IS
constant lcdLineBitNb : positive := 6;
constant lcdPageBitNb : positive := 4;
constant lcdColumnBitNb : positive := 8;
type fontDisplayStateType is (
init, idle, readChar, displayColumns
);
signal fontDisplayState : fontDisplayStateType;
signal asciiColumnCounter : unsigned(requiredBitNb(fontColumnNb)-1 downto 0);
signal pixelOffset : unsigned(requiredBitNb(fontColumnNb*fontRowNb-1)-1 downto 0);
signal pageCounter : unsigned(requiredBitNb(lcdPageNb)-1 downto 0);
signal columnCounter : unsigned(requiredBitNb(lcdColumnNb)-1 downto 0);
signal A0 : std_ulogic;
signal pixelPage : std_ulogic_vector(fontRowNb-1 downto 0);
signal pixelColumnHigh : std_ulogic_vector(fontRowNb-1 downto 0);
signal pixelColumnLow : std_ulogic_vector(fontRowNb-1 downto 0);
BEGIN
------------------------------------------------------------------------------
-- diplay FSM
fontDisplaySequencer: process(reset, clock)
begin
if reset = '1' then
fontDisplayState <= init;
elsif rising_edge(clock) then
case fontDisplayState is
when init =>
if lcdBusy = '0' then
fontDisplayState <= idle;
end if;
when idle =>
if asciiSend = '1' then
fontDisplayState <= readChar;
end if;
when readChar =>
fontDisplayState <= displayColumns;
when displayColumns =>
if (asciiColumnCounter = 0) and (lcdBusy = '0') then
fontDisplayState <= idle;
end if;
end case;
end if;
end process fontDisplaySequencer;
asciiBusy <= '0' when fontDisplayState = idle
else '1';
a0_proc: process(reset ,clock)
begin
if reset = '1' then
A0 <= '0';
elsif rising_edge(clock) then
if asciiSend = '1' then
if unsigned(asciiData) < 32 then
A0 <= '0';
else
A0 <= '1';
end if;
end if;
end if;
end process a0_proc;
------------------------------------------------------------------------------
-- ascii column counter
asciiCountColums: process(reset, clock)
begin
if reset = '1' then
asciiColumnCounter <= (others => '0');
elsif rising_edge(clock) then
if asciiColumnCounter = 0 then
if (fontDisplayState = idle) and (asciiSend = '1') then
asciiColumnCounter <= asciiColumnCounter + 1;
end if;
else
if (fontDisplayState = displayColumns) and (lcdBusy = '0') then
if asciiColumnCounter < fontColumnNb then
asciiColumnCounter <= asciiColumnCounter + 1;
else
asciiColumnCounter <= (others => '0');
end if;
end if;
end if;
end if;
end process asciiCountColums;
------------------------------------------------------------------------------
-- page, column counter
counter: process(reset, clock)
begin
if reset = '1' then
pageCounter <= (others => '0');
columnCounter <= (others => '0');
clearDisplay <= '0';
elsif rising_edge(clock) then
clearDisplay <= '0';
if asciiSend = '1' then
case to_integer(unsigned(asciiData)) is
when 2 => -- Start of text (home)
pageCounter <= (others => '0');
columnCounter <= (others => '0');
when 3 => -- End of text (end)
pageCounter <= to_unsigned(lcdPageNb - 1,pageCounter'length);
columnCounter <= to_unsigned(lcdColumnNb - fontColumnNb, columnCounter'length);
when 8 => -- BS (backspace) (column back)
if (columnCounter - fontColumnNb) < 0 then
columnCounter <= (others => '0');
else
columnCounter <= columnCounter - fontColumnNb;
end if;
when 10 => -- LF (linefeed) (next line)
if pageCounter = (lcdPageNb-1) then
pageCounter <= (others => '0');
else
pageCounter <= pageCounter + 1;
end if;
when 11 => -- Vertical Tab (prev line)
if pageCounter = 0 then
pageCounter <= to_unsigned(lcdPageNb - 1,pageCounter'length);
else
pageCounter <= pageCounter - 1;
end if;
when 13 => -- CR (carriage return) (coloumn back)
columnCounter <= (others => '0');
when 24 => -- CAN (cancel) (clear display)
clearDisplay <= '1';
when others =>
if asciiData >= x"20" then -- normal ascii char
columnCounter <= columnCounter + fontColumnNb;
end if;
end case;
end if;
end if;
end process counter;
lcdSend <= '1' when
(fontDisplayState = displayColumns) and
(lcdBusy = '0') and
(asciiColumnCounter > 0)
else '0';
------------------------------------------------------------------------------
-- Ram Data
pixelOffset <= resize(
resize(fontColumnNb-asciiColumnCounter, pixelOffset'length)*fontRowNb,
pixelOffset'length
) when asciiColumnCounter > 0
else (others => '0');
pixelPage <=
pixelData(
to_integer(pixelOffset) + fontRowNb-1 downto
to_integer(pixelOffset) + lcdPageBitNb
) &
std_ulogic_vector(resize(pageCounter,lcdPageBitNb));
pixelColumnHigh <=
pixelData(
to_integer(pixelOffset) + fontRowNb-1 downto
to_integer(pixelOffset) + (lcdColumnBitNb/2)
) &
std_ulogic_vector(columnCounter(
columnCounter'high downto (columnCounter'length/2)
));
pixelColumnLow <=
pixelData(
to_integer(pixelOffset) + fontRowNb-1 downto
to_integer(pixelOffset) + (lcdColumnBitNb/2)
) &
std_ulogic_vector(columnCounter(
(columnCounter'length/2)-1 downto columnCounter'low
));
buildLcdData: process(
A0, pixelData, pixelOffset,
pixelPage, pixelColumnHigh, pixelColumnLow
)
begin
lcdData(lcdData'high) <= A0;
if A0 = '1' then
lcdData(lcdData'high-1 downto 0) <= pixelData(
to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset)
);
elsif pixelOffset >= 40 then
lcdData(lcdData'high-1 downto 0) <= pixelData(
to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset)
);
elsif pixelOffset >= 32 then
lcdData(lcdData'high-1 downto 0) <= pixelPage;
elsif pixelOffset >= 24 then
lcdData(lcdData'high-1 downto 0) <= pixelColumnHigh;
elsif pixelOffset >= 16 then
lcdData(lcdData'high-1 downto 0) <= pixelColumnLow;
else
lcdData(lcdData'high-1 downto 0) <= pixelData(
to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset)
);
end if;
end process buildLcdData;
--lcdData <= A0 & pixelData(to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset)) when (A0 = '1')
-- else A0 & pixelData(to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset)) when (pixelOffset >= 40)
-- else A0 & pixelPage when (pixelOffset >= 32)
-- else A0 & pixelColumnHigh when (pixelOffset >= 24)
-- else A0 & pixelColumnLow when (pixelOffset >= 16)
-- else A0 & pixelData(to_integer(pixelOffset)+fontRowNb-1 downto to_integer(pixelOffset));
END ARCHITECTURE Encoder;