?? uc_interface.vhd
字號:
stat_en <= '1';
cntrl_en <= '0';
xmit_en <= '0';
rcv_en <= '0';
ssel_en <= '0';
when SPICR_ADDR => -- control register has been addressed
stat_en <= '0';
cntrl_en <= '1';
xmit_en <= '0';
rcv_en <= '0';
ssel_en <= '0';
when SPITR_ADDR => -- transmit data register has been addressed
stat_en <= '0';
cntrl_en <= '0';
xmit_en <= '1';
rcv_en <= '0';
ssel_en <= '0';
when SPIRR_ADDR => -- transmit data register has been addressed
stat_en <= '0';
cntrl_en <= '0';
xmit_en <= '0';
rcv_en <= '1';
ssel_en <= '0';
when SPISSR_ADDR => -- slave select register has been addressed
stat_en <= '0';
cntrl_en <= '0';
xmit_en <= '0';
rcv_en <= '0';
ssel_en <= '1';
when others => -- error condition, no registers are enabled
stat_en <= '0';
cntrl_en <= '0';
xmit_en <= '0';
rcv_en <= '0';
ssel_en <= '0';
end case;
else
-- this device is not addressed
address_match <= '0';
stat_en <= '0';
cntrl_en <= '0';
xmit_en <= '0';
rcv_en <= '0';
ssel_en <= '0';
end if;
end if;
end process;
--************************** Read/Write uC registers **********************************
-- This process reads data from or writes data to the enabled register
register_rw: process(clk, reset)
begin
-- Initialize all internal registers upon reset
if reset = RESET_ACTIVE then
-- Status Register
spierr_reset <= RESET_ACTIVE;-- write to this bit clears it
int_reset <= RESET_ACTIVE;-- write to this bit clears it
-- Control Register
spien <= '0'; -- enables the SPI interface
inten <= '0'; -- enables interrupts
start <= '0'; -- instructs SPI interface to start transfer
clkdiv <= (others => '0'); -- divisor for SCLK from system clock
cpha <= '0'; -- clock phase
cpol <= '0'; -- clock polarity
rcv_cpol <= '0'; -- edge to use to clock incoming data
-- Slave Select Register
spissr <= (others => '0'); -- initialize to no slaves selected
-- Transmit data register
spitr <= (others => '0'); -- initialize transmit data to 0
xmit_empty_reset <= (RESET_ACTIVE); -- when transmit register is written,
-- the empty flag is reset
-- Receive data register
rcv_full_reset <= (RESET_ACTIVE); -- when receive register is read, the
-- full flag is reset
-- Initialize data bus
data_out <= (others => '0');
-- Check for rising edge of clock
elsif clk'event and (clk = '1') then
-- Check for data transfer state
if (prs_state = DATA_TRS) then
-- Control Register
if cntrl_en = '1' then
if wr_n = '0' then
-- uC write
spien <= data_in(7);
inten <= data_in(6);
start <= data_in(5);
clkdiv <= data_in(4 downto 3);
cpha <= data_in(2);
cpol <= data_in(1);
rcv_cpol<= data_in(0);
end if;
if rd_n = '0' then
-- uC read
data_out <= spien & inten & start &
clkdiv & cpha & cpol & rcv_cpol;
end if;
end if;
-- Status Register
if stat_en = '1' then
if wr_n = '0' then
-- uC write to these bits generates a reset
if data_in(6) = '0' then
spierr_reset <= RESET_ACTIVE;
else
spierr_reset <= not(RESET_ACTIVE);
end if;
end if;
if rd_n = '0' then
-- uC read
data_out <= dt & spierr & bb & int_n &
xmit_empty & rcv_full & "00";
end if;
end if;
-- Transmit Data Register
if xmit_en = '1' then
if wr_n = '0' then
-- uC write
spitr <= data_in;
-- reset the empty flag
xmit_empty_reset <= RESET_ACTIVE;
end if;
if rd_n = '0' then
-- uC Read
data_out <= spitr;
end if;
end if;
-- Receive Data Register
if rcv_en = '1' then
if rd_n = '0' then
-- uC Read
data_out <= spirr;
-- reset the full flag
rcv_full_reset <= RESET_ACTIVE;
end if;
end if;
-- Slave select Register
if ssel_en = '1' then
if wr_n = '0' then
-- uC write
spissr <= data_in;
end if;
if rd_n = '0' then
-- uC Read
data_out <= spissr;
end if;
end if;
else
xmit_empty_reset<= not(RESET_ACTIVE);
rcv_full_reset <= not(RESET_ACTIVE);
spierr_reset <= not(RESET_ACTIVE);
end if;
end if;
end process;
--************************** Status register **********************************
-- This process implements the bits in the status register
statusreg_process: process(clk, reset)
begin
if reset = RESET_ACTIVE then
bb <= '0';
spierr <= '0';
int_n <= '1';
dt <= '0';
elsif clk'event and clk = '1' then
-- bus busy asserts when slave select is asserted
if ss_n = '0' then
bb <= '1';
else
bb <= '0';
end if;
-- spi error asserts when the input slave select is asserted
-- once asserted, this bit stays asserted until written to by the uC
if spierr_reset = RESET_ACTIVE then
spierr <= '0';
elsif ss_in_int = '0' then
spierr <= '1';
end if;
-- interrupt is asserted when the SPITR is empty or an error
-- occurs IF interrupts are enabled
-- interrupt service routine should read status register to determine
-- cause of interrupt. After the first byte transfer, the RCV_FULL flag
-- should be set when XMIT_EMPTY asserts so that uC can read receive data
-- once asserted, this bit stays asserted until uC reads the status register.
if spierr_reset = RESET_ACTIVE or xmit_empty_reset = RESET_ACTIVE or
rcv_full_reset = RESET_ACTIVE then
int_n <= '1';
elsif inten = '1' then
-- interrupts are enabled
-- interrupt processor if there is an spierr, the xmit buffer is
-- empty or if the receive buffer is full and its the end of the
-- transmission
if spierr = '1' or
(start = '1' and xmit_empty = '1') or
(start = '0' and rcv_full = '1') then
int_n <= '0';
end if;
end if;
-- data transfer bit asserts when done is asserted
if done = '1' then
dt <= '1';
else
dt <= '0';
end if;
end if;
end process;
--************************** Receive data register **********************************
-- This process implements the bits in the receive register
receivereg_process: process(clk, reset)
begin
if reset = RESET_ACTIVE then
spirr <= (others => '0');
elsif clk'event and clk = '1' then
if spien = '0' then
spirr <= (others => '0');
elsif rcv_load = '1' then
-- load the receive register
spirr <= receive_data;
else
spirr <= spirr;
end if;
end if;
end process;
end BEHAVIOUR;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -