Перейти к содержанию
    

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 соответствующий бит не взводится и обработчик прерывания, соответственно, не вызывается. Что я делаю не так???

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

image.thumb.png.fefa1b31404a7b9bca92c709e6f441f6.png

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...