spartan 3e500, i am looking for examples in order to test the uart - Page 1
Forum section: electronics / general

author: legacy
author_rank: Super Contributor
timestamp: April 26, 2014, 08:38:41 pm
content: hi guysi have boughtthisboard, i need a tiny project example in order to test the uart, it may be the 232 level shifter is broken.anyone with a good tiny and very simple project which- put something on the uart- get something from the uartit may be good to have a sort of "echo"

author: miguelvp
author_rank: Super Contributor
timestamp: April 26, 2014, 10:15:57 pm
content: Do you have the jumpers installed to use the UART? The pins are not connected and uses the jumper block C in the datasheet to make the connection to the chip.I don't have that board, or any Xilinx board for that matter, and the sample code on that page only shows the leds, although the schematic tells you what pins are used and the datasheet has some information:https://www.sparkfun.com/datasheets/DevTools/FPGA/Spartan3E_DS_rev1-1.pdfMore info about the RS232 chip here:http://datasheets.maximintegrated.com/en/ds/MAX220-MAX249.pdfpage 17 has the functional and typical configuration.andhttp://www.ti.com/lit/ds/symlink/max232.pdfNot sure if they use Maxim, TI or something else but should be the same

author: miguelvp
author_rank: Super Contributor
timestamp: April 26, 2014, 10:26:07 pm
content: For what I see in the schematic all the pins are on Bank1CTS is IO_L02N_1/A13DTR/RTS is IO_L02P_1/A14TXD is IO_L01N_1/A15RXD is IO_L01P_1/A16I attached the picture of that part of the schematic, also note JP9 in there is where the jumpers need to be placed as the datasheet states.Edit: note the schematic mentions also a cut trace for selecting between request to send (RTS) or data terminal ready (DTR) with a jumper defaults to DTR if you want RTS you need to cut the trace and then you always will need a jumper there not sure I can locate the jumper so you might want to stick to data terminal ready.Edit again: Added the image where the jumper might be at, but can't see where you will need to cut the trace to disable DTR and enable RTS

author: miguelvp
author_rank: Super Contributor
timestamp: April 26, 2014, 10:49:30 pm
content: The eagle board provides a better view of the trace to cut.But then you have to jumper 2 and 3 for RTSEdit: their implementation from the schematic is just not right, if you cut the trace from pin 8 on the chip to pin 4 on the connector, you can't revert it. They should have wired it from pin 8 on the chip to (2) in the jumper, then from 1 to pin 4 on the connector.That way you could cut the trace between 1 and 2 on the jumper select and mount a three pin header that allows you to select between 1,2 or 2,3.Unless their eagle file is wrong.

author: Harvs
author_rank: Super Contributor
timestamp: April 27, 2014, 03:56:30 am
content: I don't have an example project to give you. But the Picoblaze example comes with a UART attached, so you can probably just grab that and wire up the UCF to the pins you need. At most you'll need to write a few lines of assembly for it to echo the characters (I don't remember anymore what the picoblaze example software does.)

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 06:17:47 am
content: thank you for your helpi also have a spartan3e500 kit, so i can adapt & test the picoblaze's code on this board (which is working about RS232) and then port the project to the Sparkfun board.I am also working around an hw "echo", written in vhdl

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 07:05:13 am
content: Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;entity t_serial isport(sys_clk: in std_logic;-- the code was written with a board with 100 MHz system clock-- sparkfun s3e board has 50 MHz system clockled: out std_logic_vector(7 downto 0);uart_rx: in std_logic;uart_tx: out std_logic;pmod_1: out std_logic; -- debug outputspmod_2: out std_logic;reset_btn: in std_logic);end t_serial;architecture Behavioral of t_serial iscomponent basic_uart isgeneric (DIVISOR: natural);port (clk: in std_logic; -- system clockreset: in std_logic;-- Client interfacerx_data: out std_logic_vector(7 downto 0); -- received byterx_enable: out std_logic; -- validates received byte (1 system clock spike)tx_data: in std_logic_vector(7 downto 0); -- byte to sendtx_enable: in std_logic; -- validates byte to send if tx_ready is '1'tx_ready: out std_logic; -- if '1', we can send a new byte, otherwise we won't take it-- Physical interfacerx: in std_logic;tx: out std_logic);end component;type fsm_state_t is (idle, received, emitting);type state_t isrecordfsm_state: fsm_state_t; -- FSM statetx_data: std_logic_vector(7 downto 0);tx_enable: std_logic;end record;signal reset: std_logic;signal uart_rx_data: std_logic_vector(7 downto 0);signal uart_rx_enable: std_logic;signal uart_tx_data: std_logic_vector(7 downto 0);signal uart_tx_enable: std_logic;signal uart_tx_ready: std_logic;signal state,state_next: state_t;beginbasic_uart_inst: basic_uartgeneric map (DIVISOR => 27) -- 115200port map (clk => sys_clk, reset => reset,rx_data => uart_rx_data, rx_enable => uart_rx_enable,tx_data => uart_tx_data, tx_enable => uart_tx_enable, tx_ready => uart_tx_ready,rx => uart_rx,tx => uart_tx);reset_control: process (reset_btn) isbeginif reset_btn = '1' thenreset <= '0';else--reset <= '1'; -- bypass resetreset <= '0';end if;end process;pmod_1 <= uart_tx_enable;pmod_2 <= uart_tx_ready;fsm_clk: process (sys_clk,reset) isbeginif reset = '1' thenstate.fsm_state <= idle;state.tx_data <= (others => '0');state.tx_enable <= '0';elseif rising_edge(sys_clk) thenstate <= state_next;end if;end if;end process;fsm_next: process (state,uart_rx_enable,uart_rx_data,uart_tx_ready) isbeginstate_next <= state;case state.fsm_state iswhen idle =>if uart_rx_enable = '1' thenstate_next.tx_data <= uart_rx_data;state_next.tx_enable <= '0';state_next.fsm_state <= received;end if;when received =>if uart_tx_ready = '1' thenstate_next.tx_enable <= '1';state_next.fsm_state <= emitting;end if;when emitting =>if uart_tx_ready = '0' thenstate_next.tx_enable <= '0';state_next.fsm_state <= idle;end if;end case;end process;fsm_output: process (state) isbeginuart_tx_enable <= state.tx_enable;uart_tx_data <= state.tx_data;led <= state.tx_data;end process;end Behavioral;Code:library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.STD_LOGIC_UNSIGNED.ALL;use IEEE.math_real.all;entity basic_uart isgeneric (DIVISOR: natural-- DIVISOR = 100,000,000 / (16 x BAUD_RATE)-- 2400 -> 2604-- 9600 -> 651-- 115200 -> 54-- 1562500 -> 4-- 2083333 -> 3-- DIVISOR = 50,000,000 / (16 x BAUD_RATE)-- 115200 -> 27);port (clk: in std_logic; -- clockreset: in std_logic; -- reset-- Client interfacerx_data: out std_logic_vector(7 downto 0); -- received byterx_enable: out std_logic; -- validates received byte (1 system clock spike)tx_data: in std_logic_vector(7 downto 0); -- byte to sendtx_enable: in std_logic; -- validates byte to send if tx_ready is '1'tx_ready: out std_logic; -- if '1', we can send a new byte, otherwise we won't take it-- Physical interfacerx: in std_logic;tx: out std_logic);end basic_uart;architecture Behavioral of basic_uart isconstant COUNTER_BITS : natural := integer(ceil(log2(real(DIVISOR))));type fsm_state_t is (idle, active); -- common to both RX and TX FSMtype rx_state_t isrecordfsm_state: fsm_state_t; -- FSM statecounter: std_logic_vector(3 downto 0); -- tick countbits: std_logic_vector(7 downto 0); -- received bitsnbits: std_logic_vector(3 downto 0); -- number of received bits (includes start bit)enable: std_logic; -- signal we received a new byteend record;type tx_state_t isrecordfsm_state: fsm_state_t; -- FSM statecounter: std_logic_vector(3 downto 0); -- tick countbits: std_logic_vector(8 downto 0); -- bits to emit, includes start bitnbits: std_logic_vector(3 downto 0); -- number of bits left to sendready: std_logic; -- signal we are accepting a new byteend record;signal rx_state,rx_state_next: rx_state_t;signal tx_state,tx_state_next: tx_state_t;signal sample: std_logic; -- 1 clk spike at 16x baud ratesignal sample_counter: std_logic_vector(COUNTER_BITS-1 downto 0); -- should fit values in 0..DIVISOR-1begin-- sample signal at 16x baud rate, 1 CLK spikessample_process: process (clk,reset) isbeginif reset = '1' thensample_counter <= (others => '0');sample <= '0';elsif rising_edge(clk) thenif sample_counter = DIVISOR-1 thensample <= '1';sample_counter <= (others => '0');elsesample <= '0';sample_counter <= sample_counter + 1;end if;end if;end process;-- RX, TX state registers update at each CLK, and RESETreg_process: process (clk,reset) isbeginif reset = '1' thenrx_state.fsm_state <= idle;rx_state.bits <= (others => '0');rx_state.nbits <= (others => '0');rx_state.enable <= '0';tx_state.fsm_state <= idle;tx_state.bits <= (others => '1');tx_state.nbits <= (others => '0');tx_state.ready <= '1';elsif rising_edge(clk) thenrx_state <= rx_state_next;tx_state <= tx_state_next;end if;end process;-- RX FSMrx_process: process (rx_state,sample,rx) isbegincase rx_state.fsm_state iswhen idle =>rx_state_next.counter <= (others => '0');rx_state_next.bits <= (others => '0');rx_state_next.nbits <= (others => '0');rx_state_next.enable <= '0';if rx = '0' then-- start a new byterx_state_next.fsm_state <= active;else-- keep idlerx_state_next.fsm_state <= idle;end if;when active =>rx_state_next <= rx_state;if sample = '1' thenif rx_state.counter = 8 then-- sample next RX bit (at the middle of the counter cycle)if rx_state.nbits = 9 thenrx_state_next.fsm_state <= idle; -- back to idle state to wait for next start bitrx_state_next.enable <= rx; -- OK if stop bit is '1'elserx_state_next.bits <= rx & rx_state.bits(7 downto 1);rx_state_next.nbits <= rx_state.nbits + 1;end if;end if;rx_state_next.counter <= rx_state.counter + 1;end if;end case;end process;-- RX outputrx_output: process (rx_state) isbeginrx_enable <= rx_state.enable;rx_data <= rx_state.bits;end process;-- TX FSMtx_process: process (tx_state,sample,tx_enable,tx_data) isbegincase tx_state.fsm_state iswhen idle =>if tx_enable = '1' then-- start a new bittx_state_next.bits <= tx_data & '0'; -- data & starttx_state_next.nbits <= "0000" + 10; -- send 10 bits (includes '1' stop bit)tx_state_next.counter <= (others => '0');tx_state_next.fsm_state <= active;tx_state_next.ready <= '0';else-- keep idletx_state_next.bits <= (others => '1');tx_state_next.nbits <= (others => '0');tx_state_next.counter <= (others => '0');tx_state_next.fsm_state <= idle;tx_state_next.ready <= '1';end if;when active =>tx_state_next <= tx_state;if sample = '1' thenif tx_state.counter = 15 then-- send next bitif tx_state.nbits = 0 then-- turn idletx_state_next.bits <= (others => '1');tx_state_next.nbits <= (others => '0');tx_state_next.counter <= (others => '0');tx_state_next.fsm_state <= idle;tx_state_next.ready <= '1';elsetx_state_next.bits <= '1' & tx_state.bits(8 downto 1);tx_state_next.nbits <= tx_state.nbits - 1;end if;end if;tx_state_next.counter <= tx_state.counter + 1;end if;end case;end process;-- TX outputtx_output: process (tx_state) isbegintx_ready <= tx_state.ready;tx <= tx_state.bits(0);end process;end Behavioral;Code:NET sys_clk TNM_NET = sys_clk_pin;TIMESPEC TS_sys_clk_pin = PERIOD sys_clk_pin 50000 kHz;NET sys_clk LOC = "P181" | IOSTANDARD=LVCMOS33;net uart_rx LOC=P107 | IOSTANDARD=LVCMOS33;net uart_tx LOC=P106 | IOSTANDARD=LVCMOS33;what do you think about it ?(not working, something is wrong)

author: hamster_nz
author_rank: Super Contributor
timestamp: April 27, 2014, 08:26:17 am
content: Hi,This code below cuts all the cr*p and transmits "Hello World" on the TX line at what ever CLK/3333 is. Use 9600-8-N-1.You should be able to amend it to your board, to at least prove that TX is working... just remember to change "3332" to whatever (clock freq) / (desired baud rate)-1 isMikeCode:--------------------------------------------------------------------------------- Use the following constraints on a Papilio One-- NET "clk"LOC = "P89" | IOSTANDARD = LVTTL;-- NET "tx" LOC = "P90" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW;-------------------------------------------------------------------------------library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL;entity hello_world isPort ( clk: in STD_LOGIC;tx : out STD_LOGIC);end hello_world ;architecture Behavioral of hello_world issignal counter : unsigned ( 11 downto 0) := (others => '0');signal shift : std_logic_vector(135 downto 0) := x"FC255346D1B5ED025D57B49D1B44D584A1";begintx <= shift(135);process(clk)beginif rising_edge(clk) thenif counter = 3332 thencounter <= (others => '0');shift <= shift(134 downto 0) & shift(135);elsecounter <= counter+1;end if;end if;end process;end Behavioral;

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 09:43:54 am
content: hii have two boards here1) sparkfun s3e breakout2) Spartan-3E Starter Kitthey are both equipped with a clock of 50Mhz, so the divider should be 50.000.000/9600bps -1 ... that should be 5206i do not understand, it is not working, i can't see anything from the tx even if the Spartan-3E Starter Kit is working with picoblaze (Xilinx has released a demo called "App flashing", it uses uart in order to get cmd from host)Code:## Time specifications for 50MHz clock## I/O constraints for Spartan-3E Starter Kit (Rev.B)## soldered 50MHz Clock#NET clk LOC = "C9" | IOSTANDARD=LVCMOS33;### UART connections#NET "tx" LOC = "M14" | IOSTANDARD = LVTTL | DRIVE = 4 | SLEW = SLOW;#NET "rx" LOC = "R7" | IOSTANDARD = LVTTL;what may be wrong ?

author: hamster_nz
author_rank: Super Contributor
timestamp: April 27, 2014, 09:52:17 am
content: If you have 50Mhz clock. counter may need to be one bit longer, allowing it to count up to 8192. The updated line is:signal counter : unsigned ( 12 downto 0) := (others => '0');However, are you sure that they TX is actually the transmit-to-host? The FPGA might be documented as if it is a DCE, and in which case you actually want to send down the RX line...

author: mrflibble
author_rank: Super Contributor
timestamp: April 27, 2014, 09:56:15 am
content: Working verilog code for an uart can be found here:http://www.fpga4fun.com/SerialInterface.htmlUsed it in several projects.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: April 27, 2014, 10:17:52 am
content: Why do you need a UART - just do something to wiggle the pins and check the pins with a scope

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 10:24:09 am
content: Quote from: hamster_nz on April 27, 2014, 09:52:17 amthis part is ok on the Spartan-3E Starter Kit, in fact i am able to run picoblaze with an Application which uses the uart.

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 10:25:42 am
content: Quote from: mikeselectricstuff on April 27, 2014, 10:17:52 amcause i have no DSO here, i left it at my job =D

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 10:42:14 am
content: Quote from: hamster_nz on April 27, 2014, 09:52:17 amwith this patch it is now working @ 9600bps on Spartan-3E Starter Kiti am adapting the constraints for the sparkfun board

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 11:23:50 am
content: about the "echo" code i have posted, i have grabbed if fromhere, but it is now working for me.

author: mikeselectricstuff
author_rank: Super Contributor
timestamp: April 27, 2014, 11:29:28 am
content: Quote from: legacy on April 27, 2014, 10:25:42 amtoggle it slowly and use a DMM!

author: legacy
author_rank: Super Contributor
timestamp: April 27, 2014, 12:40:21 pm
content: i removed the jumpers which connect fpga to maxim232 and i wired rx and tx to an external RS232 adapter: it is working!there is also a mistake in the constraints provided with my board: rx and tx have been swappedthis one is okCode:## constraints for Spartan-3E breakout (sparkfun kit)### Time specifications for 50MHz clock (soldered)#NET clk LOC = "P181" | IOSTANDARD=LVCMOS33;## UART connections### jumpers to rs232 adapter## P109 <-- CTS is IO_L02N_1/A13# P108 <-- DTR/RTS is IO_L02P_1/A14# P107 <-- TXD is IO_L01N_1/A15# P106 <-- RXD is IO_L01P_1/A16#net uart_rx LOC=P106 | IOSTANDARD=LVCMOS33;net uart_tx LOC=P107 | IOSTANDARD=LVCMOS33;## reset button (not soldered yet)##net reset_btn loc=T15 | IOSTANDARD=LVCMOS33;so the conclusion is: the onboard chip RS232 is damaged on the tx side, the rx side is still not testedanyway i am able to use the external adapter and i will replace the smd chip (by hot air, i have the equipment at my job)anyone has understood what may be wrong with the "echo" vhdl code ?