Chris_C Posted November 28, 2013 Report Share Posted November 28, 2013 I've been digging round on the site trying to find anything about usb specific to the pro... so code for an echo server would be nice! Can I use channel A just like the other papilio's are there pin/timing differences? basically I want to have two way communications between my development machine and the fpga (without needing to swap cables about) so I can for example while "running" designs I can send data to change a state machine for example (instead of using switches) and also recieve messages back by way of feedback... Looks like my Pro has been stuck in the same sorting station for the last three days, but I'm wanting to do all the theoretical research and learning I can so I'm ready for my first breadboard face plant ) as soon as it lands.... I have to say making my own vga controller looks way more interesting than when I used a microcontroller to bit bang a tv signal - and that was fun - so I can't wait Link to comment Share on other sites More sharing options...
Jack Gassett Posted November 28, 2013 Report Share Posted November 28, 2013 Chris, the Pro is exactly the same as the Papilio One when it comes to USB, just the pins are different. There are several options:1) Use any of the soft processors and ZAP IDE.2) Use stand alone VHDL3) Make your own custom Soft Processor using the new Papilio Schematic Library. Jack. Link to comment Share on other sites More sharing options...
Chris_C Posted November 28, 2013 Author Report Share Posted November 28, 2013 I don't want to use a soft core, be it picoblaze or similar, I've done microcontrollers to death! and I'm looking at using just HDLThe link (2) you supplied seems to be for the picoblaze, I was hoping it would be possible to create a circuit to drive the usb chip directly, using some of the fpga's internal ram as a buffer if needed. in a similar way that there are a bunch of VGA controllers that don't necessary need a processor... Link to comment Share on other sites More sharing options...
hamster Posted November 28, 2013 Report Share Posted November 28, 2013 Hi Chris, The short summary is it shifts bits into a 40-bit shift register at a rate 4x that of the serial link. When oldest three are zero (the start bits), then the 5th, 9th, 13th, 17th, 21st, 25th, 29th and 33th bits are taken as the data bits, and the contents of oldest 39 bits are reset to '1' (the idle state of the link). You could also check the 37th bit of the shift register for a stop bit if you want. Far quicker to hack up than a proper UART. Mike Link to comment Share on other sites More sharing options...
Chris_C Posted November 28, 2013 Author Report Share Posted November 28, 2013 there only seems to be TX/RX pins? I see the jtag clk but not channel A clk?, its not clear looking at the schematic or even the constraint file how the FT2232D is wired to the fpga (save the jtag half)The eprom connected to the FT2232D pasumably provides power on settings but can the settings of the FT2232D be changed given the physical circuit the FT2232D is in... or is it even worth changing anything.... Link to comment Share on other sites More sharing options...
hamster Posted November 28, 2013 Report Share Posted November 28, 2013 Having a look at BPC3010_Papilio_Pro.pdf, there is only 5 connections to the FPGA - TCK,TDI, TMS, USB_TXD & USB_RXD. Possibly this is due to the limited pin count of the FPGA's package - with 48 I/Os, the SDRAM, EPPROM, clocks and LEDs there wasn't many pins left over... Link to comment Share on other sites More sharing options...
Jack Gassett Posted November 28, 2013 Report Share Posted November 28, 2013 Channel A is just used to program the FPGA and channel B just has the tx and rx pins connected. You need to use the classic UART mode. Jack. Link to comment Share on other sites More sharing options...
Chris_C Posted November 28, 2013 Author Report Share Posted November 28, 2013 okay I'm away from my computer ATM but I think I see where I got confused! channel A is the JTAG channel then?I'll read up on the classic mode in the data sheet when I get back...thanks guys! Link to comment Share on other sites More sharing options...
hamster Posted November 29, 2013 Report Share Posted November 29, 2013 Hi Jack & Chris This sounds like an excellent learn.gadgetfactory.net topic - would you like me to write one? Mike Link to comment Share on other sites More sharing options...
Chris_C Posted November 29, 2013 Author Report Share Posted November 29, 2013 Well as a replacement for physical switches usb is ideal as your programming machine is already connected... any tutorial that can be done soley with a pro without external circuitary has to be onto a winner as it covers ALL pro owners regardless of what wings they have bought, although having said that with a breadboard and 20 mins.... Given your great writing style in the last ebook of yours i read I would welcome this for sure! Link to comment Share on other sites More sharing options...
Jack Gassett Posted November 29, 2013 Report Share Posted November 29, 2013 Hamster, That would be really great! If you create an account at learn.gadgetfactory.net I will give you access to write tutorials. I think everything is dialed in to the point where it will be very easy to use now. Jack. Link to comment Share on other sites More sharing options...
hamster Posted November 30, 2013 Report Share Posted November 30, 2013 Hi Jack - all ready to go - you zap me through an account I'll post this up with more pictures... The quickest way to implement PC-to-FPGA comms on a Papilio FPGA board. The design of the Papilio family has USB interface chip, which presents two 'COM' ports to the PC. The first is usually used as a JTAG interface for programming the FPGA. The second can be used to talk with a design running in the FPGA using the RS232 protocol. RS232 is a very old and simple protocol, and has lots of signals that help co-ordinate the data transfer, however for simple applications only the "TX" (transmit) and "RX" (receive) signals need to be used. The same protocol used over both these wires, the difference is that the data is sent in opposite directions. To send an 8-bit byte it is changed to a 10-bit frame, but adding 'start bit' of '0' before the least significant bit, and adding a 'stop bit' of '1' after the most significant bit. These values are chosen as when the line is idle it is held at logical '1', so on an idle line the first 1->0 transition can be used to indicate when a frame starts. The frame is is then transmitted down the wire, start bit first, stop bit last at the desired baud (bits per second) rate The actual wiring is where it starts getting tricky. RS232 was originally used for dumb terminals and printers to talk with mainframe computes using analog modems, and in the context of a terminal it is pretty easy to understand the wiring. The 'TX' connection on a terminal sends data to the 'TX' connection on the modem, and the modem then sends it off down the phone line as a series of beeps. Data being received from the analogue line appears on the 'RX' signal on the modem, which is connected to the 'RX' connection on the terminal. The names used in the different configurations (the one used on a terminal and the one used on a modem) are called DTE ("Data Terminal Equipment") and DCE ("Data Communication Equipment"). So what happens when there are no modems in the link between two DTEs? Like when a printer is plugged directly into a serial port? The short answer is it gets really confusing. The TX on one device needs to be wired to the RX on the other. This model gives two points of view for labeling signals. On the Papilio boards the signals are labelled from the perspective of the USB interface - data from the interface is received on the TX line, and sent on the RX line. An easier way of thinking about the Papilio board is this: "It is wired as you would expect it to be if it was a modem". Incoming data form the host is presented to the FPGA on the "TX" line (in this context "please transmit this"), and the FPGA can send data to the host on the the RX line (in this context, "I've received this for you"). So the aim for this project is to receive data off of the TX line (yeah, it sucks) and display it on a LogicStart's LEDs. The easiest place to start is the constraints required for the ten pins that will be used - 8 LEDs, the TX signal and the clock: These are the constraints for the Papilio Pro: CONFIG PROHIBIT=P144; CONFIG PROHIBIT=P69; CONFIG PROHIBIT=P60; NET CLK LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK NET TX LOC="P105" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # TX NET LED(7) LOC="P114" | IOSTANDARD=LVTTL; # C0 NET LED(6) LOC="P115" | IOSTANDARD=LVTTL; # C1 NET LED(5) LOC="P116" | IOSTANDARD=LVTTL; # C2 NET LED(4) LOC="P117" | IOSTANDARD=LVTTL; # C3 NET LED(3) LOC="P118" | IOSTANDARD=LVTTL; # C4 NET LED(2) LOC="P119" | IOSTANDARD=LVTTL; # C5 NET LED(1) LOC="P120" | IOSTANDARD=LVTTL; # C6 NET LED(0) LOC="P121" | IOSTANDARD=LVTTL; # C7 These are the constraints for the Papilio One: ########## Papilio One #########CONFIG PROHIBIT=P99;CONFIG PROHIBIT=P43;CONFIG PROHIBIT=P42;CONFIG PROHIBIT=P39;CONFIG PROHIBIT=P49;CONFIG PROHIBIT=P48;CONFIG PROHIBIT=P47;CONFIG PART=XC3S250E-VQ100-4; NET CLK LOC="P89" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLKNET TX LOC="P88" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # TXNET LED(7) LOC="P17" | IOSTANDARD=LVTTL; # C0NET LED(6) LOC="P16" | IOSTANDARD=LVTTL; # C1NET LED(5) LOC="P15" | IOSTANDARD=LVTTL; # C2NET LED(4) LOC="P12" | IOSTANDARD=LVTTL; # C3NET LED(3) LOC="P11" | IOSTANDARD=LVTTL; # C4NET LED(2) LOC="P10" | IOSTANDARD=LVTTL; # C5NET LED(1) LOC="P9" | IOSTANDARD=LVTTL; # C6NET LED(0) LOC="P5" | IOSTANDARD=LVTTL; # C7 Great, with that done we can move on to what the high-level receiving component will look like. Working from what signals it needs to source and sink, and what it needs to be correctly configured. I ended up with the following design ('frequency' is the clock frequency, 'baud' is the bits per second rate of the RS232 connection - 9600 is pretty much the de facto standard for human-speed transfers). COMPONENT rs232_rx GENERIC ( frequency : natural; baud : natural); PORT ( clk : IN std_logic; rx : IN std_logic; data : OUT std_logic_vector(7 downto 0); data_strobe : OUT std_logic); END COMPONENT; This component can be added into a top level design. In the top level design we don't have to to much, just map the external connections of the FPGA through to the rs232_rx module (Note how "rx" is mapped to the "tx" pin - you can understand why this is now that you are a pro at serial comms): library IEEE;use IEEE.STD_LOGIC_1164.ALL; entity rs232_rx_demo is Port ( clk : in STD_LOGIC; tx : in STD_LOGIC; led : out STD_LOGIC_VECTOR (7 downto 0));end rs232_rx_demo; architecture Behavioral of rs232_rx_demo is COMPONENT rs232_rx GENERIC ( frequency : natural; baud : natural); PORT ( clk : IN std_logic; rx : IN std_logic; data : OUT std_logic_vector(7 downto 0); data_strobe : OUT std_logic); END COMPONENT;beginInst_rs232_rx: rs232_rx GENERIC MAP (frequency => 32000000, baud => 9600) PORT MAP(clk => clk, rx => tx, data => led, data_strobe => open); end Behavioral; So now we come down to the tricky bit. How do you receive the bits coming in at a given rate, then present them on the 'data' signals? There are plenty of ways to do this, but I'm using a nieve approach based on oversampling. If we sample the signal four times quicker than needed, and remember the last 40 quater-bits (for a full 10 bit frame). To control when the samples are taken I use a counter ("baud_x4") which rolls over after the correct number of clock ticks. When the oldest three bits are zeros then I assume they are the start bit and grab every forth bit (bits 34, 30, 26, 22, 18, 14, 10, 6) to present as the received data. I don't bother presenting the start bit or stop bit - they are just used for framing the data on the wire - however If you are at all worried about data integrity you should test that bit 2 is a valid stop bit (value of '1'). library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL; entity rs232_rx is GENERIC ( frequency : natural; baud : natural ); Port ( clk : in STD_LOGIC; rx : in STD_LOGIC; data : out STD_LOGIC_VECTOR (7 downto 0); data_strobe : out STD_LOGIC);end rs232_rx; architecture Behavioral of rs232_rx is signal oversampled_bits : std_logic_vector(39 downto 0); signal baud_x4 : unsigned(11 downto 0) := (others => '0');begin process(clk) begin if rising_edge(clk) then data_strobe <= '0'; if baud_x4 = 0 then -- If a start bit is seen then capture the data and reset the shift registers if oversampled_bits(39 downto 37) = "000" then data_strobe <= '1'; data <= oversampled_bits(34) & oversampled_bits(30) & oversampled_bits(26) & oversampled_bits(22) & oversampled_bits(18) & oversampled_bits(14) & oversampled_bits(10) & oversampled_bits( 6); oversampled_bits(39 downto 1) <= (others => '1'); oversampled_bits(0) <= rx; else -- Just capture another bit in the shift register. oversampled_bits <= oversampled_bits(38 downto 0) & rx; end if; end if; -- process the interval counter if baud_x4 = frequency / (baud*4) - 1 then baud_x4 <= (others => '0'); else baud_x4 <= baud_x4+1; end if; end if; end process;end Behavioral; And that is it! Just build the project, download the project to the FPGA, open a terminal program (I recommend "Putty"), connect to the higher number COM port on the Papilio with the following parameters:9600 baud No parity1 stop bit Then press some keys to light some LEDs. Link to comment Share on other sites More sharing options...
Chris_C Posted November 30, 2013 Author Report Share Posted November 30, 2013 amazing, thanks so much, it's so clear! yes the over sampling one way coms could be accused (by the mean spirited) of being a quick hack, but it's exactly the clear quick hack that can be easily understood / explained and its a great place to start from.... (far far better than scratch!) and I'm sure not only will I be using it, but I bet a whole raft of "newbies" like me will find it immensely useful really looking forward to playing with this and developing it further One point of confusion still mind!!! Channel A is just used to program the FPGA and channel B just has the tx and rx pins connected. You need to use the classic UART mode.http://papilio.cc/index.php?n=Papilio.PapilioPro says A is fast coms, and B is jtag looking at the circuit diagram, channel B (bus D ???) seems to have only TX/RX connected so I assumed that was the fast async coms, where as channel A (bus C ???) has a bunch of extra signals connected so I assumed that was the jtag channel (with the others signals is syncronous?) - I have to look at the datasheet again after some sleep! I couldn't seem to find the labels that these lead to so couldn't sync it up with the constraint file so easily so bit confused there...! also is it possible to solder some fly leads to the FTDI chips unconnected pins so they could be plugged into pins on an unused wing? or do the chips eeprom settings preclude this? .... and finally if I was shooting data at it at say 115200 baud would the FTDI need some change of settings or would it see the faster incoming connection and automagically configure it at spit out 115200baud over the RX pin right that’s it! all out of dumb questions and need my bed! again thanks for that really clear tutorial, even given the oddities of VHDL (for a new comer) I still understood what was going on! Link to comment Share on other sites More sharing options...
hamster Posted November 30, 2013 Report Share Posted November 30, 2013 I'll have to defer the FTDI & port questions to Jack - all I know is that COM5 is JTAG and COM6 is the serial port on my Papilio One... however, once you get your hardware it should just work - Even if you guess at random you have a 50/50 chance of it working first time! I'm sure it is possible to patch some wires onto he FTDI chip, but I would be tempted to break one of these (https://www.sparkfun.com/products/9873) instead of my Papilio Pro, saving a few $s if you make a stuff up. There is lots of other fun stuff to do before you start board modding Jack has been able to get 2Mb/s over the serial port before the USB interface or host starts dropping bytes, or the timing gets too tricky for it to work. At higher speeds you might need to use some clocking resources to run at a better frequency that 32MHz (eg. 72MHz) to minimise rounding errors in the bit timing at very high speed. Link to comment Share on other sites More sharing options...
Chris_C Posted November 30, 2013 Author Report Share Posted November 30, 2013 I'd kinda assumed to get (really) decent speeds you'd need a serial clock signal... of course like you suggest there are a whole 48 signal lines to play with so really I could just keep the onboard usb purely for programming and implement a different coms route depending on application... heck there's SPI and in any case a lot of SoC's use I2C internally between blocks as well as externally (ie cpu <> watchdog) thanks again for the run through on getting started with usb input... Link to comment Share on other sites More sharing options...
OmniTechnoMancer Posted November 30, 2013 Report Share Posted November 30, 2013 For the baud question the answer is that the FTDI chip actually acts as a USB serial port for the PC and the PC configures the baud rate, so you have to set this to the same thing that you are using on the papilio, there is no magic here and you WILL get wrong results if you set it wrong. Link to comment Share on other sites More sharing options...
Chris_C Posted November 30, 2013 Author Report Share Posted November 30, 2013 from for example Linux, is it possible to configure the FTDI driver on the fly? can I set an arbitrary baud rate for the driver and have my fpga circuit use that bit rate? Link to comment Share on other sites More sharing options...
hamster Posted December 1, 2013 Report Share Posted December 1, 2013 From the FPGA end "auto-bauding" would be possible, but error prone. The RS232 protocol isn't very well designed for recovering the send's clock. As an example, If the receiver sees "0000011111" is the a complete frame for 0x0F, or is the first two bits of something being transmitted at 1/5th the speed? Protocols like S/PDIF have fixed length symbols that are either one, two or three bit-times in length,and that all occur in each frame. This allows the receiver to observe the longest and shortest time between transitions, and then deduce the raw data rate very quickly and accurately. The gold standard serial encoding is 8b/10b coding (used in lots of stuff - like FibreChannel). It is truly awesome - and has an intrinsic beauty to it. 8b/10b makes RS232 look like the ugliest kid in town (if I can use such and un P.C. comparison). Link to comment Share on other sites More sharing options...
Chris_C Posted December 1, 2013 Author Report Share Posted December 1, 2013 I shall defiantly be googling 8b/10b when I get home! Link to comment Share on other sites More sharing options...
OmniTechnoMancer Posted December 1, 2013 Report Share Posted December 1, 2013 from for example Linux, is it possible to configure the FTDI driver on the fly?can I set an arbitrary baud rate for the driver and have my fpga circuit use that bit rate? Yes you can change the baud rate on linux whenever, its a standard serial port operation, I don't know if you can use arbitrary rates though, you can definitely pick any of the usual ones like 115200 though. Link to comment Share on other sites More sharing options...
Jack Gassett Posted December 2, 2013 Report Share Posted December 2, 2013 Chris, seriously, all of your questions should be answered in the high speed UART example. That example is not a picoblaze implementation, the UART is a standalone VHDL or Verilog example. It's just a part of the picoblaze code base, but it is not implementing a picoblaze soft processor. So even though it will probably be better to use Hamster's code, you will get a lot of Papilio specific answers by watching the tutorial I put together... For channel B only rx and tx are connected in the 232 UART Interface mode described in the datasheet on page 31. This mode is capable of speeds up to 3Mbaud according to the first page of the datasheet and as tested out in the high speed UART example. In order to achieve this speed you need to set the transfer rate of the UART you are implementing in the FPGA to run at 3Mbaud and you need your PC client to be set at the same speed. For the high speed UART example the speed was set by controlling the oversample clock speed from what I remember... Link to comment Share on other sites More sharing options...
Jack Gassett Posted December 2, 2013 Report Share Posted December 2, 2013 Hamster, thank you so much for putting this together. I created an account for you on learn.gadgetfactory.net, its good to know I can do that. You should be getting an email with the username/password. Writing an article on the learn site is super easy, all you need to know is that you create a new section in the table of contents by using the H1 header. When you preview or publish the article the stylesheet will applied and you will see the table of contents and the section boxes applied to your article. You can also use the "Snippet Vault" on the right to add callout boxes such as tip, information, post it notes. The stylesheets are applied to the editor too so you should get a WYSIWYG experience with those. Let me know if there are any problems or issues. Thanks!Jack. Hi Jack - all ready to go - you zap me through an account I'll post this up with more pictures... The quickest way to implement PC-to-FPGA comms on a Papilio FPGA board. The design of the Papilio family has USB interface chip, which presents two 'COM' ports to the PC. The first is usually used as a JTAG interface for programming the FPGA. The second can be used to talk with a design running in the FPGA using the RS232 protocol. RS232 is a very old and simple protocol, and has lots of signals that help co-ordinate the data transfer, however for simple applications only the "TX" (transmit) and "RX" (receive) signals need to be used. The same protocol used over both these wires, the difference is that the data is sent in opposite directions. To send an 8-bit byte it is changed to a 10-bit frame, but adding 'start bit' of '0' before the least significant bit, and adding a 'stop bit' of '1' after the most significant bit. These values are chosen as when the line is idle it is held at logical '1', so on an idle line the first 1->0 transition can be used to indicate when a frame starts. The frame is is then transmitted down the wire, start bit first, stop bit last at the desired baud (bits per second) rate The actual wiring is where it starts getting tricky. RS232 was originally used for dumb terminals and printers to talk with mainframe computes using analog modems, and in the context of a terminal it is pretty easy to understand the wiring. The 'TX' connection on a terminal sends data to the 'TX' connection on the modem, and the modem then sends it off down the phone line as a series of beeps. Data being received from the analogue line appears on the 'RX' signal on the modem, which is connected to the 'RX' connection on the terminal. The names used in the different configurations (the one used on a terminal and the one used on a modem) are called DTE ("Data Terminal Equipment") and DCE ("Data Communication Equipment"). So what happens when there are no modems in the link between two DTEs? Like when a printer is plugged directly into a serial port? The short answer is it gets really confusing. The TX on one device needs to be wired to the RX on the other. This model gives two points of view for labeling signals. On the Papilio boards the signals are labelled from the perspective of the USB interface - data from the interface is received on the TX line, and sent on the RX line. An easier way of thinking about the Papilio board is this: "It is wired as you would expect it to be if it was a modem". Incoming data form the host is presented to the FPGA on the "TX" line (in this context "please transmit this"), and the FPGA can send data to the host on the the RX line (in this context, "I've received this for you"). So the aim for this project is to receive data off of the TX line (yeah, it sucks) and display it on a LogicStart's LEDs. The easiest place to start is the constraints required for the ten pins that will be used - 8 LEDs, the TX signal and the clock: These are the constraints for the Papilio Pro: CONFIG PROHIBIT=P144; CONFIG PROHIBIT=P69; CONFIG PROHIBIT=P60; NET CLK LOC="P94" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLK NET TX LOC="P105" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # TX NET LED(7) LOC="P114" | IOSTANDARD=LVTTL; # C0 NET LED(6) LOC="P115" | IOSTANDARD=LVTTL; # C1 NET LED(5) LOC="P116" | IOSTANDARD=LVTTL; # C2 NET LED(4) LOC="P117" | IOSTANDARD=LVTTL; # C3 NET LED(3) LOC="P118" | IOSTANDARD=LVTTL; # C4 NET LED(2) LOC="P119" | IOSTANDARD=LVTTL; # C5 NET LED(1) LOC="P120" | IOSTANDARD=LVTTL; # C6 NET LED(0) LOC="P121" | IOSTANDARD=LVTTL; # C7 These are the constraints for the Papilio One: ########## Papilio One #########CONFIG PROHIBIT=P99;CONFIG PROHIBIT=P43;CONFIG PROHIBIT=P42;CONFIG PROHIBIT=P39;CONFIG PROHIBIT=P49;CONFIG PROHIBIT=P48;CONFIG PROHIBIT=P47;CONFIG PART=XC3S250E-VQ100-4; NET CLK LOC="P89" | IOSTANDARD=LVTTL | PERIOD=31.25ns; # CLKNET TX LOC="P88" | IOSTANDARD=LVTTL | DRIVE=8 | SLEW=FAST | PULLUP; # TXNET LED(7) LOC="P17" | IOSTANDARD=LVTTL; # C0NET LED(6) LOC="P16" | IOSTANDARD=LVTTL; # C1NET LED(5) LOC="P15" | IOSTANDARD=LVTTL; # C2NET LED(4) LOC="P12" | IOSTANDARD=LVTTL; # C3NET LED(3) LOC="P11" | IOSTANDARD=LVTTL; # C4NET LED(2) LOC="P10" | IOSTANDARD=LVTTL; # C5NET LED(1) LOC="P9" | IOSTANDARD=LVTTL; # C6NET LED(0) LOC="P5" | IOSTANDARD=LVTTL; # C7 Great, with that done we can move on to what the high-level receiving component will look like. Working from what signals it needs to source and sink, and what it needs to be correctly configured. I ended up with the following design ('frequency' is the clock frequency, 'baud' is the bits per second rate of the RS232 connection - 9600 is pretty much the de facto standard for human-speed transfers). COMPONENT rs232_rx GENERIC ( frequency : natural; baud : natural); PORT ( clk : IN std_logic; rx : IN std_logic; data : OUT std_logic_vector(7 downto 0); data_strobe : OUT std_logic); END COMPONENT; This component can be added into a top level design. In the top level design we don't have to to much, just map the external connections of the FPGA through to the rs232_rx module (Note how "rx" is mapped to the "tx" pin - you can understand why this is now that you are a pro at serial comms): library IEEE;use IEEE.STD_LOGIC_1164.ALL; entity rs232_rx_demo is Port ( clk : in STD_LOGIC; tx : in STD_LOGIC; led : out STD_LOGIC_VECTOR (7 downto 0));end rs232_rx_demo; architecture Behavioral of rs232_rx_demo is COMPONENT rs232_rx GENERIC ( frequency : natural; baud : natural); PORT ( clk : IN std_logic; rx : IN std_logic; data : OUT std_logic_vector(7 downto 0); data_strobe : OUT std_logic); END COMPONENT;beginInst_rs232_rx: rs232_rx GENERIC MAP (frequency => 32000000, baud => 9600) PORT MAP(clk => clk, rx => tx, data => led, data_strobe => open); end Behavioral; So now we come down to the tricky bit. How do you receive the bits coming in at a given rate, then present them on the 'data' signals? There are plenty of ways to do this, but I'm using a nieve approach based on oversampling. If we sample the signal four times quicker than needed, and remember the last 40 quater-bits (for a full 10 bit frame). To control when the samples are taken I use a counter ("baud_x4") which rolls over after the correct number of clock ticks. When the oldest three bits are zeros then I assume they are the start bit and grab every forth bit (bits 34, 30, 26, 22, 18, 14, 10, 6) to present as the received data. I don't bother presenting the start bit or stop bit - they are just used for framing the data on the wire - however If you are at all worried about data integrity you should test that bit 2 is a valid stop bit (value of '1'). library IEEE;use IEEE.STD_LOGIC_1164.ALL;use IEEE.NUMERIC_STD.ALL; entity rs232_rx is GENERIC ( frequency : natural; baud : natural ); Port ( clk : in STD_LOGIC; rx : in STD_LOGIC; data : out STD_LOGIC_VECTOR (7 downto 0); data_strobe : out STD_LOGIC);end rs232_rx; architecture Behavioral of rs232_rx is signal oversampled_bits : std_logic_vector(39 downto 0); signal baud_x4 : unsigned(11 downto 0) := (others => '0');begin process(clk) begin if rising_edge(clk) then data_strobe <= '0'; if baud_x4 = 0 then -- If a start bit is seen then capture the data and reset the shift registers if oversampled_bits(39 downto 37) = "000" then data_strobe <= '1'; data <= oversampled_bits(34) & oversampled_bits(30) & oversampled_bits(26) & oversampled_bits(22) & oversampled_bits(18) & oversampled_bits(14) & oversampled_bits(10) & oversampled_bits( 6); oversampled_bits(39 downto 1) <= (others => '1'); oversampled_bits(0) <= rx; else -- Just capture another bit in the shift register. oversampled_bits <= oversampled_bits(38 downto 0) & rx; end if; end if; -- process the interval counter if baud_x4 = frequency / (baud*4) - 1 then baud_x4 <= (others => '0'); else baud_x4 <= baud_x4+1; end if; end if; end process;end Behavioral; And that is it! Just build the project, download the project to the FPGA, open a terminal program (I recommend "Putty"), connect to the higher number COM port on the Papilio with the following parameters:9600 baud No parity1 stop bit Then press some keys to light some LEDs. Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.