[SOLVED] STM32F4 Hal: SPI problems: SPI sets itself to slave mode  - Page 1
Forum section: electronics / general

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 23, 2016, 08:28:08 pm
content: Dear all,I do apologize for the mundane and boring question, but unfortunately I am learning all this by myself, so I need some very basic help.I am using the Eclipse/GCC setup to develop a simple STM32F407 program to be able to communicate with the MPU9250.So I though a logical first step would be to try and spit out some data out of the pins. Here is my code:Code:#include <stdio.h>#include <stdlib.h>#include "diag/Trace.h"#include <stm32f4xx.h>#include <stm32f4xx_hal.h>#pragma GCC diagnostic push#pragma GCC diagnostic ignored "-Wunused-parameter"#pragma GCC diagnostic ignored "-Wmissing-declarations"#pragma GCC diagnostic ignored "-Wreturn-type"intmain(int argc, char* argv[]){__HAL_RCC_SPI1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();//PA4 NSS//PA5 SCK//PA6 MISO//PA7 MOSIGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_6;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);SPI_InitTypeDef SPI_InitStruct;SPI_InitStruct.Mode = SPI_MODE_MASTER;SPI_InitStruct.Direction = SPI_DIRECTION_2LINES;SPI_InitStruct.DataSize = SPI_DATASIZE_8BIT;SPI_InitStruct.CLKPolarity = SPI_POLARITY_HIGH;SPI_InitStruct.CLKPhase = SPI_PHASE_2EDGE;SPI_InitStruct.NSS = SPI_NSS_HARD_OUTPUT;SPI_InitStruct.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;SPI_InitStruct.FirstBit = SPI_FIRSTBIT_MSB;SPI_InitStruct.TIMode = SPI_TIMODE_DISABLE;SPI_InitStruct.CRCCalculation = SPI_CRCCALCULATION_DISABLE;SPI_HandleTypeDef SPI_MPU;SPI_MPU.Init = SPI_InitStruct;SPI_MPU.Instance = SPI1;HAL_SPI_Init(&SPI_MPU);trace_printf("Spi on \n");uint8_t t;uint8_t r;while(1){t = 0x1A;HAL_SPI_TransmitReceive(&SPI_MPU,&t,&r,1,1000);t = 0x00;HAL_SPI_TransmitReceive(&SPI_MPU,&t,&r,1,1000);trace_printf("Sent: %#x Received: %#x \n",0x1A,r);t = 0x1A | 0x80;HAL_SPI_TransmitReceive(&SPI_MPU,&t,&r,1,1000);t = 0xFF;HAL_SPI_TransmitReceive(&SPI_MPU,&t,&r,1,1000);trace_printf("Sent: %#x Received: %#x \n",0x1A | 0x80,r);}}#pragma GCC diagnostic popMy problem: When I probe the pins with my oscilloscope I get a square wave of around 12khz on the data lines and spiking on the clock, which seems to occur every transition of the data and every half period of the data.And In all honesty I dont know where to start debugging. I feel like the GPIO pins are setup correctly because something is coming out, but i dont know why it is not the signal I am looking for.On a different note, I am using semihosting on the stlink v2 and it is awfully slow (think a second per transmission slow). Am I doing something wrong? Is the stlink that slow? Is semihosting in general that slow? Any better options that are cheap? FTDI on a UART?Thank you for all your considerations, and please do scream at me for any malpractices etc. This forum is my only way to interact about this kind of stuff so the more I learn the better

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 23, 2016, 08:40:05 pm
content: Maybe do I need to poll something after the transmit method? I looked into the method and it seems like it already polls at the endThe Pictures:http://imgur.com/a/EE0gZCode:HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout){#ifdef USE_SPI_CRC__IO uint16_t tmpreg = 0U;#endifuint32_t tickstart = 0U;HAL_StatusTypeDef errorcode = HAL_OK;/* Check Direction parameter */assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));/* Process Locked */__HAL_LOCK(hspi);/* Init tickstart for timeout managment*/tickstart = HAL_GetTick();if(!((hspi->State == HAL_SPI_STATE_READY) || \((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->State == HAL_SPI_STATE_BUSY_RX)))){errorcode = HAL_BUSY;goto error;}if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)){errorcode = HAL_ERROR;goto error;}/* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */if(hspi->State == HAL_SPI_STATE_READY){hspi->State = HAL_SPI_STATE_BUSY_TX_RX;}/* Set the transaction information */hspi->ErrorCode = HAL_SPI_ERROR_NONE;hspi->pRxBuffPtr = (uint8_t *)pRxData;hspi->RxXferCount = Size;hspi->RxXferSize = Size;hspi->pTxBuffPtr = (uint8_t *)pTxData;hspi->TxXferCount = Size;hspi->TxXferSize = Size;/*Init field not used in handle to zero */hspi->RxISR = NULL;hspi->TxISR = NULL;#ifdef USE_SPI_CRC/* Reset CRC Calculation */if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE){SPI_RESET_CRC(hspi);}#endif/* Check if the SPI is already enabled */if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE){/* Enable SPI peripheral */__HAL_SPI_ENABLE(hspi);}/* Transmit and Receive data in 16 Bit mode */if(hspi->Init.DataSize == SPI_DATASIZE_16BIT){while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)){/* Check TXE flag */if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))){hspi->Instance->DR = *((uint16_t *)pTxData);pTxData += sizeof(uint16_t);hspi->TxXferCount--;#ifdef USE_SPI_CRC/* Enable CRC Transmission */if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)){SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);}#endif}/* Check RXNE flag */if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))){*((uint16_t *)pRxData) = hspi->Instance->DR;pRxData += sizeof(uint16_t);hspi->RxXferCount--;}if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)){errorcode = HAL_TIMEOUT;goto error;}}}/* Transmit and Receive data in 8 Bit mode */else{while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)){/* check TXE flag */if((hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))){*(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);hspi->TxXferCount--;#ifdef USE_SPI_CRC/* Enable CRC Transmission */if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)){SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);}#endif}/* Wait until RXNE flag is reset */if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))){(*(uint8_t *)pRxData++) = hspi->Instance->DR;hspi->RxXferCount--;}if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >= Timeout)){errorcode = HAL_TIMEOUT;goto error;}}}#ifdef USE_SPI_CRC/* Read CRC from DR to close CRC calculation process */if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE){/* Wait until TXE flag */if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK){/* Error on the CRC reception */SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);errorcode = HAL_TIMEOUT;goto error;}/* Read CRC */tmpreg = hspi->Instance->DR;/* To avoid GCC warning */UNUSED(tmpreg);}/* Check if CRC error occurred */if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)){SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);/* Clear CRC Flag */__HAL_SPI_CLEAR_CRCERRFLAG(hspi);errorcode = HAL_ERROR;}#endif/* Check the end of the transaction */if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK){SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);errorcode = HAL_ERROR;}error :hspi->State = HAL_SPI_STATE_READY;__HAL_UNLOCK(hspi);return errorcode;}

author: thm_w
author_rank: Super Contributor
timestamp: November 24, 2016, 12:46:01 am
content: Yes HAL function should be polling and wait for data, up until the timeout you've specified (1000).Where is your clock setup and HAL init? To determine if you are using PLL, internal external clock, what frequency, etc. Use cubemx to generate the clock setup code. ex:Code:/* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();stlink is usually quite fast, but I haven't used semihosting. You can try switching to j-link if you've confirmed problem is stlink (can upgrade, check jtag speed, etc.)I use breakpoint or live watch, but I think either method is good.I don't know what the default clock speed of F407 would be, so maybe its really slow if it hasn't been setup.You can also test if config is successful:Code:if (HAL_SPI_Init(&SPI_MPU) != HAL_OK){Error_Handler();}

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 24, 2016, 05:22:59 am
content: Quote from: thm_w on November 24, 2016, 12:46:01 amI am using the setup code generate by the eclipse plugin that is made for the disco4 board I am using.Here is the content of SystemClockConfig(void):Code:// Enable Power Control clock__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);#warning "Please check if the SystemClock_Config() settings match your board!"// Comment out the warning after checking and updating.RCC_OscInitTypeDef RCC_OscInitStruct;#if defined(HSE_VALUE) && (HSE_VALUE != 0)// Enable HSE Oscillator and activate PLL with HSE as source.// This is tuned for STM32F4-DISCOVERY; update it for your board.RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;// This assumes the HSE_VALUE is a multiple of 1 MHz. If this is not// your case, you have to recompute these PLL constants.RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE/1000000u);which is called here:Code:void__initialize_hardware(void){// Initialise the HAL Library; it must be the first function// to be executed before the call of any HAL function.HAL_Init();// Enable HSE Oscillator and activate PLL with HSE as sourceSystemClock_Config();// Call the CSMSIS system clock routine to store the clock frequency// in the SystemCoreClock global RAM location.SystemCoreClockUpdate();}The outside crystal is 8mhz.Could I probe the oscillator with an oscilloscope to confirm it is working, or would the extra capacitance from the tip screw it up? What kind of waveform would I excpect? I saw a very badly distorted sine/triangle wave at around 500Hz...

author: stfsux
author_rank: Contributor
timestamp: November 24, 2016, 01:18:07 pm
content: Before checking the data line, check if clock line has the correct baudrate.Check also your predefined macro (generally passed to the compiler command line (e.g. -D for gcc)).There are a lot of #ifdef #ifndef in stmlib for your specific architecture.

author: thm_w
author_rank: Super Contributor
timestamp: November 24, 2016, 07:36:18 pm
content: Any reason the initialize call is not in main function listed above? Did you leave it out or does the compiler include it automatically.You could probe the crystal or probe a buffered clock output:Code:HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1);Although I would try some other things first, and probe spi clock as stfsux noted.SPI1 is on APB1 or 2 prescaler, although you have not set it the default should be 1x. You also have the SPI_BAUDRATEPRESCALER_x if it needs to be any slower.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 02:26:18 pm
content: Quote from: thm_w on November 24, 2016, 07:36:18 pmQuote from: stfsux on November 24, 2016, 01:18:07 pmQuote from: thm_w on November 24, 2016, 12:46:01 amDear All,taking the advice I received I decided my best next steps would be to create a project using CubeMX, import it into eclipse/arm add a while loop that constantly sensd a increasigng number and then check the SPU clock rate. However, after I did this, my project is refusing to boot. As soon as the debug persepcive opens I am stuck in the Hardwarefault Handler. The board is fine, I tested with previously know good projects/code.My best guess is that the startup code from cubemx is bad, or I screwed up while importing it (more likely). Any ideas on how to debug the HardwareFault?Any Idea on how I can best share the code/setup I have?

author: Brutte
author_rank: Frequent Contributor
timestamp: November 27, 2016, 03:05:12 pm
content: Quote from: BurnedResistor on November 27, 2016, 02:26:18 pmIt is not HardwareFault but HardFault handler (just to help you google that).

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 04:18:55 pm
content: Yup:) Thanks for helping me catch that typo

author: tatus1969
author_rank: Super Contributor
timestamp: November 27, 2016, 05:32:46 pm
content: have you compared your solution against the SPI demo project that normally comes with the ST HAL package?

author: jmsigler
author_rank: Regular Contributor
timestamp: November 27, 2016, 06:52:07 pm
content: I had the same problem when I was using plain gnrarmeclipse. I ended up switching to a method outlined in the book mastering stm32, which fixed my problem.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 07:09:32 pm
content: Quote from: jmsigler on November 27, 2016, 06:52:07 pmThats what I have been followingI decided to say screw it at switch to Atollic Free. short of printf it has everything I need and I am sick of dicking around with eclipse...So I imported everything in atollic from cubeMX (which took all of 10 seconds I am in heaven)But I am still not able to produce a clock from the SPI port...However, a bit of progress: I managed to output the HSE to the clock out pin and I am getting 8mhz! Wohoo!Is there any way of accesing the system or peripheral clock? RCC_MCO1SOURCE_PLLCLK flag did nothing in Hal.. pint at gndAlright, here is my code:the main function where the CLock, SPI and GPIO init functions are called, plus the infinte spi loopCode:/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration----------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* Configure the system clock */SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();MX_SPI1_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */uint8_t t = 0;uint8_t r = 0;while (1){t++;/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_SPI_TransmitReceive(&hspi1,&t,&r,1,3);}/* USER CODE END 3 */}[\code]Here is the Clock intialization:void SystemClock_Config(void){RCC_OscInitTypeDef RCC_OscInitStruct;RCC_ClkInitTypeDef RCC_ClkInitStruct;/**Configure the main internal regulator output voltage*/__HAL_RCC_PWR_CLK_ENABLE();__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);/**Initializes the CPU, AHB and APB busses clocks*/RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE;RCC_OscInitStruct.HSEState = RCC_HSE_ON;RCC_OscInitStruct.HSIState = RCC_HSI_ON;RCC_OscInitStruct.HSICalibrationValue = 16;RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;RCC_OscInitStruct.PLL.PLLM = 8;RCC_OscInitStruct.PLL.PLLN = 330;RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;RCC_OscInitStruct.PLL.PLLQ = 4;if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK){Error_Handler();}/**Initializes the CPU, AHB and APB busses clocks*/RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK|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();}HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_PLLCLK, RCC_MCODIV_1);/**Configure the Systick interrupt time*/HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);/**Configure the Systick*/HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);/* SysTick_IRQn interrupt configuration */HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);}[\code]GPIO and SPI init:/* SPI1 init function */static void MX_SPI1_Init(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_LOW;hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;hspi1.Init.NSS = SPI_NSS_HARD_INPUT;hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128;hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;hspi1.Init.TIMode = SPI_TIMODE_DISABLE;hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;hspi1.Init.CRCPolynomial = 10;if (HAL_SPI_Init(&hspi1) != HAL_OK){Error_Handler();}}/** Configure pins as* Analog* Input* Output* EVENT_OUT* EXTIPA8 ------> RCC_MCO_1*/static void MX_GPIO_Init(void){GPIO_InitTypeDef GPIO_InitStruct;/* GPIO Ports Clock Enable */__HAL_RCC_GPIOH_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin : PA8 */GPIO_InitStruct.Pin = GPIO_PIN_8;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;GPIO_InitStruct.Alternate = GPIO_AF0_MCO;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);}[\code]And finally the spi hardware init called from the SPI_init hal function: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 */__HAL_RCC_SPI1_CLK_ENABLE();/**SPI1 GPIO ConfigurationPA4 ------> SPI1_NSSPA5 ------> SPI1_SCKPA6 ------> SPI1_MISOPA7 ------> SPI1_MOSI*/GPIO_InitStruct.Pin = GPIO_PIN_4|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_FREQ_VERY_HIGH;GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* USER CODE BEGIN SPI1_MspInit 1 *//* USER CODE END SPI1_MspInit 1 */}}[\code]Making progress :)

author: jmsigler
author_rank: Regular Contributor
timestamp: November 27, 2016, 07:51:27 pm
content: You may have to add _HAL_SPI_ENABLE(&hspi) or something similar? I remember an enable function for spi, but I'm pretty sure that it would still work even if you didn't call this so maybe that isn't your problem.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 08:25:26 pm
content: Quote from: jmsigler on November 27, 2016, 07:51:27 pmHmm.... I just added but no cigar...

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 08:31:27 pm
content: Upon further inspection, the Transmit function actually makes sure it is enabeled:Code:if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE){/* Enable SPI peripheral */__HAL_SPI_ENABLE(hspi);}I also just debug-single stepped through the code, the spi config regs are definetly being written to. I have not checked them against my setup yet!

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 27, 2016, 08:35:53 pm
content: Also just checked that the Hal is not timing out.....

author: thm_w
author_rank: Super Contributor
timestamp: November 28, 2016, 10:43:12 pm
content: Can you get the return value of the HAL function? Does it return an error, it should be timeout due to nothing received I would assume?QuoteI'm using:QuoteBut my code does not expect any reply. If you just want to blast data out, it might be worth trying.Although it looks like what you have is OK. You could check the SPI regs if there is an enable clock or power on, etc.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 30, 2016, 09:02:35 pm
content: Quote from: thm_w on November 28, 2016, 10:43:12 pmOh. It seems the hal is timing out! it returns HAL_TIMEOUT!Two possible options: The systick is not working causing it to timeout immediatlyThe spi is not setup correctly and does not return :/

author: BurnedResistor
author_rank: Regular Contributor
timestamp: November 30, 2016, 09:06:15 pm
content: Just confirmed that it is not the systick....

author: thm_w
author_rank: Super Contributor
timestamp: November 30, 2016, 11:23:45 pm
content: But do you have something connected that will return a response?If not use the transmit only function. Or even use it for now for debugging.The transmit should not return timeout unless something was really wrong.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: December 01, 2016, 04:42:46 am
content: Quote from: thm_w on November 30, 2016, 11:23:45 pmCode:uint8_t t = 0;hspi1.Instance->CR1 |= SPI_CR1_SPE;volatile HAL_StatusTypeDef state;while (1){t++;/* USER CODE END WHILE *//* USER CODE BEGIN 3 */state = HAL_SPI_Transmit(&hspi1, &t, 1, 100);asm volatile("mov r0, r0");asm volatile("mov r0, r0");asm volatile("mov r0, r0");asm volatile("mov r0, r0");asm volatile("mov r0, r0");}I am break pointing on the last NOP because I wanted to make sure the debug was not interfering with the systick timer on which the timeout is based!Still returning HAL_TIMEOUT!I am at a loss. I hope I will have time to sit my ass down, and compare the values in the SPI regs against the datasheet! Any other ideas about what could be wrong?Out of curiosity, would a spi transmit receive call without anything attached work but read 0 in return as there is no acknowledge built into the protocol?

author: BurnedResistor
author_rank: Regular Contributor
timestamp: December 01, 2016, 06:06:08 am
content: Just checked, on the disco 4 board I am using the spi bus is connected to a MEMS device. However that should not cause it to timeout?I dont need any of the other devices on the board, so I might just cut the traces for good measure. Sadly no jumpers to do so:(...WTF?For some reason the SPI periph's Master/Slave bit is set to master after the init, but cleared during the Transmit call?...Further narrowed it down. Appearantly enabeling the SPI peripheral:Code:hspi1.Instance->CR1 |= SPI_CR1_SPE;Does not enable it, but disables master mode! I did check the SPI_CR1_SPE is the correct bitmask!Nothing on the ST errate for the chip...

author: tatus1969
author_rank: Super Contributor
timestamp: December 01, 2016, 07:13:50 am
content: does your code contaion concurrent access, like main+interrupt, or multithreading?

author: BurnedResistor
author_rank: Regular Contributor
timestamp: December 01, 2016, 07:47:26 am
content: Quote from: tatus1969 on December 01, 2016, 07:13:50 amnope.It only contains the spi handler

author: Jeroen3
author_rank: Super Contributor
timestamp: December 01, 2016, 09:05:55 am
content: I noticed you had to set the SSM bit for MSTR and SPE to stay engaged. Makes sense if you think about it.Code:__HAL_RCC_SPI2_FORCE_RESET();__NOP();__HAL_RCC_SPI2_RELEASE_RESET();SPI2->CR1 |= (4<<SPI_CR1_BR_Pos);SPI2->CR1 |= SPI_CR1_SSM; // Software chip selectSPI2->CR1 |= SPI_CR1_SSI;SPI2->CR1 |= SPI_CR1_MSTR | SPI_CR1_SPE;Btw: this is all init required for master mode.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: December 01, 2016, 11:00:19 am
content: Quote from: Jeroen3 on December 01, 2016, 09:05:55 amOh wow! That did itThank you so much!Not noted in the cube mx anywhere, what agreatpiece of softwareThank you all for your help!For future reference, I will attach the final working code

author: Jeroen3
author_rank: Super Contributor
timestamp: December 02, 2016, 01:40:52 pm
content: I try to avoid hal and cube as much as possible. It is included when starting, but converted to save ROM and complexity.Only the headers stay inluded for the definitions, and the rcc. Since that is usually working fine, and significantly complicated.

author: BurnedResistor
author_rank: Regular Contributor
timestamp: December 03, 2016, 12:12:38 pm
content: Quote from: Jeroen3 on December 02, 2016, 01:40:52 pmI am planning on implementing the project with the cube hal, to gain an understanding of what the exact requirements for me are, and then write my own HAL which perfecty meets those requirements. I tried going straight to that, but this is my first time developing such a big project and on this platform so I did not get far!Interestingly I did not see the whole SSM bit business anywhere in the datasheet nor reference manual!Fun times....Thank you everybody for helping!

author: Jeroen3
author_rank: Super Contributor
timestamp: December 03, 2016, 01:08:30 pm
content: Quote from: BurnedResistor on December 03, 2016, 12:12:38 pmNot quite true.QuoteThese things make mcu development hell sometimes. There is this peripheral that only works if you set some bit in specific way, described only at one place in the middle of the text. Which you didn't read since you skipped to the registers immediately.Goodluck!

author: Geryboy666
author_rank: Newbie
timestamp: March 14, 2017, 12:30:39 pm
content: I had the same problem, STM32F411RE, Gnu Arm Eclipse HAL Lib 1.4.xxHowever the problem wasn't enabling any Bits in the Control Registers...1st I got a Timeout Error because my Baudratescaler was to small, I used 2 and got Timeouts, then I used 64 which was fine.In the inital post his MISO PIN was declared Input, however all 3 PINS, MISO, MOSI, SCK need to be AF_PP in MODE, and AF5_SPIx in Alternate.then use NSS as Software, and declare another random GPIO PIN as NSS and select the Slave via your own Code.Code://GLOBAL VARSPI_HandleTypeDef SPI_Handle; // global fuer ISRintmain(int argc, char* argv[]){// CLKs Enable__HAL_RCC_SPI1_CLK_ENABLE(); // MUSS an sein, ist richtig__HAL_RCC_GPIOA_CLK_ENABLE();// SPI Config startSPI_Handle.Instance = SPI1; // D13 bis D11SPI_Handle.Init.Mode = SPI_MODE_MASTER;SPI_Handle.Init.Direction = SPI_DIRECTION_2LINES; // transmit and receiveSPI_Handle.Init.DataSize = SPI_DATASIZE_8BIT; // 8 bit PacketeSPI_Handle.Init.CLKPolarity = SPI_POLARITY_LOW; // idle @ low stateSPI_Handle.Init.CLKPhase =SPI_PHASE_1EDGE; // Phase = 0, rising edge = sampleSPI_Handle.Init.NSS = SPI_NSS_SOFT;SPI_Handle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64;SPI_Handle.Init.FirstBit = SPI_FIRSTBIT_MSB;SPI_Handle.Init.TIMode = SPI_TIMODE_DISABLE; // Motorola standard verwendenSPI_Handle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;SPI_Handle.Init.CRCPolynomial =0;// SPI Config end// SPI Initif (HAL_SPI_Init(&SPI_Handle)!= HAL_OK){printf("Fehler bei SPI Init\n");}// Interrupt enableHAL_NVIC_SetPriority(SPI1_IRQn, 2,1);HAL_NVIC_EnableIRQ(SPI1_IRQn);// GPIO Config start// CLK,MISO,MOSIGPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_PIN_9; // D8GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_5| GPIO_PIN_6 |GPIO_PIN_7; // D13 = CLK, A2 = NSS , D11 = MOSI, D12 = MISOGPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // Push PullGPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;//GPIO InitHAL_GPIO_Init(GPIOA,&GPIO_InitStruct);//varconst uint32_t timeout = 100;const uint16_t SIZE = 3; // Puffergroeße = 1 Bytedouble temp;HAL_StatusTypeDef HAL_Status; // 0 = ok, 1 = Error, 2 = Busy, 3 = timeoutHAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); // Slave sleepwhile (1){uint8_t transmit = {0b00000110, 0b00000000, 0b00000000};uint8_t receive  = {0,0,0};HAL_Delay(2000);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); // Slave wake upif( (HAL_Status = HAL_SPI_TransmitReceive(&SPI_Handle,&transmit,&receive,SIZE,timeout)) != HAL_OK){printf("1st TransmitReceive Error: %d\n", HAL_Status);}HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); // Slave sleep//temp = (receive2 <<8) | receive3; // 12 BIT ADC Wert zusammenfuegenprintf("Receive: %d\t%d\n", receive, receive ); // debugprintf("Transmit: %d\t%d\t %d\n", transmit,transmit,transmit ); // debugprintf("Temp = %f\n", temp); // debugprintf("SIZE = %d\n", SIZE);//temp = (temp *500.0)/4096; // 5 V Ref, 1°C pro 10mV => 500/2^12//printf("Temp = %f\n", temp);}}this codes makes the nucleo master, and uses the MCP3208 as Slave, which reads out a Temp sensor on Channel 0. The 1st Transfer Byte is the setup, the 2nd is the channel select, the 3rd is 0 to give the IC enough clocks. The 2nd and 3rd Receive Bytes are the result.