MartijnPieterse

No switch bouncing on Pro?

Recommended Posts

Hi,

 

i'm working my way trough the excellent IntroToSpartanFPGA book, and at the beginning of Chapter17 (State Machines) it says the following:

 

Try running it in hardware - it most probably won’t work reliably - 50:50 if you are lucky.
 

But, i cannot seem to get it to not work! Is there something different with the switches between the One and the Pro? Even when i move the switches really slow it works just fine.

 

Any ideas?

 

 

Share this post


Link to post
Share on other sites

You should see some bouncing then, at least when pressing the switch.

 

The only way to see is to capture them into a block RAM, and then looking at its contents. But the probability it is not happening is very low (I'd say it's impossible).

Share this post


Link to post
Share on other sites

You could also download the latest version of the ZAP IDE and use the Logic Analyzer example to capture those pins at 100Mhz and see what happens.

 

Jack.

Share this post


Link to post
Share on other sites

Hi,

I managed to get the Logic Analyzer to work, and this are my results. I used the ZAP IDE 2.3.0, Benchy_Sump_LogicAnalyzer, changed the code into:

HardwareSerial mySerial1(5);int counter = 0;void setup() {  // put your setup code here, to run once://  delay(3000);    Serial.begin(115200);  mySerial1.begin(115200);   pinMode(WAL0, OUTPUT);  pinMode(WAL1, OUTPUT);  pinMode(WAL2, OUTPUT);  pinMode(WAL3, OUTPUT);  pinMode(WAL4, OUTPUT);  pinMode(WAL5, OUTPUT);  pinMode(WAL6, OUTPUT);  pinMode(WAL7, OUTPUT);  pinMode(WC1, INPUT);  pinMode(WC2, INPUT);  pinMode(WC3, INPUT);  pinMode(WC4, INPUT);  pinMode(WC5, INPUT);  pinMode(WC6, INPUT);}void loop() {  // put your main code here, to run repeatedly:   if (mySerial1.available()) {   Serial.write(mySerial1.read());   }  if (Serial.available()) {   mySerial1.write(Serial.read());   }    GPIODATA(0) = 0x80*digitalRead(WC5);//  counter++;//  if (counter >= 127)//    counter = 0;}

I assume this does not run anywhere close to 100Mhz, but.. i have no feeling for speed/timing (yet)...

 

Then i managed to setup a trigger on Channel 7, and this is the picture i get:

logic.png

 

this does not show any bouncing (right?), as i already noticed in the "State Machine" chapter...

 

(some other things i don't understand: Why are channel 0 and 2 always "1", and why are all channels "1" for 1 sample when switching...

 

again, using the ZAP IDE, ZPUino, and FPGA programming are all new to me.

 

For completeness, this is the VHDL code of the (mis)behaving state machine:

library ieee;use ieee.std_logic_1164.all;entity CombinationLock is    Port ( clk      : in STD_LOGIC;           switches : in STD_LOGIC_VECTOR (7 downto 0);           sdSeg    : out STD_LOGIC_VECTOR (0 to 6);           sdAN     : out STD_LOGIC_VECTOR (3 downto 0)    );end CombinationLock;architecture Behavioral of CombinationLock is    component sevensegdisplay        port (            clk                 : in    STD_LOGIC;            digit0              : in    STD_LOGIC_VECTOR(3 downto 0);            digit1              : in    STD_LOGIC_VECTOR(3 downto 0);            digit2              : in    STD_LOGIC_VECTOR(3 downto 0);            digit3              : in    STD_LOGIC_VECTOR(3 downto 0);            anodes              : out   STD_LOGIC_VECTOR(3 downto 0);            sevenseg            : out   STD_LOGIC_VECTOR(6 downto 0);            dp                  : out   STD_LOGIC        );            end component;    constant state_error        : STD_LOGIC_VECTOR(3 downto 0) := "0000";    constant state_start        : STD_LOGIC_VECTOR(3 downto 0) := "0001";    constant state_one_right    : STD_LOGIC_VECTOR(3 downto 0) := "0010";    constant state_two_right    : STD_LOGIC_VECTOR(3 downto 0) := "0011";    constant state_three_right  : STD_LOGIC_VECTOR(3 downto 0) := "0100";    constant state_open         : STD_LOGIC_VECTOR(3 downto 0) := "1000";    signal state : STD_LOGIC_VECTOR(3 downto 0) := (others => '0');    signal dummy : STD_LOGIC;begin    process (clk, switches)    begin        if rising_edge(clk) then            case state is                when state_error =>                    case switches is                        when "00000000" => state <= state_start;                        when others     => state <= state_error;                    end case;                when state_start =>                    case switches is                        when "00000000" => state <= state_start;                        when "01000000" => state <= state_one_right;                        when others     => state <= state_error;                    end case;                when state_one_right =>                    case switches is                        when "01000000" => state <= state_one_right;                        when "01100000" => state <= state_two_right;                        when others     => state <= state_error;                    end case;                when state_two_right =>                    case switches is                        when "01100000" => state <= state_two_right;                        when "01110000" => state <= state_three_right;                        when others     => state <= state_error;                    end case;                when state_three_right =>                    case switches is                        when "01110000" => state <= state_three_right;                        when "01111000" => state <= state_open;                        when others     => state <= state_error;                    end case;                when state_open =>                    case switches is                        when "01111000" => state <= state_open;                        when others     => state <= state_error;                    end case;                when others => state <= state_error;            end case;        end if;    end process;    sevenseg : sevensegdisplay    port map (        clk => clk,        digit0 => state,        digit1 => "0000",        digit2 => "0000",        digit3 => "0000",        anodes => sdAN,        sevenseg => sdSeg,        dp => dummy    );end Behavioral;

I haven't tried capturing it in block ram, because at the moment i'm not capable of doing that. (I have never written data to BRAM, so i'm not comfortable doing that for debugging purposes just yet, and, sending all data to the host is something i have not covered yet. I will try that when i've finished the introduction book.)

 

-Martijn

Share this post


Link to post
Share on other sites

Hello Martijn,

 

You are heading in the right direction, but I'm still not sure what I'm looking at with the information you provided. Lets talk about capturing what happens when you flip one of the switches first.

 

In the logic analyzer project there are two parts, the schematic for the bit file and the code. You showed us the code but I don't see anything about the schematic for the bit file. In order to capture the slide switches you will also have to modify the schematic and change it so the logic analyzer inputs are connected to Wingslot C0-C7 instead of A0-A7. In the comments for the sketch you should see a link to edit the schematic. That should open the schematic in ISE and let you use the schematic editor to change how the Logic Analyzer probes are connected.

 

The Logic Analyzer is indeed capable of capturing at speeds up to 100Mhz, but it depends on what you set the capture speed to.

 

Jack.

Share this post


Link to post
Share on other sites

Hi,

 

i loaded the  .xise in the ise, but i can't see to get it to generate a bit file. I haven't changed anything yet, but i get the following errors:

Running sch2hdl...Command Line: sch2hdl -batch /mnt/Data3/opt/papilio-zap-ide/examples/00.Papilio_Schematic_Library/examples/Benchy_Sump_LogicAnalyzer/LX9/sch2HdlBatchFileRelease 14.7 - sch2hdl P.20131013 (lin64)Copyright (c) 1995-2013 Xilinx, Inc.  All rights reserved.ERROR: Failed to load symbols for /mnt/Data3/opt/papilio-zap-ide/examples/00.Papilio_Schematic_Library/examples/Benchy_Sump_LogicAnalyzer/Papilio_Pro.sch no netlist will be generatedERROR: Could not find symbol "Papilio_Wing_Pinout"ERROR: Could not find symbol "Wing_GPIO"ERROR: Could not find symbol "Wishbone_Empty_Slot"ERROR: Could not find symbol "COMM_zpuino_wb_UART"ERROR: Could not find symbol "ZPUino_Papilio_Pro_V1"ERROR: Could not find symbol "BENCHY_sa_SumpBlaze_LogicAnalyzer8"

I assume this should be all OK when loading the .xise file, this is the view from my ISE:

ise.png

 

I didn't have a lot of time to fiddle with it, so i'm still busy, just letting you know i'm trying things. :)

Share this post


Link to post
Share on other sites

I followed the tutorial, but i still get the same error. Maybe it is due to the 64-bit linux ISE version I am using? I don't know, just guessing.

 

Anyways, i'm putting this quest on-hold for a while until i'm more comfortable with everything. Once that is done i'll return to this topic. :)

 

 

Edit: Found the workaround: http://forum.gadgetfactory.net/index.php?/topic/1529-papilio-soc-build-system-on-chip-with-schematic-editor/page-6#entry12434

Share this post


Link to post
Share on other sites

Hi,

 

to show switch bounce, simply define a counter. Keep a register for "old button state". Increment counter at clock if old state != current state.

Then put the 3 lowest bits to LEDs.

Most likely they'll show a totally random pattern every time you hit the button.

 

Using C code and a logic analyzer for this sort of study is maybe a little overkill when a handful of gates will do the job (may be useful in its own right, though).

Share this post


Link to post
Share on other sites

Hi,

 

to show switch bounce, simply define a counter. Keep a register for "old button state". Increment counter at clock if old state != current state.

Then put the 3 lowest bits to LEDs.

Most likely they'll show a totally random pattern every time you hit the button.

 

Using C code and a logic analyzer for this sort of study is maybe a little overkill when a handful of gates will do the job (may be useful in its own right, though).

 

I did this, and the switch bouncing only appears in 1 direction.

 

When changing the original problem to include not just going from 0 to 1, but also from 1 to 0, the problem described manifested itself.

 

So i was 50% right. :huh:  And there is something fishy about my switches.

 

thanks for the help.

Share this post


Link to post
Share on other sites

Dang that modern technology. Wishing back those good ol' days where men were real men and switches were _reliably_ unreliable...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now