cancel
Showing results for 
Search instead for 
Did you mean: 

Program upload and Erase from IAR not working

lv9
Associate II
Posted on October 03, 2011 at 16:49

I've been using this forum to get started with my STM32VLDiscovery board and EWARM6, and it really helped me out. Thank you all very much.

I have an issue now, though. I have 2 VL Discovery boards, used to play with one of them, the other is still new. After a couple of weeks, during a standard flashing procedure, something went wrong and the flashing was terminated with an error. If i try to perform it again, it shows an error that the flash program can't be started. I close the IAR and reopen it, start the flashing procedure - and the board starts blinking with the comms led endlessly. if i click on cancel, it stops blinking, and again i have to reopen the IAR to perform another attempt. Same thing happens with Erase function. Tried different computers.

I took the new board, it flashed once, and on the second time did the same thing. Nevertheless, Erase function worked well with it, but now i'm kind of afraid to go on and use it, it is my last board.

I tried using the boot pin as i saw on one of the posts, didn't help.

Is my board dead? What can be wrong?

Thanks!

#flash-erasing-programming #stm32vldiscovery
5 REPLIES 5
Posted on October 03, 2011 at 17:41

Then consider adding some code very close to the reset vector that checks an external GPIO pin and then spins in a loop rather than executing your potentially broken code. A breakout/recovery switch if you will.

The ST-LINK is not very good at wrestling control of the processor at reset, consequently there are a number of things you can do that will effectively brick the board. There are typically TWO solutions to this, a) use the BOOTx pins so your code doesn't run, or b) use the BOOTx pins and attach a serial port to PA9/PA10 and use the serial boot loader.

You could also try wiring up a more expensive JTAG pod to the board, but that kind of defeats the point.

Check also that you have current drivers and firmware for the ST-LINK, and try using the ST-LINK utilities. There was a firmware update for it, I would definitely check that out.

Add some functionality to you code to erase your firmware, or download some new firmware. Probably want a serial port to do that, but it's very helpful for debugging/telemetry.

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

I have tried different things, however the only thing i could do to return the discovery board to operation was replacement of the main cortex controller. It worked, until i done the same mistake again. The program i burn in is a simple mixture of two examples by ST, and is supposed to have two outputs with triangular waves, and read an array from ADC through DMA. Then i connect the triangular wave output physically to the ADC input, and watch the array filled with correct values in the debugger. This is just a test, and it works - but after flashing it to the board it can be even debugged, but never reprogrammed or erased. I feel it's very important for me to understand why, since i've done plenty of playing with the examples and their clones. Any idea?

#include ''stm32f10x.h''

#define ADC1_DR_Address    ((uint32_t)0x4001244C)

ADC_InitTypeDef ADC_InitStructure;

DMA_InitTypeDef DMA_InitStructure;

__IO uint16_t ADCConvertedValue[0xFF];

DAC_InitTypeDef            DAC_InitStructure;

TIM_TimeBaseInitTypeDef    TIM_TimeBaseStructure;

void RCC_Configuration(void);

void GPIO_Configuration(void);

int main(void)

{

  RCC_Configuration();

  GPIO_Configuration();

  /* DMA1 channel1 configuration ----------------------------------------------*/

  DMA_DeInit(DMA1_Channel1);

  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;

  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;

  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

  DMA_InitStructure.DMA_BufferSize = 0xFF;

  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

  DMA_InitStructure.DMA_Priority = DMA_Priority_High;

  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  /* Enable DMA1 channel1 */

  DMA_Cmd(DMA1_Channel1, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

  ADC_InitStructure.ADC_ScanConvMode = ENABLE;

  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;

  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfChannel = 1;

  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel14 configuration */ 

  ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5);

  /* Enable ADC1 DMA */

  ADC_DMACmd(ADC1, ENABLE);

    /* Enable ADC1 */

  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibaration register */   

  ADC_ResetCalibration(ADC1);

  /* Check the end of ADC1 reset calibration register */

  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */

  ADC_StartCalibration(ADC1);

  /* Check the end of ADC1 calibration */

  while(ADC_GetCalibrationStatus(ADC1));

  /* Start ADC1 Software Conversion */ 

  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  TIM_TimeBaseStructInit(&TIM_TimeBaseStructure);

  TIM_TimeBaseStructure.TIM_Period = 25;          

  TIM_TimeBaseStructure.TIM_Prescaler = 2;       

  TIM_TimeBaseStructure.TIM_ClockDivision = 0x0;    

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  

  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  /* TIM2 TRGO selection */

  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_Update);

  /* DAC channel1 Configuration */

  DAC_InitStructure.DAC_Trigger = DAC_Trigger_T2_TRGO;

  DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_Triangle;

  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_2047;

  DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Disable;

  DAC_Init(DAC_Channel_1, &DAC_InitStructure);

  /* DAC channel2 Configuration */

  DAC_InitStructure.DAC_LFSRUnmask_TriangleAmplitude = DAC_TriangleAmplitude_1023;

  DAC_Init(DAC_Channel_2, &DAC_InitStructure);

  /* Enable DAC Channel1: Once the DAC channel1 is enabled, PA.04 is 

     automatically connected to the DAC converter. */

  DAC_Cmd(DAC_Channel_1, ENABLE);

  /* Enable DAC Channel2: Once the DAC channel2 is enabled, PA.05 is 

     automatically connected to the DAC converter. */

  DAC_Cmd(DAC_Channel_2, ENABLE);

  /* Set DAC dual channel DHR12RD register */

  DAC_SetDualChannelData(DAC_Align_12b_R, 0x100, 0x100);

  /* TIM2 enable counter */

  TIM_Cmd(TIM2, ENABLE);

  while (1)

  {

  }

}

void RCC_Configuration(void)

{

  RCC_ADCCLKConfig(RCC_PCLK2_Div8); 

  /* Enable peripheral clocks ------------------------------------------------*/

  /* Enable DMA1 clock */

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

  /* Enable ADC1 and GPIOC clock */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC, ENABLE);

  /* GPIOA Periph clock enable */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  /* DAC Periph clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE);

  /* TIM2 Periph clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

}

void GPIO_Configuration(void)

{

  GPIO_InitTypeDef GPIO_InitStructure;

  /* Configure PC.04 (ADC Channel14) as analog input -------------------------*/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_4 | GPIO_Pin_5;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

}

#ifdef  USE_FULL_ASSERT

void assert_failed(uint8_t* file, uint32_t line)

  /* Infinite loop */

  while (1)

  {

  }

}

#endif

Posted on October 07, 2011 at 13:54

It's because you're ploughing directly into the DMA configuration, a device that generates constant bus traffic externally to the core. This interferes with the ability of the JTAG to wrestle control away from your code in the hundreds of thousand of cycles that might take to achieve.

After you configure the GPIO, wait for a couple of seconds before proceeding, or check for an external button press on one of the GPIO pins.

It's surprising that using the BOOTx pins can't recover the part.

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

Thank you for the quick reply, again. I will definitely try that, if i succeed to recover the boards. Any link to using BOOTx pins to do that? Thanks!!

Update - I kept reading through the posts and got it. Applying 3.3v on the BOOT pin on the discovery board doesn't let the program to start running after a reset and lets me reprogram the damn thing. Clear.

This happens (and not only to me as i have noticed) when using the ADC. Any way to resolve it somehow?

Thanks for your help!!!
Posted on October 08, 2011 at 19:25

Others have seen problems with DMA+ADC, I've seen it with DMA+TIM generating PWM width variations from a table.

It's a question of DMA generating bus traffic, which is independent to the core. Once JTAG has control you can enable it. The problem is the ST-LINK is a pretty low rent solution, other more commercial solutions have multiple boot strategies to overcome various issues. The other factor is perhaps using a full JTAG connection rather than SWD.

The resolution is to architect your start up code and sequencing to accommodate the tools you want to use.

Use other means to debug and analyze your system behaviour, including telemetry from the serial port, or create a simple console/debug interface to interact with your system.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..