diff options
| author | Väinö Kauppila <vaino@vke.fi> | 2026-04-19 19:02:42 +0300 |
|---|---|---|
| committer | Väinö Kauppila <vaino@vke.fi> | 2026-04-19 19:02:42 +0300 |
| commit | 46e1210381106707c2df7f07c56023eb6b760763 (patch) | |
| tree | 6740a17199f76e2965a511dafcbc7ffb61ceafeb /hdl/onewire.vhd | |
| parent | eb8643ddbef43547eb7bfe58789a3908926c7258 (diff) | |
| download | vhdl_pic-46e1210381106707c2df7f07c56023eb6b760763.tar.gz vhdl_pic-46e1210381106707c2df7f07c56023eb6b760763.zip | |
BSRAM progmem. fix Makefile memory command that does not work. add interrupts, bank 1, timer0. Timer0 not tested.
Diffstat (limited to 'hdl/onewire.vhd')
| -rw-r--r-- | hdl/onewire.vhd | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/hdl/onewire.vhd b/hdl/onewire.vhd new file mode 100644 index 0000000..440d34d --- /dev/null +++ b/hdl/onewire.vhd @@ -0,0 +1,195 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; + +entity onewire is + generic ( + CLK_FREQ : positive := 50_000_000 + ); + port ( + clk : in std_logic; + reset : in std_logic; + + ow_pin : inout std_logic; -- 4.7 kohm pull-up to 3.3 V externally + + start : in std_logic; + op : in std_logic_vector(1 downto 0); -- "00" reset, "01" write, "10" read + tx_byte : in std_logic_vector(7 downto 0); + rx_byte : out std_logic_vector(7 downto 0); + presence : out std_logic; + busy : out std_logic; + done : out std_logic + ); +end entity onewire; + +architecture rtl of onewire is + + constant us : positive := CLK_FREQ / 1_000_000; + + constant RESET_LOW_TICKS : positive := 480 * us; + constant PRESENCE_WAIT_TICKS : positive := 15 * us; + constant PRESENCE_SAMPLE_END : positive := 75 * us; + constant RESET_RECOVER_TICKS : positive := 480 * us; + constant WRITE0_LOW_TICKS : positive := 60 * us; + constant WRITE1_LOW_TICKS : positive := 6 * us; + constant SLOT_TICKS : positive := 70 * us; + constant READ_INIT_TICKS : positive := 6 * us; + constant READ_SAMPLE_TICKS : positive := 15 * us; + + type state_t is ( + IDLE, + RST_PULL, RST_RELEASE, RST_SAMPLE, RST_RECOVER, + WR_PULL, WR_RELEASE, + RD_PULL, RD_RELEASE, RD_SAMPLE, RD_RECOVER, + BYTE_NEXT + ); + + signal state : state_t := IDLE; + signal ow_drive : std_logic := '0'; + signal ow_sense : std_logic; + signal timer : natural range 0 to RESET_LOW_TICKS + 1 := 0; + signal bit_index : natural range 0 to 8 := 0; + signal shift_reg : std_logic_vector(7 downto 0) := (others => '0'); + signal cur_bit : std_logic := '0'; + signal is_read : std_logic := '0'; + signal rx_byte_i : std_logic_vector(7 downto 0) := (others => '0'); + + signal presence_internal : std_logic := '0'; +begin + + ow_pin <= '0' when ow_drive = '1' else 'Z'; + ow_sense <= ow_pin; + + presence <= presence_internal; + + rx_byte <= rx_byte_i; + busy <= '0' when state = IDLE else '1'; + + process(clk) + begin + if rising_edge(clk) then + done <= '0'; + timer <= timer + 1; + + if reset = '1' then + state <= IDLE; + ow_drive <= '0'; + timer <= 0; + else + case state is + when IDLE => + timer <= 0; + + if start = '1' then + presence_internal <= '0'; + case op is + -- reset + when "00" => + timer <= 0; + state <= RST_PULL; + + -- write + when "01" => + state <= WR_PULL; + shift_reg <= tx_byte; + bit_index <= 0; + is_read <= '0'; + + -- read + when "10" => + state <= RD_PULL; + bit_index <= 0; + is_read <= '1'; + + when others => null; + end case; + end if; + + when RST_PULL => + ow_drive <= '1'; + + if timer >= RESET_LOW_TICKS then + state <= RST_RELEASE; + end if; + + + when RST_RELEASE => + ow_drive <= '0'; + timer <= 0; + state <= RST_SAMPLE; + + when RST_SAMPLE => + if ow_sense = '0' then + presence_internal <= '1'; + end if; + + if (ow_sense = '1' and presence_internal = '1') or + timer >= PRESENCE_SAMPLE_END then + state <= RST_RECOVER; + end if; + + when RST_RECOVER => + -- wait for 480us since RST_RELEASE + if timer >= RESET_RECOVER_TICKS then + done <= '1'; + state <= IDLE; + end if; + + when WR_PULL => + ow_drive <= '1'; + if (shift_reg(bit_index) = '1' and timer >= WRITE1_LOW_TICKS) or + (shift_reg(bit_index) = '0' and timer >= WRITE0_LOW_TICKS) then + state <= WR_RELEASE; + end if; + + when WR_RELEASE => + ow_drive <= '0'; + + if timer >= SLOT_TICKS then + state <= BYTE_NEXT; + end if; + + when RD_PULL => + ow_drive <= '1'; + + if timer >= READ_INIT_TICKS then + state <= RD_RELEASE; + end if; + + when RD_RELEASE => + ow_drive <= '0'; + + if timer >= READ_INIT_TICKS + 2 * us then + state <= RD_SAMPLE; + end if; + + when RD_SAMPLE => + rx_byte_i <= ow_sense & rx_byte_i(7 downto 1); + state <= RD_RECOVER; + + when RD_RECOVER => + if timer >= SLOT_TICKS then + state <= BYTE_NEXT; + end if; + + when BYTE_NEXT => + timer <= 0; + if bit_index = 7 then + bit_index <= 0; + done <= '1'; + state <= IDLE; + else + bit_index <= bit_index + 1; + if is_read = '1' then + state <= RD_PULL; + else + state <= WR_PULL; + end if; + end if; + when others => state <= IDLE; + end case; + end if; + end if; + end process; + +end architecture rtl; |
