> For the complete documentation index, see [llms.txt](https://mujoseph.gitbook.io/mujoseph-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://mujoseph.gitbook.io/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim.md).

# High-Resolution Timer (HRTIM)

## Special Thanks

Many thanks to **wieser** from <https://highvoltageforum.net>, whose [firmware ](https://github.com/dertrennawieser/stm32_resonance_driver)served as the foundation for the *DRSSTC\_Driver*, specifically the HRTIM peripheral configuration.

Forum topic where he discusses his project can be found [here](https://highvoltageforum.net/index.php?topic=3375.0).

## General Overview

In the context of the *Emma Mk1*, the HRTIM peripheral uses the [External Event block](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/external-event-eev-configuration.md) to interface with external input signals (i.e., [interrupter](/mujoseph-docs/emma-mk1-drsstc/hardware-overview/electrical-design/pcb-design/motherboard.md#interrupter-signal-source-selection), [ZCD](/mujoseph-docs/emma-mk1-drsstc/hardware-overview/electrical-design/pcb-design/current-sense.md#zero-crossing-detection-zcd), and [OCD ](/mujoseph-docs/emma-mk1-drsstc/hardware-overview/electrical-design/pcb-design/current-sense.md#over-current-detection-ocd)signals) and six internal timers to synthesize the four H-bridge output drive signals ([TB1/TB2](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timb-half-bridge-1-driver.md#timb-outputs-tb1-and-tb2-roles) and [TC1/TC2](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timc-half-bridge-2-driver.md#timc-outputs-tc1-and-tc2-roles)).&#x20;

The diagram below illustrates a high-level overview of the HRTIM peripheral within the *Emma Mk1*.

<div data-with-frame="true"><figure><img src="https://2297250131-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FzNHSl7dsTOS0XjlMXnIe%2Fuploads%2FJ8jnnKBLlyxus1Aim6tg%2Femma_mk1_hrtim_overview.svg?alt=media&amp;token=49c5cb39-3763-437f-bd0b-3ef987b21872" alt=""><figcaption><p>HRTIM overview with the <em>Emma Mk1</em></p></figcaption></figure></div>

Refer to the respective sections for more information:

{% content-ref url="/pages/Wt2tfjmOCk3ymz4lM31d" %}
[External Event (EEV) Configuration](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/external-event-eev-configuration.md)
{% endcontent-ref %}

{% content-ref url="/pages/70aNArlmTG57h6Dj7rmw" %}
[TIMA: Resonant-Cycle Timing Reference](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/tima-resonant-cycle-timing-reference.md)
{% endcontent-ref %}

{% content-ref url="/pages/U5pRYFGKV0gVQfO95JtG" %}
[TIMB: Half-Bridge 1 Driver](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timb-half-bridge-1-driver.md)
{% endcontent-ref %}

{% content-ref url="/pages/79HXcxPANQnOTwTJdz1E" %}
[TIMC: Half-Bridge 2 Driver](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timc-half-bridge-2-driver.md)
{% endcontent-ref %}

{% content-ref url="/pages/9p8gYA2Hho9Axe44wZPE" %}
[TIMD: Pulse-Skipping Timer](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timd-pulse-skipping-timer.md)
{% endcontent-ref %}

{% content-ref url="/pages/1fLtgVI53yOt5ZvczNp4" %}
[TIME: Resonant Frequency Capture](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/time-resonant-frequency-capture.md)
{% endcontent-ref %}

{% content-ref url="/pages/g3MG4rr9Yeupx45vx5Sm" %}
[TIMF: Feedback Timeout Watchdog](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timf-feedback-timeout-watchdog.md)
{% endcontent-ref %}

## Global Configuration

What follows are configuration parameters that are shared across the internal HRTIM timers:

* TIMA through TIMF all have a tick frequency, $$f\_{tick(HRTIM)}$$, of 170 MHz
* TIMA through TIMF are all configured as single-shot, re-triggerable counters
* All timers, excluding TIMD, have preload enabled
  * Timers with preload enabled have their respective active registers (e.g., general configuration registers and compare registers) updated from their shadow register counterparts when that timer's update event trigger occurs

## Timer Specific Configurations

All HRTIM internal timer configurations are located within `mujoe_hrtim_timx_settings.c` .

The `hrtim_timx_cfg_tbl` array contains a `hrtim_timx_cfg_t` structure for each of the HRTIM's internal timers:

```c
// HRTIM Configuration table
const hrtim_timx_cfg_tbl_entry_t  hrtim_timx_cfg_tbl[HRTIM_NUM_TIMERS] =
{
	{ .timer = LL_HRTIM_TIMER_A, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timA_cfg},
	{ .timer = LL_HRTIM_TIMER_B, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timB_cfg},
	{ .timer = LL_HRTIM_TIMER_C, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timC_cfg},
	{ .timer = LL_HRTIM_TIMER_D, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timD_cfg},
	{ .timer = LL_HRTIM_TIMER_E, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timE_cfg},
	{ .timer = LL_HRTIM_TIMER_F, .pCfg = (hrtim_timx_cfg_t*)&hrtim_timF_cfg},

};// hrtim_timx_cfg_tbl

```

The `hrtim_timx_cfg_t` structure contains elements for configuring that specific timer's parameters, such as reset source(s), output configuration, etc. Here is the configuration structure for [TIMB](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/timb-half-bridge-1-driver.md):

{% code lineNumbers="true" expandable="true" %}

```c
// HRTIM TIMER B Config
const hrtim_timx_cfg_t hrtim_timB_cfg =
{
	.preloadEnabled 			= true,
	// f_tim = f_hrtim/1 = 170e6/1 = 170 MHz
	.pscRatio 					= LL_HRTIM_PRESCALERRATIO_DIV1,
	.timPeriod					= HRTIM_TIM_MAX_PERIOD,
	// Update triggers:
	// On timer reset/roll-over
	.updateTrig					= LL_HRTIM_UPDATETRIG_RESET,
	// Reset triggers
	// EEV2: TIM2 TRGO
	// EEV6: COMP1 Output, digitally filtered (ZCD CT1 Tap)
	.resetTrig 					= LL_HRTIM_RESETTRIG_EEV_2 | LL_HRTIM_RESETTRIG_EEV_6,
#if TIMB_TIMC_CMP2_DMA_EN==1
	// Triggered Half mode DISABLED
	.triggerHalfModeEn			= false,
#else
	// Triggered Half mode ENABLED
	.triggerHalfModeEn			= true,
#endif // #if TIMB_TIMC_CMP2_DMA_EN==1

#ifdef HRTIM_TIMB_DLYPRT_DISABLE
	// Delayed Protection
	// Disabled:
	.dlyPrt = { .enabled = false, .mode = LL_HRTIM_DLYPRT_DELAYBOTH_EEV7 },
#else
	// Delayed Protection
	// Enabled: Output 1 and output 2 delayed idle on external event 7 (COMP4 out)
	.dlyPrt = { .enabled = true, .mode = LL_HRTIM_DLYPRT_DELAYBOTH_EEV7 },
#endif // #ifdef HRTIM_TIMB_DLYPRT_DISABLE
	.countingMode 				= LL_HRTIM_COUNTING_MODE_UP,
	.counterMode				= LL_HRTIM_MODE_RETRIGGERABLE,
	.capCfg =
	{
			// Capture 1 config
			// Capture triggers:
		    // EEV2: TIM2 TRGO
			// EEV6: COMP1 Output, digitally filtered (ZCD CT1 Tap)
			{ .capTrig = LL_HRTIM_CAPTURETRIG_EEV_2 | LL_HRTIM_CAPTURETRIG_EEV_6 },
			// Capture 2 cfg
			// Capture trigger(s):
			// EEV8: COMP3 (OCD, rising)
			// NOTE: Captured value is not used, the Capture 2 event is simply
			// used to trigger a DMA2 request on CH2
			{ .capTrig = LL_HRTIM_CAPTURETRIG_EEV_8  },
	},

	.cmp1EqualToMode = true,
	.cmp2Mode = LL_HRTIM_COMPAREMODE_REGULAR,
	.cmp3EqualToMode = true,
	.cmp4Mode = LL_HRTIM_COMPAREMODE_REGULAR,

	.outCfg =
	{
			// TB1 - Half Bridge 1 High Side
			{
				.enabled = true,
				.positivePolarity = true,
				.Output  = LL_HRTIM_OUTPUT_TB1,
				.setSrcs = LL_HRTIM_OUTPUTSET_TIMCMP2,
				.rstSrcs = LL_HRTIM_OUTPUTRESET_EEV_2 | LL_HRTIM_OUTPUTRESET_EEV_6,
			},
			// TB2 - Half Bridge 1 Low Side
			{
				.enabled = true,
				.positivePolarity = true,
				.Output  = LL_HRTIM_OUTPUT_TB2,
				.setSrcs = LL_HRTIM_OUTPUTSET_EEV_2 | LL_HRTIM_OUTPUTSET_EEV_6,
				.rstSrcs = LL_HRTIM_OUTPUTRESET_TIMCMP2,
			},
	},
	.pEEVBlankFltrs				= (hrtim_timx_eev_blank_t *)timB_eev_blankFltrs,
	.numBlankFltrs			 	= sizeof(timB_eev_blankFltrs)/sizeof(hrtim_timx_eev_blank_t),
}; // hrtim_timB_cfg
```

{% endcode %}

The `hrtim_timx_eev_blank_t` structure contains blanking settings for filtering the [EEV bus](/mujoseph-docs/emma-mk1-drsstc/drsstc_driver-firmware-overview/high-resolution-timer-hrtim/external-event-eev-configuration.md) for that specific timer:

{% code lineNumbers="true" %}

```c
// HRTIM TIMB EEV Blanking Filter(s)
static const hrtim_timx_eev_blank_t timB_eev_blankFltrs[] =
{
	// EEV1 - COMP2 (CT1) Rising Edge: Blanked from reset to cmp2 (half-triggered mode: 1/f_resonant*0.5).
	// This is blanking for quarter period (1/f_resonant*0.25) after TIM2 TRGO
	{.event = LL_HRTIM_EVENT_1, .filter = LL_HRTIM_EEFLTR_BLANKINGCMP2, .latchEn = false},
	// EEV2 - TIM2 TRGO Rising Edge: Blanked from reset to cmp1
	{.event = LL_HRTIM_EVENT_2, .filter = LL_HRTIM_EEFLTR_BLANKINGCMP1, .latchEn = false},
	// EEV4 - COMP1 (ZCD CT1) Rising Edge: Blanked from reset to cmp2 (half-triggered mode: 1/f_resonant*0.5)
	// This is blanking for quarter period (1/f_resonant*0.25) after TIM2 TRGO
	{.event = LL_HRTIM_EVENT_4, .filter = LL_HRTIM_EEFLTR_BLANKINGCMP2, .latchEn = false},
	// EEV6 - COMP1 (ZCD CT1, filtered) Rising Edge: Blanked from reset to cmp2 (half-triggered mode: 1/f_resonant*0.5)
	// This is blanking for quarter period (1/f_resonant*0.25) after TIM2 TRGO
	{.event = LL_HRTIM_EVENT_6, .filter = LL_HRTIM_EEFLTR_BLANKINGCMP2, .latchEn = false},
	// EEV8 - COMP3 (OCD) Rising Edge: Blanking from another timing unit (TIMFLT3 src, e.g. TIM A Ch2 Output, TA2)
	// This is to avoid DMA overrun from multiple OCD events (while still allowing TIMD resets)
	{.event = LL_HRTIM_EVENT_8, .filter = LL_HRTIM_EEFLTR_BLANKING_TIMBEEF3_TIMAOUT2, .latchEn = false},
};
```

{% endcode %}
