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