ATIM
ATIM (Advanced Timer) is based on a 32-bit counter, capable of timing, measuring input signal pulse length (input capture) or generating output waveforms (output compare and PWM). It supports 3 channels of complementary PWM output with dead-time protection, supports multi-channel PWM phase switching, and has 2 brake inputs for quickly switching output to safe state. The counter itself can count up, down, or up/down, with counting clock from system pclk or external input signal, and can be prescaled by 1~65536 times. ATIM has 6 channels that can be independently configured as input capture or output mode. Counting, input capture and output compare results can be notified to the system through interrupts or DMA. ATIM contains master-slave mode interface for multi-level cascading, implementing multi-level counting or synchronous triggering functions.
ATIM Main Features:
32-bit up, down, up/down auto-reload counter
16-bit programmable (can be modified in real-time) prescaler, counter clock frequency division factor can be any value between 1~65536
16-bit configurable repetition counter
Supports One Pulse Mode (OPM), automatically stops counter when repetition counting is complete
6 independent channels
Channels 1~3 can be configured as input or output mode, each channel can output two complementary PWM signals with dead-time protection
Channel 4 can be configured as input or output mode, can output single PWM
Channels 5~6 can be configured as output compare mode
Input mode
Rising/falling edge capture
PWM pulse width and period capture (requires two channels)
Selectable from 4 input ports or 1 external trigger port, supports anti-jitter filtering and pre-frequency division
Output mode
Force output high/low level
Output high/low/toggle level when count reaches compare value
PWM output with configurable pulse width and period
Multi-channel PWM combined output, can generate multiple PWM signals with mutual relationships
Single pulse/retriggerable single pulse mode output
Master-slave mode
Supports multiple GPT interconnection, can generate control signals as master device while being controlled by external input or other master devices as slave device
Control modes include reset, trigger, gate, etc.
Supports synchronous start, reset of multiple GPTs
Encoder mode input, controls counter up/down counting
Supports Hall sensor circuit for positioning
2 brake inputs, supports anti-jitter filtering, can quickly put output in safe state. Brake signal sources include:
CPU exception
Comparator
External input
Software trigger
Generate interrupt/DMA when following events occur:
Update: counter up overflow/down underflow, counter initialization (by software or internal/external trigger)
Trigger event (counter start, stop, initialization or internal/external trigger counting)
Input capture
Output compare
Brake
Commutation
SF32LB58X HCPU has two ATIMs: ATIM1 and ATIM2. SF32LB56X HCPU has one ATIM: ATIM1.
For detailed ATIM interface, please refer to TIM_EX
Using ATIM
The following ATIM usage is the same as GPT basic function usage, except setting Instance to ATIMx during initialization. For specific usage, please refer to GPT
Using ATIM HAL Interface for Timer Function
{
#define FREQENCY (10000)
#define TIME_MS (3500)
static GPT_HandleTypeDef TIM_Handle = {0};
TIM_Handle.Instance = (GPT_TypeDef *)hwp_atim1;
TIM_Handle.Init.Prescaler = HAL_RCC_GetPCLKFreq(CORE_ID_HCPU, 1) / FREQENCY; /*Prescaler is 16 bits, please select correct frequency*/
TIM_Handle.core = CORE_ID_HCPU;
TIM_Handle.Init.CounterMode = GPT_COUNTERMODE_UP; /*GPTIM could support counter up/down, BTIM only support count up*/
TIM_Handle.Init.RepetitionCounter = 0;
TIM_Handle.Init.Period = TIME_MS * FREQENCY / 1000;
if (HAL_GPT_Base_Init(&TIM_Handle) == HAL_OK) /*init timer*/
{
HAL_NVIC_SetPriority(ATIM1_IRQn, 3, 0); /* set the TIMx priority */
HAL_NVIC_EnableIRQ(ATIM1_IRQn); /* enable the TIMx global Interrupt */
__HAL_GPT_CLEAR_FLAG(&TIM_Handle, GPT_FLAG_UPDATE); /* clear update flag */
__HAL_GPT_URS_ENABLE(&TIM_Handle); /* enable update request source */
}
else
{
LOG_E("Timer init error");
return;
}
if (HAL_GPT_Base_Start_IT(&TIM_Handle) != HAL_OK) /* start timer */
{
LOG_E("Timer start error");
return;
}
/*atimer interrupt handler*/
void ATIM1_IRQHandler(void)
{
ENTER_INTERRUPT();
HAL_GPT_IRQHandler(&TIM_Handle);
LEAVE_INTERRUPT();
}
}
Using ATIM HAL Interface for Complementary PWM Output
ATIM PWM init code:
{
GPT_HandleTypeDef gpt_Handle = {0};
GPT_OC_InitTypeDef oc_config = {0};
GPT_ClockConfigTypeDef clock_config = {0};
gpt_Handle.Instance = (GPT_TypeDef *)hwp_atim1;
gpt_Handle.core = CORE_ID_HCPU;
gpt_Handle.Channel = GPT_CHANNEL_1;
gpt_Handle.Init.CounterMode = GPT_COUNTERMODE_UP;
/*atimer base init*/
if (HAL_GPT_Base_Init(&gpt_Handle) != HAL_OK)
{
LOG_E("atimer base init failed");
return;
}
/*atimer clock source select*/
clock_config.ClockSource = GPT_CLOCKSOURCE_INTERNAL;
if (HAL_GPT_ConfigClockSource(&gpt_Handle, &clock_config) != HAL_OK)
{
LOG_E("atimer clock init failed");
return;
}
/*atimer pwm init*/
if (HAL_GPT_PWM_Init(&gpt_Handle) != HAL_OK)
{
LOG_E("atimer pwm init failed");
return;
}
/*atimer pwm channel config*/
oc_config.OCMode = GPT_OCMODE_PWM1;
oc_config.Pulse = 0;
oc_config.OCPolarity = GPT_OCPOLARITY_HIGH;
oc_config.OCFastMode = GPT_OCFAST_DISABLE;
if (HAL_GPT_PWM_ConfigChannel(&gpt_Handle, &oc_config, GPT_CHANNEL_1) != HAL_OK)
{
LOG_E("atimer pwm channel config failed");
return;
}
}
ATIM PWM parameter set:
{
#define PWM_PERIOD (500000000) //ns
#define PWM_PULSE (250000000) //ns
#define MAX_PERIOD_ATM (0xFFFFFFFF) //32bit
rt_uint32_t period, pulse;
rt_uint32_t GPT_clock, psc;
GPT_clock = HAL_RCC_GetPCLKFreq(CORE_ID_HCPU, 1);
/* Convert nanosecond to frequency and duty cycle. 1s = 1 * 1000 * 1000 * 1000 ns */
GPT_clock /= 1000000UL;
period = (unsigned long long)PWM_PERIOD * GPT_clock / 1000ULL;
psc = period / MAX_PERIOD_ATM + 1;
period = period / psc;
/*set atimer prescaler*/
__HAL_GPT_SET_PRESCALER(&gpt_Handle, psc - 1);
/*set atimer auto reload*/
__HAL_GPT_SET_AUTORELOAD(&gpt_Handle, period - 1);
/*set atimer pulse*/
pulse = (unsigned long long)PWM_PULSE * GPT_clock / psc / 1000ULL;
__HAL_GPT_SET_COMPARE(htim, GPT_CHANNEL_1, pulse - 1);
HAL_GPT_GenerateEvent(htim, GPT_EVENTSOURCE_UPDATE);
}
ATIM PWM brake dead time set:
{
TIMEx_BreakDeadTimeConfigTypeDef bdt = {0};
bdt.AutomaticOutput = 0;
bdt.BreakFilter = 0;
bdt.BreakPolarity = 0;
bdt.BreakState = 0;
bdt.Break2Filter = 0;
bdt.Break2Polarity = 0;
bdt.Break2State = 0;
bdt.DeadTime = 200; /*0~1023*/
bdt.OffStateIDLEMode = 0;
bdt.OffStateRunMode = 0;
bdt.DeadTimePsc = 0;
HAL_TIMEx_ConfigBreakDeadTime(htim, &bdt);
}