cancel
Showing results for 
Search instead for 
Did you mean: 

Need Support regarding Drivers of STM32 F401 board.

Sarthakk_Sharma
Associate II

Hello Everyone,

I wrote the code by self for GPIO drivers , as a step by step process i am adding code for other peripherals & buses after taking due time in learning , the code progress as of now (as per my knowledge) should be enough to enable the GPIO peripherals & further toggling the internal LED at PA5 , but the LED is not toggling.
Any Solutions are invited. 
Below attached are the driver files of MCU.

File 1: STM32f401xx.h (stm32 F4 general drivers Header File)
File 2: STM32f401xx_gpio_driver.h (stm32 F4 GPIO drivers specific Header File)
File 3: STM32f401xx_gpio_drivers.c (stm32 F4 GPIO driver file).

/**********************The Code for Toggling Led ***********************/

#include <stdint.h>
#include "stm32F401xx.h"


void delay(uint32_t time_period)
{
    for(uint32_t i =0 ; i < time_period ; i++);
}
int main()
{
    GPIO_Handle_t GPIO_Internal_LED;

    GPIO_Internal_LED.pGPIOx = GPIOA;
    GPIO_Internal_LED.pGPIO_PinConfig_t->GPIO_PinNumber = GPIO_PIN_NO_5;
    GPIO_Internal_LED.pGPIO_PinConfig_t->GPIO_PinMode = GPIO_MODE_OUT;
    GPIO_Internal_LED.pGPIO_PinConfig_t->GPIO_PinSpeed = GPIO_SPEED_MEDIUM;
    GPIO_Internal_LED.pGPIO_PinConfig_t->GPIO_PinOPType = GPIO_OP_TYPE_PP;
    GPIO_Internal_LED.pGPIO_PinConfig_t->GPIO_PinPuPdControl = GPIO_NO_PU_PD;

    GPIO_PeriClkControl(GPIOA , ENABLE);
    GPIO_Init(&GPIO_Internal_LED);

    while(1)
    {
        GPIO_TogglePin(GPIOA,GPIO_PIN_NO_5);
        delay(1500);
    }
   
    return 0;
}

(All the functions are defined in "File 3").

Thanks !

12 REPLIES 12
TDK
Guru

I don't immediately see an issue, but use the debugger to examine the GPIOA register values just before/after GPIO_TogglePin. No doubt the problem will become clear if you show those.

If you feel a post has answered your question, please click "Accept as Solution".
Sarthakk_Sharma
Associate II

Hi @TDK,
The issue i am facing is before i call the function GPIO_TogglePin ,
when i call the function GPIO_PeriClkControl(GPIOA , ENABLE); in the program the SFR does not show any changes in the respective bit position , below attached are the snips to have a better understanding.

Can you suggest me a solution in this regard.
Kindly refer to the PDF attached.

 

Hi @TDK,
The issue i am facing is before i call the function GPIO_TogglePin ,
when i call the function GPIO_PeriClkControl(GPIOA , ENABLE); in the program the SFR does not show any changes in the respective bit position , below attached are the snips to have a better understanding.

Can you suggest me a solution in this regard.
Kindly refer to the PDF attached.

TDK
Guru

It can take a few cycles for the bit to update. Note how HAL does this by doing a read which gives it enough time to update. I don't think that's the issue here, but maybe.

Recommend trying the HAL macro. If that doesn't work, something is wrong in your register definitions or SVD file or something else.

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

 

If you feel a post has answered your question, please click "Accept as Solution".

I already wrote it in another topic, but I'll repeat this for the topic author...

That HAL code is still broken. It just reads the RCC register, which has nothing to do with the actual requirement to wait for two peripheral clock cycles. RCC and the peripheral, for which the clock is enabled, can be on different buses with different frequencies and the requirement calls for two cycles.

KnarfB
Principal III

Your delay function is wrong. The compiler might optimize the loop away because it doesn't produce any side effects. As a result, the delay would be too short for a human to recognize blinking. Declare i volatile or search for better delay implementations.

hth

KnarfB

> requirement to wait for two peripheral clock cycles

so, could you pls. share a generic implementation how to ensure that?

KnarfB

The erratum in question mentions 3 possible workarounds:


• Use the DSB instruction to stall the Arm ® Cortex ® -M4 CPU pipeline until the instruction has completed.
• Insert “n” NOPs between the RCC enable bit write and the peripheral register writes (n = 2 for AHB
peripherals, n = 1 + AHB/APB prescaler for APB peripherals).
• Simply insert a dummy read operation from the corresponding register just after enabling the peripheral
clock.

In this particular case, GPIO on 'F4, it's an AHB peripheral; so according to text of the erratum (which I don't care to reproduce here), the delay shall be two AHB cycles.

However, I experimentally found the readback mentioned in the 3rd workaround to be inadequate. ST never commented on that thread; mentioned solution is still in the errata up to this day, and that's also what they use in above Cube/HAL implementation. So I too find that inadequate, too.

As I've said in that thread, I found the other two workarounds (DSB and two NOPs) to work (and two NOPs undoubtedly do insert two AHB cycles, as probably no existing CM4 does remove them from the pipeline as ARM threatened); but that of course does not prove they are adequate (and at this point, I don't believe in competence of whomever wrote that erratum).

JW

Pavel A.
Evangelist III

@waclawek.janIn the 3rd - what do you think is the "corresponding register": RCC register of the GPIO register?

As for the "HAL" code quality ...  reading parts of it indeed takes a nervous system of a professional maintainer. Does not look like European work. But I'd wish this is the world worst problem.