Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9094783
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T23:26:05+00:00 2026-06-16T23:26:05+00:00

I’m needing to do continual SPI communication to read values from a dual channel

  • 0

I’m needing to do continual SPI communication to read values from a dual channel ADC I have, and have written a kinda state-machine to do so. However, it doesn’t seem to be getting into the state that reads the second channel and I can’t figure out why. here’s the VHDL…

SPI_read: process (mclk)
                                                        --command bits: Start.Single.Ch.MSBF....
    constant query_x: unsigned(ADC_datawidth-1 downto 0) := "11010000000000000";    -- Query ADC Ch0 ( inclinometer x-axis)
    constant query_y: unsigned(ADC_datawidth-1 downto 0) := "11110000000000000";    -- Query ADC Ch1 ( inclinometer y-axis)

begin

    if rising_edge(mclk) then

        -- when SPI is not busy, change state and latch Rx data from last communication
        if (SPI_busy = '0') then

            case SPI_action is
                when SETUP => 
                    SPI_pol <= '0'; -- Clk low when not active
                    SPI_pha <= 1;       -- First edge is half an SCLK period after CS activated
                    SPI_action <= READ_X;
                when READ_X =>
                    SPI_Tx_buf <= query_x; -- Load in command
                    y_data <= "00000" & SPI_Rx_buf(11 downto 1);
                    SPI_send <= '1';
                    SPI_action <= READ_Y;
                when READ_Y =>
                    SPI_Tx_buf <= query_y; -- Load in command
                    x_data <= "00000" & SPI_Rx_buf(11 downto 1);
                    SPI_send <= '1';
                    SPI_action <= READ_X;
            end case;

        else
            SPI_send <= '0'; -- Deassert send pin
        end if;

    end if;

end process SPI_read;

The command is sent to the Tx buffer, and the value from the last received data is written to a signal which is output to some seven segment displays. A pulse from SPI_send is required to start the transfer, and when started, SPI_busy is set high until the transfer is completed.

Right now it’ll only send the query_x over SPI, and I can know this since I can see it on the scope. Interestingly, however, It’s outputting the same value to both displays which leads me to think that it’s still getting into it’s READ_Y state, but not changing the Tx Data it’s outputting.

I’ve been staring at this code for hours now, and I can’t figure it out. Sometimes a fresh pair of eyes makes life easier, so if you spot anything please let me know.
Also, I’m very open to suggestions of better ways to deal with this, I’m just learning VHDL so I’m not even sure I’m doing things the right way mostly!

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T23:26:06+00:00Added an answer on June 16, 2026 at 11:26 pm

    You are thinking along the right basic lines, but there are various things not-quite-right with your state machine – as the other answers say – and these are easy to discover in simulation.

    For example

            when READ_X =>
                SPI_Tx_buf <= query_x; -- Load in command
                y_data <= "00000" & SPI_Rx_buf(11 downto 1);
                SPI_send <= '1';
                SPI_action <= READ_Y;
    

    Now if SPI_Busy stays low for a second cycle, this will clearly not stay in state READ_X but transition directly to READ_Y which is probably not what you want.

    A more normal state machine would treat the states as outermost, and interpret the input signals differently for each state :

       case SPI_Action is             
          when READ_X => 
                         if SPI_Busy = '0' then    -- Wait here if busy
                            SPI_Tx_buf <= query_x; -- Load in command
                            y_data <= "00000" & SPI_Rx_buf(11 downto 1);
                            SPI_send <= '1';
                            SPI_action <= READING_X;
                         end if;
          when READING_X =>
                         if SPI_Busy = '1' then   -- command accepted
                            SPI_action <= READ_Y; -- ready to send next one
                         end if;
          when READ_Y => 
                         if SPI_Busy = '0' then    -- Wait here if busy
    

    You can see that this version treats the Busy signal as a handshake, and only progresses when Busy changes state. I am certain you can make your approach (IF outermost) work if you want, but you will have tofigure out how to apply the handshaking principle yourself.

    There is also no “Idle” state where neither X or Y is being read; this SM will read X and Y alternately as fast as it can. Commonly you would read them both, then return to Idle until some other Start signal commanded you to leave Idle and perform a fresh set of reads.

    You can possibly also make the state machine more robust with a “when others” clause. It’s not a must, if you guarantee to cover all your defined states, but it can make maintenance easier. On the other hand, without such a clause, the compilers will let you know of any uncovered states, guarding against mistakes.

    There is a myth that a “when others” clause is essential and synthesis tools generate safer but less optimal state machines from a “when others” clause. However there are synthesis attributes or command line options to control how synth tools generate state machines.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a text area in my form which accepts all possible characters from
I have a view passing on information from a database: def serve_article(request, id): served_article
I have a bunch of posts stored in text files formatted in yaml/textile (from
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I have a .ini file as follows: [playlist] numberofentries=2 File1=http://87.230.82.17:80 Title1=(#1 - 365/1400) Example
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
For some reason, after submitting a string like this Jack’s Spindle from a text
this is what i have right now Drawing an RSS feed into the php,
I have a small JavaScript validation script that validates inputs based on Regex. I

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.