cancel
Showing results for 
Search instead for 
Did you mean: 

Program flow gets stuck. Why doesn't CC1IF Capture/compare interupt flag gets set, while debugging the next program on my STM32F723E-DISCOVERY?

Zeron
Associate III

A while ago I received an STM32 discoveryboard as a gift, after I told some people on a fair that I'm a software engineer. Because I'm allready experienced in C/C++ but new to embedded software engineering, I ordered a course. Now I get stuck on the chapter on Timers, because the software I wrote just isn't working as it should. Here's my source file, I'm working with Atollic Truestudio.

#include "stm32f7xx.h"

int period;

float freq;

int main(void)

{

int last_value   = 0;

int current_value = 0;

RCC->AHB1ENR   |= 0x109; // GPIOA for PA5 blue led, GPIOD for TIM4, GPIOI for TIM5

GPIOD->MODER   |= 0x2000000; // Select alternate function for PD12

GPIOD->AFR[1]   |= 0x20000; // Alternate function 2 (TIM4_CH1) for PD12

RCC->APB1ENR   |= 0x4; // Enable clock for TIM4

// This sets up a 1Hz Timer, TIM4_CH1 in output compare mode

TIM4->PSC     = 1600-1; // Set the value for the prescaler

TIM4->ARR     = 10000-1; // Set the value for the autoreloadregister

// Set the output to toggle on match

TIM4->CCMR1    |= 0x30; // Set the output to toggle on match

TIM4->CCR1    |= 0x0; // Set the match value

TIM4->CCER    |= 0x1; // Set OC1 signal as output on PD12

TIM4->CNT     = 0x0;

TIM4->CR1     = 0x1; // Counter Enable

// This sets up TIM5_CH4 in input capture mode

GPIOI->MODER   |= 0x2; // Set alternate function for PI0

GPIOI->AFR[0]   |= 0x2; // Alternate function 2 (TIM5_CH4) for PI0

RCC->APB1ENR   |= 0x8; // Enable clock for TIM5

TIM5->PSC     |= 16000-1;

TIM5->CCMR2    |= 0x4100; // Channel 4 is input, sampling every 6 ocurrences

TIM5->CCER    |= 0xB000; // Enable capture, Capture rising and falling edge

TIM5->CR1     |= 0x1; // Counter enable

while (1)

{

while(!(TIM5->SR & 0x10)){} // Wait until edge is captured. HERE PROGRAM FLOW GETS STUCK

// The part below this comment never gets executed,

// except when I disconnect and reconnect the jumper wire between PD12 and PI0,

// then the while loop condition gets matched once.

current_value = TIM5->CCR4;

period = current_value - last_value;

last_value = current_value;

freq = 1000.0f / period;

}

}

According to what I learned from the course and what I found in the reference manual, https://www.st.com/content/ccc/resource/technical/document/reference_manual/group0/c8/6b/6e/ce/dd/f7/4b/97/DM00305990/files/DM00305990.pdf/jcr:content/translations/en.DM00305990.pdf , this should work.

However, I noticed something remarkable in the manual. In chapter '19.4.7 TIMx capture/compare mode register 1 (TIMx_CCMR1)(x = 2 to 5)', 'Bits 6:4 OC1M: Output compare 1 mode.'

OC1M is a three bit field in the register diagram, however the options provided in this chapter for setting up this register all consist out of four bits. This doesn't make sense to me. Anyways, following the instructions from chapter '19.3.8 Output compare mode' I set OC1M to '011' to toggle on match.

If I understood everything right, this should set the output on PD12 to high when it's low and to low when it's high, when the value in CNT matches the value in CR1. This should be the signal that goes trough the jumper wire and should get captured by TIM5 that I assume to be running in input capture mode.

I suppose that TIM5 indeed is capturing input, due to the fact that the while loop condition that I have marked in the source file's comments gets matched when I unplug and then replug the jumperwire.

I also have a different version of this program, where I commented out the part on setting up and enabling TIM4 and decided to use plain GPIO output from PD12, by setting up GPIOD in General purpose output mode and replacing the while (1) statement with the following code.

GPIOD->MODER = 0x100000;

GPIOD->ODR = 0;

while (1)

{

while(!(TIM5->SR & 0x10))

{

//GPIOI->BSRR = (GPIOI->BSRR & 0x1) ? 0x10000 : 0x1;

if(GPIOD->ODR&0x1000)

{

GPIOD->ODR=0;

}

else

{

GPIOD->ODR=0x1000;

}

delayMs(25);

} // Wait until edge is captured

current_value = TIM5->CCR4;

period = current_value - last_value;

last_value = current_value;

freq = 1000.0f / period;

}

If I'm right this should work more or less the same as the blinking led example that I got to work earlier in the same course, but now on the timer input.

I would appreciate it if anyone with more experience than me or with better equipment available as I got could take a closer look on this issue.

Thanks in advance, Ronnie van Aarle.

15 REPLIES 15

What course teaches you this style? I mean, it's nice to see register-level programming, but you should use more the symbols from the device header for the individual values, to make it more readable. Particular values used in above program appear to be OK, though.

Observe the TIM (and GPIO and RCC) registers' value in debugger. Observe the output pin using oscilloscope or LA.

> I also have a different version of this program,

And that one does work as expected?

JW

PS. Change your username to a normal nick

0690X00000AtNnQQAV.png

This is for historical reasons. You write 0 to them so that's OK.

JW

I've just looked at UM2140 and noticed, that PD12 is not brought out to any header/pin!

How exactly did you connect it?

(PI0 is brought out through an analog switch which is also suspicious, but it appears that by default it is switched to PI0 - but again, how exactly did you connect it?)

JW

The course that I'm working on is 'bare metal c programming' from udemy.com.

I don't have a logic analyser or osciloscope, someone I know promised me to bring a multimeter that can measure frequencies. That should be sufficient to see wether or not there is output on the pin.

No, the other version of the program where I replaced the timer output with basic gpio output also does not work.

Ah, now I see.

Zeron
Associate III

Well, I used the 'alternate function mapping' table from the 'STM32F722xx STM32F723xx product specification'. This combined with what's printed on the board itself.

To connect the ports together I put a jumper wire between the fifth connecter output on the bottom of the board, the arduino connector, the one that says PD12, to PI0 in the PMOD connector on top of the board.

Can you tell me where I should search in the User Manual and to what I should pay attention to find usable timer input and output pins?

What I need to know to find appropriate pins that I can use for timer output and timer input, so I can wire these together and see if I can get the program to work afterall?

Thanks allready.

Zeron
Associate III

Hello again,

I also took a look at UM2140 'Appendix A 32F723EDISCOVERY Discovery board I/O assignment'. I once again changed the program, this time I'm using PA15 TIM2_CH1 and PB0 TIM3_CH3. Here's the modified file.

#include "stm32f7xx.h"
 
int period;
float freq;
 
int main(void)
{
	int last_value     = 0;
	int current_value  = 0;
 
	// TIM2_CH1->PA15 for output compare mode TIM3_CH3->PB0 for input capture
 
	RCC->AHB1ENR      |= 0x3;			// GPIOA for TIM2_CH1, GPIOB for TIM3_CH3
	GPIOA->MODER      |= 0x80000000;	// Select alternate function for PA15
	GPIOA->AFR[1]     |= 0x10000000;	// Alternate function 2 (TIM2_CH1) for PA15
 
	RCC->APB1ENR      |= 0x1;			// Enable clock for TIM2
 
	// This sets up a 1Hz Timer, TIM2_CH1 in output compare mode
	TIM2->PSC          = 1600-1;		// Set the value for the prescaler
	TIM2->ARR          = 10000-1;		// Set the value for the autoreloadregister
 
	// Set the output to toggle on match
	TIM2->CCMR1       |= 0x30;			// Set the output to toggle on match
	TIM2->CCR1        |= 0x0;			// Set the match value
	TIM2->CCER        |= 0x1;			// Capture/Compare 1 output enable
	TIM2->CNT          = 0x0;
	TIM2->CR1          = 0x1;			// Counter Enable
 
	// This sets up TIM3_CH4 in input capture mode
	GPIOB->MODER      |= 0x2;			// Set alternate function for PI0
	GPIOB->AFR[0]     |= 0x2;			// Alternate function 2 (TIM3_CH4) for PI0
	RCC->APB1ENR      |= 0x2;			// Enable clock for TIM3
	TIM3->PSC         |= 16000-1;
	TIM3->CCMR2       |= 0x41;			// Channel 3 is input, sampling every 6 ocurrences
	TIM3->CCER        |= 0xB0;			// Enable capture, Capture rising and falling edge
	TIM3->CR1         |= 0x1;			// Counter enable
 
	while (1)
	{
		while(!(TIM3->SR & 0x8))		// Wait until edge is captured. HERE PROGRAM FLOW GETS STUCK
		{
			int i = 0 ? 1 : 0;
		}
 
		// The part below this comment never gets executed,
		// except when I disconnect and reconnect the jumper wire between PD12 and PI0,
		// then the while loop condition gets matched once.
 
		current_value = TIM3->CCR3;
		period = current_value - last_value;
		last_value = current_value;
		freq = 1000.0f / period;
	}
}

Nevertheless, the result remains the same despite using different timers and pins. Also, according to the user manual, the gpio uses multiplexers on the different pins so the functions of the pins can be selected using the alternate function modes. Following what's written in the reference manual and the user manual, this means that my initial program should still be right. I'm using Reference Manual RM0431 and Datasheet https://static6.arrow.com/aropdfconversion/29737e50fc5e53cf3b25bd139bc2d144ac0a47a/179979946274536379.pdf

after searching for "STM32F722xx STM32F723xx" in google, st.com comes shows another datasheet belonging to another device, despite what the link in the search result says.

Anyways, when I connect PA15 and PB0 with the jumper wire, the same issue occurs.

I'll ad a screenshot of the debugger with TIM3 registers open. The only value that keeps changing while the program runs is CNT.

Well, I used the 'alternate function mapping' table from the 'STM32F722xx STM32F723xx product specification'. This combined with what's printed on the board itself.

To connect the ports together I put a jumper wire between the fifth connecter output on the bottom of the board, the arduino connector, the one that says PD12, to PI0 in the PMOD connector on top of the board.

Can you tell me where I should search in the User Manual and to what I should pay attention to find usable timer input and output pins?

What I need to know to find appropriate pins that I can use for timer output and timer input, so I can wire these together and see if I can get the program to work afterall?

Thanks allready.

Zeron
Associate III

I'm new to this messageboard, I sent answers where replies probably would have been more appropriate. My appologies.