FPGARelated.com
Forums

RS-232 Bus controller design in VHDL

Started by ikki November 4, 2008
LittleAlex wrote:


> Just to pick a nit....
> RS-232 does have a protocol. RTS-CTS, DSR-DTR, etc. V.24 describes > the signal levels without mentioning the signal assertion/response.
True, but much of it is rarely used. In the days of half duplex communication with line turn around (the hardware could physically only transmit one direction at a time) that protocol was needed. For connecting a terminal to a modem, or a computer to a printer, it isn't needed and isn't used.
> So the OP is really saying "I want RS-232 protocol WITHOUT the > protocol". Still a miss-formed question.
See above. -- glen
>LittleAlex wrote: > > >> Just to pick a nit.... > >> RS-232 does have a protocol. RTS-CTS, DSR-DTR, etc. V.24 describes >> the signal levels without mentioning the signal assertion/response. > >True, but much of it is rarely used. In the days of half >duplex communication with line turn around (the hardware >could physically only transmit one direction at a time) >that protocol was needed. For connecting a terminal to >a modem, or a computer to a printer, it isn't needed >and isn't used. > >> So the OP is really saying "I want RS-232 protocol WITHOUT the >> protocol". Still a miss-formed question. > >See above. > >-- glen > >
thanks a bunch of all the comments here.... so far i manage to taken care of the reciever part of the rs232 bus controller, but im still having problem with transmitter part.. any idea how to come out with the state machine of transmitter part ? ... guidance is much appreciated
>so far i manage to taken care of the reciever part of the rs232 bus >controller, but im still having problem with transmitter part.. >any idea how to come out with the state machine of transmitter part ? ...
Most people think the receiver is harder.... Tx is comparatively easy. Load the 8-bit data you want to send into a 10-bit shift register, like so: bit #... 9 8 7 6 5 4 3 2 1 0 contents 1 d7 d6 d5 d4 d3 d2 d1 d0 0 Drive bit 0 of this register out to the RS-232 level shifter. The fact there's now a 0 in this position will create your start bit. Now clock the register as a shift register, pushing its more significant bits rightwards towards its least significant bits, and being sure to shift in '1' at the left end every time: bit #........ 9 8 7 6 5 4 3 2 1 0 initial value 1 d7 d6 d5 d4 d3 d2 d1 d0 0 after 1 clock 1 1 d7 d6 d5 d4 d3 d2 d1 d0 after 2 clocks 1 1 1 d7 d6 d5 d4 d3 d2 d1 ... So you can see that the output end (right-hand end) step- by-step gives you first the start bit 0, then d0, then d1 and so on... after 7 clocks 1 1 1 1 1 1 1 1 d7 d6 after 8 clocks 1 1 1 1 1 1 1 1 1 d7 after 9 clocks 1 1 1 1 1 1 1 1 1 1 And now you have your stop bit appearing at the output. The fact that the whole register now contains all-1 means two things: 1) you can use this as a "ready" indication to say that it's now safe to load a new value on the next clock; 2) you don't need to stop; you can continue shifting, and the line will correctly continue to idle, if there is no new data. Sounds easy to me. No counters or (explicit) state machines required. -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
> after 7 clocks 1 1 1 1 1 1 1 1 d7 d6 > after 8 clocks 1 1 1 1 1 1 1 1 1 d7 > after 9 clocks 1 1 1 1 1 1 1 1 1 1 > >And now you have your stop bit appearing at the output. >The fact that the whole register now contains all-1 >means two things: >1) you can use this as a "ready" indication to say that > it's now safe to load a new value on the next clock;
Nope. What if d7 is a 1? -- These are my opinions, not necessarily my employer's. I hate spam.
On Sun, 09 Nov 2008 14:22:45 -0600, Hal Murray wrote:

>Nope. What if d7 is a 1?
Urrrm, yes. That'll teach me not to post half-baked recollections of earlier projects without thinking properly :-) Thanks for the correction. The *correct* implementation of that idea is to shift in zeros instead of 1s: bit #........ 9 8 7 6 5 4 3 2 1 0 initial value 1 d7 d6 d5 d4 d3 d2 d1 d0 0 after 1 clock 0 1 d7 d6 d5 d4 d3 d2 d1 d0 after 2 clocks 0 0 1 d7 d6 d5 d4 d3 d2 d1 ... after 7 clocks 0 0 0 0 0 0 0 1 d7 d6 after 8 clocks 0 0 0 0 0 0 0 0 1 d7 after 9 clocks 0 0 0 0 0 0 0 0 0 1 Then detect the "000000001" condition and use it to STOP the shifting process, as well as enabling loading of the register with "1dddddddd0" when the next data becomes available. Sincere apologies. [retires to bathroom to wipe egg from face] -- Jonathan Bromley, Consultant DOULOS - Developing Design Know-how VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK jonathan.bromley@MYCOMPANY.com http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated.
Jonathan Bromley wrote:

> Urrrm, yes. That'll teach me not to post > half-baked recollections of earlier projects > without thinking properly :-) Thanks for the > correction.
To be fair, I would call it a fully-baked idea missing only a bit of frosting on one corner. The most painful part of any design process is getting from that blank page to a sketch of some plausible design strategy. Fixing the bits around the edges, while compiling code or running a sim, is fun by comparison. I would also point out that text comments as in your example
> bit #........ 9 8 7 6 5 4 3 2 1 0 > initial value 1 d7 d6 d5 d4 d3 d2 d1 d0 0 > after 1 clock 0 1 d7 d6 d5 d4 d3 d2 d1 d0 > after 2 clocks 0 0 1 d7 d6 d5 d4 d3 d2 d1 > ... > after 7 clocks 0 0 0 0 0 0 0 1 d7 d6 > after 8 clocks 0 0 0 0 0 0 0 0 1 d7 > after 9 clocks 0 0 0 0 0 0 0 0 0 1
are just the thing to head up a block of code. Thoughts are always more fleeting than I expect. I applaud Jonathan and other posters here for having the simple bravery to share their raw ideas, or the polite scrutiny of such ideas, for the benefit of unknown readers. -- Mike Treseler (full disclosure: I have been merrily stealing Mr Bromley's ideas since i discovered usenet ;)
>>so far i manage to taken care of the reciever part of the rs232 bus >>controller, but im still having problem with transmitter part.. >>any idea how to come out with the state machine of transmitter part ?
...
> >Most people think the receiver is harder.... > >Tx is comparatively easy. Load the 8-bit data you want to send >into a 10-bit shift register, like so: > > bit #... 9 8 7 6 5 4 3 2 1 0 > contents 1 d7 d6 d5 d4 d3 d2 d1 d0 0 > >Drive bit 0 of this register out to the RS-232 level shifter. >The fact there's now a 0 in this position will create your >start bit. Now clock the register as a shift register, >pushing its more significant bits rightwards towards its >least significant bits, and being sure to shift in '1' at >the left end every time: > > bit #........ 9 8 7 6 5 4 3 2 1 0 > initial value 1 d7 d6 d5 d4 d3 d2 d1 d0 0 > after 1 clock 1 1 d7 d6 d5 d4 d3 d2 d1 d0 > after 2 clocks 1 1 1 d7 d6 d5 d4 d3 d2 d1 > ... > >So you can see that the output end (right-hand end) step- >by-step gives you first the start bit 0, then d0, then d1 >and so on... > > after 7 clocks 1 1 1 1 1 1 1 1 d7 d6 > after 8 clocks 1 1 1 1 1 1 1 1 1 d7 > after 9 clocks 1 1 1 1 1 1 1 1 1 1 > >And now you have your stop bit appearing at the output. >The fact that the whole register now contains all-1 >means two things: >1) you can use this as a "ready" indication to say that > it's now safe to load a new value on the next clock; >2) you don't need to stop; you can continue shifting, > and the line will correctly continue to idle, if > there is no new data. > >Sounds easy to me. No counters or (explicit) state >machines required. >-- >Jonathan Bromley, Consultant > >DOULOS - Developing Design Know-how >VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services > >Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK >jonathan.bromley@MYCOMPANY.com >http://www.MYCOMPANY.com > >The contents of this message may contain personal views which >are not the views of Doulos Ltd., unless specifically stated. >
Hi there, In response to your msg at http://www.fpgarelated.com/usenet/fpga/show/80222-1.php, I would like to ask you about the coding for it. I do understand the concept of it. But, how do I shift it right so that every clock cycle the LSB will be transferred out ? I mean i know how to shift it to the right but, the problem i see is that start bit might be ignored as I shifted the iTxdbuffer before i actually send the LSB of iTxd buffer to the TxD here are my codes ,. .. do you see any errrors about this ? ...how can i edit from here... comments are appreciated... thanks library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity Rs232Txd is port( Reset, Send, Clock16x: in std_logic; DataIn: in std_logic_vector(7 downto 0); Txd: out std_logic); end Rs232Txd; architecture Rs232Txd_Arch of Rs232Txd is attribute enum_encoding: string; -- state definitions type stateType is (stIdle, stData, stStop, stTxdCompleted); attribute enum_encoding of stateType: type is "00 01 11 10"; signal presState: stateType; signal nextState: stateType; signal iSend, iReset, iClock1xEnable, iEnableTxdBuffer, iEnableShift: std_logic; signal iTxdBuffer: std_logic_vector (9 downto 0); signal iClockDiv: std_logic_vector (3 downto 0); signal iClock1x: std_logic; signal iNoBitsSent: std_logic_vector (3 downto 0); begin process (Clock16x) begin if Clock16x'event and Clock16x = '1' then if Reset = '1' or iReset = '1' then iSend <= '0'; iEnableTxdBuffer <= '0'; iEnableShift <= '0'; iClock1xEnable <= '0'; iClockDiv <= (others=>'0'); end if; if Send = '1' or iSend = '1' then iClock1xEnable <= '1'; end if; if iClock1xEnable = '1' then iClockDiv <= iClockDiv + '1'; end if; if iEnableTxdBuffer = '1' then iTxdBuffer <= '1' & DataIn & '0'; -- inserting start bit and stop bit end if; end if; end process; iClock1x <= iClockDiv(3); process (iClock1xEnable, iClock1x) begin if iClock1xEnable = '0' then iNoBitsSent <= (others=>'0'); presState <= stIdle; elsif iClock1x'event and iClock1x = '1' then iNoBitsSent <= iNoBitsSent + '1'; presState <= nextState; end if; if iClock1x'event and iClock1x = '1' then if iEnableShift = '1' then iTxdBuffer <= '0' & iTxdBuffer(9 downto 1); end if; end if; end process; Txd <= iTxdBuffer(0); process (presState, iClock1xEnable, iNoBitsSent) begin -- signal defaults iReset <= '0'; iEnableTxdBuffer <= '0'; iEnableShift <= '0'; case presState is when stIdle => if iClock1xEnable = '1' then iEnableTxdBuffer <= '1'; nextState <= stData; else nextState <= stIdle; end if; when stData => i if iNoBitsSent = "1010" then iEnableShift <= '0'; nextState <= stStop; else iEnableShift <= '1'; nextState <= stData; end if; when stStop => nextState <= stTxdCompleted; when stTxdCompleted => iReset <= '1'; nextState <= stIdle; end case; end process; end Rs232Txd_Arch;
ikki wrote:

> I would like to ask you about the coding for it. I do understand the > concept of it. But, how do I shift it right so that every clock cycle the > LSB will be transferred out ?
Use a <= assignment from the reg bit to the out port.
> here are my codes ,. .. do you see any errrors about this ? ...how can i > edit from here...
Reread this thread. Several solutions to your problem are described. If you want to debug your own code, get a simulator and do it yourself. -- Mike Treseler