cancel
Showing results for 
Search instead for 
Did you mean: 

How to start a STM32 without active JTAG or SWD Pins....??

askansimon2
Associate II
Posted on October 17, 2011 at 20:07

Hello,

I use STM32 for several years, but know I dont know how to solve this problem.

When I start my STM32

int 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

Simon

11 REPLIES 11
Posted on October 17, 2011 at 20:50

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
askansimon2
Associate II
Posted on October 17, 2011 at 22:27

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

Simon

Posted on October 18, 2011 at 00:09

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?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
askansimon2
Associate II
Posted on October 18, 2011 at 12:17

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

simon

askansimon2
Associate II
Posted on October 18, 2011 at 12:26

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....

Posted on October 18, 2011 at 16:16

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.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
askansimon2
Associate II
Posted on October 18, 2011 at 23:29

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

Simon

Posted on October 19, 2011 at 14:06

Look at startup_stm32f10x_xx.s, and system_stm32f10x.c,SystemInit() 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
askansimon2
Associate II
Posted on October 19, 2011 at 19:47

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