2016-02-09 11:03 AM
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
2016-02-09 02:49 PM
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