1
\$\begingroup\$

I am currently having an issue setting up a communication protocol between an STM32F discovery board (using the latest HAL drivers) and a Nucleo64 board (using the same drivers). Essentially each board has an output handshake line, which the other board waits on at a given moment in order to proceed with its own code.

The problem is that either board is unable to read each other's handshake line when it is set to a high state (GPIO_PIN_SET). Though they can read each other at a low state (GPIO_PIN_RESET) I am unsure if this is because the setup is actually correct or not. I have tied the grounds of the two boards together to ensure they are at a similar reference level, as a reference level is the only problem I can possibly see in one or the other not being able to read a high state. I am very sure that both boards output at about 3.0V in this high state, so I feel like they are close enough that this shouldn't be an issue, but I am stumped. Why is my Nucleo board unable to detect the GPIO_PIN_STATE off of the Discovery handshake line when it is clearly set to high and measured as so on my oscilloscope???

If I could get any help on this it would be greatly appreciated as I have been banging my head against a wall for this project, which is due soon. Below I have posted the code for the set up of the GPIO pins and the line of code at which either board gets stuck. I am pretty certain the issue is hardware related, or revolves around me not actually understanding the GPIO pins (though I have read everything I can on them to understand this issue).

Setup of the Discovery board and the corresponding logic line it gets stuck at...

#define NUCLEO_TO_DISCOVERY_GPIO_PORT       GPIOA
#define NUCLEO_TO_DISCOVERY_PIN             GPIO_PIN_3

#define DISCOVERY_TO_NUCLEO_GPIO_PORT       GPIOA
#define DISCOVERY_TO_NUCLEO_PIN             GPIO_PIN_10 

#define DISCOVERY_DATAio_CLOCK_ENABLE()     __GPIOD_CLK_ENABLE()
#define DISCOVERY_HSI_CLOCK_ENABLE()        __GPIOA_CLK_ENABLE()

void Communication_config(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    DISCOVERY_DATAio_CLOCK_ENABLE();
    DISCOVERY_HSI_CLOCK_ENABLE();                                                 

    /* .... */

    // Discovery to Nucleo  (Output - Active Low)
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Pin   = DISCOVERY_TO_NUCLEO_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(DISCOVERY_TO_NUCLEO_GPIO_PORT, &GPIO_InitStructure);

    /* .... */

    /* Instantiate HS pin to high for active low state */
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT,                DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_SET);

    /* .... */

    // Nucleo to Discovery Handshake  (Input - Active Low)
    GPIO_InitStructure.Pull  = GPIO_NOPULL;
    GPIO_InitStructure.Pin   = NUCLEO_TO_DISCOVERY_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(NUCLEO_TO_DISCOVERY_GPIO_PORT, &GPIO_InitStructure);

    /* .... */ 
}

void Slave_Write(float input){

    int i;

    // Can only write decimal values between 0.0 & 0.99
    int numIntegerDigits = 0;
    int tempDecimalValue = 0;
    int tempIntegerValue = 0;

    int integerValue[8];
    int tempArray[4];

    /* ... */


    // Write first four bits of integer value (MSB first)
    for(i=0;i<4;i++)integerValue[i]=tempArray[i];
    Set_DataLines(tempArray);

    // Signal to Nucleo that pins are ready
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT,    DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_RESET);

    // Wait for Nucleo to finish reading
    while(HAL_GPIO_ReadPin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN) == GPIO_PIN_SET);

    // Write next four bits of integer value (MSB first)
    for(i=0;i<4;i++)integerValue[i+4]=tempArray[i];
    Set_DataLines(tempArray);

    // Signal to Nucleo that pins are ready
    HAL_GPIO_WritePin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN, GPIO_PIN_SET);

    // Wait for Nucleo to finish reading
    while(HAL_GPIO_ReadPin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN) == GPIO_PIN_RESET);

    /* The code gets stuck here, after the discovery to nucleo 

    handshake line is written high. The while loop never evaluates to false 

    because the other piece of code never reads that the handshake line from 

    the discovery is set to high (if it did then it would set the nucleo to 

    discovery handshake line high in response) */

    /* ... */

}

Below is the setup of the Nucleo board and the corresponding line communication gets stuck at...

#define NUCLEO_TO_DISCOVERY_GPIO_PORT           GPIOA
#define NUCLEO_TO_DISCOVERY_PIN                     GPIO_PIN_10  // GPIO_A10

#define DISCOVERY_TO_NUCLEO_GPIO_PORT           GPIOA
#define DISCOVERY_TO_NUCLEO_PIN                     GPIO_PIN_2  // GPIO_A2

#define NUCLEO_DATAo_CLOCK_ENABLE()     __GPIOB_CLK_ENABLE()
#define NUCLEO_DATAi_CLOCK_ENABLE()     __GPIOC_CLK_ENABLE()
#define NUCLEO_HSI_CLOCK_ENABLE()       __GPIOA_CLK_ENABLE()

void NucleoComm_Config(void){

    GPIO_InitTypeDef GPIO_InitStructure;

    NUCLEO_DATAi_CLOCK_ENABLE();
    NUCLEO_DATAo_CLOCK_ENABLE();
    NUCLEO_HSI_CLOCK_ENABLE();                                                 

    /* ... */

    // NUCLEO to Discovery Handshake Pin  (Output - Active Low)
    GPIO_InitStructure.Pull  = GPIO_PULLUP;
    GPIO_InitStructure.Pin   = NUCLEO_TO_DISCOVERY_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(NUCLEO_TO_DISCOVERY_GPIO_PORT, &GPIO_InitStructure);

    /* ... */

    /* Instantiate HS pin to high for active low state */
    HAL_GPIO_WritePin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN, GPIO_PIN_SET);

    /* ... */

    // Discovery to Nucleo Handshake Pin  (Input - Active Low)
    GPIO_InitStructure.Pull  = GPIO_NOPULL;
    GPIO_InitStructure.Pin   = DISCOVERY_TO_NUCLEO_PIN;
    GPIO_InitStructure.Mode  = GPIO_MODE_INPUT;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_MEDIUM;
    HAL_GPIO_Init(DISCOVERY_TO_NUCLEO_GPIO_PORT, &GPIO_InitStructure);

/* ... */


}

float Master_Read(){

    int i;

    // Can only read decimal values between 0.0 & 0.99
    int integerValue[8];
    int decimalValue[8];
    int tempArray[4];

    float tempDecimalValue;
    float returnValue;

    // Wait for Discovery to finish writing
    while(HAL_GPIO_ReadPin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN) == GPIO_PIN_SET);

    // Read first four bits of integer value (MSB first)
    Read_DataLines(tempArray);
    for(i=0;i<4;i++)integerValue[i]=tempArray[i];

    // Signal to Discovery that pins have been read
    HAL_GPIO_WritePin(NUCLEO_TO_DISCOVERY_GPIO_PORT, NUCLEO_TO_DISCOVERY_PIN, GPIO_PIN_RESET);

    // Wait for Discovery to finish writing
    while(HAL_GPIO_ReadPin(DISCOVERY_TO_NUCLEO_GPIO_PORT, DISCOVERY_TO_NUCLEO_PIN) == GPIO_PIN_RESET);

    /* Code gets stuck at this while loop, pin read never returns a 

    GPIO_PIN_SET and thus the while loop never evaluates to true. This is 

    regardless of the fact that the pin is definitely reading 3.0V on my 

    oscilloscope. I am more confused as to why this while loop is stuck than 

    the one in the discovery communication because I know that while loop is 

    simply waiting for the next instruction here, which would be to write 

    Nucleo to Discovery high. Why is the system not reading a high pin state 

    when it clearly is high? */

    /* ... */

}
\$\endgroup\$
  • \$\begingroup\$ Remember to ask questions when asking questions (part of the forum rules). Please edit your question and ask actual question(s) in the question. It makes it easier for others to help you. ("I want help" is not a question). Thanks \$\endgroup\$ – Voltage Spike Apr 13 '16 at 16:31
  • \$\begingroup\$ @laptop2d Hey! sorry about that, I amended the question. \$\endgroup\$ – Luke S Apr 13 '16 at 17:56
  • \$\begingroup\$ (comment removed) \$\endgroup\$ – user6030 Apr 15 '16 at 2:16
1
\$\begingroup\$

Have you checked if adding a resistor to the voltage not detected properly helps? Some boards use high resistance in place of one of the two states you seem to expect (high and low voltages), and therefore need a pullup or pulldown resistor to convert the high resistance to a definite voltage state.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.