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é

  1. #1
    Membre actif
    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
    Points : 292
    Points
    292
    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!
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    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 !!!!
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  3. #3
    Membre actif
    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
    Points : 292
    Points
    292
    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
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    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 !!!
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  5. #5
    Membre actif
    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
    Points : 292
    Points
    292
    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  
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  6. #6
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    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+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  7. #7
    Membre actif
    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
    Points : 292
    Points
    292
    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   
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  8. #8
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    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
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  9. #9
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Salut Vincent,

    Voici le lien vers l'errata section 2.1.13 ==> http://www.st.com/web/en/resource/te...DM00037591.pdf

    Et pour le second document section 3.12.4 ==>

    http://infocenter.arm.com/help/topic...ex_m4_dgug.pdf


    Merci.
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  10. #10
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Ah... je me suis trompé (enfin oui et non), je t'ai donné une réponse mais pas à la bonne question.
    En effet l'USART échantillonne les données de manière asynchrone via le USART Baude Rate (USART_BRR) mais ça n'a rien à voir avec ta question initiale.

    Mais je pense avoir trouvé la vraie réponse !
    Je viens de lire en détail le chapitre 8 General-Purpose I/Os (GPIO) et le chapitre 2 Memory and bus architecture du Reference Manual et tout est écrit dedans.

    Voilà ce que j'ai compris (et ton micro est une bête de course si mon anglais est bon)
    Dans ton micro il y a une espèce de gros multiplexeur qui te permet de rediriger des périphériques, comme l'USART, vers les GPIO de ton choix. C'est ce qu'ils appellent le "maping".
    Les GPIO ne sont pas sur le même bus de l'USART et c'est pour cette raison que tu dois activer l'horloge des GPIO (sur AHB1) puis l'horloge de l'USART (sur APB2)
    Dans ton schéma on voit bien qui est relié où et il y a des bus "low speed" et "hight speed"

    Dans l'ordre il faut faire le maping entre le périphérique et les GPIO dont tu as besoin.
    Activer le ou les horloges si jamais on est pas sur le même bus.

    Voir aussi dans la datasheet chapitre 3.7 Multi-AHB bus matrix qui donne la même définition.
    The 32-bit multi-AHB bus matrix interconnects all the masters (CPU, DMAs, Ethernet, USB
    HS, LCD-TFT, and DMA2D) and the slaves (Flash memory, RAM, FMC, AHB and APB
    peripherals) and ensures a seamless and efficient operation even when several high-speed
    peripherals work simultaneously.

    Est ce que tu peux lire ces 2 chapitres et me dire ce que tu en penses ? Moi ça me paraît très clair.
    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  11. #11
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Cela devient plus clair maintenant pour ma part et grâce a ton aide et pourtant les chapitres GPIO et MEMORY je les ai lu bon nombre de fois.

    Si par exemple je prends la Pin 9 ==> PA9, 4 fonctions sont possible ( USART1;TIM1;I2C3;DCMI).

    Pour l'USART périphérique comme tu l'as précisé il faut activer la clock via le bus APB2 et ensuite avec un multiplexage on passe sur le PORT A qui lui est géré par le bus AHB1 direction les registres, la mémoire etc...

    Voila ce que j'ai relevé qui a mon sens semble intéressant a retenir, et une fois de plus merci Vincent.

    Je continu....

    pour comprendre on peut prendre comme image un trafic automobile dense, pour que les véhicules circulent il faut réguler le trafic, du coup on peut facilement faire l'analogie avec nos bus, nos mémoires et notre processeur.

    Les voitures correspondent au données qui transite d'un registre a un autre, les bus sont les routes empruntées par les données, le bus matrice et l'agent de police qui laisse passer tels ou tels données et pour terminer le processeur c'est la tour de contrôle qui effectue les opérations et donne les ordres. ( c'est une vision très simplifiée).

    Concernant les bus du µcontroleur STM32F429ZI, il y a 3 Advanced High-performance Bus (AHB) et notamment AHB1 celui qui nous intéresse il peut fonctionner a une fréquence de 180MHz (via HSE + PLL) AHB1 a une autre particularité il est le seul bus qui peut faire une passerelle avec 2 autres sous-bus (vulgarisation) APB1 et APB2 la encore le sous-bus qui nous intéresse c'est APB2 (the High-speed APB) qui peut avoir pour fréquence max 90MHz.

    Ce qu'il faut également retenir, le bus sollicité pour les General purpose IO c'est le bus AHB1 tandis que pour l'USART1 c'est le sous-bus APB2.

    Dans la section embedded bootloader j'ai trouvé cette phrase:
    -L'USART opère a la fréquence de l'oscillateur interne (HSI) soit a 16MHZ (cette phrase me laisse perplexe car première question est-ce spécifique au bootloader et ensuite 16MHz cela me parait énorme pour le protocole USART car j'ai pour habitude de voir l'usart utilisé a 9600 baud par seconde soit 9.6KHz bref, a creuser)

    Ensuite voir le fichier attaché (System architecture) car il donne une bonne indication de comment c'est fait on retrouve les 10 maîtres sur l'axe des abscisses et 8 esclaves sur l'axe des ordonnées.

    Pour l'instant, il y a une chose dont je ne suis pas certains, peut-on charger des donnés depuis le registre USART_DR vers une embedded SRAM1 par exemple en utilisant seulement la passerelle entre APB2 et AHB1 puis de AHB1 vers SRAM1 ? Car le Bus LCD-controller ne communique qu'avec les différentes mémoires embarqué (SRAMx et Flash memory) et la FMC.

    Bon je m'égard... j'ai fait un peu le tour de la question pour les bus et la mémoire.

    Demain j'essayerais d'ajouter ce que j'ai cru comprendre pour les fonctions alternées, le multiplexage etc...


    General Purpose Input Output

    Généralité a propos des entrées/ sorties (STM32F429ZI):

    -Jusqu’à 16 I/O par port, avec 11 port (A,...I,J,K)
    -Registre initialisation et de ré-initialisation via le registre ==> GPIOx_BSSR (je n'ai pas encore étudié ce registre et sa fonction)
    -Fonction analogique
    -Plusieurs fonctions possible par pin via les registres ==> GPIOx_AFRH & GPIOx_AFRL
    EX: Port-A pin 09 (USART1;TIM1;I2C3;DCMI) soit 4 fonctions possible sur cette pin.
    Comment ça fonctionne pour notre exemple le registre GPIOx_AFRH sera sollicité car c'est la pin 9 ( pin 0-7 = GPIOx_AFRL & pin 8-15 = GPIOx_AFRH) donc selon le mot binaire mis ds ce registre on obtiendra la fonction désiré, dans notre exemple il y a 4 choix possible:

    AF7: 0111 (USART1)
    AF1: 0001 (TIM1)
    AF4: 0100 (I2C3)
    AF13: 1101 (DCMI_D0)

    -4 modes possible par pin ==> Input; Output; Alternate function; Analog
    -2 types de sortie ==> push-pull ou open-drain
    -4 vitesses sélectionnable pour chaque I/O ==> Low speed; Medium speed; Fast speed; High speed ( je n'ai pas encore trouvé les vitesses de transfert correspondant)
    -2 registres de données ==> GPIOx_IDR et GPIOx_ODR
    -3 modes pull-up / pull-down possible par I/O ==> No pull- up/down / Pull-up/ Pull down

    Voila pour les caractéristiques général après il y a encore d'autres fonctions que je n'ai pas eu le tps de voir par exemple le registre de verrouillage qui verrouille après une séquence d'écriture spécifique tous les registres suivant ==> GPIOx_MODER, GPIOx_OTYPER,
    GPIOx_OSPEEDR, GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH, jusqu'au prochain reset du device.

    Multiplexage des pins I/O:


    -Les pins sont connectées sur un multiplexeur qui autorise une fonction alterné a la fois
    -De cette façon, il ne peut pas y avoir de conflit entre les périphériques qui partagent la même pin.
    -Après un reset les I/O sont connectées à la fonction alternée 0
    -Les fonctions alternées dites fonctions périphériques sont dédicacées de AF1 a AF13 sur le multiplexeur
    -AF15 "EVENTOUT" est elle dédicacé pour le cortex-M4

    Voila j'ai fait un peu le tour de la question, il reste quelques petites zones d'ombre mais plus pour très longtemps...
    Images attachées Images attachées  
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  12. #12
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Citation Envoyé par julien terrier Voir le message
    -4 vitesses sélectionnable pour chaque I/O ==> Low speed; Medium speed; Fast speed; High speed ( je n'ai pas encore trouvé les vitesses de transfert correspondant)
    GPIO_Speed: Select GPIO speed
    GPIO_Speed_100MHz
    GPIO_Speed_50MHz
    GPIO_Speed_25MHz
    GPIO_Speed_2MHz
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  13. #13
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Bon bah là tu n'as plus besoin de moi, tu arrives à naviguer dans la datasheet + dans le firmware donc tu trouveras toutes les réponses à tes questions
    A+

    Vincent
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  14. #14
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Citation Envoyé par Vincent PETIT Voir le message
    Bon bah là tu n'as plus besoin de moi, tu arrives à naviguer dans la datasheet + dans le firmware donc tu trouveras toutes les réponses à tes questions
    A+

    Vincent
    Tu ne vas pas te débarrasser de moi comme ça . En ce moment je ne pose pas trop de question parce que j'essaye d'utiliser la bibliothèque STemWin avec ma disco-board pour afficher des chaines de caractères mais je rencontre un pb car j'ai une version lite de keil µvision5 et donc je suis limité a 32ko par prg et tous les exemples fournit par ST dépassent cette taille.

    Du coup j'ai changé d'IDE j'ai dl Coocox (open source), j'ai réussi a faire marché un programme grâce a un tutoriel mais bon pour l'instant je nage un peu avec cette environnement.
    Au travers de ces recherches j'ai trouvé un site vraiment pas mal ou il fournit beaucoup d'exemple qui fonctionne avec les STM32F4 http://stm32f4-discovery.com/2014/04...429-discovery/ impressionant le travail qu'il a fournit!

    Sur ce site il y a plusieurs exemples qui utilisent le LCD tout est très bien fait mais je souhaites utiliser seulement les librairies "officiel". Car je peux m'appuyer sur des docs etc...

    Pense tu que c'est un bon choix ?
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  15. #15
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Salut Julien,
    De toute manière si tu n'as plus de limite de taille de code alors oui c'est le bon choix ! (j'ai fait aussi le choix de l'open source avec mes micros Texas Eclipse + GCC-MSP et je suis sous Linux comme ça tout est gratuit et mon banquier est d'accord aussi avec ça )

    Je viens de regarder ton site, il est très bien dans le sens où les tutos sont simples et efficaces, je viens de regarder celui du PWM et il y a que le stricte nécessaire.
    Je n'ai pas vu celui où il parle du LCD ?
    Et j'ai l'impression qu'ils utilisent le firmware officiel ? Non ?

    Me gourge je ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  16. #16
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Citation Envoyé par Vincent PETIT Voir le message
    Salut Julien,
    De toute manière si tu n'as plus de limite de taille de code alors oui c'est le bon choix ! (j'ai fait aussi le choix de l'open source avec mes micros Texas Eclipse + GCC-MSP et je suis sous Linux comme ça tout est gratuit et mon banquier est d'accord aussi avec ça )
    Pour l'instant je ne suis pas vraiment séduit par Coocox mais bon dans tout les cas il faut que j'apprenne a m'en servir.


    Citation Envoyé par Vincent PETIT Voir le message
    Je n'ai pas vu celui où il parle du LCD ?
    Je ne sais pas si il y a un tuto pour ce programme, j'ai directement téléchargé l'ensemble des ses projets sur Github (https://github.com/MaJerle/stm32f429) ensuite j'ai navigué dans le dossier et j'ai trouvé plusieurs projet avec le LCD en question.

    Citation Envoyé par Vincent PETIT Voir le message
    Et j'ai l'impression qu'ils utilisent le firmware officiel ? Non ?

    Me gourge je ?
    Je dirais oui et non il y a certains fichier qui sont d'origines et d'autres totalement modifiés comme par exemple, tu te rappel de la manière dont ST active la clock sur un périphérique avec leur macro bizarre?

    Exemple ST pour le port G (led3):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define __HAL_RCC_GPIOG_CLK_ENABLE()    do { \
                                            __IO uint32_t tmpreg; \
                                            SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\
                                            /* Delay after an RCC peripheral clock enabling */ \
                                            tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\
                                            UNUSED(tmpreg); \
                                            } while(0)
    Exemple Majerle Tilen selon le port utilisé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* Private functions */
    void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx) {
    	/* Set bit according to the 1 << portsourcenumber */
    	RCC->AHB1ENR |= (1 << TM_GPIO_GetPortSource(GPIOx));
    Fonction GetPortSource:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx) {
    	/* Get port source number */
    	/* Offset from GPIOA                       Difference between 2 GPIO addresses */
    	return ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE));
    }
    La pour le coup je vois a peu près ou il veut en venir mais je n'ai pas saisi les subtilités!
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  17. #17
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    Par défaut
    En tout cas le code de Majerle Tilen est plutôt propre !
    Moi c'est celui de ST que je trouve violent

    Je peux voir la version ST de GetPortSource ?
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  18. #18
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Citation Envoyé par Vincent PETIT Voir le message
    Je peux voir la version ST de GetPortSource ?
    Voici l'exemple pour initialiser l'horloge du port ou se trouve la led, en l’occurrence la led3.

    La fameuse macro avec la tempo de 2 coups d'horloge:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #define __HAL_RCC_GPIOG_CLK_ENABLE()    do { \
                                            __IO uint32_t tmpreg; \
                                            SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\
                                            /* Delay after an RCC peripheral clock enabling */ \
                                            tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOGEN);\
                                            UNUSED(tmpreg); \
                                            } while(0)
    Et comment on arrive a cette macro pour initialiser l'horolge sur le port G, en partant du main:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     /* Configure LED3 and LED4 */
      BSP_LED_Init(LED3);
    avec cette énumeration:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef enum 
    {
      LED3 = 0,
      LED4 = 1
    }Led_TypeDef;
    Appel de la fonction ds le main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    /**
      * @brief  Configures LED GPIO.
      * @param  Led: Specifies the Led to be configured. 
      *   This parameter can be one of following parameters:
      *     @arg LED3
      *     @arg LED4
      * @retval None
      */
    void BSP_LED_Init(Led_TypeDef Led)
    {
      GPIO_InitTypeDef  GPIO_InitStruct;
      
      /* Enable the GPIO_LED Clock */
      LEDx_GPIO_CLK_ENABLE(Led);
    La dernière ligne nous envoi vers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    #define LEDx_GPIO_CLK_ENABLE(__INDEX__)  do{if((__INDEX__) == 0) LED3_GPIO_CLK_ENABLE(); else \
                                                if((__INDEX__) == 1) LED4_GPIO_CLK_ENABLE(); \
                                                }while(0)
    Comme LED3 = 0 on execute ==> LED3_GPIO_CLK_ENABLE()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define LED3_GPIO_CLK_ENABLE()                  __GPIOG_CLK_ENABLE()
    La on commence a comprendre que ça va se passer sur le port G, cette macro nous envoi vers:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define __GPIOG_CLK_ENABLE     __HAL_RCC_GPIOG_CLK_ENABLE
    On y est voir le premier code du message!

    Donc on activera le bit 6 du registre RCC_AHB1ENR en effectuant un OU avecce qu'il appel "bit definition" RCC_AHB1ENR_GPIOGEN qui est l'image du registre avec le bit 6 (clock port G enable)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    #define  RCC_AHB1ENR_GPIOGEN                 ((uint32_t)0x00000040)
    Du coup on a traversé 4 fichiers depuis le main pour arriver a la macro qui active ce bit

    Si je compare avec le fichier de Tilen (1 << TM_GPIO_GetPortSource(GPIOx)) équivaut a RCC_AHB1ENR_GPIOGEN du prg ST.

    Du coup j'essaye de calculer ( j'adore manipuler les bits (ça risque d’être censuré)):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx) {
    	/* Get port source number */
    	/* Offset from GPIOA                       Difference between 2 GPIO addresses */
    	return ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE));
    En sachant que (uint32_t)GPIOx ==> GPIOG, car si on remonte l'origine ( je vais aller plus vite a l'essentiel):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    /* Initialize leds on board */
    	TM_DISCO_LedInit();
    
    void TM_DISCO_LedInit(void) {
    	/* Set pins as output */
    	TM_GPIO_Init(TM_DISCO_LED_PORT, LED_ALL, TM_GPIO_Mode_OUT, TM_GPIO_OType_PP, TM_GPIO_PuPd_NOPULL, TM_GPIO_Speed_High);
    Avec:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #define TM_DISCO_LED_PORT			GPIOG
    #define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
    #define GPIOG_BASE            (AHB1PERIPH_BASE + 0x1800)
    #define AHB1PERIPH_BASE       (PERIPH_BASE + 0x00020000)
    #define PERIPH_BASE           ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region
    Après calcul:

    GPIOG ==> 0x40001800
    GPIOA ==> 0x40000000
    GPIOB ==> 0x40000400

    Ensuite j'ai quelques questions concernant la soustraction binaire, quand on parle de soustraction binaire complémenté, on parle ici d'une technique pour faire une soustraction binaire?

    Complément a 2 de GPIOA:
    +GPIOA ==> 0b 0100 0000 0000 0000 0000 0000 0000 0000
    -GPIOA ==> 0b 1100 0000 0000 0000 0000 0000 0000 0000

    Le complément a 2 est bon ?

    J'arrete la parce que je veux etre sur du résultat pour passer aux soustraction GPIOG-GPIOA et GPIOB-GPIOA.

    Merci et désolé pour le bloc qui je pense et difficile a lire quand on est pas concerné.

    Si je reviens a l'appel de ==> TM_GPIO_Init:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void TM_GPIO_Init(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, TM_GPIO_Mode_t GPIO_Mode, TM_GPIO_OType_t GPIO_OType, TM_GPIO_PuPd_t GPIO_PuPd, TM_GPIO_Speed_t GPIO_Speed) {	
    	/* Check input */
    	if (GPIO_Pin == 0x00) {
    		return;
    	}
    	
    	/* Enable clock for GPIO */
    	TM_GPIO_INT_EnableClock(GPIOx);
    On arrive a l'activation de l'horloge sur le portx:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /* Private functions */
    void TM_GPIO_INT_EnableClock(GPIO_TypeDef* GPIOx) {
    	/* Set bit according to the 1 << portsourcenumber */
    	RCC->AHB1ENR |= (1 << TM_GPIO_GetPortSource(GPIOx));
    Avec l'appel de la fonction TM_GPIO_GetPortSource(GPIOx):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    uint16_t TM_GPIO_GetPortSource(GPIO_TypeDef* GPIOx) {
    	/* Get port source number */
    	/* Offset from GPIOA                       Difference between 2 GPIO addresses */
    	return ((uint32_t)GPIOx - (GPIOA_BASE)) / ((GPIOB_BASE) - (GPIOA_BASE));
    }
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

  19. #19
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 187
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    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 187
    Points : 11 568
    Points
    11 568
    Par défaut
    Je n'ai pas regardé le "Après calcul" je te fais confiance.

    Pour ta question :
    Citation Envoyé par Julien
    quand on parle de soustraction binaire complémenté, on parle ici d'une technique pour faire une soustraction binaire?
    Quand on parle de complément à 2 (qui correspond bien a ce que tu as fait, c'est à dire faire d'abord le complément à 1 puis ajouter 1) ce n'est pas une soustraction que l'on fait. On rend un nombre positif en nombre négatif de même valeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    transformer 17 en -17 par le complément à 2
    
       00010001 (17)
    
       11101110 (complément à 1) 
    +  00000001 (on ajoute 1)
       -------------
    =  11101111 (complément à 2)
    
    -17 en binaire, s'écrit 11101111
    Donc tu as bien transformé +GPIOA en -GPIOA
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  20. #20
    Membre actif
    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
    Points : 292
    Points
    292
    Par défaut
    Merci pour la réponse donc si je comprends bien je dois complémenté a 2 un nombre pour le rendre négatif:

    GPIOA nécessite d’être complémenté a 2 si:

    GPIOG - (-GPIOA)

    Par contre dans cette soustraction j'effectue une soustraction binaire a retenu (standard):

    GPIOG-GPIOA

    Merci pour tes réponses

    Bizarre mais après relecture j'ai l'impression de dire une betise?

    NB: tu vois que j'ai encore besoin de toi!
    L’art est une activité humaine, le produit de cette activité ou l'idée que l'on s'en fait s'adressant délibérément aux sens, aux émotions, aux intuitions et à l'intellect. www.elise-galerie.com

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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, 21h14
  2. [STM32] Firmware STM32F4 (UART)
    Par julien terrier dans le forum Embarqué
    Réponses: 21
    Dernier message: 29/08/2015, 20h03
  3. question sur les message box !
    Par krown dans le forum Langage
    Réponses: 7
    Dernier message: 02/08/2002, 16h11
  4. Question de faisabilité
    Par lisarasu dans le forum CORBA
    Réponses: 3
    Dernier message: 14/05/2002, 11h26
  5. [HyperFile] 2 questions de débutant
    Par khan dans le forum HyperFileSQL
    Réponses: 2
    Dernier message: 29/04/2002, 23h18

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