cancel
Showing results for 
Search instead for 
Did you mean: 

SPI Issue: Cannot Receive Data

rheb1026
Associate II
Posted on February 09, 2016 at 20:03

I've been trying to start using the HAL libraries since I was hoping that it would allow me to get things up and running quickly. Unfortunately this hasn't been the case and I've been struggling with basic SPI communication for a number of days now.

I used the CubeMX program to write the initialization code for duplex communication, so I would assume that it is correct. I am trying to use the HAL_SPI_Transmit and HAL_SPI_Receive functions and toggling the CS pin by software. I seem to be able to transmit just fine, but cannot receive anything. I've hooked up a logic analyzer and the analyzer shows that everything is working perfectly as it should, but for some reason the variable never shows any value other than 0x00. I'm doing a basic test read of a register on an AD7124, to which the ADC should respond with 0x The logic analyzer confirms that the ADC is responding correctly, so I'm unsure where I could be going wrong and would appreciate it if a fresh set of eyes could take a look at my code. I'm using a Nucleo Board with an F042K6. SPI Initialization:


/* SPI1 init function */

void SPI1_Init_Mode3(void)

{

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi1.Init.NSS = SPI_NSS_SOFT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLED;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;

hspi1.Init.CRCPolynomial = 0;

hspi1.Init.CRCLength = SPI_CRC_LENGTH_DATASIZE;

hspi1.Init.NSSPMode = SPI_NSS_PULSE_DISABLED;

HAL_SPI_Init(&hspi1);

}


void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)

{



GPIO_InitTypeDef GPIO_InitStruct;

if (hspi->Instance == SPI1)

{

/* USER CODE BEGIN SPI1_MspInit 0 */



/* USER CODE END SPI1_MspInit 0 */

/* Peripheral clock enable */

__SPI1_CLK_ENABLE();

__GPIOA_CLK_ENABLE();


/**SPI1 GPIO Configuration 

PA4 ------> CS

PA5 ------> SPI1_SCK

PA6 ------> SPI1_MISO

PA7 ------> SPI1_MOSI 

*/

GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 |GPIO_PIN_7;


GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

GPIO_InitStruct.Alternate = GPIO_AF0_SPI1;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


/*Configure GPIO pins : PA4 for CS */

GPIO_InitStruct.Pin = ADC_PIN;

GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;

GPIO_InitStruct.Pull = GPIO_PULLUP;

GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;

HAL_GPIO_Init(ADC_GPIO_PORT, &GPIO_InitStruct);

}

}

My Setup and Main Function:


#include <
stm32f0xx_hal.h
>

#include ''SPI.h''


#define LOW 0

#define HIGH 1


void SysTick_Handler(void)

{

HAL_IncTick();

HAL_SYSTICK_IRQHandler();

}


void SystemClock_Config(void)

{

RCC_OscInitTypeDef RCC_OscInitStruct;

RCC_ClkInitTypeDef RCC_ClkInitStruct;

RCC_PeriphCLKInitTypeDef PeriphClkInit;


RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;

RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;

RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

HAL_RCC_OscConfig(&RCC_OscInitStruct);


RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;

RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI48;

RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1);


PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;

PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;

HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);


HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / 1000);


HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);


/* SysTick_IRQn interrupt configuration */

HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

}


int main(void)

{


uint8_t ad7124_id_reg = 0x45;

uint8_t id_reg_return_val = 0;


HAL_Init();

SystemClock_Config();

SPI1_Init_Mode3();

CS(HIGH);



for (;;)

{


CS(LOW);

HAL_SPI_Transmit(&hspi1, (uint8_t *) &ad7124_id_reg, 1, 5000);

HAL_SPI_Receive(&hspi1, (uint8_t *) &id_reg_return_val, 1, 5000);

while ((SPI1->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY)

;

CS(HIGH);


HAL_Delay(1000);

}

}

I've attached an image of the logic analyzer output
1 REPLY 1
rheb1026
Associate II
Posted on February 09, 2016 at 23:49

It seems that I've solved my own problem, but wanted to put up the solution for anyone else who may come across this. It's also a good working, basic SPI communication function.

uint8_t SPI_WriteRead (uint8_t data)
{
uint8_t rxbyte = 0;
HAL_SPI_TransmitReceive(&hspi1, (uint8_t *) &data, (uint8_t *) &rxbyte, 1, 5000);
while ((SPI1->SR & SPI_FLAG_BUSY) == SPI_FLAG_BUSY)
;
return rxbyte
}

And the function in use:

CS(LOW);
// Write command
SPI_WriteRead(ad7124_id_reg);
// Write dummy byte, return register value
id_reg_return_val = SPI_WriteRead(0xFF);
CS(HIGH);

Still not entirely sure why this works and the previous doesn't... possibly some bug in the HAL SPI Receive function