IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Firmware STM32F4 (GPIO question n°1) [STM32]


Sujet :

Embarqué

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut Firmware STM32F4 (GPIO question n°1)
    Bonjour,

    chose promis chose due, pour planter un peu le décor, j'essaye de comprendre comment les ingénieurs/programmeurs/que sais-je de ST manipulent et configures les I/O du µcontroleur ayant pris comme source le firmware disponible sur le site de ST relatif a une communication USART entre 2 discovery-board STM32F429I.

    Second point, en ne s'attardant que sur les fichiers sources disponibles dans le projet, ils sont aux nombres de 3:

    -Main.c
    -stm32f4xx_hal_msp.c
    -stm32f4xx_it.c

    Et stm32f4xx_hal_msp.c est celui qui nous interesses car c'est dans ce fichier que sont configuré les GPIOs. Tout au long de ce post, et afin d'avoir un fil conducteur je mettrais les questions en rapport avec la configuration des GPIOs.

    Donc ma première question concerne une macro servent a activer l'horloge sur le GPIO port A.

    Voici la macro en question:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /** @defgroup RCC_AHB1_Clock_Enable_Disable AHB1 Peripheral Clock Enable Disable
      * @brief  Enable or disable the AHB1 peripheral clock.
      * @note   After reset, the peripheral clock (used for registers read/write access)
      *         is disabled and the application software has to enable this clock before 
      *         using it.   
      * @{
      */
    #define __HAL_RCC_GPIOA_CLK_ENABLE()	do { \
                                            __IO uint32_t tmpreg; \
                                            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(0)
    donc la boucle do , la declaration de tmpreg et la fonction SET_BIT pas de problème j'ai compris. Pour info la fonction/macro SET_BIT fait une affectation OU entre bit soit entre RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN ce qui a pour conséquence de mettre a 1 le bit 0 du registre RCC_AHB1ENR.
    Bit 0 ==> 1 = IO port A clock enabled (selon le manuel de référence).

    Par contre je ne comprends pas l'utilité des lignes suivantes. je comprends la manipulation de READ_BIT qui fait un ET entre bit mais dans quel but comme le nom l'indique lire un bit mais pourquoi faire ?:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define READ_BIT(REG, BIT)    ((REG) & (BIT))
    et UNUSED je ne sais pas bien, peut être supprime la lecture du bit ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define UNUSED(x) ((void)(x))
    merci pour vos retours!

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Salut Julien,
    Alors ça c'est une sacrée bonne question... quel est l'intérêt de lire le bit d'un registre et mettre ça dans tmpreg et ne rien faire avec si ce n'est de de faire un cast du type ((void) tmpreg); ???

    Peux tu poster l'endroit dans le code où __HAL_RCC_GPIOA_CLK_ENABLE(); est utilisé ?

    Ne serait ce pas une séquence a respecter pour le registre RCC_AHB1ENR ?

    Je vais regarder ça mais c'est sacrément bizarre !!!!

  3. #3
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut
    Heureux de faire ta connaissance Vincent .

    Pétard je n'avais pas vu le cast il y a encore du boulot...

    L'endroit ou est défini __HAL_RCC_GPIOA_CLK_ENABLE(); c'est le Main.h (ci-dessous un extrait)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* Definition for USARTx clock resources */
    #define USARTx                           USART1
    #define USARTx_CLK_ENABLE()              __HAL_RCC_USART1_CLK_ENABLE();
    
    #define USARTx_RX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
    #define USARTx_TX_GPIO_CLK_ENABLE()      __HAL_RCC_GPIOA_CLK_ENABLE()
    Ensuite voici la fonction complète d'initialisation pour les GPIOs et les interruptions provenant du fichier source stm32f4xx_hal_msp.c:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    /**
      * @brief UART MSP Initialization 
      *        This function configures the hardware resources used in this example: 
      *           - Peripheral's clock enable
      *           - Peripheral's GPIO Configuration  
      *           - NVIC configuration for UART interrupt request enable
      * @param huart: UART handle pointer
      * @retval None
      */
    void HAL_UART_MspInit(UART_HandleTypeDef *huart)
    {  
      GPIO_InitTypeDef  GPIO_InitStruct;
      
      /*##-1- Enable peripherals and GPIO Clocks #################################*/
      /* Enable GPIO TX/RX clock */
      USARTx_TX_GPIO_CLK_ENABLE();
      USARTx_RX_GPIO_CLK_ENABLE();
      /* Enable USART1 clock */
      USARTx_CLK_ENABLE(); 
      
      /*##-2- Configure peripheral GPIO ##########################################*/  
      /* UART TX GPIO pin configuration  */
      GPIO_InitStruct.Pin       = USARTx_TX_PIN;
      GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull      = GPIO_NOPULL;
      GPIO_InitStruct.Speed     = GPIO_SPEED_FAST;
      GPIO_InitStruct.Alternate = USARTx_TX_AF;
      
      HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
        
      /* UART RX GPIO pin configuration  */
      GPIO_InitStruct.Pin = USARTx_RX_PIN;
      GPIO_InitStruct.Alternate = USARTx_RX_AF;
        
      HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
        
      /*##-3- Configure the NVIC for UART ########################################*/
      /* NVIC for USART1 */
      HAL_NVIC_SetPriority(USARTx_IRQn, 0, 1);
      HAL_NVIC_EnableIRQ(USARTx_IRQn);
    }
    Donc comme tu as pu le remarqué USARTx_TX_GPIO_CLK_ENABLE(); USARTx_RX_GPIO_CLK_ENABLE(); renvoi vers les defines présent ds le Main.h pour ensuite appeler le macro en question.

    Voila ce que j'ai comme info pour le moment je vais creuser du coté driver RCC voir ce que ce fichier comporte...

    Merci pour ton implication

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Il suffit de lire en faite
    After reset, the peripheral clock (used for registers read/write access) is disabled and the application software has to enable this clock before using it.
    On doit activer l'horloge avant utilisation et la vraie question est, une fois qu'on a activé l'horloge (Bit 0 du registre RCC_AHB1ENR à 1 = IO port A clock enabled) combien de temps faut il avant que l'horloge ne soit vraiment active ?

    La réponse on la voit lorsqu'on regarde ce code :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define __HAL_RCC_GPIOA_CLK_ENABLE()	do { \
                                            __IO uint32_t tmpreg; \
                                            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(0)
    Toute de suite on voit que la boucle do while ne sert strictement a rien puisqu'elle ne s'exécute qu'une seule fois ! Donc on pourrait la retirer (c'est le premier non sens). Ensuite on voit la déclaration d'une variable "tmpreg" qui ne sert à rien si ce n'est qu'elle sert à lire un bit puis c'est tout ! (second non sens) Enfin on voit un commentaire très important qui dit "attendre après qu'une horloge RCC d'un périphérique soit activée" (RCC étant le Reset and clock control décrit dans le Reference Manual)


    D'où la réponse... c'est juste une manière d'attendre. Sur d'autre micro, ça pourrait ressembler a des NOP

    Voyons la doc constructeur. Allez go ! Paragraphe 6.2.6 System clock (SYSCLK) selection du Reference Manual
    A switch from one clock source to another occurs only if the target clock source is ready (clock stable after startup delay or PLL locked)
    Il y a des histoires de délais là dedans.

    Il faudrait que tu regardes dans ton programme qu'elle(s) horloge(s) est choisie(s) pour activer les périphériques. Il faut remonter dans le Firmware et chercher après.
    Cette macro ressemble a un garde fou générique pour éviter des problèmes d'horloge interne non synchronisée.

    Quoi que t'en pense ? Moi j'en suis quasi sur.

    ps : Ju si tu veux que le code que tu postes ait de la coloration syntaxique tu peux ajouter le langage dans la balise "[ CODE=C]....[/CODE]"

    Ah oui, j'allais oublier... heureux également de faire ta connaissance !!!

  5. #5
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut
    Et bonsoir,

    suite a ta réponse voila ce que j'ai trouvé dans une des docs (traduit si quelque chose te parait étrange dis moi le je te mets la version originale):

    45.2.2 Limitations de RCC:

    Un délai entre RCC peripheral clock enable et l'utilisation du périphérique en question doit être pris en compte afin de gérer la lecture / écriture du périphérique vers les registres.

    Ce délai dépend du bus sur lequel est le périphérique.

    Si le périphérique est sur AHB: le délai est de 2 AHB cycle d'horloge après que l'activation de l'horloge soit mise de manière matériel.

    Si le périphérique est sur APB: le délai est de 2 APB cycle d'horloge après que l'activation de l'horloge soit mise de manière matériel.

    Solution mise en œuvre:
    Pour AHB & APB périphériques, une lecture fictive du registre périphérique a été inséré dans chaque macro __HAL_RCC_PPP_CLK_ENABLE ().
    -Ensuite j'avais posé la mm question sur le forum de ST et une personne m'a répondu ceci (traduit):

    Il y a plusieurs choses qui se passent ici.

    La macro UNUSED utilise la variable de manière a ce qu'elle ne fasse rien, et arrête le compilateur avertissant qu'il est assigné par une valeur et par la suite non utilisé.

    La relecture du masque est un tour de passe provoquant la lecture du registre, la lecture doit avoir lieu, et forces la valeur dans la mémoire tampon d'écriture dans le premier registre de RCC (l'écriture se distingue grâce à ce système de mise en mémoire tampon, car il accélère l'exécution en cours).

    Cela évite également le risque d'activer un périphérique, et ensuite immédiatement de commencer a travailler avec les registres de programmation , cela permet de verrouillé le bit de validation , afin que plusieurs cycles (d'horloge) se produisent avant de l'utiliser.

    La question est évoqué dans l'errata.
    la version originale:

    There's a couple of things going on here.

    The UNUSED macro uses the variable in a manner that does nothing, and stops the compiler warning that it's assigned a value and subsequently not used.

    The read back masking is a slight of hand causing the register to be read, the read has to happen, and forces the write buffer to commit the value to the RCC register first (the write gets differed through this buffering scheme, as it accelerates execution in the pipeline).

    This also avoids a hazard where someone enables the peripheral and then immediately starts programming registers in it, it allows the enable bit to get latched, and several cycles to occur prior to use.

    There mention of the issue in the errata.
    J'en conclu comme tu l'a indiqué ds ton précédent mail que c'est un délais afin d'attendre que l'horloge utilisé se stabilise ou que la PLL soit verrouillée mais comme tu as plus d'expérience que moi je voulais te demander n'est-ce pas une manière étrange de faire un délais ?

    Et pour répondre a ta question je pense que l'horloge utilisé est la PLL avec comme source HSE.


    Main.c:

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    /**
      * @brief  System Clock Configuration
      *         The system Clock is configured as follow : 
      *            System Clock source            = PLL (HSE)
      *            SYSCLK(Hz)                     = 180000000
      *            HCLK(Hz)                       = 180000000
      *            AHB Prescaler                  = 1
      *            APB1 Prescaler                 = 4
      *            APB2 Prescaler                 = 2
      *            HSE Frequency(Hz)              = 8000000
      *            PLL_M                          = 8
      *            PLL_N                          = 360
      *            PLL_P                          = 2
      *            PLL_Q                          = 7
      *            VDD(V)                         = 3.3
      *            Main regulator output voltage  = Scale1 mode
      *            Flash Latency(WS)              = 5
      * @param  None
      * @retval None
      */
    static void SystemClock_Config(void)
    {
      RCC_ClkInitTypeDef RCC_ClkInitStruct;
      RCC_OscInitTypeDef RCC_OscInitStruct;
     
      /* Enable Power Control clock */
      __HAL_RCC_PWR_CLK_ENABLE();
     
      /* The voltage scaling allows optimizing the power consumption when the device is 
         clocked below the maximum system frequency, to update the voltage scaling value 
         regarding system frequency refer to product datasheet.  */
      __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
     
      /* Enable HSE Oscillator and activate PLL with HSE as source */
      RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
      RCC_OscInitStruct.HSEState = RCC_HSE_ON;
      RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
      RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
      RCC_OscInitStruct.PLL.PLLM = 8;
      RCC_OscInitStruct.PLL.PLLN = 360;
      RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
      RCC_OscInitStruct.PLL.PLLQ = 7;
      if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
      {
        Error_Handler();
      }
     
      /* Activate the Over-Drive mode */
      HAL_PWREx_EnableOverDrive();
     
      /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 
         clocks dividers */
      RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
      RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
      RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
      RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;  
      RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;  
      if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
      {
        Error_Handler();
      }
    }

    Par contre j'en reviens a l'une de mes premières questions puisque GPIOs utilise le bus AHB1 et l'USART1 utilise le bus APB2 comment faire la relation entre les deux et d'ailleurs on voit que l'on active l'horloge périphérique sur GPIOA et sur USART1 ds HAL_MSP_init ?

    Ensuite je t'ai également joint le schéma d'horloges !


    Merci l'ami, oula on serait pas entrain de devenir intime la faut pas le dire a nos femmes...
    Images attachées Images attachées  

  6. #6
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Citation Envoyé par julien terrier Voir le message
    J'en conclu comme tu l'a indiqué ds ton précédent mail que c'est un délais afin d'attendre que l'horloge utilisé se stabilise ou que la PLL soit verrouillée mais comme tu as plus d'expérience que moi je voulais te demander n'est-ce pas une manière étrange de faire un délais ?
    Oui en effet c'est assez bizarre comme temporisation et ça cache quelque chose de subtil à mon avis. Le langage assembleur des micro possède toujours une instruction NOP (not opération) ou un équivalent qui ne sert qu'a attendre de manière précise : NOP dure 1 cycle d'horloge.
    Le fait que cette macro soit plus complexe pour réaliser une simple attente est étrange et il est possible que la personne qui t'a répondu ait tout à fait raison (mais n'ayant jamais travaillé sur ST je ne peux pas être sur). Tu as le lien de l'ERRATA où tu as trouvé cette réponse ? A moins que tu ne m'aies donné la réponse complète ?

    Citation Envoyé par julien terrier Voir le message
    Par contre j'en reviens a l'une de mes premières questions puisque GPIOs utilise le bus AHB1 et l'USART1 utilise le bus APB2 comment faire la relation entre les deux et d'ailleurs on voit que l'on active l'horloge périphérique sur GPIOA et sur USART1 ds HAL_MSP_init ?
    En fait ta question est :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
      /* Enable GPIO TX/RX clock */
      USARTx_TX_GPIO_CLK_ENABLE();
      USARTx_RX_GPIO_CLK_ENABLE();
      /* Enable USART1 clock */
      USARTx_CLK_ENABLE();
    Pourquoi faire un USARTx_CLK_ENABLE alors que juste avant on fait des USARTx_TX_GPIO_CLK_ENABLE et USARTx_RX_GPIO_CLK_ENABLE ? Et qu'est ce qui diffère entre ces CLK issus de bus différents ?


    Tu peux poster le schéma de cette histoire de bus d'horloge différent AHB1 et APB2 (où l'on voit les GPIOs et l'USART) ? Il me semble que dans le poste précédent nous ne regardions pas le même schéma ! Tu t'en rappelles ?

    J'ai ma petite idée mais il faudrait que je vois ça pour ne pas de donner une réponse à côté de la plaque. Quoi que je vais quand même te dire à quoi je pense pour que tu jettes un oeil :
    Il se peut que les bus soient différents parce que USARTx_TX_GPIO_CLK_ENABLE() USARTx_RX_GPIO_CLK_ENABLE() sont synchronisés avec tous les registres internes du micro alors que USARTx_CLK_ENABLE() ne sert qu'a échantillonner les données qui entrent ou qui partent de l'USART. En effet, l'USART est asynchrone (sous entendu par rapport à l'horloge interne) ce qui veut dire que contrairement à d'autres BUS comme I2C ou SPI qui eux reçoivent et envoient des données aux rythmes des fronts montant ou descendant d'une horloge, l'USART échantillonne les données entrantes à une certaine fréquence (et pas forcément la même que le micro) et les placent dans un registre. Ce registre, par contre, est synchrone avec l'horloge du micro et une fois remplie (voir les flags dont nous parlions dans un autre sujet), le micro s'en sert.

    Je ne sais pas si j'ai été clair mais je pense que la réponse est dans la datasheet section UART.

    A+

  7. #7
    Membre éclairé
    Homme Profil pro
    Technicien Layout
    Inscrit en
    Août 2015
    Messages
    275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Technicien Layout

    Informations forums :
    Inscription : Août 2015
    Messages : 275
    Par défaut
    Tu as le lien de l'ERRATA où tu as trouvé cette réponse ? A moins que tu ne m'aies donné la réponse complète ?
    En faite je ne sais pas exactement de quel ERRATA il parle, je le lui ai demandé, j'attends sa réponse.

    De mon coté j'ai trouvé cette explication dans l'User Manual 1725 (Description of STM32F4xx HAL drivers) au chapitre 45.2.2 RCC limitation.

    Tu semble encore une fois être dans le vrai, cette histoire de synchrone/asynchrone me plait bien, du coup j'ai mis en pj le schéma global des bus et le schéma I/O en mode fonction alternée

    Donc si j'ai bien compris ce que tu as expliqueé, Input Data Register est le registre tampon entre les deux bus, du coté I/O pin on est sur le bus APB2 (asynchrone) puis de l'autre coté on passe sur le bus AHB1 vers les registres internes du µcontroleur ?

    Et en mode fonction alternée USART la fréquence d'APB2 est géré par le registre ==> Baud rate register (USART_BRR) ?

    Je ne sais pas si je m'égard, bref j'essaye également de voir du coté du programme si je trouve quelque chose!

    Je modifie mon message avec ci-joint l'ERRATA dont parlé la personne:

    Delay after an RCC peripheral clock enabling
    Description
    A delay between an RCC peripheral clock enable and the effective peripheral enabling
    should be taken into account in order to manage the peripheral read/write to registers.
    This delay depends on the peripheral’s mapping:
    • If the peripheral is mapped on AHB: the delay should be equal to 2 AHB cycles.
    • If the peripheral is mapped on APB: the delay should be equal to 1 + (AHB/APB
    prescaler) cycles.
    Workarounds
    1. Use the DSB instruction to stall the Cortex-M4 CPU pipeline until the instruction is
    completed.
    2. Insert “n” NOPs between the RCC enable bit write and the peripheral register writes
    (n = 2 for AHB peripherals, n = 1 + AHB/APB prescaler in case of APB peripherals).
    Les délais sont différent car l'errata concerne les STM32F40x and STM32F41x au lieu des STM32F42x and STM32F43x

    DSB instruction:

    Data Synchronization Barrier.
    Syntax
    DSB{cond}
    where:
    cond Is an optional condition code, see Conditional execution on page 3-18.
    Operation
    DSB acts as a special data synchronization memory barrier. Instructions that come after the DSB,
    in program order, do not execute until the DSB instruction completes. The DSB instruction
    completes when all explicit memory accesses before it complete.
    Condition flags
    This instruction does not change the flags.
    Examples
    DSB ; Data Synchronisation Barrier
    Images attachées Images attachées   

  8. #8
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 254
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 254
    Par défaut
    Ok donc l'Errata confirme que :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define __HAL_RCC_GPIOA_CLK_ENABLE()	do { \
                                            __IO uint32_t tmpreg; \
                                            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(0)
    Est bien une tempo que l'on pouvait remplacer par des instructions assembleur NOP et BSD. Je suis surpris que le Firmware fasse ce genre de tempo mais surement que d'un point de vue timing c'est la même chose.

    Et en mode fonction alternée USART la fréquence d'APB2 est géré par le registre ==> Baud rate register (USART_BRR) ?
    A mon avis oui mais je ne vois pas ce que j'aimerai voir dans les documents attachés au sujet....

    Tu peux me donner le lien vers la doc où tu as eu ces informations ? (je sais ça fait au moins trois fois que je te demande les doc mais c'est plus simple pour moi et ça m'évite de parcourir toutes les docs qui sont franchement énormes. Cumulées, on dépasse les 2500 pages)

    A+
    Vincent

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [STM32] Firmware STM32F4 (UART question n°2)
    Par julien terrier dans le forum Embarqué
    Réponses: 12
    Dernier message: 10/09/2015, 22h14
  2. [STM32] Firmware STM32F4 (UART)
    Par julien terrier dans le forum Embarqué
    Réponses: 21
    Dernier message: 29/08/2015, 21h03
  3. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 17h11
  4. Question de faisabilité
    Par lisarasu dans le forum CORBA
    Réponses: 3
    Dernier message: 14/05/2002, 12h26
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 30/04/2002, 00h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo