From f00beecba446947a48706fc6b4124cc62d9d8bdf Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:25:38 +0200
Subject: [PATCH 01/10] :warning: [top] remove GPTMR capture input
---
docs/datasheet/soc.adoc | 4 +---
rtl/core/neorv32_package.vhd | 4 +---
rtl/core/neorv32_top.vhd | 6 +-----
3 files changed, 3 insertions(+), 11 deletions(-)
diff --git a/docs/datasheet/soc.adoc b/docs/datasheet/soc.adoc
index 01a039d47..e3a7ed6c9 100644
--- a/docs/datasheet/soc.adoc
+++ b/docs/datasheet/soc.adoc
@@ -36,7 +36,7 @@ image::neorv32_processor.png[align=center]
* _optional_ custom functions subsystem for custom co-processor extensions (<<_custom_functions_subsystem_cfs,**CFS**>>)
* _optional_ NeoPixel(TM)/WS2812-compatible smart LED interface (<<_smart_led_interface_neoled,**NEOLED**>>)
* _optional_ external interrupt controller with up to 32 channels (<<_external_interrupt_controller_xirq,**XIRQ**>>)
-* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>) with capture input
+* _optional_ general purpose 32-bit timer (<<_general_purpose_timer_gptmr,**GPTMR**>>)
* _optional_ execute in-place module (<<_execute_in_place_module_xip,**XIP**>>)
* _optional_ 1-wire serial interface controller (<<_one_wire_serial_interface_controller_onewire,**ONEWIRE**>>), compatible to the 1-wire standard
* _optional_ autonomous direct memory access controller (<<_direct_memory_access_controller_dma,**DMA**>>)
@@ -151,8 +151,6 @@ Some interfaces (like the TWI and the 1-Wire bus) require tri-state drivers in t
| `neoled_o` | 1 | out | - | asynchronous serial data output
5+^| **<<_machine_system_timer_mtime>>**
| `mtime_time_o` | 64 | out | - | MTIME system time output
-5+^| **<<_general_purpose_timer_gptmr>>**
-| `gptmr_trig_i` | 1 | in | `'L'` | timer capture input
5+^| **<<_external_interrupt_controller_xirq>>**
| `xirq_i` | 32 | in | `'L'` | external interrupt requests
5+^| **RISC-V Machine-Mode <<_processor_interrupts>>**
diff --git a/rtl/core/neorv32_package.vhd b/rtl/core/neorv32_package.vhd
index a954295aa..c67b3f84a 100644
--- a/rtl/core/neorv32_package.vhd
+++ b/rtl/core/neorv32_package.vhd
@@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
- constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100009"; -- hardware version
+ constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100010"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width
@@ -879,8 +879,6 @@ package neorv32_package is
neoled_o : out std_ulogic;
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o : out std_ulogic_vector(63 downto 0);
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i : in std_ulogic := 'L';
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L');
-- CPU Interrupts --
diff --git a/rtl/core/neorv32_top.vhd b/rtl/core/neorv32_top.vhd
index 43b0244d5..64d47a177 100644
--- a/rtl/core/neorv32_top.vhd
+++ b/rtl/core/neorv32_top.vhd
@@ -222,9 +222,6 @@ entity neorv32_top is
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o : out std_ulogic_vector(63 downto 0); -- current system time
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i : in std_ulogic := 'L'; -- capture trigger
-
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(31 downto 0) := (others => 'L'); -- IRQ channels
@@ -1485,8 +1482,7 @@ begin
bus_rsp_o => iodev_rsp(IODEV_GPTMR),
clkgen_en_o => cg_en(CG_GPTMR),
clkgen_i => clk_gen,
- irq_o => firq(FIRQ_GPTMR),
- capture_i => gptmr_trig_i
+ irq_o => firq(FIRQ_GPTMR)
);
end generate;
From ecc187597fa6d3d436805778644a75b67fa23322 Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:25:57 +0200
Subject: [PATCH 02/10] [sim] remove GPTMR capture input
---
sim/neorv32_tb.vhd | 2 --
sim/simple/neorv32_tb.simple.vhd | 2 --
2 files changed, 4 deletions(-)
diff --git a/sim/neorv32_tb.vhd b/sim/neorv32_tb.vhd
index 1d98bc3f8..1fc680a09 100644
--- a/sim/neorv32_tb.vhd
+++ b/sim/neorv32_tb.vhd
@@ -357,8 +357,6 @@ begin
neoled_o => open, -- async serial data line
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o => open,
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i => gpio(63), -- capture trigger
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i => gpio(31 downto 0), -- IRQ channels
-- CPU Interrupts --
diff --git a/sim/simple/neorv32_tb.simple.vhd b/sim/simple/neorv32_tb.simple.vhd
index 7a2f2a07e..a15df093b 100644
--- a/sim/simple/neorv32_tb.simple.vhd
+++ b/sim/simple/neorv32_tb.simple.vhd
@@ -333,8 +333,6 @@ begin
neoled_o => open, -- async serial data line
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o => open,
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i => gpio(63), -- capture trigger
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i => gpio(31 downto 0), -- IRQ channels
-- CPU Interrupts --
From 5aee115c0ddf43dbab0a4898034bf294ddab000a Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:26:19 +0200
Subject: [PATCH 03/10] [vivado_ip] [sim] remove GPTMR capture input
---
rtl/system_integration/neorv32_vivado_ip.tcl | 1 -
rtl/system_integration/neorv32_vivado_ip.vhd | 4 ----
2 files changed, 5 deletions(-)
diff --git a/rtl/system_integration/neorv32_vivado_ip.tcl b/rtl/system_integration/neorv32_vivado_ip.tcl
index f145ea588..7a154950b 100644
--- a/rtl/system_integration/neorv32_vivado_ip.tcl
+++ b/rtl/system_integration/neorv32_vivado_ip.tcl
@@ -86,7 +86,6 @@ set_property enablement_dependency {$io_pwm_num_ch > 0} [ipx::get_ports
set_property enablement_dependency {$io_cfs_en = true} [ipx::get_ports cfs_* -of_objects [ipx::current_core]]
set_property enablement_dependency {$io_neoled_en = true} [ipx::get_ports neoled_o -of_objects [ipx::current_core]]
set_property enablement_dependency {$io_mtime_en = true} [ipx::get_ports mtime_time_o -of_objects [ipx::current_core]]
-set_property enablement_dependency {$io_gptmr_en = true} [ipx::get_ports gptmr_trig_i -of_objects [ipx::current_core]]
set_property enablement_dependency {$xirq_num_ch > 0} [ipx::get_ports xirq_i -of_objects [ipx::current_core]]
set_property enablement_dependency {$io_mtime_en = false} [ipx::get_ports mtime_irq_i -of_objects [ipx::current_core]]
diff --git a/rtl/system_integration/neorv32_vivado_ip.vhd b/rtl/system_integration/neorv32_vivado_ip.vhd
index c7559571e..793e99da3 100644
--- a/rtl/system_integration/neorv32_vivado_ip.vhd
+++ b/rtl/system_integration/neorv32_vivado_ip.vhd
@@ -226,8 +226,6 @@ entity neorv32_vivado_ip is
neoled_o : out std_ulogic;
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o : out std_ulogic_vector(63 downto 0);
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i : in std_ulogic := '0';
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i : in std_ulogic_vector(XIRQ_NUM_CH-1 downto 0) := (others => '0');
-- CPU Interrupts --
@@ -437,8 +435,6 @@ begin
neoled_o => neoled_o,
-- Machine timer system time (available if IO_MTIME_EN = true) --
mtime_time_o => mtime_time_o,
- -- GPTMR timer capture (available if IO_GPTMR_EN = true) --
- gptmr_trig_i => gptmr_trig_i,
-- External platform interrupts (available if XIRQ_NUM_CH > 0) --
xirq_i => xirq_i_aux,
-- CPU Interrupts --
From cfb8f65a01864c77374cbe92cc4883ed62ab2b15 Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:40:45 +0200
Subject: [PATCH 04/10] :warning: [gptmr] rework
* remove capture mode
* re-add MODE select (single-shot or continuous)
* fix IRQ ack race conditions
---
rtl/core/neorv32_gptmr.vhd | 210 +++++++++++--------------------------
1 file changed, 62 insertions(+), 148 deletions(-)
diff --git a/rtl/core/neorv32_gptmr.vhd b/rtl/core/neorv32_gptmr.vhd
index 37a7af380..f6680dd0e 100644
--- a/rtl/core/neorv32_gptmr.vhd
+++ b/rtl/core/neorv32_gptmr.vhd
@@ -1,8 +1,6 @@
-- ================================================================================ --
-- NEORV32 SoC - General Purpose Timer (GPTMR) --
-- -------------------------------------------------------------------------------- --
--- Can operate in interval timer mode and/or in input capture mode. --
--- -------------------------------------------------------------------------------- --
-- The NEORV32 RISC-V Processor - https://github.com/stnolting/neorv32 --
-- Copyright (c) NEORV32 contributors. --
-- Copyright (c) 2020 - 2024 Stephan Nolting. All rights reserved. --
@@ -25,55 +23,35 @@ entity neorv32_gptmr is
bus_rsp_o : out bus_rsp_t; -- bus response
clkgen_en_o : out std_ulogic; -- enable clock generator
clkgen_i : in std_ulogic_vector(7 downto 0);
- irq_o : out std_ulogic; -- timer match interrupt
- capture_i : in std_ulogic -- capture input
+ irq_o : out std_ulogic -- timer match interrupt
);
end neorv32_gptmr;
architecture neorv32_gptmr_rtl of neorv32_gptmr is
-- control register --
- constant ctrl_en_c : natural := 0; -- r/w: global enable
- constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler select bit 0
- constant ctrl_prsc1_c : natural := 2; -- r/w: clock prescaler select bit 1
- constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler select bit 2
- constant ctrl_irqm_c : natural := 4; -- r/w: enable interrupt on timer match
- constant ctrl_irqc_c : natural := 5; -- r/w: enable interrupt on capture trigger
- constant ctrl_rise_c : natural := 6; -- r/w: capture on rising edge
- constant ctrl_fall_c : natural := 7; -- r/w: capture on falling edge
- constant ctrl_filter_c : natural := 8; -- r/w: filter capture input signal
+ constant ctrl_en_c : natural := 0; -- r/w: global enable
+ constant ctrl_prsc0_c : natural := 1; -- r/w: clock prescaler select bit 0
+ constant ctrl_prsc1_c : natural := 2; -- r/w: clock prescaler select bit 1
+ constant ctrl_prsc2_c : natural := 3; -- r/w: clock prescaler select bit 2
+ constant ctrl_mode_c : natural := 4; -- r/w: mode (0=single-shot, 1=continuous)
--
- constant ctrl_trigm_c : natural := 30; -- r/c: timer-match has fired, cleared by writing 0
- constant ctrl_trigc_c : natural := 31; -- r/c: capture-trigger has fired, cleared by writing 0
+ constant ctrl_irq_clr_c : natural := 30; -- -/w: set to clear timer-match interrupt
+ constant ctrl_irq_c : natural := 31; -- r/-: timer-match interrupt pending
--
- signal ctrl : std_ulogic_vector(8 downto 0);
-
- -- trigger flags --
- signal trig_match, trig_capture : std_ulogic;
+ signal ctrl : std_ulogic_vector(4 downto 0);
-- timer core --
type timer_t is record
- count : std_ulogic_vector(31 downto 0); -- counter register
- thres : std_ulogic_vector(31 downto 0); -- threshold register
- tick : std_ulogic; -- clock generator tick
- match : std_ulogic; -- count == thres
- match_ff : std_ulogic;
- trigger : std_ulogic; -- match trigger (single-shot)
- cnt_we : std_ulogic; -- write access to count register
+ tick : std_ulogic; -- clock generator tick
+ thres : std_ulogic_vector(31 downto 0); -- threshold register
+ count : std_ulogic_vector(31 downto 0); -- counter register
+ match : std_ulogic; -- counter register == threshold register
end record;
signal timer : timer_t;
- -- sampling and capture logic --
- type capture_t is record
- sync : std_ulogic_vector(1 downto 0); -- synchronizer (prevent metastability)
- sreg : std_ulogic_vector(3 downto 0); -- input sampling
- state : std_ulogic_vector(1 downto 0); -- state buffer to detect edges
- count : std_ulogic_vector(31 downto 0); -- capture register
- trigger : std_ulogic; -- edge detector has been triggered
- rising : std_ulogic; -- rising-edge detector
- falling : std_ulogic; -- falling-edge detector
- end record;
- signal capture : capture_t;
+ -- interrupt generator --
+ signal irq_pnd, irq_clr : std_ulogic;
begin
@@ -82,167 +60,103 @@ begin
bus_access: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
- bus_rsp_o <= rsp_terminate_c;
- ctrl <= (others => '0');
- trig_match <= '0';
- trig_capture <= '0';
- timer.cnt_we <= '0';
- timer.thres <= (others => '0');
+ bus_rsp_o <= rsp_terminate_c;
+ ctrl <= (others => '0');
+ timer.thres <= (others => '0');
+ irq_clr <= '0';
elsif rising_edge(clk_i) then
-- defaults --
bus_rsp_o.ack <= bus_req_i.stb;
bus_rsp_o.err <= '0'; -- no access error possible
bus_rsp_o.data <= (others => '0');
- timer.cnt_we <= '0';
-
- -- IRQ trigger --
- trig_match <= ctrl(ctrl_en_c) and ctrl(ctrl_irqm_c) and (trig_match or timer.trigger);
- trig_capture <= ctrl(ctrl_en_c) and ctrl(ctrl_irqc_c) and (trig_capture or capture.trigger);
-
+ irq_clr <= '0';
-- actual bus access --
if (bus_req_i.stb = '1') then
if (bus_req_i.rw = '1') then -- write access
if (bus_req_i.addr(3 downto 2) = "00") then -- control register
- ctrl(ctrl_en_c) <= bus_req_i.data(ctrl_en_c);
- ctrl(ctrl_prsc0_c) <= bus_req_i.data(ctrl_prsc0_c);
- ctrl(ctrl_prsc1_c) <= bus_req_i.data(ctrl_prsc1_c);
- ctrl(ctrl_prsc2_c) <= bus_req_i.data(ctrl_prsc2_c);
- ctrl(ctrl_irqm_c) <= bus_req_i.data(ctrl_irqm_c);
- ctrl(ctrl_irqc_c) <= bus_req_i.data(ctrl_irqc_c);
- ctrl(ctrl_rise_c) <= bus_req_i.data(ctrl_rise_c);
- ctrl(ctrl_fall_c) <= bus_req_i.data(ctrl_fall_c);
- ctrl(ctrl_filter_c) <= bus_req_i.data(ctrl_filter_c);
- if (bus_req_i.data(ctrl_trigm_c) = '0') then -- clear by writing zero
- trig_match <= '0';
- end if;
- if (bus_req_i.data(ctrl_trigc_c) = '0') then -- clear by writing zero
- trig_capture <= '0';
- end if;
+ ctrl(ctrl_en_c) <= bus_req_i.data(ctrl_en_c);
+ ctrl(ctrl_prsc0_c) <= bus_req_i.data(ctrl_prsc0_c);
+ ctrl(ctrl_prsc1_c) <= bus_req_i.data(ctrl_prsc1_c);
+ ctrl(ctrl_prsc2_c) <= bus_req_i.data(ctrl_prsc2_c);
+ ctrl(ctrl_mode_c) <= bus_req_i.data(ctrl_mode_c);
+ --
+ irq_clr <= bus_req_i.data(ctrl_irq_clr_c);
end if;
if (bus_req_i.addr(3 downto 2) = "01") then -- threshold register
timer.thres <= bus_req_i.data;
end if;
- if (bus_req_i.addr(3 downto 2) = "10") then -- counter register
- timer.cnt_we <= '1';
- end if;
else -- read access
case bus_req_i.addr(3 downto 2) is
when "00" => -- control register
- bus_rsp_o.data(ctrl_en_c) <= ctrl(ctrl_en_c);
- bus_rsp_o.data(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
- bus_rsp_o.data(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
- bus_rsp_o.data(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
- bus_rsp_o.data(ctrl_irqm_c) <= ctrl(ctrl_irqm_c);
- bus_rsp_o.data(ctrl_irqc_c) <= ctrl(ctrl_irqc_c);
- bus_rsp_o.data(ctrl_rise_c) <= ctrl(ctrl_rise_c);
- bus_rsp_o.data(ctrl_fall_c) <= ctrl(ctrl_fall_c);
- bus_rsp_o.data(ctrl_filter_c) <= ctrl(ctrl_filter_c);
+ bus_rsp_o.data(ctrl_en_c) <= ctrl(ctrl_en_c);
+ bus_rsp_o.data(ctrl_prsc0_c) <= ctrl(ctrl_prsc0_c);
+ bus_rsp_o.data(ctrl_prsc1_c) <= ctrl(ctrl_prsc1_c);
+ bus_rsp_o.data(ctrl_prsc2_c) <= ctrl(ctrl_prsc2_c);
+ bus_rsp_o.data(ctrl_mode_c) <= ctrl(ctrl_mode_c);
--
- bus_rsp_o.data(ctrl_trigm_c) <= trig_match;
- bus_rsp_o.data(ctrl_trigc_c) <= trig_capture;
+ bus_rsp_o.data(ctrl_irq_c) <= irq_pnd;
when "01" => -- threshold register
bus_rsp_o.data <= timer.thres;
- when "10" => -- counter register
+ when others => -- counter register
bus_rsp_o.data <= timer.count;
- when others => -- capture register
- bus_rsp_o.data <= capture.count;
end case;
end if;
end if;
end if;
end process bus_access;
- -- interrupt request --
- irq_o <= trig_match or trig_capture;
+ -- clock generator enable --
+ clkgen_en_o <= ctrl(ctrl_en_c);
-- Timer Core -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
- counter_core: process(rstn_i, clk_i)
+ timer_core: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
- timer.count <= (others => '0');
- timer.match_ff <= '0';
+ timer.tick <= '0';
+ timer.count <= (others => '0');
elsif rising_edge(clk_i) then
- if (timer.cnt_we = '1') then -- write access
- timer.count <= bus_req_i.data; -- data_i will remain stable for at least 1 cycle after WREN has returned to low
- elsif (ctrl(ctrl_en_c) = '1') and (timer.tick = '1') then -- enabled and clock tick
- if (timer.match = '1') then -- timer-match
- timer.count <= (others => '0');
+ timer.tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c)))); -- prescaler clock tick
+ if (ctrl(ctrl_en_c) = '0') then -- timer disabled
+ timer.count <= (others => '0');
+ elsif (timer.tick = '1') then -- timer enabled and clock tick
+ if (timer.match = '1') then
+ if (ctrl(ctrl_mode_c) = '1') then -- reset counter if continuous mode
+ timer.count <= (others => '0');
+ end if;
else
timer.count <= std_ulogic_vector(unsigned(timer.count) + 1);
end if;
end if;
- timer.match_ff <= timer.match;
end if;
- end process counter_core;
+ end process timer_core;
-- counter = threshold? --
- timer.match <= '1' when (timer.count = timer.thres) and (ctrl(ctrl_en_c) = '1') else '0';
+ timer.match <= '1' when (timer.count = timer.thres) else '0';
- -- match edge detector --
- timer.trigger <= '1' when (timer.match_ff = '0') and (timer.match = '1') else '0';
- -- clock select --
- clock_select: process(rstn_i, clk_i)
- begin
- if (rstn_i = '0') then
- timer.tick <= '0';
- elsif rising_edge(clk_i) then
- timer.tick <= clkgen_i(to_integer(unsigned(ctrl(ctrl_prsc2_c downto ctrl_prsc0_c))));
- end if;
- end process clock_select;
-
- -- clock generator enable --
- clkgen_en_o <= ctrl(ctrl_en_c);
-
-
- -- Capture Control ------------------------------------------------------------------------
+ -- Interrupt Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
- signal_capture: process(rstn_i, clk_i)
+ irq_generator: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
- capture.sync <= (others => '0');
- capture.sreg <= (others => '0');
- capture.state <= (others => '0');
- capture.count <= (others => '0');
+ irq_pnd <= '0';
elsif rising_edge(clk_i) then
- -- synchronizer - prevent metastability --
- capture.sync <= capture.sync(0) & capture_i;
-
- -- sample shift register, running at reduced sample rate --
- if (clkgen_i(clk_div4_c) = '1') then
- capture.sreg <= capture.sreg(2 downto 0) & capture.sync(1);
- end if;
-
- -- sample state buffer --
- capture.state(1) <= capture.state(0);
- if (ctrl(ctrl_filter_c) = '0') then -- no filter, use synchronized input
- capture.state(0) <= capture.sync(1);
- else -- active filter: change state only if input is stable for 4 sample clocks
- if (capture.sreg = "1111") then
- capture.state(0) <= '1';
- elsif (capture.sreg = "0000") then
- capture.state(0) <= '0';
- else
- capture.state(0) <= capture.state(0);
+ if (ctrl(ctrl_en_c) = '1') then
+ if (timer.match = '1') then
+ irq_pnd <= '1';
+ elsif (irq_clr = '1') then
+ irq_pnd <= '0';
end if;
- end if;
-
- -- timer capture --
- if (ctrl(ctrl_en_c) = '1') and (capture.trigger = '1') then
- capture.count <= timer.count;
+ else
+ irq_pnd <= '0';
end if;
end if;
- end process signal_capture;
-
- -- edge detectors --
- capture.rising <= '1' when (capture.state = "01") else '0';
- capture.falling <= '1' when (capture.state = "10") else '0';
+ end process irq_generator;
- -- capture trigger --
- capture.trigger <= (ctrl(ctrl_rise_c) and capture.rising) or -- rising-edge trigger
- (ctrl(ctrl_fall_c) and capture.falling); -- falling-edge trigger
+ -- interrupt request --
+ irq_o <= irq_pnd;
end neorv32_gptmr_rtl;
From 62d0af81c42dd99003232073dcbb34ac5be1d5d3 Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:41:01 +0200
Subject: [PATCH 05/10] [svd] update GPTMR module
---
sw/svd/neorv32.svd | 38 +++++++-------------------------------
1 file changed, 7 insertions(+), 31 deletions(-)
diff --git a/sw/svd/neorv32.svd b/sw/svd/neorv32.svd
index 7b7a2bf49..16e5ea1c0 100644
--- a/sw/svd/neorv32.svd
+++ b/sw/svd/neorv32.svd
@@ -712,39 +712,20 @@
Clock prescaler select
- GPTMR_CTRL_IRQM
+ GPTMR_CTRL_MODE
[4:4]
- Enable interrupt on timer match
+ Operation mode (0=single-shot, 1=continuous)
- GPTMR_CTRL_IRQC
- [5:5]
- Enable interrupt on capture trigger
-
-
- GPTMR_CTRL_RISE
- [6:6]
- Capture on rising edge; capture-mode only
-
-
- GPTMR_CTRL_FALL
- [7:7]
- Capture on falling edge; capture-mode only
-
-
- GPTMR_CTRL_FILTER
- [8:8]
- Filter capture input; capture-mode only
-
-
- GPTMR_CTRL_TRIGM
+ GPTMR_CTRL_IRQ_CLR
[30:30]
- Timer-match has fired, cleared by writing 0
+ Set to clear timer-match interrupt
- GPTMR_CTRL_TRIGC
+ GPTMR_CTRL_IRQ_PND
[31:31]
- Capture-trigger has fired, cleared by writing
+ read-only
+ Timer-match interrupt pending
@@ -757,11 +738,6 @@
COUNT
Counter register
0x08
-
-
- CAPTURE
- Capture register
- 0x0C
read-only
From 48cf7ca17ba49ed8c3ae70654b0465d32d1978fc Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:41:20 +0200
Subject: [PATCH 06/10] [sw/lib] update GPTMR HAL
---
sw/lib/include/neorv32_gptmr.h | 32 ++++-------
sw/lib/source/neorv32_gptmr.c | 97 +++-------------------------------
2 files changed, 18 insertions(+), 111 deletions(-)
diff --git a/sw/lib/include/neorv32_gptmr.h b/sw/lib/include/neorv32_gptmr.h
index bd8a355c6..2450c60d5 100644
--- a/sw/lib/include/neorv32_gptmr.h
+++ b/sw/lib/include/neorv32_gptmr.h
@@ -27,10 +27,9 @@
/**@{*/
/** GPTMR module prototype */
typedef volatile struct __attribute__((packed,aligned(4))) {
- uint32_t CTRL; /**< offset 0: control register (#NEORV32_GPTMR_CTRL_enum) */
- uint32_t THRES; /**< offset 4: threshold register */
- uint32_t COUNT; /**< offset 8: counter register */
- uint32_t CAPTURE; /**< offset 12: capture register */
+ uint32_t CTRL; /**< offset 0: control register (#NEORV32_GPTMR_CTRL_enum) */
+ uint32_t THRES; /**< offset 4: threshold register */
+ const uint32_t COUNT; /**< offset 8: counter register, read-only */
} neorv32_gptmr_t;
/** GPTMR module hardware access (#neorv32_gptmr_t) */
@@ -42,14 +41,10 @@ enum NEORV32_GPTMR_CTRL_enum {
GPTMR_CTRL_PRSC0 = 1, /**< GPTMR control register(1) (r/w): Clock prescaler select bit 0 */
GPTMR_CTRL_PRSC1 = 2, /**< GPTMR control register(2) (r/w): Clock prescaler select bit 1 */
GPTMR_CTRL_PRSC2 = 3, /**< GPTMR control register(3) (r/w): Clock prescaler select bit 2 */
- GPTMR_CTRL_IRQM = 4, /**< GPTMR control register(4) (r/w): Enable interrupt on timer match */
- GPTMR_CTRL_IRQC = 5, /**< GPTMR control register(5) (r/w): Enable interrupt on capture trigger */
- GPTMR_CTRL_RISE = 6, /**< GPTMR control register(6) (r/w): Capture on rising edge; capture-mode only */
- GPTMR_CTRL_FALL = 7, /**< GPTMR control register(7) (r/w): Capture on falling edge; capture-mode only */
- GPTMR_CTRL_FILTER = 8, /**< GPTMR control register(8) (r/w): Filter capture input; capture-mode only */
+ GPTMR_CTRL_MODE = 4, /**< GPTMR control register(4) (r/w): Operation mode (0=single-shot, 1=continuous) */
- GPTMR_CTRL_TRIGM = 30, /**< GPTMR control register(30) (r/c): Timer-match has fired, cleared by writing 0 */
- GPTMR_CTRL_TRIGC = 31, /**< GPTMR control register(31) (r/c): Capture-trigger has fired, cleared by writing 0 */
+ GPTMR_CTRL_IRQ_CLR = 30, /**< GPTMR control register(30) (-/w): Set to clear timer-match interrupt */
+ GPTMR_CTRL_IRQ_PND = 31, /**< GPTMR control register(31) (r/-): Timer-match interrupt pending */
};
/**@}*/
@@ -58,16 +53,11 @@ enum NEORV32_GPTMR_CTRL_enum {
* @name Prototypes
**************************************************************************/
/**@{*/
-int neorv32_gptmr_available(void);
-void neorv32_gptmr_setup(int prsc, uint32_t threshold, int match_irq);
-void neorv32_gptmr_capture(int rising, int falling, int filter, int capture_irq);
-void neorv32_gptmr_disable(void);
-void neorv32_gptmr_enable(void);
-int neorv32_gptmr_trigger_matched(void);
-int neorv32_gptmr_trigger_captured(void);
-void neorv32_gptmr_restart(void);
-uint32_t neorv32_gptmr_counter_get(void);
-uint32_t neorv32_gptmr_capture_get(void);
+int neorv32_gptmr_available(void);
+void neorv32_gptmr_setup(int prsc, uint32_t threshold, int cont_mode);
+void neorv32_gptmr_disable(void);
+void neorv32_gptmr_enable(void);
+void neorv32_gptmr_irq_ack(void);
/**@}*/
diff --git a/sw/lib/source/neorv32_gptmr.c b/sw/lib/source/neorv32_gptmr.c
index 1d485cbb3..9015f3345 100644
--- a/sw/lib/source/neorv32_gptmr.c
+++ b/sw/lib/source/neorv32_gptmr.c
@@ -40,38 +40,17 @@ int neorv32_gptmr_available(void) {
*
* @param[in] prsc Clock prescaler select (0..7). See #NEORV32_CLOCK_PRSC_enum.
* @param[in] threshold Threshold value, counter will reset to zero when reaching this.
- * @param[in] match_irq Fire interrupt when counter matches threshold value.
+ * @param[in] cont_mode Set to operate timer in continuous mode (instead of single-shot mode).
**************************************************************************/
-void neorv32_gptmr_setup(int prsc, uint32_t threshold, int match_irq) {
+void neorv32_gptmr_setup(int prsc, uint32_t threshold, int cont_mode) {
- NEORV32_GPTMR->CTRL = 0; // reset configuration
+ NEORV32_GPTMR->CTRL = 0; // reset module
NEORV32_GPTMR->THRES = threshold;
- NEORV32_GPTMR->COUNT = 0; // reset counter
uint32_t tmp = 0;
tmp |= (uint32_t)(1 & 0x01) << GPTMR_CTRL_EN;
tmp |= (uint32_t)(prsc & 0x07) << GPTMR_CTRL_PRSC0;
- tmp |= (uint32_t)(match_irq & 0x01) << GPTMR_CTRL_IRQM;
- NEORV32_GPTMR->CTRL = tmp;
-}
-
-
-/**********************************************************************//**
- * Configure timer capture feature.
- * @note This function needs to be called after the general GPTMR setup #neorv32_gptmr_setup.
- *
- * @param[in] rising Capture on rising edge.
- * @param[in] falling Capture on falling edge.
- * @param[in] filter Enable filtering of capture input.
- * @param[in] capture_irq Fire interrupt when on capture trigger.
- **************************************************************************/
-void neorv32_gptmr_capture(int rising, int falling, int filter, int capture_irq) {
-
- uint32_t tmp = NEORV32_GPTMR->CTRL;
- tmp |= (uint32_t)(rising & 0x01) << GPTMR_CTRL_RISE;
- tmp |= (uint32_t)(falling & 0x01) << GPTMR_CTRL_FALL;
- tmp |= (uint32_t)(filter & 0x01) << GPTMR_CTRL_FILTER;
- tmp |= (uint32_t)(capture_irq & 0x01) << GPTMR_CTRL_IRQC;
+ tmp |= (uint32_t)(cont_mode & 0x01) << GPTMR_CTRL_MODE;
NEORV32_GPTMR->CTRL = tmp;
}
@@ -95,71 +74,9 @@ void neorv32_gptmr_enable(void) {
/**********************************************************************//**
- * Check if timer match has triggered. Clear trigger flag in that case.
- *
- * @return 1 if match trigger has fired, 0 if not.
- **************************************************************************/
-int neorv32_gptmr_trigger_matched(void) {
-
- uint32_t tmp = NEORV32_GPTMR->CTRL;
-
- if (tmp & (1 << GPTMR_CTRL_TRIGM)) {
- tmp &= ~((uint32_t)(1 << GPTMR_CTRL_TRIGM));
- NEORV32_GPTMR->CTRL = tmp;
- return 1;
- }
- else {
- return 0;
- }
-}
-
-
-/**********************************************************************//**
- * Check if capture input has triggered. Clear trigger flag in that case.
- *
- * @return 1 if capture trigger has fired, 0 if not.
- **************************************************************************/
-int neorv32_gptmr_trigger_captured(void) {
-
- uint32_t tmp = NEORV32_GPTMR->CTRL;
-
- if (tmp & (1 << GPTMR_CTRL_TRIGC)) {
- tmp &= ~((uint32_t)(1 << GPTMR_CTRL_TRIGC));
- NEORV32_GPTMR->CTRL = tmp;
- return 1;
- }
- else {
- return 0;
- }
-}
-
-
-/**********************************************************************//**
- * Reset general purpose timer's counter register (timer-mode only).
- **************************************************************************/
-void neorv32_gptmr_restart(void) {
-
- NEORV32_GPTMR->COUNT = 0;
-}
-
-
-/**********************************************************************//**
- * Get current counter value.
- *
- * @return Current counter value.
- **************************************************************************/
-uint32_t neorv32_gptmr_counter_get(void) {
-
- return NEORV32_GPTMR->COUNT;
-}
-
-
-/**********************************************************************//**
- * Get latest capture value.
- *
- * @return Capture timer value.
+ * Clear pending timer interrupt.
**************************************************************************/
-uint32_t neorv32_gptmr_capture_get(void) {
+void neorv32_gptmr_irq_ack(void) {
- return NEORV32_GPTMR->CAPTURE;
+ NEORV32_GPTMR->CTRL |= ((uint32_t)(1 << GPTMR_CTRL_IRQ_CLR));
}
From b09324331d62ad52bbf52d8c528ec413abc541fb Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:41:40 +0200
Subject: [PATCH 07/10] [sw/example] update GPTMR examples
---
sw/example/demo_dma/main.c | 5 +++--
sw/example/demo_gptmr/main.c | 6 +++---
sw/example/processor_check/main.c | 7 +++----
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/sw/example/demo_dma/main.c b/sw/example/demo_dma/main.c
index ad59b6f07..2e14bc7d2 100644
--- a/sw/example/demo_dma/main.c
+++ b/sw/example/demo_dma/main.c
@@ -238,7 +238,7 @@ int main() {
// configure GPTMR
neorv32_gptmr_setup(CLK_PRSC_2, // GPTM clock = 1/2 main clock
4096, // counter threshold for triggering IRQ
- 1); // enable timer-match interrupt
+ 0); // single-shot mode
// configure transfer type
cmd = DMA_CMD_B2B | // read source in byte quantities, write destination in byte quantities
@@ -270,6 +270,7 @@ int main() {
neorv32_uart0_printf("Transfer succeeded!\n");
}
+ neorv32_gptmr_disable(); // disable GPTMR
show_arrays();
}
else {
@@ -338,7 +339,7 @@ void show_arrays(void) {
**************************************************************************/
void dma_firq_handler(void) {
- neorv32_gptmr_trigger_matched(); // clear GPTMR timer-match interrupt
+ neorv32_gptmr_irq_ack(); // clear GPTMR timer-match interrupt
NEORV32_DMA->CTRL &= ~(1<>\n");
diff --git a/sw/example/demo_gptmr/main.c b/sw/example/demo_gptmr/main.c
index c1c5d0d32..69332f147 100644
--- a/sw/example/demo_gptmr/main.c
+++ b/sw/example/demo_gptmr/main.c
@@ -34,7 +34,7 @@ void gptmr_firq_handler(void);
*
* @note This program requires the GPTMR unit to be synthesized (and UART0 and GPIO).
*
- * @return Should not return;
+ * @return Should not return.
**************************************************************************/
int main() {
@@ -63,7 +63,7 @@ int main() {
// install GPTMR interrupt handler
neorv32_rte_handler_install(GPTMR_RTE_ID, gptmr_firq_handler);
- // configure timer for 0.5Hz ticks with clock divisor = 8 and enable timer-match interrupt
+ // configure timer for 0.5Hz ticks with clock divisor = 8 and set to run in continuous mode
neorv32_gptmr_setup(CLK_PRSC_8, NEORV32_SYSINFO->CLK / (8 * 2), 1);
// enable interrupt
@@ -87,7 +87,7 @@ int main() {
**************************************************************************/
void gptmr_firq_handler(void) {
- neorv32_gptmr_trigger_matched(); // clear timer-match interrupt
+ neorv32_gptmr_irq_ack(); // clear pending timer-internal interrupt
neorv32_uart0_putc('.'); // send tick symbol via UART0
neorv32_gpio_pin_toggle(0); // toggle output port bit 0
diff --git a/sw/example/processor_check/main.c b/sw/example/processor_check/main.c
index 829840cef..da139526d 100644
--- a/sw/example/processor_check/main.c
+++ b/sw/example/processor_check/main.c
@@ -1494,8 +1494,8 @@ int main() {
// enable GPTMR FIRQ
neorv32_cpu_csr_write(CSR_MIE, 1 << GPTMR_FIRQ_ENABLE);
- // match-interrupt after CLK_PRSC_2*THRESHOLD = 2*2 = 8 clock cycles
- neorv32_gptmr_setup(CLK_PRSC_2, 2, 1);
+ // match-interrupt after CLK_PRSC_2*THRESHOLD = 2*2 = 8 clock cycles, single-shot mode
+ neorv32_gptmr_setup(CLK_PRSC_2, 2, 0);
// wait for interrupt
asm volatile ("nop");
@@ -1504,8 +1504,7 @@ int main() {
neorv32_cpu_csr_write(CSR_MIE, 0);
if ((neorv32_cpu_csr_read(CSR_MCAUSE) == GPTMR_TRAP_CODE) && // correct interrupt?
- (neorv32_gptmr_trigger_matched() == 1) && // IRQ caused by timer match?
- (neorv32_gptmr_trigger_captured() == 0)) { // no capture trigger?
+ (NEORV32_GPTMR->CTRL & (1 << GPTMR_CTRL_IRQ_PND))) { // timer interrupt pending?
test_ok();
}
else {
From 662f8a831f6cc855a9b9c8bce52824f9107df438 Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:46:10 +0200
Subject: [PATCH 08/10] [readme] cleanup
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 9ecfea861..477171336 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,6 @@ For example, the CPU ensures _all_ memory accesses are properly acknowledged and
instructions are always detected as such. Whenever an unexpected state occurs the application software is
informed via _precise_ and resumable hardware exceptions.
-* :books: For detailed information see the [NEORV32 online documentation](https://stnolting.github.io/neorv32/).
* :recycle: Looking for an **all-Verilog** version? Have a look at [neorv32-verilog](https://github.com/stnolting/neorv32-verilog).
* :heavy_check_mark: [Continuous integration](#project-status) to check for regressions (including RISC-V ISA compatibility check using **RISCOF**).
* :open_file_folder: [Exemplary setups](https://github.com/stnolting/neorv32-setups) and
@@ -46,6 +45,7 @@ targeting various FPGA boards and toolchains to get started.
* :label: The project's change log is available in [CHANGELOG.md](https://github.com/stnolting/neorv32/blob/main/CHANGELOG.md).
* :rocket: Check out the [quick links below](#5-getting-started) and the
[*User Guide*](https://stnolting.github.io/neorv32/ug/) to get started setting up _your_ NEORV32 processor!
+* :books: For detailed information see the [NEORV32 online documentation](https://stnolting.github.io/neorv32/).
* :interrobang: Want to know more? Check out the [project's rationale](https://stnolting.github.io/neorv32/#_rationale).
Feel free to open a new [issue](https://github.com/stnolting/neorv32/issues) or start a new
@@ -140,7 +140,7 @@ allows booting application code via UART or from external SPI flash
**Timers and Counters**
* 64-bit machine timer ([MTIME](https://stnolting.github.io/neorv32/#_machine_system_timer_mtime)), RISC-V spec. compatible
-* 32-bit general purpose timer ([GPTMR](https://stnolting.github.io/neorv32/#_general_purpose_timer_gptmr)) with capture input
+* 32-bit general purpose timer ([GPTMR](https://stnolting.github.io/neorv32/#_general_purpose_timer_gptmr))
* watchdog timer ([WDT](https://stnolting.github.io/neorv32/#_watchdog_timer_wdt))
**Input / Output**
From 31d1933d69fbf763fafa3a94797b8b2c7460e1d5 Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:46:32 +0200
Subject: [PATCH 09/10] [docs] update GPTMR section
---
docs/datasheet/soc_gptmr.adoc | 72 ++++++++++++-----------------------
1 file changed, 25 insertions(+), 47 deletions(-)
diff --git a/docs/datasheet/soc_gptmr.adoc b/docs/datasheet/soc_gptmr.adoc
index 48aead7dc..4663c3cc4 100644
--- a/docs/datasheet/soc_gptmr.adoc
+++ b/docs/datasheet/soc_gptmr.adoc
@@ -8,7 +8,7 @@
| Hardware source files: | neorv32_gptmr.vhd |
| Software driver files: | neorv32_gptmr.c |
| | neorv32_gptmr.h |
-| Top entity ports: | `gptmr_trig_i` | timer capture input
+| Top entity ports: | none |
| Configuration generics: | `IO_GPTMR_EN` | implement general purpose timer when `true`
| CPU interrupts: | fast IRQ channel 12 | timer interrupt (see <<_processor_interrupts>>)
|=======================
@@ -18,14 +18,13 @@
The general purpose timer module implements a simple yet universal 32-bit timer. It is implemented if the processor's
`IO_GPTMR_EN` top generic is set `true`. The timer provides a pre-scaled counter register that can trigger an interrupt
-when reaching a programmable threshold value. Additionally, a timer-capture feature is implemented that copies the current
-counter value to a dedicated register if a programmable edge occurs at the `gptmr_trig_i` input signal.
+when reaching a programmable threshold value.l.
-Four interface registers are available: a control register (`CTRL`), a 32-bit counter register (`COUNT`), a 32-bit
-threshold register (`THRES`) and a 32-bit read-only capture register (`CAPTURE`). The timer is globally enabled by setting the
-`GPTMR_CTRL_EN` bit in the device's control register `CTRL`. When the timer is enable the `COUNT` register will start
-incrementing at a programmable rate, which scales the main processor clock. The pre-scaler value is configured via the
-three `GPTMR_CTRL_PRSCx` control register bits:
+The GPTMR provides three interface registers : a control register (`CTRL`), a 32-bit counter register (`COUNT`) and a
+32-bit threshold register (`THRES`). The timer is globally enabled by setting the `GPTMR_CTRL_EN` bit in the module's
+control register. When the timer is enable the `COUNT` register will start incrementing from zero at a programmable
+rate that scales the main processor clock. this pre-scaler is configured via the three `GPTMR_CTRL_PRSCx`
+control register bits:
.GPTMR prescaler configuration
[cols="<4,^1,^1,^1,^1,^1,^1,^1,^1"]
@@ -35,40 +34,24 @@ three `GPTMR_CTRL_PRSCx` control register bits:
| Resulting `clock_prescaler` | 2 | 4 | 8 | 64 | 128 | 1024 | 2048 | 4096
|=======================
-[NOTE]
-Disabling the timer will not clear the `COUNT` register. However, it can be manually reset at any time by
-writing zero to it.
-
-
-**Interval Timer**
-
-Whenever the counter register `COUNT` reaches the programmable threshold value `THRES` the counter register
-is reset to zero and the _timer-match_ flag `GPTMR_CTRL_TRIGM` gets set. This flag has to be cleared manually
-by writing zero to it. Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQM` bit is set.
+Whenever the counter register `COUNT` equals the programmable threshold value `THRES` the module's interrupt
+signal becomes pending (indicated by `GPTMR_CTRL_IRQ_PND` being set). Note that a pending interrupt has to be
+cleared manually by writing a `1` to `GPTMR_CTRL_IRQ_CLR`.
+The control register's `GPTMR_CTRL_MODE` bit defines what will happen when `COUNT == THRES`.
-**Timer Capture**
+* `GPTMR_CTRL_MODE = 0`: **single-shot mode** - the `COUNT` register will stop incrementing
+* `GPTMR_CTRL_MODE = 1`: **continuous mode** - the `COUNT` register is automatically reset and restarts incrementing from zero
-In addition to the the internal timer, the GPTMR provides a timer-capture feature. Whenever an edge is detected
-at the `gptmr_trig_i` input signal the current `COUNT` value is copied to the read-only `CAPTURE` register and the
-_capture-trigger_ flag `GPTMR_CTRL_TRIGC` gets set. This flag has to be cleared manually by writing zero to it.
-Optionally, an interrupt can be triggered if the `GPTMR_CTRL_IRQC` bit is set.
-
-The triggering edge can be a rising-edge (if `GPTMR_CTRL_RISE` is set), a falling-edge (if `GPTMR_CTRL_FALL` is
-set) or even both. By default, the `gptmr_trig_i` is sampled two times at the processor clock for checking for
-edges. This simple edge detection is sufficient for trigger signals that are generated by (on-chip) digital logic.
-
-For sampling chip-external signals an optional filtering mode is available that can be enabled by the
-`GPTMR_CTRL_FILTER` bit. If this bit is set, the `gptmr_trig_i` is sampled at a reduced clock speed (1/4 of the
-processor clock) and the signal has to be stable for at lest 4 sample clock in order to be considered high or low.
-This stabilized signal is then fed to the edge detection logic.
+.Resetting the Counter
+[NOTE]
+Disabling the GPTMR will also clear the `COUNT` register.
**Interrupt**
-The GPTRM provides a single interrupt line that can be trigger by a timer-match event and/or by a timer-compare
-event. Once triggered, the interrupt will stay active until explicitly cleared by writing zero to the according
-interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
+The GPTRM provides a single interrupt line is triggered whenever `COUNT` equals `THRES`. Once triggered, the interrupt will
+stay pending until explicitly cleared by writing a 1 to `GPTMR_CTRL_IRQ_CLR`.
**Register Map**
@@ -78,17 +61,12 @@ interrupt flag (`GPTMR_CTRL_TRIGM` or `GPTMR_CTRL_TRIGC`).
[options="header",grid="all"]
|=======================
| Address | Name [C] | Bit(s), Name [C] | R/W | Function
-.10+<| `0xfffff100` .10+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag
- <|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
- <|`4` `GPTMR_CTRL_IRQM` ^| r/w <| Enable interrupt on timer-match
- <|`5` `GPTMR_CTRL_IRQC` ^| r/w <| Enable interrupt on capture-trigger
- <|`6` `GPTMR_CTRL_RISE` ^| r/w <| Capture on rising edge
- <|`7` `GPTMR_CTRL_FALL` ^| r/w <| Capture on falling edge
- <|`8` `GPTMR_CTRL_FILTER` ^| r/w <| Filter capture input
- <|`29:9` - ^| r/- <| _reserved_, read as zero
- <|`30` `GPTMR_CTRL_TRIGM` ^| r/c <| Timer-match has fired, cleared by writing 0
- <|`31` `GPTMR_CTRL_TRIGC` ^| r/c <| Capture-trigger has fired, cleared by writing 0
+.6+<| `0xfffff100` .6+<| `CTRL` <|`0` `GPTMR_CTRL_EN` ^| r/w <| Timer enable flag
+ <|`3:1` `GPTMR_CTRL_PRSC2 : GPTMR_CTRL_PRSC0` ^| r/w <| 3-bit clock prescaler select
+ <|`4` `GPTMR_CTRL_MODE` ^| r/w <| Operation mode (0=single-shot, 1=continuous)
+ <|`29:5` - ^| r/- <| _reserved_, read as zero
+ <|`30` `GPTMR_CTRL_IRQ_CLR` ^| -/w <| Write `1` to clear timer-match interrupt; auto-clears
+ <|`31` `GPTMR_CTRL_IRQ_PND` ^| r/- <| Timer-match interrupt pending
| `0xfffff104` | `THRES` |`31:0` | r/w | Threshold value register
-| `0xfffff108` | `COUNT` |`31:0` | r/w | Counter register
-| `0xfffff10C` | `CAPTURE` |`31:0` | r/- | Capture register
+| `0xfffff108` | `COUNT` |`31:0` | r/- | Counter register
|=======================
From c1f14444e27c48ec2219b1eb6dc9952dffaefcee Mon Sep 17 00:00:00 2001
From: stnolting <22944758+stnolting@users.noreply.github.com>
Date: Thu, 4 Jul 2024 12:54:51 +0200
Subject: [PATCH 10/10] [changelog] add v1.10.0.10
---
CHANGELOG.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 11fa53dcf..6da21f9d4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
+| 04.07.2024 | 1.10.0.10 | :warning: rework GPTMRM and remove capture mode | [#939](https://github.com/stnolting/neorv32/pull/939) |
| 03.07.2024 | 1.10.0.9 | :warning: remove `AMO_RVS_GRANULARITY` generic, reservation set granularity is now fixed to 4 bytes | [#938](https://github.com/stnolting/neorv32/pull/938) |
| 03.07.2024 | 1.10.0.8 | :test_tube: add XBUS to AHB3-lite bridge | [#937](https://github.com/stnolting/neorv32/pull/937) |
| 02.07.2024 | 1.10.0.7 | minor rtl and software edits and cleanups | [#936](https://github.com/stnolting/neorv32/pull/936) |