Hi Does anybody have a working example of an STM32F407VG reading and or writing an SD card using SPI3.
I have tried everything but always fails on mount with fsMediaError am at my wits end, i have even tried to follow example http://www.keil.com/appnotes/files/apnt_273.pdf and still not working.
The OP isn't using the JTAG pins, got F1 board that does and you need to disable Full JTAG
LED = PB1 LED = PB2 CS = PD3 SCK = PC10 MISO = PC11 MOSI = PC12
HSE = 25 MHZ SYSCLK = 150 MHZ
SPI3 = APB1 = 37.5 MHZ?
I don't know what board this is, and don't have resources to fool with. Would suggest dissecting clocks and peripheral register settings in viewer.
Probably a silly question but how do I do this? I was looking for the JTAG disable about 3 weeks ago. Could not find it in data sheet so assumed I was wrong.
On the F1, I used this to free SPI2 on PB13,14 and 15 while keeping SWD/SWV viable, not salient on F4
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); /* JTAG-DP Disabled and SW-DP Enabled */ GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
On the F2/F4 GPIO_AF_SWJ and GPIO_AF_TRACE is zero, so should be able to mux off functionality
Thanks, looking at data sheet it says jtag is not for PC10,11,12 but pb3 and 4. Does jtag effect spi3 or the specific pins?
Ok, let's not get distracted by pins John selected. The PB3 pin is problematic, as are the pins I mentioned on the STM32F1.
The pin muxing on the F2/F4 is far more flexible, the pins you mentioned should not conflict with JTAG.
That's what I was thinking, so I still am stuck on why I can't get the SD card to mount.
Do we have any other ideas?
Ok, so if I understood correctly the same hardware configuration worked with another compiler, and using Keil and its libraries you don't see signals at the pins, and you don't have a working card. There's an interference that it works on a different SPI bus.
I'm not yet convinced that the clocks, peripherals and pins are correctly configured, you've made declarative statements that they are correct, but you're also man-weeks into "not working". Beyond that you'd need to dig into the middleware code itself. I'm not looking to wade into this with my own resources, or build equivalent hardware, if you have code to present I'll look at that, guessing isn't my game.
Clock Config
void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct; /**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_HSE|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 25; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLQ = 7; 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(); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } /**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, 15, 15); }
SPI Config
/* SPI3 init function */ static void MX_SPI3_Init(void) { hspi3.Instance = SPI3; hspi3.Init.Mode = SPI_MODE_MASTER; hspi3.Init.Direction = SPI_DIRECTION_2LINES; hspi3.Init.DataSize = SPI_DATASIZE_8BIT; hspi3.Init.CLKPolarity = SPI_POLARITY_LOW; hspi3.Init.CLKPhase = SPI_PHASE_1EDGE; hspi3.Init.NSS = SPI_NSS_SOFT; hspi3.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; hspi3.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi3.Init.TIMode = SPI_TIMODE_DISABLE; hspi3.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi3.Init.CRCPolynomial = 10; if (HAL_SPI_Init(&hspi3) != HAL_OK) { Error_Handler(); } __SPI3_CLK_ENABLE(); }
GPIO Config
static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOH_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOD, GPIO_PIN_3, GPIO_PIN_RESET); /*Configure GPIO pins : PB0 PB1 PB2 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PD3 */ GPIO_InitStruct.Pin = GPIO_PIN_3; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOD, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; GPIO_InitStruct.Alternate = GPIO_AF6_SPI3; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); }
Blink Thread - This Flashes every Second
/* USER CODE BEGIN 4 */ void Blink(void const *arg){ while (1){ osDelay(1000); HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_0); WriteFile(); } }
It calls the writefile routine which should mount the card but fails.
int32_t fs_mc_spi_control_ss (uint32_t drive_num, uint32_t ss){ if (ss==0) { HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_SET); return 1; } else { HAL_GPIO_WritePin(GPIOD,GPIO_PIN_3,GPIO_PIN_RESET); return 0; } } void WriteFile() { fsStatus st; if (finit("") == fsOK) { st=fmount(""); if (st == fsOK) HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1); ; } FILE *f=fopen("try.txt","a"); if (f!=NULL) { HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_2); fprintf(f,"Test\n"); fclose(f); } }
The fs_mc_spi_control_ss function is setting the CS pin, I have tried reversing polarity. Also tried to lengthen the delay on the thread.
Thanks so much for your time.
Enable the clock before you initialize the interface, the part is synchronous
__SPI3_CLK_ENABLE(); // DO IT BEFORE
OK, I tried moving the __SPI3_CLK_ENABLE(); Still no luck, could cry at this point :(