Author Topic: spartan 3e500, i am looking for examples in order to test the uart  (Read 6734 times)

0 Members and 1 Guest are viewing this topic.

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
hi guys
i have bought this board, 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 uart

it may be good to have a sort of "echo"
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #1 on: April 26, 2014, 10:15:57 pm »
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.pdf


More info about the RS232 chip here:
http://datasheets.maximintegrated.com/en/ds/MAX220-MAX249.pdf
page 17 has the functional and typical configuration.

and

http://www.ti.com/lit/ds/symlink/max232.pdf

Not sure if they use Maxim, TI or something else but should be the same
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #2 on: April 26, 2014, 10:26:07 pm »
For what I see in the schematic all the pins are on Bank1

CTS is IO_L02N_1/A13
DTR/RTS is IO_L02P_1/A14
TXD is IO_L01N_1/A15
RXD is IO_L01P_1/A16

I 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
« Last Edit: April 26, 2014, 10:41:24 pm by miguelvp »
 

Offline miguelvp

  • Super Contributor
  • ***
  • Posts: 5550
  • Country: us
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #3 on: April 26, 2014, 10:49:30 pm »
The eagle board provides a better view of the trace to cut.

But then you have to jumper 2 and 3 for RTS

Edit: 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.
« Last Edit: April 26, 2014, 11:23:24 pm by miguelvp »
 

Offline Harvs

  • Super Contributor
  • ***
  • Posts: 1202
  • Country: au
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #4 on: April 27, 2014, 03:56:30 am »
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.)
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #5 on: April 27, 2014, 06:17:47 am »
thank you for your help

i 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

 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #6 on: April 27, 2014, 07:05:13 am »
Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity t_serial is
port(
  sys_clk: in std_logic;
-- the code was written with a board with 100 MHz system clock
-- sparkfun s3e board has 50 MHz system clock
 
  led: out std_logic_vector(7 downto 0);
  uart_rx: in std_logic;
  uart_tx: out std_logic;
 
  pmod_1: out std_logic; -- debug outputs
  pmod_2: out std_logic;
 
  reset_btn: in std_logic
);
end t_serial;

architecture Behavioral of t_serial is

component basic_uart is
generic (
  DIVISOR: natural
);
port (
  clk: in std_logic;   -- system clock
  reset: in std_logic;
 
  -- Client interface
  rx_data: out std_logic_vector(7 downto 0);  -- received byte
  rx_enable: out std_logic;  -- validates received byte (1 system clock spike)
  tx_data: in std_logic_vector(7 downto 0);  -- byte to send
  tx_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 interface
  rx: in std_logic;
  tx: out std_logic
);
end component;

type fsm_state_t is (idle, received, emitting);
type state_t is
record
  fsm_state: fsm_state_t; -- FSM state
  tx_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;

begin

  basic_uart_inst: basic_uart
  generic map (DIVISOR => 27) -- 115200
  port 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) is
  begin
    if reset_btn = '1' then
      reset <= '0';
    else
      --reset <= '1'; -- bypass reset
      reset <= '0';
    end if;
  end process;
 
  pmod_1 <= uart_tx_enable;
  pmod_2 <= uart_tx_ready;
 
  fsm_clk: process (sys_clk,reset) is
  begin
    if reset = '1' then
      state.fsm_state <= idle;
      state.tx_data <= (others => '0');
      state.tx_enable <= '0';
    else
      if rising_edge(sys_clk) then
        state <= state_next;
      end if;
    end if;
  end process;

  fsm_next: process (state,uart_rx_enable,uart_rx_data,uart_tx_ready) is
  begin
    state_next <= state;
    case state.fsm_state is
   
    when idle =>
      if uart_rx_enable = '1' then
        state_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' then
        state_next.tx_enable <= '1';
        state_next.fsm_state <= emitting;
      end if;
     
    when emitting =>
      if uart_tx_ready = '0' then
        state_next.tx_enable <= '0';
        state_next.fsm_state <= idle;
      end if;
     
    end case;
  end process;
 
  fsm_output: process (state) is
  begin
 
    uart_tx_enable <= state.tx_enable;
    uart_tx_data <= state.tx_data;
    led <= state.tx_data;
   
  end process;
 
end Behavioral;

Code: [Select]
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.math_real.all;

entity basic_uart is
  generic (
    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;                         -- clock
    reset: in std_logic;                       -- reset
   
    -- Client interface
    rx_data: out std_logic_vector(7 downto 0); -- received byte
    rx_enable: out std_logic;                  -- validates received byte (1 system clock spike)
    tx_data: in std_logic_vector(7 downto 0);  -- byte to send
    tx_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 interface
    rx: in std_logic;
    tx: out std_logic
  );
end basic_uart;

architecture Behavioral of basic_uart is
  constant COUNTER_BITS : natural := integer(ceil(log2(real(DIVISOR))));
  type fsm_state_t is (idle, active); -- common to both RX and TX FSM
  type rx_state_t is
  record
    fsm_state: fsm_state_t;                -- FSM state
    counter: std_logic_vector(3 downto 0); -- tick count
    bits: std_logic_vector(7 downto 0);    -- received bits
    nbits: std_logic_vector(3 downto 0);   -- number of received bits (includes start bit)
    enable: std_logic;                     -- signal we received a new byte
  end record;
  type tx_state_t is
  record
    fsm_state: fsm_state_t; -- FSM state
    counter: std_logic_vector(3 downto 0); -- tick count
    bits: std_logic_vector(8 downto 0); -- bits to emit, includes start bit
    nbits: std_logic_vector(3 downto 0); -- number of bits left to send
    ready: std_logic; -- signal we are accepting a new byte
  end 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 rate
  signal sample_counter: std_logic_vector(COUNTER_BITS-1 downto 0); -- should fit values in 0..DIVISOR-1
 
begin

  -- sample signal at 16x baud rate, 1 CLK spikes
  sample_process: process (clk,reset) is
  begin
    if reset = '1' then
      sample_counter <= (others => '0');
      sample <= '0';
    elsif rising_edge(clk) then
      if sample_counter = DIVISOR-1 then
        sample <= '1';
        sample_counter <= (others => '0');
      else
        sample <= '0';
        sample_counter <= sample_counter + 1;
      end if;
    end if;
  end process;

  -- RX, TX state registers update at each CLK, and RESET
  reg_process: process (clk,reset) is
  begin
    if reset = '1' then
      rx_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) then
      rx_state <= rx_state_next;
      tx_state <= tx_state_next;
    end if;
  end process;
 
  -- RX FSM
  rx_process: process (rx_state,sample,rx) is
  begin
    case rx_state.fsm_state is
   
    when 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 byte
        rx_state_next.fsm_state <= active;
      else
        -- keep idle
        rx_state_next.fsm_state <= idle;
      end if;
     
    when active =>
      rx_state_next <= rx_state;
      if sample = '1' then
        if rx_state.counter = 8 then
          -- sample next RX bit (at the middle of the counter cycle)
          if rx_state.nbits = 9 then
            rx_state_next.fsm_state <= idle; -- back to idle state to wait for next start bit
            rx_state_next.enable <= rx; -- OK if stop bit is '1'
          else
            rx_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 output
  rx_output: process (rx_state) is
  begin
    rx_enable <= rx_state.enable;
    rx_data <= rx_state.bits;
  end process;
 
  -- TX FSM
  tx_process: process (tx_state,sample,tx_enable,tx_data) is
  begin
    case tx_state.fsm_state is
   
    when idle =>
      if tx_enable = '1' then
        -- start a new bit
        tx_state_next.bits <= tx_data & '0';  -- data & start
        tx_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 idle
        tx_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' then
        if tx_state.counter = 15 then
          -- send next bit
          if tx_state.nbits = 0 then
            -- turn idle
            tx_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';
          else
            tx_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 output
  tx_output: process (tx_state) is
  begin
    tx_ready <= tx_state.ready;
    tx <= tx_state.bits(0);
  end process;

end Behavioral;

Code: [Select]
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)
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #7 on: April 27, 2014, 08:26:17 am »
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 is

Mike

Code: [Select]
-------------------------------------------------------------------------------
-- 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 is
Port ( clk : in STD_LOGIC;
tx : out STD_LOGIC);
end hello_world ;
architecture Behavioral of hello_world is
signal counter : unsigned ( 11 downto 0) := (others => '0');
signal shift : std_logic_vector(135 downto 0) := x"FC255346D1B5ED025D57B49D1B44D584A1";
begin
   tx  <= shift(135);
process(clk)
   begin
if rising_edge(clk) then
if counter = 3332 then
counter <= (others => '0');
shift <= shift(134 downto 0) & shift(135);
else
counter <= counter+1;
end if;
end if;
   end process;
end Behavioral;
Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #8 on: April 27, 2014, 09:43:54 am »
hi
i have two boards here
1) sparkfun s3e breakout
2) Spartan-3E Starter Kit

they are both equipped with a clock of 50Mhz, so the divider should be 50.000.000/9600bps -1 ... that should be 5206

i 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: [Select]
#
# 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 ?
 

Offline hamster_nz

  • Super Contributor
  • ***
  • Posts: 2803
  • Country: nz
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #9 on: April 27, 2014, 09:52:17 am »
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...

Gaze not into the abyss, lest you become recognized as an abyss domain expert, and they expect you keep gazing into the damn thing.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 2051
  • Country: nl
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #10 on: April 27, 2014, 09:56:15 am »
Working verilog code for an uart can be found here: http://www.fpga4fun.com/SerialInterface.html

Used it in several projects.  :)
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13744
  • Country: gb
    • Mike's Electric Stuff
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #11 on: April 27, 2014, 10:17:52 am »
Why do you need a UART - just do something to wiggle the pins and check the pins with a scope
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #12 on: April 27, 2014, 10:24:09 am »
However, are you sure that they TX is actually the transmit-to-host?

this part is ok on the Spartan-3E Starter Kit, in fact i am able to run picoblaze with an Application which uses the uart.
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #13 on: April 27, 2014, 10:25:42 am »
Why do you need a UART - just do something to wiggle the pins and check the pins with a scope

cause i have no DSO here, i left it at my job =D
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #14 on: April 27, 2014, 10:42:14 am »
signal counter : unsigned ( 12 downto 0) := (others => '0');

with this patch it is now working @ 9600bps on Spartan-3E Starter Kit
i am adapting the constraints for the sparkfun board
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #15 on: April 27, 2014, 11:23:50 am »
about the "echo" code i have posted, i have grabbed if from here, but it is now working for me.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 13744
  • Country: gb
    • Mike's Electric Stuff
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #16 on: April 27, 2014, 11:29:28 am »
Why do you need a UART - just do something to wiggle the pins and check the pins with a scope

cause i have no DSO here, i left it at my job =D
toggle it slowly and use a DMM!
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline legacyTopic starter

  • Super Contributor
  • ***
  • !
  • Posts: 4415
  • Country: ch
Re: spartan 3e500, i am looking for examples in order to test the uart
« Reply #17 on: April 27, 2014, 12:40:21 pm »
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 swapped

this one is ok

Code: [Select]
#
# 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 tested



anyway 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 ?
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf