Loading...
 

SW4STM32 and SW4Linux fully supports the STM32MP1 asymmetric multicore Cortex/A7+M4 MPUs

   With System Workbench for Linux, Embedded Linux on the STM32MP1 family of MPUs from ST was never as simple to build and maintain, even for newcomers in the Linux world. And, if you install System Workbench for Linux in System Workbench for STM32 you can seamlessly develop and debug asymmetric applications running partly on Linux, partly on the Cortex-M4.
You can get more information from the ac6-tools website and download (registration required) various documents highlighting:

System Workbench for STM32


Input Capture does not work

Hello,

I have a problem with the Input Capturing on Timer 8.I use these advanced Timer becuase if the timer has count up, I set the “overflow” variable to one and the rotary frequency is defined as 0,otherwise if a rising edge occures I want the TIM->CCR to be written via input capture and calculate it by my algorithm. My rotary encoder produces a nearly perfect edge form 0V to 5V. I tried neary everything. I switched the input channel an so on. Do you maybe see any mistakes in my Timer and Input declaration below? I would be very thankful for any advice. Do I have to program the transfer of TIM8->CNT to TIM-CCRx in my Interrupt or has anything else to be done?


void start_timer8(uint16_t period, uint16_t prescaler/*, uint16_t ccr1, uint16_t ccr2, uint16_t ccr3, uint16_t ccr4*/)
{


NVIC_InitTypeDef NVIC_InitStructure;
//Clock für den Timer

/*TIM8 clock enable 1)*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);

//GPIOC clock enable
// RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
//2)
GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM8);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);


// unsigned short PrescalerValue = (unsigned short) (SYSTEM_TIMERCLOCK / TIMER_TAKT) - 1;
//3)
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
uint16_t PrescalerValue = (uint16_t) prescaler-1;
TIM_TimeBaseStructure.TIM_Period= (period-1); //
TIM_TimeBaseStructure.TIM_Prescaler= (prescaler-1); //15381;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);

TIM_PrescalerConfig(TIM8, PrescalerValue, TIM_PSCReloadMode_Immediate);
TIM_ICInitTypeDef TIM_ICInitStructure;
//4)
TIM_ICInitStructure.TIM_Channel = 1; //TIM_Channel_1;
TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //Which Edge capture occures
TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; // Div:1, every edge detected
TIM_ICInitStructure.TIM_ICFilter = 0x1;
//5)
TIM_ICInit(TIM8, &TIM_ICInitStructure);

//6) Enable the TIM8 gloabal Interrupt //
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

/* Enable the TIM8 CC Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = TIM8_CC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

//7)
/* Enable the CCx Interrupt Request */
TIM_ClearITPendingBit(TIM8, 1); //TIM_IT_CCx);
TIM_ITConfig(TIM8, TIM_IT_Update | TIM_IT_CC1, ENABLE); //TIM_IT_UPDATE for Timer UP Interrupt; TIM_IT_CC1 für Captureinterrupt


//8)
/* TIM4 enable counter */
TIM_Cmd(TIM8, ENABLE);
}

Kind Regards Jan

I usually do not use the STM HAL in my projects, so I can’t say for certain if your setup is correct because I’m not sure what some of the HAL-defined symbols equate to.

However, with that disclaimer out of the way, I’d say that your setup appears to be correct for both input capture configuration for TIM8 using CC1 on PC6.

To determine if the HAL is doing what you think it should be, I’d suggest running your application under the debugger, and following execution of the above code, check the contents of TIM8->CCMR1. I would expect it to be set to 0x??01 (MSB sets CC2 configuration so its value is not relevant)
IC1F = 0b0000 — no filter
IC1PSC = 0b00 — prescaler x1
CC1S = 0b01 — IC1 mapped to TI1, input capture mode

Check the value in TIM8->CCER:
Bit 0 (CC1E) should be 1/set (CC1 input capture enabled)
Bits 1,2 (CC1P) should be 0b01 (capture on positive edge)
All other bits are dont-care

Confirm that CC1’s interrupt is enabled in TIM8->DIER:
Bit 1 (CC1IE) is 1/set (CC1 event interrupt enabled)
Other bits are dont-care

Rotate your encoder, then break your program and check if bit 1 in TIM8->SR (CC1IF) is set. CC1IF = CC1 event interrupt flag

If all the above is confirmed, but you’re not seeing interrupts (have you defined the TIM8_CC_IRQHandler ?) then try changing the NVIC PreemptionPriority for it. I don’t recall if ‘0’ is the lowest or highest priority. Try setting it to 1 instead.

I’ve used input capture in some of my own applications (albeit not on the F407) and have used a setup similar to what you describe here, using the same sort of timer. As far as I can tell w/o greater familiarity with the HAL, your setup looks good.