Hi guys..
I am at the moment trying to implement an SPI interface onto my FPGA, but i am bit confused on how i TX and RX a byte onto my MISO and MOSI which consist of being one port.
Should i just send one bit every time the CLK has a rising_edge, or is on the falling_edge or on a full clock.. How do transfer/receive a byte (actually more than a byte when receiving) using one MISO and MOSI pin ??
*Most commonly.TX is done on the falling edge of the clock
RX is done on the rising edge of the clock
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 receive: process(newClock, MISO, init_rx, state_rx, RX) begin if init_rx = '1' then case state_rx is when bit9 => if rising_edge(newClock) then RX(9) <= MISO; state_rx <= bit8; end if; when bit8 => if rising_edge(newClock) then RX(8) <= MISO; state_rx <= bit7; end if; when bit7 => if rising_edge(newClock) then RX(7) <= MISO; state_rx <= bit6; end if; when bit6 => if rising_edge(newClock) then RX(6) <= MISO; state_rx <= bit5; end if; when bit5 => if rising_edge(newClock) then RX(5) <= MISO; state_rx <= bit4; end if; when bit4 => if rising_edge(newClock) then RX(4) <= MISO; state_rx <= bit3; end if; when bit3 => if rising_edge(newClock) then RX(3) <= MISO; state_rx <= bit2; end if; when bit2 => if rising_edge(newClock) then RX(2) <= MISO; state_rx <= bit1; end if; when bit1 => if rising_edge(newClock) then RX(1) <= MISO; state_rx <= bit0; end if; when bit0 => if rising_edge(newClock) then RX(0) <= MISO; state_rx <= bit9; init_rx <= '0'; end if; end case; end if; end process;
Figure 1- 1of the datasheet tells "output data on falling edge" and "input data on rising edge" in both directions.has to be send at a rising edge.
It because the ADC (MCP3008) outputs 10 bit value.
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 ---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 10/07/2015 10:57:05 PM -- Design Name: -- Module Name: main - Behavioral -- Project Name: -- Target Devices: -- Tool Versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeric_std.all; use IEEE.STD_LOGIC_ARITH.all; use IEEE.STD_logic_unsigned.all; use ieee.numeric_std.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values --use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity main is Port ( MISO : in STD_LOGIC; MOSI : out STD_LOGIC; CS : out STD_LOGIC; SCLK : out STD_LOGIC; CLK : in STD_LOGIC); end main; architecture Behavioral of main is --signal prescaler : integer range 0 to 3500000 := 3500000 ; signal prescaler_counter : integer range 0 to 50000000 := 0; signal newClock : std_logic := '0'; signal TX :std_logic_vector(7 downto 0) := "00000000"; signal RX : std_logic_vector(9 downto 0) := "0000000000"; type state_type is (start,state2,state3,state4,state5,state6); --type of state machine. type TXRX is (waiting, working); signal state : state_type := start; signal shift_counter: integer range 0 to 10:= 0; signal init_tx: TXRX := waiting; signal init_rx: TXRX := waiting; begin prescaler01: process(clk, newClock) begin if rising_edge(clk) then if prescaler_counter <= 6 then prescaler_counter <= prescaler_counter + 1; else newClock <= not newClock; prescaler_counter <= 0; end if; end if; end process; SCLK <= newClock; -- FPGA transmit data on falling_edge -- FPGA reads data on rising_edge SPI_state: process(newClock) begin if rising_edge(newClock) then case state is when start => CS <= '1'; state <= state2; when state2 => case init_tx is when waiting => TX <= "00000001"; init_tx <= working; when working => shift_counter <= shift_counter + 1; MOSI <= TX(shift_counter); -- For at få optimal speed bør denne sætte ved falling_edge(newClock og ikke rising_edge) if shift_counter = 8 then MOSI <= '0'; init_tx <= waiting; shift_counter<= 0; state <= state3; end if; end case; when state3 => case init_tx is when waiting => TX <= "10000000"; init_tx <= working; when working => shift_counter <= shift_counter + 1; MOSI <= TX(shift_counter); if shift_counter = 8 then init_tx <= waiting; shift_counter<= 0; state <= state4; MOSI <= '0'; end if; end case; when state4 => case init_tx is when waiting => TX <= "00000000"; init_tx <= working; when working => shift_counter <= shift_counter+1; MOSI <= TX(shift_counter); if shift_counter = 8 then init_tx <= waiting; shift_counter <= 0; state <= state5; MOSI <= '0'; end if; end case; when state5 => state <= state6; when state6 => case init_rx is when waiting => init_rx <= working shift_counter <= 10; when working => shift_counter <= shift_counter-1; RX(shift_counter) <= MISO; if shift_counter = 0 then init_rx <= waiting; shift_counter <= 0; state <= start; end if; end case; when others => state <= start; end case; end if; end process; end Behavioral;
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 begin if rising_edge(newClock) then case state is when start => -- assignments when state2 => case init_tx is when waiting => -- assignments when working => -- assignments if shift_counter = 8 then -- assginments end if;
Code VHDL - [expand] 1 prescaler01: process(clk, newClock)
Code VHDL - [expand] 1 2 RX(shift_counter) <= MISO; MOSI <= TX(shift_counter);
Code VHDL - [expand] 1 shift_reg <= shift_reg(shift_reg'left -1 downto 0) & '0';
Yes. Doesn't happen in your code.The ADC only operates when the CS is pulled low
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?