Skip to main content
Graduate
March 24, 2024
Question

Cannot get CC1 on TIM15 to go low using CCMR1 register

  • March 24, 2024
  • 8 replies
  • 9840 views

Using a Nucleo-F072RB.  I am trying to get the output of CC1 to go low after the CPU does something.  Everything is working as expected except I cannot get the line to go low.  I have tried both variants of the CC1P bit and neither seems to work.  I place a breakpoint at the first line where I touch CCMR1 register and single step.  I see that the bits are as I believe they should be but for the life of me I cannot force the output line low (line 3 below --- monitoring with scope).  Can someone tell me what I am missing?

 

	__HAL_TIM_DISABLE_IT(&htim15, TIM_DIER_CC1IE);
	htim15.Instance->CCMR1 = TIM_OCMODE_TIMING;
	htim15.Instance->CCMR1 = TIM_OCMODE_FORCED_INACTIVE;
	htim15.Instance->CCMR1 = TIM_OCMODE_TIMING;
	htim15.Instance->CCMR1 = TIM_OCMODE_ACTIVE;

 

 Thanks 

    This topic has been closed for replies.

    8 replies

    Super User
    March 24, 2024

    Did you try ...

    HAL_TIM_OC_Stop(xx);

    >

    * @brief Stops the TIM Output Compare signal generation.

    * @PAram htim TIM handle

    * @PAram Channel TIM Channel to be disabled

    <

    SWenn.1Author
    Graduate
    March 25, 2024

    This does nothing to change the OC output value.

    Super User
    March 25, 2024

    What you set for the xx channel out (in Cube ?) ?

    like this:

    AScha3_0-1711372316381.png

     

    Super User
    March 24, 2024

    Read out and check/post content of TIM and relevant GPIO registers.

    JW

    SWenn.1Author
    Graduate
    March 25, 2024

    SWenn1_0-1711327223155.png

    timer registers at said breakpoint in original post and GPIO (PB14 is signal I am monitoring)....this is after a reset and the 1st time hitting the breakpoint

     

    SWenn1_1-1711327337765.png

     

    Super User
    March 25, 2024

    I was hoping you were going to decipher the registers, thus find out what's wrong, yourself.

    GPIOB_MODER=0x10000000

    that means, the field for PB14 is set to 0b01, i.e. GPIO Output, not AF (which would be 0b10).

    And AFR for PB14 is set to 0, for TIM15_CH1 it would need to be set to 1 (see Alternate functions table in DS).

    In other words, you don't have PB14 set as TIM15_CH1 at all.

    But even if you would have PB14 set as AF/TIM15_CH1, as both TIM15_CCER.CC1E = 0 and TIM15_BDTR.MOE = 0, that output would be disabled anyway.

    JW

    SWenn.1Author
    Graduate
    March 25, 2024

    I would not have posted if I hadn't already looked at those registers (and as you seem to indicate your suggestion would not alter the outcome) ....To me they all looked fine plus the scope is showing me that the I/O is performing to the "toggle on match" as expected.  I used CubeMX to initialize things and intentionally I specifically set Channel 1 as "Output Compare No Output" and am using the I/O just as a test to validate something.  I am just trying to get the I/O low after it toggles ....

    The manual clearly states:

    SWenn1_0-1711374148291.png

    I have tried CCxP both high and low in conjunction with using "FORCE INACTIVE" and "FORCE ACTIVE" but none of the combinations seem to work.

    Super User
    March 25, 2024

    > To me they all looked fine plus the scope is showing me that the I/O is performing to the "toggle on match" as expected.

    Not with these settings.

    You have PB14 set as GPIO Out, and set to 1 in GPIOB_ODR.

    JW

    SWenn.1Author
    Graduate
    March 25, 2024

    If I change GPIO->MODER to AF my signal (yellow scope trace) completely disappears.  That is not what I want.  I am bound to pin PB14 so I cannot change CCR1 in CubeMX to "Output Compare Ch1" which then forces me to use GPIO and generate an Interrupt on match. Here is a scope picture (both micro and macro) showing the issue:

    It literally is just a matter of changing the toggle on the I/O to fall low at the end of each toggle.  I have attached macro and micro pics showing scope on rising and falling edge of a 4 second sample rate (pink trace).

     

    Super User
    March 25, 2024

    > If I change GPIO->MODER to AF my signal (yellow scope trace) completely disappears. 

    How do you generate that signal at the first place?

    Show some code, CubeMX setting, whatever.

    JW

    Super User
    March 25, 2024

    OK so you are *not* using TOGGLE mode of TIM15_CH1 at all. You set PB14=YELLOW_Pin as GPIO Out and then toggle it using HAL_GPIO_TogglePin() in HAL_TIM_OC_DelayElapsedCallback().

    So what don't you simply set that pin to the desired level using HAL_GPIO_WritePin() when done, i.e. after disabling the interrupt in HAL_ADC_ConvCpltCallback()?

    JW

    SWenn.1Author
    Graduate
    March 25, 2024

    Because I am using the GPIO to indicate activity of the counter / timer and I want to see that it powers down, stops counting, etc. ....by forcing the GPIO of course will take it low but it doesn't tell me that the peripheral is doing what I expect it to do, hence I would like to see the commanding of the peripheral cause the event on the GPIO

    Super User
    March 25, 2024

    > I would like to see the commanding of the peripheral cause the event on the GPIO

    You mean, the timer should drive the pin directly.

    Then you have to set the pin to AF, and its AFR to TIM15_CH1.

    And you have to enable given channel in TIMx_CCER and globally by TIMx_BDTR.MOE.

    JW

     

    SWenn.1Author
    Graduate
    March 25, 2024

    So let me ask you this:

    I have the CCR ISR (OC_DelayElapsedCallback) where I am allowing the GPIO to toggle each time which 'sort' of indicates to me the #A/D samples are being taken correctly (it's my way of visualizing that the DMA and Update Event are clocking off the correct # samples). I am going to this detail because I would eventually like to familiarize myself with low power (wake, sleep, etc.) on these processors and these are clearly not MSP430 (STM32s are way more complicated).  GPIOs are a great way to monitor and trigger current measurments. 

    Now when DMA expires I opt to use the "FORCE_ACTIVE' etc. mechanism in CCMR1....Are you saying that I should pick either GPIO path or AF path and that I am mixing the two which is not allowed?

    The reason I chose GPIO over AF was because the AF (in CubeMX) wanted to use one pins that I already had set aside for functionality.

     

    ADDITION HERE:  Also using AF didn't appear to be working for me (I probably was doing something wrong here) as the DMA was taking samples at 7.5 clocks + 12.5 clocks for conversion all at 14MHz a/d sampling.  So I set my timer update event for 5us....as mentioned it was grabbing samples and displaying them just fine but when I tried to introduce the monitor (CCR1 toggling) to see a very close approximation of the a/ds getting sampled then the code did not want to work hence it lead me down this rabbit hole

    Super User
    March 25, 2024

    > mixing the two which is not allowed

    It's not "not allowed". You either have the pin set in GPIO_MODER to Out, when its state is controlled by GPIO_ODR; or to AF, when it's state is controlled by whichever peripheral is chosen via GPIO_AFRx.

    That's either-or, there's no hardware which would allow you to have both in some way.

    > I have the CCR ISR (OC_DelayElapsedCallback) where I am allowing the GPIO to toggle each time which 'sort' of indicates [...]

    If you set the pin to AF/TIM15_CH1 and enable that channel as I've said both in TIM15_CCER and TIM15_BDTR, and that channel is set to Toggle mode, you will see the same toggling on the pin.

    JW

    SWenn.1Author
    Graduate
    March 25, 2024

    Ok....so firstly (THANK YOU for your patience!!!)....I took CubeMX and set Channel 1 as Output Compare CH1..ie AF bit gets set now...It seems the code does not touch the CCER / BDTR registers so I did this manually in the 4 second ISR.  It does not toggle (notice I removed the toggling code out of the ISR as I believe it should automatically toggle here without doing anything???).  I have attached my new code along with a scope shot showing what the yellow NOW looks like.  It toggles but stays high (what should my CCxP bit be and should I be using 'FORCE_ACTIVE' or FORCE_INACTIVE here?)

     

    + it looks a little strange on the tail end...any comments there?

     

    I don't want to muddy the waters here but recall I said 7.5clks + 12.5clks at 14MHZ which means I should be able to trigger the dma with 5us....so the scope shows this toggling using your method and this is what I have been seeing using the AF....it never stops toggling and you notice the green line never goes low (I am collecting only 6 samples) ...everything breaks here

     

    ADDITION:  I find that if I remove trying to track the A/D samples that timing looks pretty reasonable on the DMA (GREEN) time but when you add monitoring of the A/D sampling I get more toggling than samples and it won't even work (DMA never comes out of ISR to trigger the data to the UART) if I take the sampling below 15us (which is waaaaay longer than 20/14mhz needed per sample)...this translates to wasted energy

    Super User
    March 25, 2024

    Sorry, but I failed to follow.

    Maybe it's simpler if you revert to the GPIO based solution, since you are familiar with how it works.

    JW

    SWenn.1Author
    Graduate
    March 26, 2024

    Thank you very much for all the help!  After taking your information and going back a few steps then rebuilding from scratch up I got something that works pretty well.

    Your MOE and CC1E bits were important.

    Clock frequency played a role as when I moved the clock up to 48MHz from 20MHz things seemed to get better.

    Finally I used HAL_TIM_BASE_Start instead of HAL_TIM_BASE_Start_IT for the CCR1 output and a/d sampling.....

    With that said here is a pic of my final signals....I guess it seems reasonable to think that there is a 'front' and 'back' porch for DMA as the total time for 6 samples at 5us measures about 60us instead of the theoretical 30us (5*6).  I set CCR1 to go off at 0 and toggle every 5us....As you can see there are 11 toggles (the last one going high to low does not count as this is forced active here, where active is defined as low)...

    It consistently seems to do this so I think all is good here now.  YELLOW is CCR1 going off every 5us, GREEN is measuring the DMA length and PINK just represents a toggling 2 second waveform where sampling is done.

    Once again thanks for the insight!