Jump to content
    

STM32H503 - не вызываются прерывания LPTIM

Инициализация:

Спойлер
    LPTIM1->CFGR = 0                                            // must be modified when LPTIM is disabled
        | 0 * LPTIM_CFGR_ENC                                    // Encoder mode enable
        | 0 * LPTIM_CFGR_COUNTMODE                              // Increment source if CKSEL = 0, 0: internal, 1: LPTIM_IN1
        | 0 * LPTIM_CFGR_PRELOAD                                // ARR and CMP update, 0: after each APB access, 1: at the end of LPTIM period
        | 0 * LPTIM_CFGR_WAVE                                   // Waveform shape, 0: normal node, 1: set-once mode
        | 0 * LPTIM_CFGR_TIMOUT                                 // Trigger event when timer is started, 0: ignored, 1: reset and restart timer
        | 0 * (LPTIM_CFGR_TRIGEN & -LPTIM_CFGR_TRIGEN)          // Trigger edge selection, 0: software, 1: rising edge, 2: falling edge, 3: both edges
        | 0 * (LPTIM_CFGR_TRIGSEL & -LPTIM_CFGR_TRIGSEL)        // Trigger selection,
                                                                // h5xx LPTIM1: 0: LPTIM_ETR, 1: RTC alarm A, 2: RTC alarm B, 3...4: TAMP1..2, 5: GPDMA_CH1, 6: COMP1_OUT, 7: EVENTOUT
        | 0 * (LPTIM_CFGR_PRESC & -LPTIM_CFGR_PRESC)            // Clock prescaler, 0..7: div 2^N
        | 0 * (LPTIM_CFGR_TRGFLT & -LPTIM_CFGR_TRGFLT)          // Trigger filter, 0: off, 1: 2 clk cycles, 2: 4 clk cycles, 3: 8 clk cycles
        | 0 * (LPTIM_CFGR_CKFLT & -LPTIM_CFGR_CKFLT)            // Clock filter, 0: off, 1: 2 int. clk cycles, 2: 4 int. clock cycles, 3: 8 int. clk cycles
        | 0 * (LPTIM_CFGR_CKPOL & -LPTIM_CFGR_CKPOL)            // Clock active edge, 0: rising, 1: falling, 2: both (if CKSEL=0 only), 3: forbidden
        | 0 * LPTIM_CFGR_CKSEL                                  // Clock selection, 0: internal, 1: LPTIM_IN1
        ;

    // clear flags. Interrupt not asserted if flag set before enabling in DIER
    LPTIM1->ICR = uint32_t(-1);

    LPTIM1->DIER = 0
        | 0 * LPTIM_DIER_UEIE                                   // Update event DMA request enable
        | 0 * LPTIM_DIER_CMP2OKIE                               // CCR2 update complete interrupt enable
        | 1 * LPTIM_DIER_CC2IE                                  // Capture/Compare 2 interrupt enable
        | 0 * LPTIM_DIER_REPOKIE                                // RCR update interrupt enable
        | 0 * LPTIM_DIER_UEIE                                   // Update event interrupt enable
        | 0 * LPTIM_DIER_DOWNIE                                 // Direction change to down interrupt enable
        | 0 * LPTIM_DIER_UPIE                                   // Direction change to up interrupt enable
        | 0 * LPTIM_DIER_ARROKIE                                // ARR update complete interrupt enable
        | 0 * LPTIM_DIER_CMP1OKIE                               // CCR1 update complete interrupt enable
        | 0 * LPTIM_DIER_EXTTRIGIE                              // External trigger valid edge interrupt enable
        | 0 * LPTIM_DIER_ARRMIE                                 // Autoreload match interrupt enable
        | 0 * LPTIM_DIER_CC1IE                                  // Capture/Compare 1 interrupt enable
        ;

    LPTIM1->CCMR1 = 0
        | 0 * (LPTIM_CCMR1_IC2F & -LPTIM_CCMR1_IC2F)            // IC2 filter, 0: no filter, 1: 2 cycles, 2: 4 cycles, 3: 8 cycles
        | 0 * (LPTIM_CCMR1_IC2PSC & -LPTIM_CCMR1_IC2PSC)        // IC2 prescaler, 0: disabled, 1: /2, 2: /4, 3: /8
        | 1 * (LPTIM_CCMR1_CC2P & -LPTIM_CCMR1_CC2P)            // CC2 polarity, compare mode: 0, 2: active high, 1,3: active low
                                                                // capture mode: 0: rising, 1: falling, 3: both edges
        | 0 * LPTIM_CCMR1_CC2E                                  // CC2 enable
        | 0 * LPTIM_CCMR1_CC2SEL                                // CC2 selection, 0: output PWM, 1: capture
        | 0 * (LPTIM_CCMR1_IC1F & -LPTIM_CCMR1_IC1F)            // IC1 filter, 0: no filter, 1: 2 cycles, 2: 4 cycles, 3: 8 cycles
        | 0 * (LPTIM_CCMR1_IC1PSC & -LPTIM_CCMR1_IC1PSC)        // IC1 prescaler, 0: disabled, 1: /2, 2: /4, 3: /8
        | 0 * (LPTIM_CCMR1_CC1P & -LPTIM_CCMR1_CC1P)            // CC1 polarity, compare mode: 0, 2: active high, 1,3: active low
                                                                // capture mode: 0: rising, 1: falling, 3: both edges
        | 0 * LPTIM_CCMR1_CC1E                                  // CC1 enable
        | 0 * LPTIM_CCMR1_CC1SEL                                // CC1 selection, 0: output PWM, 1: capture
        ;

    // enable timer
    LPTIM1->CR = 0
        | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
        | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
        | 0 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
        | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
        | 1 * LPTIM_CR_ENABLE                                   // Enable
        ;
	// CCRx must only be modified when LPTIM is enabled
    LPTIM1->CCR2 = (LPTIM1_CLK + 1000000 - 1) / 1000000;        // 1 us minimal driver pulse width
	// CCRx must only be modified when LPTIM is enabled
    LPTIM1->ARR = LPTIM1_CLK / 1000;                            // просто для примера
	
	// Enable NVIC interrupt
    NVIC->ISER[2] = 0
        | (1 << (-64 + LPTIM1_IRQn))                // M4_STEP
        | (1 << (-64 + LPTIM2_IRQn))                // M3_STEP
        | (1 << (-64 + USB_DRD_FS_IRQn))
        | (0 << (-64 + CRS_IRQn))
        | (0 << (-64 + GPDMA2_Channel0_IRQn))
        | (0 << (-64 + GPDMA2_Channel1_IRQn))
        | (0 << (-64 + GPDMA2_Channel2_IRQn))
        | (0 << (-64 + GPDMA2_Channel3_IRQn))
        | (0 << (-64 + GPDMA2_Channel4_IRQn))
        | (0 << (-64 + GPDMA2_Channel5_IRQn))
        ;

    // start timer
    LPTIM1->CR = 0
        | 0 * LPTIM_CR_RSTARE                                   // Reset after read enable, can be set when LPTIM is enabled
        | 0 * LPTIM_CR_COUNTRST                                 // Reset counter, can be set when LPTIM is enabled
        | 1 * LPTIM_CR_CNTSTRT                                  // Start in continuous mode, can be set when LPTIM is enabled
        | 0 * LPTIM_CR_SNGSTRT                                  // Start in single pulse mode, can be set when LPTIM is enabled
        | 1 * LPTIM_CR_ENABLE                                   // Enable
        ;

 

Таймер стартует, импульсы на выходе вижу, в регистре LPTIMx->ISR нужные флаги появляются, а в NVIC->ISPR2 соответствующий бит не взводится и обработчик прерывания, соответственно, не вызывается. Что я делаю не так???

 

 

 

Share this post


Link to post
Share on other sites

50 минут назад, Сергей Борщ сказал:

Таймер стартует, импульсы на выходе вижу, в регистре LPTIMx->ISR нужные флаги появляются, а в NVIC->ISPR2 соответствующий бит не взводится и обработчик прерывания, соответственно, не вызывается. Что я делаю не так???

Что в этот момент в PRIMASK и BASEPRI?

Share this post


Link to post
Share on other sites

Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?

1 час назад, Arlleex сказал:

Что в этот момент в PRIMASK

По идее - PRIMASK не должен никак влиять на появление флагов-запросов в NVIC.

Share this post


Link to post
Share on other sites

1 час назад, jcxz сказал:

По идее - PRIMASK не должен никак влиять на появление флагов-запросов в NVIC.

Ни разу не хочу ставить под сомнение внимательность Сергея, но по себе знаю, что иногда на форум пишу одно, при этом подразумевая чутка другое) Когда замыливается поток мыслей🙂 Вдруг он смотрел вовсе не в NVIC->ISPR, а в регистр рядом? Всякое бывает же.

Share this post


Link to post
Share on other sites

3 часа назад, Arlleex сказал:

Что в этот момент в PRIMASK и BASEPRI?

Забыл упомянуть, что остальные задействованные прерывания (USB, USART, GPDMA, TIM1, TIM3, COMP, EXTI_10) в это время работают. А с LPTIM  не доходит до выставления флагов в NVIC. Причем и с LPTIM1 и с LPTIM2.

1 час назад, jcxz сказал:

Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?

Интересная мысль. Маловероятно, но сейчас проверю.

Share this post


Link to post
Share on other sites

Ради интереса, попробуйте настроить таймер на обычный счет и ловите прерывание по переполнению. Ну или по любым другим прерываниям.

Share this post


Link to post
Share on other sites

А всяких режимов Low Power сейчас нет? Т.е. используете как обычный таймер?

Share this post


Link to post
Share on other sites

А сами значения в регистрах таймера (после инита) проверили? Сравнили с мануальными?

А то кто его знает - не накосячено ли с определениями всех этих множества define-ов, там где вы их взяли?

Share this post


Link to post
Share on other sites

5 часов назад, jcxz сказал:

Можно попробовать: При запрещённых всех прочих источниках прерываний сделать полную очистку всех pending (все ICPRx = ~0) (до инита таймера); потом запустить таймер и посмотреть - может где-то запрос появляется в другом регистре/бите?

Не взлетело - ни в одном ISPR ни один бит не взводится.

1 час назад, Arlleex сказал:

проверить хотя бы заход в прерывание

В другие прерывания заходит...

Share this post


Link to post
Share on other sites

4 минуты назад, Сергей Борщ сказал:

В другие прерывания заходит...

Другие - это Вы про UART и т.д. говорили. А я имел в виду возбудить именно этот вектор прерывания через активацию pending в NVIC (регистр ISPR вроде).

Share this post


Link to post
Share on other sites

1 час назад, Arlleex сказал:

image.thumb.png.fefa1b31404a7b9bca92c709e6f441f6.png

Это условие выполняется. Код в исходном сообщении исправил.

48 минут назад, Arlleex сказал:

А я имел в виду возбудить именно этот вектор прерывания через активацию pending в NVIC (регистр ISPR вроде).

А смысл делать это вручную? Таймер должен сам взвести именно этот бит, но не взводит. 

Share this post


Link to post
Share on other sites

Про CC2IE есть сноска в таблице.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...