📄 multiio_apb.vhd
字号:
for i in 0 to 1 loop
if i = MUXCounter then
MultiIO_out.led_ca_out(i) <= '1' xnor led7act;
else
MultiIO_out.led_ca_out(i) <= '0' xnor led7act;
end if;
end loop; -- i
-- when 3 =>
when others =>
MultiIO_out.led_a_out <= r.lcdreg(0);
MultiIO_out.led_b_out <= r.lcdreg(1);
MultiIO_out.led_c_out <= r.lcdreg(2);
MultiIO_out.led_d_out <= r.lcdreg(3);
MultiIO_out.led_e_out <= r.lcdreg(4);
MultiIO_out.led_f_out <= r.lcdreg(5);
MultiIO_out.led_g_out <= r.lcdreg(6);
MultiIO_out.led_dp_out <= r.lcdreg(7);
-- when 3 =>
-- MultiIO_out.lcd_enable <= '0';
-- -- data has been processed
-- if r.serviced = '1' then
-- v.new_data := '0';
-- end if;
end case;
MultiIO_out.lcd_rw <= r.lcdreg(8);
MultiIO_out.lcd_regsel <= r.lcdreg(9);
if MUXCounter = 3 then
MultiIO_out.lcd_enable <= '1';
else
MultiIO_out.lcd_enable <= '0';
end if;
if MUXCounter = MUXMAX-1 then
-- reset new data flag
v.new_data := '0';
v.serviced := '1';
end if;
-- register inputs from expansion connector
v.exp_in_reg(N_EXPBITS/2-1 downto 0) := MultiIO_in.exp_in;
MultiIO_out.exp_out <= r.exp_out_reg(N_EXPBITS/2-1 downto 0);
-- MultiIO_out.lcd_enable <= r.lcdreg(10);
-- configure control port of audio codec for SPI mode
MultiIO_out.codec_mode <= '1';
apbo.prdata <= readdata; -- output data to Leon
apbo.pirq <= irqs; -- output IRQs to Leon
apbo.pindex <= pindex; -- output index to Leon
rin <= v; -- update registers
end process;
apbo.pconfig <= pconfig; -- output config to Leon
regs : process(clk) -- update registers
begin
if rising_edge(clk) then
r <= rin;
end if;
end process;
KeyBoard : process(clk, rst_n)
variable ColumnStrobe : std_logic_vector(2 downto 0);
variable FirstTime : boolean;
variable NewColumnRow : std_logic_vector(6 downto 0);
begin
if rst_n = '0' then
MultiIO_out.column_out <= (others => '0'); -- all column off
Key <= X"40"; -- default '@' after Reset and no key pressed
OldColumnRow1 <= "1111111";
OldColumnRow2 <= "1110011";
ColumnStrobe := "001";
FirstTime := true;
elsif rising_edge(clk) then
if Enable1ms then
if MultiIO_in.row_in = "0000" then -- no key pressed
ColumnStrobe := ColumnStrobe(1) & ColumnStrobe(0) & ColumnStrobe(2); -- rotate column
MultiIO_out.column_out <= ColumnStrobe;
if not FirstTime then
Key <= X"3F"; -- no key pressed '?'
end if;
else -- key pressed
OldColumnRow2 <= OldColumnRow1;
-- check whether button inputs produce a high or a
-- low level, then assign these inputs in order that
-- they can be decoded into ASCII format
if buttonact = '1' then
NewColumnRow := ColumnStrobe & MultiIO_in.row_in;
else
NewColumnRow := ColumnStrobe & not MultiIO_in.row_in;
end if;
OldColumnRow1 <= NewColumnRow;
if (ColumnStrobe & MultiIO_in.row_in = OldColumnRow1) and
(OldColumnRow1 = OldColumnRow2)
then -- debounced
FirstTime := false; -- 1st valid key pressed
case OldColumnRow2 is -- decode keys into ascii characters
when "0010001" => Key <= x"31"; -- 1
when "0010010" => Key <= x"34"; -- 4
when "0010100" => Key <= x"37"; -- 7
when "0011000" => Key <= x"43"; -- C
when "0100001" => Key <= x"32"; -- 2
when "0100010" => Key <= x"35"; -- 5
when "0100100" => Key <= x"38"; -- 8
when "0101000" => Key <= x"30"; -- 0
when "1000001" => Key <= x"33"; -- 3
when "1000010" => Key <= x"36"; -- 6
when "1000100" => Key <= x"39"; -- 9
when "1001000" => Key <= x"45"; -- E
when others => Key <= x"39"; -- ? -- more than one key pressed
end case;
else
Key <= x"3D"; -- '<' -- bouncing
end if; -- debounce
end if; -- MultiIO_in.row_in
end if; -- Enable1ms
end if; -- rst_n
end process;
-- generate 1ms count and MUX signals for keyboard and 7Segment
Count1ms : process(clk, rst_n)
constant devider1ms : integer := clk_freq_in / 10_000;
variable frequency_counter : integer range 0 to Devider1ms;
begin
if rst_n = '0' then
frequency_counter := Devider1ms;
Enable1ms <= false;
MUXCounter <= 0;
elsif rising_edge(clk) then
-- if r.new_data = '1' then -- new LCD data has been written
-- MUXCounter <= 0;
-- frequency_counter := Devider1ms;
-- Enable1ms <= false;
if frequency_counter = 0 then -- 1-ms counter has expired
frequency_counter := Devider1ms;
Enable1ms <= true;
if (MUXCounter = MUXMAX-1) or (MUXCounter = 1 and r.new_data = '0') then
MUXCounter <= 0;
else
MUXCounter <= MUXCounter + 1;
end if;
else
frequency_counter := frequency_counter - 1;
Enable1ms <= false;
end if;
end if;
end process;
---------------------------------------------------------------------------------------
-- AUDIO CODEC SECTION
---------------------------------------------------------------------------------------
-- audio clock generation
clk_gen: ClockGenerator
port map (
Clk => clk,
Reset => rst_n,
omclk => clkgen_mclk,
obclk => clkgen_bclk,
osclk => clkgen_sclk,
olrcout => clkgen_lrclk);
-- drive clock signals by clock generator
MultiIO_out.CODEC_SCLK <= clkgen_sclk;
MultiIO_out.CODEC_MCLK <= clkgen_mclk;
MultiIO_out.CODEC_BCLK <= clkgen_bclk;
MultiIO_out.CODEC_LRCIN <= clkgen_lrclk;
MultiIO_out.CODEC_LRCOUT <= clkgen_lrclk;
-- SPI control interface
spi_xmit_1: spi_xmit
generic map (
data_width => N_CODECBITS)
port map (
clk_i => clkgen_SCLK,
rst_i => rst_n,
data_i => r.codecreg(N_CODECBITS-1 downto 0),
CODEC_SDIN => MultiIO_out.CODEC_SDIN,
CODEC_CS => MultiIO_out.CODEC_CS);
-- I2C data interface
ParToI2s_1: ParToI2s
generic map (
SampleSize_g => N_CODECI2SBITS)
port map (
Clk_i => clk,
Reset_i => rst_n,
SampleLeft_i => SampleReg,
SampleRight_i => SampleReg,
StrobeLeft_i => Strobe,
StrobeRight_i => Strobe,
SampleAck_o => SampleAck,
WaitForSample_o => WaitForSample,
SClk_i => clkgen_sclk,
LRClk_i => clkgen_lrclk,
SdnyData_o => MultiIO_out.CODEC_DIN);
audio_ctrl_sm: process(SampleAck, WaitForSample, state)
begin
next_state <= state;
next_Strobe <= '0';
case state is
when WAIT_FOR_SYNC =>
if WaitForSample='1' then
next_state <= READY;
end if;
when READY =>
next_state <= WAIT_FOR_ACK;
next_Strobe <= '1';
when WAIT_FOR_ACK =>
if SampleAck = '1' then
next_state <= READY;
end if;
when others =>
next_state <= WAIT_FOR_SYNC;
end case;
end process;
audio_ctrl_reg: process(clk, rst_n)
begin
if rst_n = '0' then -- asynchronous reset
state <= WAIT_FOR_SYNC;
Strobe <= '0';
SampleReg <= (others =>'0');
elsif clk'event and clk = '1' then
state <= next_state;
Strobe <= next_Strobe;
if (next_Strobe)='1' then
-- if Mode = '0' then
-- SampleReg <= std_ulogic_vector(unsigned(AudioSample)- X"80");
-- else
-- SampleReg <= AudioSample;
-- end if;
SampleReg <= std_ulogic_vector(r.codecreg2(N_CODECI2SBITS-1 downto 0));
end if;
end if;
end process;
---------------------------------------------------------------------------------------
-- DEBUG SECTION
---------------------------------------------------------------------------------------
-- pragma translate_off
KeyVal <=
ascii2char(conv_integer(Key)) when
(conv_integer(Key) >= 16#30#) and (conv_integer(Key) <= 16#46#)
else 'U';
bootmsg : report_version
generic map ("MultiIO_APB6:" & tost(pindex) &
", Human Interface Controller rev " & tost(REVISION) &
", IRQ " & tost(pirq));
-- pragma translate_on
end architecture;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -