2011-10-17 11:07 AM
Hello,
I use STM32 for several years, but know I dont know how to solve this problem. When I start my STM32int main(void) { RCC_Configuration(); NVIC_Configuration(); GPIO_Configuration(); ADC_Configuration(); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are availble UART_Configuration(); if (SysTick_Config(SystemFrequency / 1000)) { while (1) {;} } // Pins Off GPIOA->BRR = (GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15); GPIOB->BRR = (GPIO_Pin_4 | GPIO_Pin_5);
I have to remap JTMS/SWDIO Pins. Later I put all Pins to Off. But it is too late. PA13 has Main-Function ''JTMS/SWDIO'' and PA15 ''JTCK/SWCLK'', PA13 always starts with On, for a secound. This makes problems with additional electronic.... Does anybody know, how to start up a STM32, without active ''JTMS/SWDIO'' and ''JTCK/SWCLK'' Pin? Thank you very mutch. Best Regards Simon2011-10-17 11:50 AM
I'm not sure you can completely eliminate the pin issue at start up. You can however reduce the window significantly by doing the minimal about of work to configure the pin and remapping prior to doing all the other initialization, setting other clocks, PLL, and other things that may be delaying you ability to set up the pins.
2011-10-17 01:27 PM
Oh, this not enough. As soon as the Pins are on, at startup, electronic will
produce error. To minimize the time, will not solve the problem. What a bad thing, for us it is a very important information, that remap will not work before startup. Does anyboday have other information, is it possible to contact a STM32 Support or something. When we cant solve this (design and production is done....) we have realy big problem. Thank you Simon2011-10-17 03:09 PM
I doubt ST can change their hardware to accommodate your issue.
Normally you need to add external gating, or have hardware that can be brought up by the system when it is ready/stable. Do you have a few hundred micro-seconds of tolerance, or zero tolerance? What exactly do you have hung off here that is dependent?2011-10-18 03:17 AM
Hello clive1,
it is a servo (from rc models). This servo will move, if it get signal ON on startup, these servos measure the on length fom 1ms to 2ms (from left to right), and now will move to full right on startup Can I deactivate PORTA without calling RCC or GPIO first? Do you know this. I test it with lib function but this dont work. thank you simon2011-10-18 03:26 AM
The shortes way, I found is this
static void RCC_Configuration(void) { //ErrorStatus HSEStartUpStatus = SUCCESS; RCC_DeInit(); // RCC system reset(for debug purpose) RCC_HSEConfig(RCC_HSE_ON); // Enable HSE HSEStartUpStatus = RCC_WaitForHSEStartUp(); // Wait till HSE is ready if (HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); // Enable Prefetch Buffer FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2 RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4); // PLLCLK = 16MHz * 4 = 64 MHz RCC_PLLCmd(ENABLE); // Enable PLL while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) { } // Wait till PLL is ready RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source while(RCC_GetSYSCLKSource() != 0x08) { } // Wait till PLL is used as system clock source } else { // If HSE fails to start-up, the application will have wrong clock configuration. // User can add here some code to deal with this error while(1) { } } RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4 | RCC_APB1Periph_USART3 , ENABLE); // RCC_APB1Periph_I2C1 | RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE | RCC_APB2Periph_USART1 | RCC_APB2Periph_ADC1 | RCC_APB2Periph_AFIO, ENABLE); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); } static void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // SERVO OUTPUT // PA8 = SOUT1 | PA11 = SOUT2 | PA12 = SOUT3 | PA13 = SOUT4 | // PA14 = SOUT5 | PA15 = SOUT6 | PB4 = SOUT7 | PB5 = SOUT8 // SOUT4 (TMS/SWDIO), SOUT6 (JTDI) , SOUT7 (JNTRST) ist beim einschalten ON GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are availble GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIOA->BRR = (GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15); // ServoPins aus GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIOB->BRR = (GPIO_Pin_4 | GPIO_Pin_5); // ServoPins aus //........ } int main(void) { RCC_Configuration(); GPIO_Configuration(); //.... }
but will need ~ 0,5secounds....2011-10-18 07:16 AM
The issue here, as I pointed out earlier, is that you're horsing around with the HSE, PLL, selecting the PLL. You are spinning in loops waiting for crystals to start and PLL's to lock, all eating lots of time, probably easily in the high milli seconds, half a second seems like an age, but you've timed it.
Remember, the system boots up off the 8 MHz HSI and is immediately viable at that speed. Personally, I'd put this is assembler in the reset vector, but the functional equivalent of this : static void RCC_PreInit(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are availble GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIOA->BRR = (GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15); // ServoPins aus } int main(void) { RCC_PreInit(); RCC_Configuration(); GPIO_Configuration(); ... Now this presupposes you're using a FW library version that isn't calling other RCC startup code prior to calling main(). The older 2.x ones did not, you might want to check and understand what yours is doing.2011-10-18 02:29 PM
Dear Clive1,
thank you very mutch for you help. I have test the shorter version, but I it is nearly the same, 0,5 secounds delay with the pins, so I think I have code before main().... It is a STM32F103C8, Compiler is Sourcery G++ Lite, I use - STM32F10x_StdPeriph_Driver and CMSIS V3.1.0 ## used parts of the STM-Library SRC += $(STMSPDSRCDIR)/stm32f10x_dma.c SRC += $(STMSPDSRCDIR)/stm32f10x_flash.c SRC += $(STMSPDSRCDIR)/stm32f10x_gpio.c SRC += $(STMSPDSRCDIR)/stm32f10x_pwr.c SRC += $(STMSPDSRCDIR)/stm32f10x_rcc.c SRC += $(STMSPDSRCDIR)/stm32f10x_spi.c SRC += $(STMSPDSRCDIR)/stm32f10x_usart.c SRC += $(STMSPDSRCDIR)/stm32f10x_rtc.c SRC += $(STMSPDSRCDIR)/stm32f10x_bkp.c SRC += $(STMSPDSRCDIR)/misc.c SRC += $(STMSPDSRCDIR)/stm32f10x_tim.c SRC += $(STMSPDSRCDIR)/stm32f10x_adc.c SRC += $(STMSPDSRCDIR)/stm32f10x_exti.c SRC += $(STMSPDSRCDIR)/stm32f10x_i2c.c SRC += $(STMSPDSRCDIR)/stm32f10x_iwdg.c SRC += $(STMSPDSRCDIR)/stm32f10x_wwdg.c - Fat SD (SD Card Libary) - R0.07c - minIni (INI file parser Libary) - Version 2.0 I am not an expert for STM32, I dont know that it is possible, that any code runs befor main() function..... Do you know which part of the software is able to run before main() function? Or do you think, i should replace STM32F10x_StdPeriph_Driver 3.0 with 2.0? Best Regards Simon2011-10-19 05:06 AM
Look at startup_stm32f10x_xx.s, and system_stm32f10x.c,SystemInit()
2011-10-19 10:47 AM
Thank you very mutch, I think I found the 0,5 Secounds.
/** ****************************************************************************** * @file system_stm32f10x.c * @author MCD Application Team * @version V3.1.0 * @date 06/19/2009 * @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File. ****************************************************************************** * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * * © COPYRIGHT 2009 STMicroelectronics ****************************************************************************** */ /** * @brief Setup the microcontroller system * Initialize the Embedded Flash Interface, the PLL and update the SystemFrequency variable. * @note This function should be used only after reset. * @param None * @retval None */ void SystemInit (void) { /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */ #ifndef STM32F10X_CL RCC->CFGR &= (uint32_t)0xF8FF0000; #else RCC->CFGR &= (uint32_t)0xF0FF0000; #endif /* STM32F10X_CL */ /* Reset HSEON, CSSON and PLLON bits */ RCC->CR &= (uint32_t)0xFEF6FFFF; /* Reset HSEBYP bit */ RCC->CR &= (uint32_t)0xFFFBFFFF; /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */ RCC->CFGR &= (uint32_t)0xFF80FFFF; #ifndef STM32F10X_CL /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x009F0000; #else /* Reset PLL2ON and PLL3ON bits */ RCC->CR &= (uint32_t)0xEBFFFFFF; /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00FF0000; /* Reset CFGR2 register */ RCC->CFGR2 = 0x00000000; #endif /* STM32F10X_CL */ /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClockTo64(); } /** * @brief Sets System clock frequency to 56MHz and configure HCLK, PCLK2 * and PCLK1 prescalers. * @note This function should be used only after reset. * @param None * @retval None */ static void SetSysClockTo64(void) { __IO uint32_t StartUpCounter = 0, HSEStatus = 0; /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/ /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Enable Prefetch Buffer */ FLASH->ACR |= FLASH_ACR_PRFTBE; /* Flash 1 wait state */ FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY); FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; #ifdef STM32F10X_CL /* Configure PLLs ------------------------------------------------------*/ /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */ /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */ RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL | RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC); RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 | RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5); /* Enable PLL2 */ RCC->CR |= RCC_CR_PLL2ON; /* Wait till PLL2 is ready */ while((RCC->CR & RCC_CR_PLL2RDY) == 0) { } /* PLL configuration: PLLCLK = PREDIV1 * 4 = 64 MHz */ RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL4); #else /* PLL configuration: PLLCLK = HSE * 4 = 64 MHz */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL)); RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL4); #endif /* STM32F10X_CL */ /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0) { } /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08) { } } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ /* Go to infinite loop */ while (1) { } } }
But know I have the questions, how to call the remap before SystemInit() is called.void SystemInit (void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE); // Disable JTAG/SWD so pins are availble GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIOA->BRR = (GPIO_Pin_8 | GPIO_Pin_14 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_15); // ServoPins aus /* Reset the RCC clock configuration to the default reset state(for debug purpose) */ /* Set HSION bit */ RCC->CR |= (uint32_t)0x00000001; //......
But this wont work. (Remap dont work without any compiler error.) Do you have an idea, how to solve this? Do I need 2.0 Software-Lib? Thank you very mutch Simon