cancel
Showing results for 
Search instead for 
Did you mean: 

IO port always readuing 0v in release mode.

SSmit.13
Senior

Hi

  I am using a STM32L433 and have a digital input pin, which is checked on bootup and enables the USB if 3.3v is in the pin.  When working in debug mode, it always works, but when I switch to release mode , using stm32CubeIDE , it always reads 0v, and my optimization is None. Below is my code .

 

 

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; //Enable Port B clock

GPIOB->MODER &= ~GPIO_MODER_MODE12; //PB12 as input, check for usb interaction
inSetupMode=(GPIOB->IDR >> 12 )& 1;  //=1 when using USB


 

 

Can anyone let me know what the issue is?

 

Many thanks

 

Scott

1 ACCEPTED SOLUTION

Accepted Solutions

After the write

See how HAL does the clock enables, reads back to insure writes complete first, as forces IN-ORDER-COMPLETION for the write buffers and pipeline, and adds perhaps 4 bus cycles to the transaction.

#define __HAL_RCC_GPIOB_CLK_ENABLE()           do { \
                                                    __IO uint32_t tmpreg; \
                                                    SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); \
                                                    /* Delay after an RCC peripheral clock enabling */ \
                                                    tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); \
                                                    UNUSED(tmpreg); \
                                                  } while(0U)

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

8 REPLIES 8

Hard to know.

Enable the clocks early. There is a hazard enabling the clock and then immediately writing the peripheral registers.

Read back the RCC->AHB2ENR  /  _DSB()

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
SSmit.13
Senior

Hi ,

what is _DSB?

 

What do I check ? Is it if the B clock is enabled?

 

And if its not what do I do if its not enabled?

 

Sorry for all the questions.

 

Scott

 

Not a check, just small delay. Also, I would suggest adding some small delay between MODER setting and reading the IDR.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

Potential with all clocks, whilst design is synchronous, probably a couple of gates deep, to reset and start properly. 

DSB is a fencing instruction, clearing the pending write buffers

https://developer.arm.com/documentation/dui0489/c/arm-and-thumb-instructions/miscellaneous-instructions/dmb--dsb--and-isb

https://www.eevblog.com/forum/programming/stm32-__dsb()-vs-reading-back-register/

The HAL has a lot of lag and function calls, where as optimized register level code will potentially get you back-to-back pipelined writes, hence the hazard.

 

See how the HAL reads back the RCC register, this forces the pending writes to complete.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Many thanks for the reply. I will add a delay.

 

Thanks

Scott

 

Many thanks for your reply.

I havent come across this before, do I call it for all clocks, or is it 1 command takes care of it all?

I can add "__DSB();"  line to my code, is that all is needed?

 

Regards

Scott

SSmit.13
Senior

I added the line:

__DSB();

after the clocks being enabled, but never made a difference.

 

But when I added a 2ms delay after GPIOB->MODE and this worked.

Where do I add the DSB command, and is it just the DSB() on its own?

CHeers

Scott

 

After the write

See how HAL does the clock enables, reads back to insure writes complete first, as forces IN-ORDER-COMPLETION for the write buffers and pipeline, and adds perhaps 4 bus cycles to the transaction.

#define __HAL_RCC_GPIOB_CLK_ENABLE()           do { \
                                                    __IO uint32_t tmpreg; \
                                                    SET_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); \
                                                    /* Delay after an RCC peripheral clock enabling */ \
                                                    tmpreg = READ_BIT(RCC->IOPENR, RCC_IOPENR_GPIOBEN); \
                                                    UNUSED(tmpreg); \
                                                  } while(0U)

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..