2024-01-18 06:30 PM
Hi, I use STM32Cube IDE, and use STM32G0 - G0B1RE device. I try to enable the mod register to blink the LED here is the code that i try so far, based on the Reference Manual (rm0444), I need to enable RCC_IOPENR before modify the GPIOx_MODER. But unfortunately it still did not work.
When i try in debugging mode via the SFRs by set the value of RCC_IOPENR, GPIOA MODER (MODER5), OTYPER (OT5), PUPDR PUPDR(5), and BSRR the LED was turned on.
The LED is at GPIOA (PA5) based on the schematic.
Did i missed something? or there is anything to enable before I modifie the GPIOx_MODER?
In the reference manual to enable to peripheral in STMG0-G0B1RE the GPIO Bus is IOPORT not AHB or APB
#include "main.h"
#include "stdint.h"
int main(void)
{
uint32_t *ptr;
// RCC_IOPENR
ptr = (uint32_t *)(0x40021000 + 0x34);
*ptr |= (0x1 << 0); //set bit position 0 to value 1 (0x1) for GPIOA
// GPIO MOD Register GPIOA
// [ISSUE] THE MOD REGISTER VALUE DID NOT CHANGE
ptr = (uint32_t *)0x50000000;
*ptr |= (0x1 << 10);
//OTYPE
ptr++;
*ptr &= ~(uint32_t)(0x1 << 5); //output type
//PUPDR
ptr++;
*ptr |= (uint32_t)(0x2 << 10); //pull down
ptr++;
*ptr |= (0x1 << 5);//turn on led
*ptr |= (0x1 << 21);// turn off led
}
Solved! Go to Solution.
2024-01-18 06:46 PM
A few things:
The default value for MODE0 is 0b11, so setting bit 0 will not change anything since it's already set. That is expected. You should to unset bit 1 (not done) and set bit 0 (already set).
Using the CMSIS defines will make your code much more readable. For example:
GPIOA->MODER = (GPIOA->MODER & ~0x03) | 0x01;
Mark the register as volatile to prevent the compiler from optimizing out changes that otherwise have no effect.
volatile uint32_t *ptr;
2024-01-18 06:46 PM
A few things:
The default value for MODE0 is 0b11, so setting bit 0 will not change anything since it's already set. That is expected. You should to unset bit 1 (not done) and set bit 0 (already set).
Using the CMSIS defines will make your code much more readable. For example:
GPIOA->MODER = (GPIOA->MODER & ~0x03) | 0x01;
Mark the register as volatile to prevent the compiler from optimizing out changes that otherwise have no effect.
volatile uint32_t *ptr;
2024-01-19 02:25 AM
Thank you for your response, but still did not work, when i try with HAL it works, but manually do from the registers it did not work, there something that keep the GPIOx_MODER value not change
RCC->IOPENR = (0x1 << 0);
GPIOA->MODER = (GPIOA->MODER & ~0x03) | 0x01;
GPIOA->OTYPER = (0x0 << 10);
GPIOA->PUPDR = (0x02 << 10);
GPIOA->BSRR = (0x1 << 5);
GPIOA->BSRR = (0x1 << 21);
this is the memory value for 0x50000000 (GPIOA Register)
2024-01-19 03:59 AM
Finally did it, thanks to @TDK for suggestion, i will accept your solution.
Here is the working code:
RCC->IOPENR = (0x1 << 0);
GPIOA->MODER = (GPIOA->MODER & ~GPIO_MODER_MODE5_1)| 0x1; //or ~0x00000800
GPIOA->OTYPER = (0x0 << 10);
GPIOA->PUPDR = (0x02 << 10);
GPIOA->BSRR = (0x1 << 5);
GPIOA->BSRR = (0x1 << 21);
GPIOA->BSRR = (0x1 << 5);
GPIOA->BSRR = (0x1 << 21);
2024-01-19 06:59 AM
Sorry, thought you were setting up PA0, not PA5. But the rationale was correct. Glad you got it working.