cancel
Showing results for 
Search instead for 
Did you mean: 

While loop stucks

BG1
Senior
Posted on December 04, 2017 at 18:21

Hello ..

I am having a very weird issue with my code piece ..

The MCU is STM32F407VET6 .. What I'm trying to do is sending a string via USART1 peripheral module .. In order check if the character in the USART1 is sent out of the USART1->DR register I am continuously checking the 'Transmit Complete Bit of the usart1 status register

The code below works well ...

TC1 is defined as USART1_SR_TC register bitband alias ...

#define TC1 *((uint32_t *)(0x42220018)) //Previously defined at the top of the main file

void EXTI4_IRQHandler(void)

{

uint8_t i;

char x[6]='BURAK\n';

EXTI_PR_Bit4=1; // Cleared by writing 1

// ISR code

TC1=0;

for(i=0;i<7;i++)

{

USART1->DR=x[i];

while(!(USART1->SR&USART_SR_TC));// Transmit Complete ?

}

TC1=0;

}

BUT !

When I replace

while(!(USART1->SR&USART_SR_TC));

with

while(TC1==0);

The code stucks.. freezes ... and stops ...Why does it happen ?? Are Bit-Band Aliases not reliable things to use with while ,if , for statements ?? Does it have to be read/modify/write sequence always ??

Thanks in advance ..

#flag-check #bitband #while #stuck

Note: this post was migrated and contained many threaded conversations, some content may be missing.
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on December 04, 2017 at 18:39

#define TC1 *((volatile uint32_t *)(0x42220018))

View solution in original post

23 REPLIES 23
Posted on December 04, 2017 at 18:39

#define TC1 *((volatile uint32_t *)(0x42220018))

Posted on December 04, 2017 at 18:40

Don't look at the registers in the debugger.

Use TXE to see if the register is EMPTY first, rather than waiting for TC afterward, as that is the slowest way to do it.

Avoid looping in IRQ Handler for thousands of micro-seconds.

Bit-banding is not recommended for peripheral registers, it's not atomic and can have side-effects. Especially TIM->SR

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 04, 2017 at 19:22

Turvey.Clive.002

could you recommend any good article on bit-banding when working with registers? I would like to know how to safely do it, I know there is a feature on CortexM3/M4 which allows mapping mem regions in order to have an atomic operation.

Posted on December 04, 2017 at 20:30

You can have mostly atomic access to memory, no good for peripherals as they can change state during RMW action.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 05, 2017 at 06:52

I tried the volatile add-on with STM32F303RET6 and It failed .. But It solved my problem with STM32F407VET6 ... Thank you so much :.

Posted on December 05, 2017 at 06:57

Thanks Clive for your response ... As you know it is really annoying to deal with RMW sequence syntaxial for simple flag check-s or set-s or clear-s and with bit banding it is such a quite simple way to deal with all of these stuffs .. Maybe I think it is because I migrated from 8 Bit MCUs and got used to their union-structure bit defined compilers ... But I really would love to know the reason of '

Bit-banding is not recommended for peripheral registers' ? According to datahsheet and some people it is sometimes very helpful to cover our software from fast changing flags and bits bit with bitbanding aliases .. Why do you not suggest it .

Andrew Neil
Evangelist III
Posted on December 05, 2017 at 20:14

Cross post - on Keil forum: 

http://www.keil.com/forum/63180

 
Posted on December 07, 2017 at 11:32

Because it hides the fact that internally a RMW is performed; and there are several SFR on which RMW is not safe (Clive gave TIMx_SR as an example above).

JW

Posted on December 07, 2017 at 12:12

Burak Günay wrote:

it is really annoying to deal with RMW sequence syntaxial for simple flag check-s or set-s or clear-s

Is it?

How so?