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? */
/* ... */
}