Hi, I am trying to connect my Spartan 3 borad with PC by RS232 , and am able to echo single input in hyper temial consol. What i am trying to do is sending "hi" from the board to the pc, by only hit 1 from hyper termial. Will follow steps design work? I am not sure if the RS232 (hypertermial) has any limitation on this. I have worked on this for sevral days, but still doesn't work. any idea will welcome. 1. read input 2. if input = '1' then go to 3 else back to 1 3. send 'h' 4. send 'i'
sending multiple char on RS232
Started by ●May 16, 2006
Reply by ●May 16, 20062006-05-16
>I am trying to connect my Spartan 3 borad with PC by RS232 , and am >able to echo single input in hyper temial consol. What i am trying to >do is sending "hi" from the board to the pc, by only hit 1 from hyper >termial. Will follow steps design work? I am not sure if the RS232 >(hypertermial) has any limitation on this. I have worked on this for >sevral days, but still doesn't work. any idea will welcome. > >1. read input >2. if input = '1' then go to 3 else back to 1 >3. send 'h' >4. send 'i'You don't say in what way this isn't working. You may need to wait before step 4 until the hardware is ready to accept another character (if the transmitter has no buffer). That is, you may need to wait until the first character has been transmitted. If you need this "flow control", then the most likely behaviour without it is that only a single character is transmitted (either 'h' or a corrupted character, depending on the behaviour of the transmitter when you write a character to it when it isn't ready).
Reply by ●May 16, 20062006-05-16
I got only only signal from the UART model saying that the transmit bus is empty(TBE) if 1 then empty. Here is what I do step by step: 1. until input arrive, then go to 1 2. read input if input = '1' then go to 3, else back to 1 3. put 'h' on the data bus, wait until TBE is 0 go to 4 4. wait until TBE = 1 then go to 5 5. put 'i' on the data bus, wait until TBE is 0 go to 6 6. wait until TBE = 1 then back to 1 it hang on step 5. wait for TBE to be 0
Reply by ●May 16, 20062006-05-16
Reply by ●May 16, 20062006-05-16
the problem has solved by adding a extra clock cycle between 4 and 5, but I still don't understand why that will work. Maybe need to wait longer for sending the byte. If someone know, please tell me. anyway, thanks Mike~!
Reply by ●May 17, 20062006-05-17
YiQi wrote:> the problem has solved by adding a extra clock cycle between 4 and 5, > but I still don't understand why that will work. Maybe need to wait > longer for sending the byte. If someone know, please tell me. anyway, > > > thanks Mike~!BTW - In the UARTs I've used (Z8530, 16c450) the UART sets TBE to a 1 when it can accept a byte to be transmitted.>..I still don't understand why that will workWithout seeing your code it would be difficult to help you. -Dave
Reply by ●May 22, 20062006-05-22
Dave, sorry for late reply.
Here is the code:
entity Main is
Port (
btn : in std_logic_vector(3 downto 0);
sel : in std_logic_vector(7 downto 0);
TXD : out std_logic := '1';
RXD : in std_logic := '1';
led : out std_logic_vector(7 downto 0);
CLK : in std_logic;
RST : in std_logic := '0';
ann : out std_logic_vector(3 downto 0);
lcdout : out std_logic_vector(7 downto 0));
end Main;
architecture Behavioral of Main is
------------------------------------------------------------------------
-- Component Declarations
------------------------------------------------------------------------
component UARTcomponent
Port (
TXD : out std_logic := '1';
RXD : in std_logic;
CLK : in std_logic; --Master Clock
DBIN : in std_logic_vector (7 downto 0); --Data Bus in
DBOUT : out std_logic_vector (7 downto 0);--Data Bus out
RDA : inout std_logic; --Read Data Available
TBE : inout std_logic := '1'; --Transfer Bus Ready
RD : in std_logic; --Read Strobe
WR : in std_logic; --Write Strobe
PE : out std_logic; --Parity Error Flag
FE : out std_logic; --Frame Error Flag
OE : out std_logic; --Overwrite Error Flag
RST : in std_logic := '0'); --Master Reset
end component;
component LCDcomponent
Port ( an3 : out std_logic;
an2 : out std_logic;
an1 : out std_logic;
an0 : out std_logic;
lcddisplay : out std_logic_vector(7 downto 0);
datain : in std_logic_vector(7 downto 0));
end component;
------------------------------------------------------------------------
-- Local Type Declarations
------------------------------------------------------------------------
type mainState is (
idle, receive,
initSendX, sendX, waitSendX,
initSendY, sendY, waitSendY);
-- type sendStates is (
-- sendX,
-- sendY,
-- sendDir,
-- sendAction,
-- sendIdle);
-- signal sendState, sendNextState : sendStates := sendIdle;
------------------------------------------------------------------------
-- Signal Declarations
------------------------------------------------------------------------
signal dbInSig : std_logic_vector(7 downto 0);
signal dbOutSig: std_logic_vector(7 downto 0);
signal rdaSig : std_logic;
signal tbrSig : std_logic;
signal rdSig : std_logic;
signal wrSig : std_logic;
signal peSig : std_logic;
signal feSig : std_logic;
signal oeSig : std_logic;
signal state : mainState := idle;
signal stNext : mainState;
signal X : std_logic_vector(7 downto 0) := "00110010";
signal Y : std_logic_vector(7 downto 0) := "00110100";
signal direction: std_logic_vector(2 downto 0) := "110";
signal action : std_logic_vector(1 downto 0) := "11";
signal UARTReady : std_logic := '0';
signal clock : std_logic := '0';
signal reset : std_logic := '0';
signal dataReady : std_logic := '0';
shared variable send : std_logic := '0';
------------------------------------------------------------------------
-- Module Implementation
------------------------------------------------------------------------
begin
LCD: LCDcomponent port map (
an3 => ann(3),
an2 => ann(2),
an1 => ann(1),
an0 => ann(0),
lcddisplay => lcdout,
datain => dbOutSig);
UART: Uartcomponent port map (
TXD => TXD,
RXD => RXD,
CLK => CLK,
DBIN => dbInSig,
DBOUT=> dbOutSig,
RDA => rdaSig,
TBE => tbrSig,
RD => rdSig,
WR => wrSig,
PE => peSig,
FE => feSig,
OE => oeSig,
RST => RST);
SET_DATA: process(btn, sel)
begin
if btn(0) = '1' then --reset
reset <= '1';
dataReady <= '1';
else
reset <= '0';
end if;
if btn(2) = '1' then -- set fromX
X <= sel;
dataReady <= '0';
end if;
if btn(1) = '1' then -- set fromY
Y <= sel;
direction <= "000";
dataReady <= '0';
end if;
end process;
RUN: process(CLK, UARTready) -- generate the robotcontroller clock
begin
if dataReady = '1' AND UARTready = '1' then
clock <= CLK;
else
clock <= '0';
end if;
end process;
process (clock, reset)
variable counter : std_logic_vector(15 downto 0):=
"0000000000000000";
begin
if (CLK = '1' and CLK'Event) then
if reset = '1' then
send := '0';
counter := "0000000000000000";
else
if counter = "1100" then
send := '1';
else
send := '0';
end if;
counter := counter + "0000000000000001";
if counter > "1111111111111110" then
counter := "0000000000000000";
end if;
end if;
end if;
end process;
process (CLK, RST)
begin
if (CLK = '1' and CLK'Event) then
if RST = '1' then
state <= idle;
else
state <= stNext;
end if;
end if;
end process;
UART_STATE : process (state, tbrSig, rdaSig, dboutsig, x, y,
direction, action)
variable counter : std_logic_vector(2 downto 0) := "000";
begin
case state is
when idle =>
led(0) <= '0';
led(1) <= '1';
led(2) <= '0';
led(3) <= '1';
led(4) <= dbInSig(0);
led(5) <= dbInSig(1);
led(6) <= dbInSig(2);
led(7) <= dbInSig(3);
rdSig <= '1';
wrSig <= '0';
if send = '1' AND dataReady = '1'then
stNext <= initSendX;
UARTready <= '0';
else
UARTready <= '1';
stNext <= idle;
end if;
when initSendX =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '0';
led(2) <= '1';
led(3) <= '1';
led(4) <= '1';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
rdSig <= '1';
dbInSig <= "00110001";
if tbrSig = '0' then
wrSig <= '0';
stNext <= sendX;
else
wrSig <= '1';
stNext <= initSendX;
end if;
when sendX =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '1';
led(2) <= '0';
led(3) <= '1';
led(4) <= '1';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
dbInSig <= X; --"00110010";
rdSig <= '1';
if tbrSig = '1' then
stNext <= waitSendX;
counter := "000";
wrSig <= '0';
else
stNext <= sendX;
wrSig <= '0';
end if;
when waitSendX =>
UARTready <= '0';
stNext <= initSendY;
when initSendY =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '1';
led(2) <= '1';
led(3) <= '0';
led(4) <= '1';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
rdSig <= '1';
dbInSig <= "00110011";
if tbrSig = '0' then
wrSig <= '0'; --0
stNext <= sendY;
else
wrSig <= '1';
stNext <= initSendY;
end if;
when sendY =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '1';
led(2) <= '1';
led(3) <= '1';
led(4) <= '0';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
dbInSig <= Y; --"00110100";
rdSig <= '1';
if tbrSig = '1' then
stNext <= waitSendY;
wrSig <= '0';
else
stNext <= receive;
wrSig <= '1';
end if;
when receive =>
led(0) <= '0';
led(1) <= '1';
led(2) <= '1';
led(3) <= '1';
led(4) <= '1';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
rdSig <= '0';
wrSig <= '0';
if rdaSig = '1' then
led(4) <= dbOutSig(0);
led(5) <= dbOutSig(1);
led(6) <= dbOutSig(2);
led(7) <= dbOutSig(3);
UARTready <= '1';
stNext <= idle;
else
stNext <= receive;
end if;
when others =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '0';
led(2) <= '1';
led(3) <= '0';
led(4) <= '1';
led(5) <= '0';
led(6) <= '1';
led(7) <= '0';
end case;
end process;
Reply by ●May 22, 20062006-05-22
the sendY state should be
when sendY =>
UARTready <= '0';
led(0) <= '1';
led(1) <= '1';
led(2) <= '1';
led(3) <= '1';
led(4) <= '0';
led(5) <= '1';
led(6) <= '1';
led(7) <= '1';
dbInSig <= Y; --"00110100";
rdSig <= '1';
if tbrSig = '1' then
stNext <= receive;
<<<<<<<<<<<<<<
wrSig <= '0';
else
stNext <= sendY;
<<<<<<<<<<<<<<
wrSig <= '1';
end if;
Reply by ●May 23, 20062006-05-23
YiQi wrote:> Dave, sorry for late reply. > > Here is the code: > entity Main is > Port ( > btn : in std_logic_vector(3 downto 0); > sel : in std_logic_vector(7 downto 0); > > TXD : out std_logic := '1'; > RXD : in std_logic := '1'; > led : out std_logic_vector(7 downto 0); > CLK : in std_logic; > RST : in std_logic := '0'; > ann : out std_logic_vector(3 downto 0); > lcdout : out std_logic_vector(7 downto 0)); > end Main; > > architecture Behavioral of Main is > ------------------------------------------------------------------------ > -- Component Declarations > ------------------------------------------------------------------------ > component UARTcomponent > Port ( > TXD : out std_logic := '1'; > RXD : in std_logic; > CLK : in std_logic; --Master Clock > DBIN : in std_logic_vector (7 downto 0); --Data Bus in > DBOUT : out std_logic_vector (7 downto 0);--Data Bus out > RDA : inout std_logic; --Read Data Available > TBE : inout std_logic := '1'; --Transfer Bus Ready > RD : in std_logic; --Read Strobe > WR : in std_logic; --Write Strobe > PE : out std_logic; --Parity Error Flag > FE : out std_logic; --Frame Error Flag > OE : out std_logic; --Overwrite Error Flag > RST : in std_logic := '0'); --Master Reset > end component; > > > component LCDcomponent > Port ( an3 : out std_logic; > an2 : out std_logic; > an1 : out std_logic; > an0 : out std_logic; > lcddisplay : out std_logic_vector(7 downto 0); > datain : in std_logic_vector(7 downto 0)); > end component; > > ------------------------------------------------------------------------ > -- Local Type Declarations > ------------------------------------------------------------------------ > > type mainState is ( > idle, receive, > initSendX, sendX, waitSendX, > initSendY, sendY, waitSendY); > > -- type sendStates is ( > -- sendX, > -- sendY, > -- sendDir, > -- sendAction, > -- sendIdle); > -- signal sendState, sendNextState : sendStates := sendIdle; > > ------------------------------------------------------------------------ > -- Signal Declarations > ------------------------------------------------------------------------ > signal dbInSig : std_logic_vector(7 downto 0); > signal dbOutSig: std_logic_vector(7 downto 0); > signal rdaSig : std_logic; > signal tbrSig : std_logic; > signal rdSig : std_logic; > signal wrSig : std_logic; > signal peSig : std_logic; > signal feSig : std_logic; > signal oeSig : std_logic; > > signal state : mainState := idle; > signal stNext : mainState; > signal X : std_logic_vector(7 downto 0) := "00110010"; > signal Y : std_logic_vector(7 downto 0) := "00110100"; > signal direction: std_logic_vector(2 downto 0) := "110"; > signal action : std_logic_vector(1 downto 0) := "11"; > > > signal UARTReady : std_logic := '0'; > signal clock : std_logic := '0'; > signal reset : std_logic := '0'; > signal dataReady : std_logic := '0'; > > shared variable send : std_logic := '0'; > > ------------------------------------------------------------------------ > -- Module Implementation > ------------------------------------------------------------------------ > > begin > > > LCD: LCDcomponent port map ( > an3 => ann(3), > an2 => ann(2), > an1 => ann(1), > an0 => ann(0), > lcddisplay => lcdout, > datain => dbOutSig); > > UART: Uartcomponent port map ( > TXD => TXD, > RXD => RXD, > CLK => CLK, > DBIN => dbInSig, > DBOUT=> dbOutSig, > RDA => rdaSig, > TBE => tbrSig, > RD => rdSig, > WR => wrSig, > PE => peSig, > FE => feSig, > OE => oeSig, > RST => RST); > > SET_DATA: process(btn, sel) > begin > if btn(0) = '1' then --reset > reset <= '1'; > dataReady <= '1'; > else > reset <= '0'; > end if; > if btn(2) = '1' then -- set fromX > X <= sel; > dataReady <= '0'; > end if; > if btn(1) = '1' then -- set fromY > Y <= sel; > direction <= "000"; > dataReady <= '0'; > end if; > end process; > > > RUN: process(CLK, UARTready) -- generate the robotcontroller clock > begin > if dataReady = '1' AND UARTready = '1' then > clock <= CLK; > else > clock <= '0'; > end if; > end process; > > process (clock, reset) > variable counter : std_logic_vector(15 downto 0):= > "0000000000000000"; > begin > if (CLK = '1' and CLK'Event) then > if reset = '1' then > send := '0'; > counter := "0000000000000000"; > else > if counter = "1100" then > send := '1'; > else > send := '0'; > end if; > counter := counter + "0000000000000001"; > if counter > "1111111111111110" then > counter := "0000000000000000"; > end if; > end if; > end if; > end process; > > > > process (CLK, RST) > begin > if (CLK = '1' and CLK'Event) then > if RST = '1' then > state <= idle; > else > state <= stNext; > end if; > end if; > end process; > > UART_STATE : process (state, tbrSig, rdaSig, dboutsig, x, y, > direction, action) > variable counter : std_logic_vector(2 downto 0) := "000"; > begin > case state is > > when idle => > led(0) <= '0'; > led(1) <= '1'; > led(2) <= '0'; > led(3) <= '1'; > led(4) <= dbInSig(0); > led(5) <= dbInSig(1); > led(6) <= dbInSig(2); > led(7) <= dbInSig(3); > > rdSig <= '1'; > wrSig <= '0'; > > if send = '1' AND dataReady = '1'then > stNext <= initSendX; > UARTready <= '0'; > else > UARTready <= '1'; > stNext <= idle; > end if; > > when initSendX => > UARTready <= '0'; > > led(0) <= '1'; > led(1) <= '0'; > led(2) <= '1'; > led(3) <= '1'; > led(4) <= '1'; > led(5) <= '1'; > led(6) <= '1'; > led(7) <= '1'; > > rdSig <= '1'; > > dbInSig <= "00110001"; > if tbrSig = '0' then > wrSig <= '0'; > stNext <= sendX; > else > wrSig <= '1'; > stNext <= initSendX; > end if; > > when sendX => > UARTready <= '0'; > > led(0) <= '1'; > led(1) <= '1'; > led(2) <= '0'; > led(3) <= '1'; > led(4) <= '1'; > led(5) <= '1'; > led(6) <= '1'; > led(7) <= '1'; > > dbInSig <= X; --"00110010"; > rdSig <= '1'; > if tbrSig = '1' then > stNext <= waitSendX; > counter := "000"; > wrSig <= '0'; > else > stNext <= sendX; > wrSig <= '0'; > end if; > > when waitSendX => > UARTready <= '0'; > stNext <= initSendY; > > when initSendY => > UARTready <= '0'; > > led(0) <= '1'; > led(1) <= '1'; > led(2) <= '1'; > led(3) <= '0'; > led(4) <= '1'; > led(5) <= '1'; > led(6) <= '1'; > led(7) <= '1'; > > rdSig <= '1'; > dbInSig <= "00110011"; > if tbrSig = '0' then > wrSig <= '0'; --0 > stNext <= sendY; > else > wrSig <= '1'; > stNext <= initSendY; > end if; > > when sendY => > UARTready <= '0'; > > led(0) <= '1'; > led(1) <= '1'; > led(2) <= '1'; > led(3) <= '1'; > led(4) <= '0'; > led(5) <= '1'; > led(6) <= '1'; > led(7) <= '1'; > > dbInSig <= Y; --"00110100"; > rdSig <= '1'; > if tbrSig = '1' then > stNext <= waitSendY; > wrSig <= '0'; > else > stNext <= receive; > wrSig <= '1'; > end if; > > when receive => > > led(0) <= '0'; > led(1) <= '1'; > led(2) <= '1'; > led(3) <= '1'; > led(4) <= '1'; > led(5) <= '1'; > led(6) <= '1'; > led(7) <= '1'; > > rdSig <= '0'; > wrSig <= '0'; > > if rdaSig = '1' then > led(4) <= dbOutSig(0); > led(5) <= dbOutSig(1); > led(6) <= dbOutSig(2); > led(7) <= dbOutSig(3); > > UARTready <= '1'; > stNext <= idle; > else > stNext <= receive; > end if; > > when others => > UARTready <= '0'; > > led(0) <= '1'; > led(1) <= '0'; > led(2) <= '1'; > led(3) <= '0'; > led(4) <= '1'; > led(5) <= '0'; > led(6) <= '1'; > led(7) <= '0'; > > end case; > end process; >YiQi; In an earlier post you said: I got only only signal from the UART model saying that the transmit bus is empty(TBE) if 1 then empty. Here is what I do step by step: 1. until input arrive, then go to 1 2. read input if input = '1' then go to 3, else back to 1 3. put 'h' on the data bus, wait until TBE is 0 go to 4 4. wait until TBE = 1 then go to 5 5. put 'i' on the data bus, wait until TBE is 0 go to 6 6. wait until TBE = 1 then back to 1 it hang on step 5. wait for TBE to be 0 I would have said: 1) If the UART received a char (RDA = '1') then goto 2, else goto 1 2) Read the char from the UART. If the char is ASCII '1' (31h) then goto 3 else goto 1 ( rdSig <= '1'; if dbOutSig = x"31" then goto 3 ) 3) if the UART's Transmit Buffer is Empty (TBE = '1') then goto 4, else back to 3 4) write the 1st char into the UART (wrSig <= '1', dbInSig <= char in signal X) 5) if the UART's Transmit Buffer is Empty (TBE = '1') then goto 6, else back to 5 6) write the 2nd char into the UART ( wrSig <= '1', dbInSig <= char in signal Y ) DONE I doesn't look like your state-machine follows your step-by-step process. It's sending chars in X and Y and _then_ reading a char from the UART. It also looks like you're reading data from the UART and writing data to the UART at the same time (see state initSendX, where you set both rdSig and wrSig to '1'). I don't see the need for the process that writes into "send". This process is not related or synchronized to anything. HTH -Dave Pollum
Reply by ●May 29, 20062006-05-29
Thanks Dave. Yes, you were correct sorry that i have serval version of this code now, and i even comfuse myself. as a result, my program is not accroding to the steps. For rdSig and wrSig, I am reading and writeing at the same time, but I just ignore the incoming data while i am sending it. Since serial port using 2 different bus, it should be ok, and it shouldn't effect the outgoing data. Let me know if my assumption is wrong. The send signal is for a process(not shown here) to inform this main process the X and Y is has change and ready to send it out, that's why my program start with sending. Besides these, what are the possiblity that the simulation works correctly, and after the the design flow, the actual on-chip running becomes wired? How could I have the simulation close enough to the on-chip running Thanks for your advice and help, YiQi




