OpenCores
URL https://opencores.org/ocsvn/artec_dongle_ii_fpga/artec_dongle_ii_fpga/trunk

Subversion Repositories artec_dongle_ii_fpga

[/] [artec_dongle_ii_fpga/] [trunk/] [src/] [serial_usb/] [serial_usb_package.vhd] - Rev 9

Compare with Previous | Blame | View Log

------------------------------------------------------------------
-- Universal dongle board source code
-- 
-- Copyright (C) 2006 Artec Design <jyrit@artecdesign.ee>
-- 
-- This source code is free hardware; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- version 2.1 of the License, or (at your option) any later version.
-- 
-- This source code 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
-- Lesser General Public License for more details.
-- 
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library; if not, write to the Free Software
-- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-- 
-- 
-- The complete text of the GNU Lesser General Public License can be found in 
-- the file 'lesser.txt'.
 
 
----------------------------------------------------------------------------------
-- Company: Artec Design Ltd
-- Engineer: Jüri Toomessoo 
-- 
-- Create Date:		16:23  23/12/2011 
-- Design Name:		UART CPU interface package
-- Module Name:		serial_usb_package 
-- Project Name:	FlexyICE
-- Target Devices: 
-- Tool versions: 
-- Description: 
--
-- Dependencies: 
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
 
package serial_usb_package is
 
	type usbser_ctrl is record
		mode_en : std_logic;            -- enable this block
	end record;
 
	-- USB interface types
 
	type usb_out is record
		rx_oe_n : std_logic;            -- enables out data if low (next byte detected by edge / in usb chip)
		tx_wr : std_logic;              -- write performed on edge \ of signal
		txdata : std_logic_vector(7 downto 0); --bus data		
	end record;
 
	type usb_in is record
		tx_empty_n : std_logic;         -- tx fifo empty (redy for new data if low)
		rx_full_n : std_logic;          -- rx fifo empty (data redy if low)
		rxdata : std_logic_vector(7 downto 0); --bus data		
	end record;
 
	--UART register descriptions
 
 
	--Interrupt Enable Register (IER)
	constant SEL_IER_RXDATA_INT : natural := 0; --Enable Received Data Available Interrupt
	constant SEL_IER_TXEMPY_INT : natural := 1; --Enable Transmitter Holding Register Empty Interrupt
	constant SEL_IER_RXLINE_INT : natural := 2; --Enable Receiver Line Status Interrupt
	constant SEL_IER_MODEM_INT  : natural := 3; --Enable Modem Status Interrupt
	--SEL_IER bit 7 downto 4  --Reserved
	type uart_int_ena is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	--Interrupt Identification Register (IIR)
	constant SEL_IIR_PENDING_N : natural := 0; -- No Interrupt Pending when set to '1'
	subtype SEL_IIR_TYPE is natural range 3 downto 1; --
	constant VAL_IIR_TYPE_MODEM     : std_logic_vector(2 downto 0) := "000"; -- Modem Status Interrupt 
	constant VAL_IIR_TYPE_TXEMPTY   : std_logic_vector(2 downto 0) := "001"; -- Transmitter Holding Register Empty Interrupt
	constant VAL_IIR_TYPE_RXDATA    : std_logic_vector(2 downto 0) := "010"; -- Received Data Available Interrupt
	constant VAL_IIR_TYPE_RXLINE    : std_logic_vector(2 downto 0) := "011"; -- Receiver Line Status Interrupt
	constant SEL_IIR_TYPE_PENDING_N : std_logic_vector(2 downto 0) := "110"; -- 16550 Time-out Interrupt Pending when '1'
	-- SEL_IIR bit 4  -- Reserved 
	constant SEL_IIR_TYPE_FIFOENAB_N : natural := 5; -- 64 Byte Fifo Enabled (16750 only)
	subtype SEL_IIR_FIFO is natural range 7 downto 6; -- (16750 only)
	constant VAL_IIR_FIFO_NONE  : std_logic_vector(1 downto 0) := "00"; -- No fifo 
	constant VAL_IIR_FIFO_UNSTA : std_logic_vector(1 downto 0) := "01"; -- FIFO Enabled but Unusable 
	constant VAL_IIR_FIFO_ENAB  : std_logic_vector(1 downto 0) := "11"; -- FIFO Enabled 
	type uart_int_id is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	--(TODO "Implement self clear for bits 1 and 2")
	-- First In / First Out Control Register (FCR) (Write only)
	constant SEL_FCR_FIFO_ENA   : natural := 0; -- Enable FIFO's on '1' (data in fifo is lost when set '0')
	constant SEL_FCR_FIFO_RXCLR : natural := 1; -- Clear Receive FIFO on '1' (Self clear bit)
	constant SEL_FCR_FIFO_TXCLR : natural := 2; -- Clear Transmit FIFO '1' (Self clear bit)
	constant SEL_FCR_DMA_MODE   : natural := 3; -- DMA Mode Select. Change status of RXRDY & TXRDY pins from mode 1 to mode 2.
	--SEL_FCR bit 4  -- Reserved 
	constant SEL_FCR_LARGEFIFO_ENA : natural := 5; -- Enable 64 Byte FIFO (16750 only)
	subtype SEL_FCR_RXINTLEVEL is natural range 7 downto 6; -- 	Interrupt Trigger Level on RX FIFO 
	constant VAL_FCR_RXINTLEVEL_1  : std_logic_vector(1 downto 0) := "00"; -- 1 Byte 
	constant VAL_FCR_RXINTLEVEL_4  : std_logic_vector(1 downto 0) := "01"; -- 4 Bytes 
	constant VAL_FCR_RXINTLEVEL_8  : std_logic_vector(1 downto 0) := "10"; -- 8 Bytes 
	constant VAL_FCR_RXINTLEVEL_14 : std_logic_vector(1 downto 0) := "11"; -- 14 Bytes
	type fifo_ctrl is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	--Line Control Register (LCR)
	subtype SEL_LCR_WORDLEN is natural range 1 downto 0; --Word Length
	constant VAL_LCR_WORDLEN_5 : std_logic_vector(1 downto 0) := "00"; --  	5 Bits 
	constant VAL_LCR_WORDLEN_6 : std_logic_vector(1 downto 0) := "01"; --  	6 Bits 
	constant VAL_LCR_WORDLEN_7 : std_logic_vector(1 downto 0) := "10"; --  	7 Bits 
	constant VAL_LCR_WORDLEN_8 : std_logic_vector(1 downto 0) := "11"; --  	8 Bits 
	constant SEL_LCR_STOPLEN   : natural := 2; -- '0'One Stop Bit ; '1' 2 Stop bits for words of length 6,7 or 8 bits or 1.5 Stop Bits for Word lengths of 5 bits. 
	subtype SEL_LCR_PARITY is natural range 5 downto 3; --Parity Select
	constant VAL_LCR_PARITY_ODD  : std_logic_vector(2 downto 0) := "001"; --  	Odd Parity 
	constant VAL_LCR_PARITY_EVEN : std_logic_vector(2 downto 0) := "011"; --  	Even Parity 
	constant VAL_LCR_PARITY_HIGH : std_logic_vector(2 downto 0) := "101"; --  	High Parity (Sticky)
	constant VAL_LCR_PARITY_LOW  : std_logic_vector(2 downto 0) := "111"; --  	Low Parity (Sticky)
	constant SEL_LCR_BREAKENA    : natural := 6; -- 	Set Break Enable 
	constant SEL_LCR_DLAB        : natural := 7; -- 	'1' Divisor Latch Access Bit ; '0' Access to Receiver buffer, Transmitter buffer & Interrupt Enable Register 
	type line_ctrl is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	-- TODO "Implement Loop back mode"
	--Modem Control Register (MCR)
	constant SEL_MCR_FTERMRDY : natural := 0; -- 	Force Data Terminal Ready
	constant SEL_MCR_FREQSND  : natural := 1; -- 	Force Request to Send
	constant SEL_MCR_AUX1     : natural := 2; -- 	Aux Output 1
	constant SEL_MCR_AUX2     : natural := 3; -- 	Aux Output 2
	constant SEL_MCR_LOOP     : natural := 4; -- 	LoopBack Mode 
	constant SEL_MCR_FLWCTRL  : natural := 5; -- 	Autoflow Control Enabled (16750 only)
	type modem_ctrl is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	--Line Status Register (LSR)  (read only)
	constant SEL_LSR_DATARDY   : natural := 0; -- 	Data Ready TODO "Implement data ready"
	constant SEL_LSR_OVRERR    : natural := 1; -- 	Overrun Error (input reg over flow) TODO "Implement over run"
	constant SEL_LSR_PARERR    : natural := 2; -- 	Parity Error
	constant SEL_LSR_FRMERR    : natural := 3; -- 	Framing Error
	constant SEL_LSR_BREAKINT  : natural := 4; -- 	Break Interrupt 
	constant SEL_LSR_EMPTY_TXH : natural := 5; -- 	Empty Transmitter Holding Register
	constant SEL_LSR_EMPTY_DH  : natural := 6; -- 	Empty Data Holding Registers
	constant SEL_LSR_RXFIFOERR : natural := 7; -- 	Error in Received FIFO
	type line_status is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	--Modem Status Register (MSR)
	constant SEL_MSR_CHN_CTS  : natural := 0; -- 	Delta Clear to Send (auto falloff on reg read)
	constant SEL_MSR_CHN_RDY  : natural := 1; -- 	Delta Data Set Ready (auto falloff on reg read)
	constant SEL_MSR_CHN_RING : natural := 2; -- 	Trailing Edge Ring Indicator (auto falloff on reg read)
	constant SEL_MSR_CHN_CD   : natural := 3; -- 	Delta Data Carrier Detect (auto falloff on reg read)
	constant SEL_MSR_CTC      : natural := 4; -- 	Clear To Send (signal state)
	constant SEL_MSR_RDY      : natural := 5; -- 	Data Set Ready (signal state)
	constant SEL_MSR_RING     : natural := 6; -- 	Ring Indicator (signal state)
	constant SEL_MSR_CD       : natural := 7; -- 	Carrier Detect (signal state)
	type modem_status is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	-- Scratch Register
	type scratch is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	type general_reg is record
		reg : std_logic_vector(7 downto 0); --Register
	end record;
 
	type uart_registers is record
		txhold : general_reg;           --Register (Write)	(OFS +0 DLAB=0)	--Transmitter Holding Buffer
		rxbuff : general_reg;           --Register (Read)	(OFS +0 DLAB=0)	--Receiver Buffer 
		div_low : general_reg;          --Register (R/W)	(OFS +0 DLAB=1)	--Divisor Latch Low Byte
		ier : uart_int_ena;             --Register (R/W)	(OFS +1 DLAB=0)	--Interrupt Enable Register 
		div_high : general_reg;         --Register (R/W)	(OFS +1 DLAB=1)	--Divisor Latch High Byte	
		iir : uart_int_id;              --Register (Read)	(OFS +2 DLAB=-) --Interrupt Identification Register
		fcr : fifo_ctrl;                --Register (Write)	(OFS +2 DLAB=-) --FIFO Control Register 
		lcr : line_ctrl;                --Register (R/W)	(OFS +3 DLAB=-)	--Line Control Register 	
		mcr : modem_ctrl;               --Register (R/W)	(OFS +4 DLAB=-)	--Modem Control Register	
		lsr : line_status;              --Register (Read)	(OFS +5 DLAB=-) --Line Status Register 
		msr : modem_status;             --Register (Read)	(OFS +6 DLAB=-) --Modem Status Register  
		scr : scratch;                  --Register (R/W)	(OFS +7 DLAB=-)	--Scratch Register 
	end record;
 
	procedure uart_reset(signal uart : out uart_registers);
	procedure fifo_reset(signal fifo : out usb_out);
 
	procedure set_uart_rx_int(variable uart : inout uart_registers);
	procedure clr_uart_rx_int(variable uart : inout uart_registers);
 
	procedure set_uart_tx_int(variable uart : inout uart_registers);
	procedure clr_uart_tx_int(variable uart : inout uart_registers);
 
 
end package serial_usb_package;
package body serial_usb_package is
 
	procedure fifo_reset(
		signal fifo : out usb_out) is
		variable f : usb_out;
	begin
		f.rx_oe_n:='1';
		f.tx_wr:='0';
		f.txdata:=(others=>'0');
		fifo<=f;
	end procedure fifo_reset;
 
	procedure uart_reset(
		signal uart : out uart_registers) is
		variable u : uart_registers;
	begin
		u.txhold.reg := x"00"; --not needed direct write possible
		u.rxbuff.reg := x"00";
		u.div_low.reg := x"00";
		u.ier.reg := x"00";		
		u.div_high.reg := x"01"; -- 115200 baud
		u.iir.reg := x"41"; --no int pending, fifo enabled but unusable		
		u.fcr.reg := x"00"; --
		u.lcr.reg := x"03"; -- set 8 bit data 1 stop no parity DLA 0
		u.mcr.reg := x"00"; --
		u.lsr.reg := x"60"; -- tx empty and rx empty flags set on reset
		u.msr.reg := x"10"; -- Clear To Send is high after reset
		u.scr.reg := x"00"; --
		uart <= u;
	end procedure uart_reset;
 
 
	procedure set_uart_rx_int(variable uart : inout uart_registers) is
		begin
			if uart.ier.reg(SEL_IER_RXDATA_INT)='1' then --int enabled
				uart.iir.reg(SEL_IIR_TYPE):=VAL_IIR_TYPE_RXDATA;
				uart.iir.reg(SEL_IIR_PENDING_N):='0'; --set int pending
			end if;					
		end procedure set_uart_rx_int;
 
	procedure clr_uart_rx_int(variable uart : inout uart_registers) is
		begin
			if uart.iir.reg(SEL_IIR_TYPE)=VAL_IIR_TYPE_RXDATA and uart.iir.reg(SEL_IIR_PENDING_N)='0' then --suitable int 
				uart.iir.reg(SEL_IIR_PENDING_N):='1'; --clear int pending
			end if;					
		end procedure clr_uart_rx_int;
 
 
	procedure set_uart_tx_int(variable uart : inout uart_registers) is
		begin
			if uart.ier.reg(SEL_IER_TXEMPY_INT)='1' then --int enabled
				uart.iir.reg(SEL_IIR_TYPE):=VAL_IIR_TYPE_TXEMPTY;
				uart.iir.reg(SEL_IIR_PENDING_N):='0'; --set int pending
			end if;					
		end procedure set_uart_tx_int;
 
	procedure clr_uart_tx_int(variable uart : inout uart_registers) is
		begin
			if uart.iir.reg(SEL_IIR_TYPE)=VAL_IIR_TYPE_TXEMPTY and uart.iir.reg(SEL_IIR_PENDING_N)='0' then --suitable int 
				uart.iir.reg(SEL_IIR_PENDING_N):='1'; --clear int pending
			end if;					
		end procedure clr_uart_tx_int;
 
end package body serial_usb_package;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.