AVR32DA28 watchdog randomly resets - c

I am trying to work with Watchdog System Reset Mode.
The problem is, it is running good at the start of the mcu but after running for any random period of time it reset the mcu even if i am resetting the counter before the counter overflow. The System reset is occurring randomly. I have tried configuring the watchdog by atmel start, by manual configuration and importing the avr/wdt.h library also but the result is still same. My Mcu is running on internal 12Mhz Clock.
for your better understand i am providing all the methods i have tried below please give your valuable time to read this and share your opinion on this.
Atmel Start import
int8_t WDT_0_init()
{
ccp_write_io((void *)&(WDT.CTRLA),
WDT_PERIOD_1KCLK_gc /* 1K cycles (1.0s) */
| WDT_WINDOW_OFF_gc /* Off */);
return 0;
}
Library import
int main(void)
{
wdt_disable();
atmel_start_init();
wdt_enable(WDTO_1S);
sei();
while (1) {
wdt_reset();
}
thank you.

Related

While loop inside STM32F3xx HardFault handler does not execute forever as expected

I would like to find the cause of mysterious microcontroller resets that I am seeing in my project. The microcontroller I am using is an STM32F3 device with STM32F3xx driver library.
My setup also includes a J-link Ultra+ debugger, however frustratingly I have not yet figured out how to reproduce the resets. They occur almost always after leaving the device running for 12+ hours, and do not seem to occur when connected on a programming jig designed to interface with the debugger.
I believe that when the resets occur, the HardFault handler will be called. I have a number of these devices, and given I cannot connect them all to the debugger and the resets occur at inopportune times, I would like to be able to send some information via a serial line from the HardFault handler. The serial line would then be observed by an external device.
Further complicating things is the lack of unused UART pins. I am attempting to create a poor man's UART by flicking a GPIO on and off in the hard fault handler, with delays in between. To begin with, I just want to figure out how to flick this LED on and off with 50% duty cycle. My code currently looks something like this:
/**
* #brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
GPIO_InitTypeDef GPIO_InitStruct = {LED_Pin, GPIO_MODE_OUTPUT_PP,
GPIO_NOPULL, GPIO_SPEED_FREQ_LOW, 0};
HAL_GPIO_Init(LED_Port, &GPIO_InitStruct);
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
HAL_GPIO_WritePin(LED_Port, LED_Pin, GPIO_PIN_RESET);
HAL_Delay(10);
HAL_GPIO_WritePin(LED_Port, LED_Pin, GPIO_PIN_SET);
HAL_Delay(10);
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
I am testing this by triggering a divide-by-zero reset. I have disabled all watchdogs yet I am finding that when this while loop is entered, it does not while forever, in fact the device restarts when it first hits a HAL_Delay() command.
Questions:
What might be causing the resets upon reaching HAL_Delay()?
Can I execute instructions indefinitely in the HardFault handler, or is there a limited amount of time I have to do things before a reset occurs?
Can I use timers in the hard fault handler?
Thanks very much for your help.
HAL_Delay(10); uses systick interrupt. When in HF you will not get any interrupts and this function will wait forever and your diodes will not flash. You need to delay another way, for example:
for(unsigned x = 0; x < 100000; x++) asm("");
Can I execute instructions indefinitely in the HardFault handler, or
is there a limited amount of time I have to do things before a reset
occurs?
Yes you can stay there as long as you wish. But no interrupts!!!!
Can I use timers in the hard fault handler?
Yes, but no timer interrupts. Basically, you can use all the peripherals if you wish.
What might be causing the resets upon reaching HAL_Delay
Hard to say. Did you enable watchdog?
Basically do not use HAL in HF as most of the functions use HAL_Delay internally. Program bare registers instead

Microcontroller Programming - Program not exiting for loop

I have a simple PIC16F18877 circuit setup on my breadboard and I've successfully gotten an LED to blink within an infinite while loop. I attempted to put the same code inside a for loop that should only execute 5 times, but the LED keeps blinking.
My Code (MPLAB with XC8 Compiler):
#include <xc.h>
#define _XTAL_FREQ 8000000
int main()
{
TRISD1 = 0;
for (int i = 0; i < 5; i++)
{
RD1 = 1;
__delay_ms(500);
RD1 = 0;
__delay_ms(500);
}
return 0;
}
Where do you expect the CPU to jump on return from main? Or rather, what do you expect it to do when you don't tell it what to do? On a desktop computer, the program would normally return to the OS - On an embedded system, there is none.
Most probably, the return from main returns to the startup code and, eventually (either "by accident" or deliberately) to the reset vector, starting your program from the beginning.
If you want the MCU to "stop" actually, "do nothing" you need to force it into an infinite loop instead of return. This is, however, not a common approach on an MCU.
I tried adding a while loop after the for loop and something strange occurred. It appeared to be executing the for and while loop simultaneously. The light would blink link normal and then blink really fast, almost like a stutter and then blink normally, etc.. but it never stopped blinking
Check the watchdog timer. If it's set, the mcu will just reset after a set amount of clock cycles and run the code again and again. You can use CLRWDT() to reset the watchdog timer or just turn the WDT off.
I highly recommend to go through these steps in order to be sure that the mcu does as expected:
Check the PIC configuration bits, are they setup properly? See the documentation in the microchip program folder /docs/chips
Make sure the oscillator is setup correctly.
Read the datasheet and make sure the ports are set correctly, especially the analogue ports using the analogue selection registers.
(my reputation isn't high enough to comment, sorry about that.)
you are not on an operating system here, can you show us the disassembly to show the call to main and what it returns to? Or what if you put an infinite loop before main ends (while(1) continue;) do you get 5 blinks then?

STM32 external interrupt responds only in debug mode

I have a problem with my STM32F103C8T6 microcontroller. I am using (as an exercise) external interrupts to toggle on/off a led, by pressing an external switch wich in turn is connected to PC13. I am using StdPeriph Library.
When the chip has programmed, nothing happens. On the contrary, when I am using the debugger (debug in Coocox), the chip is working fine. I can not figure out where is the problem.
Can you help me please?
Here is my code.
#include<stm32f10x.h>
#include<stm32f10x_rcc.h>
#include<stm32f10x_gpio.h>
#include<stm32f10x_exti.h>
#include<misc.h>
typedef enum{
on,
off
}state;
state led=on;
int main(void){
// enable clocks
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
// uncomment to disable/remap JTAG pins
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
// configure PC13 as input
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
// configure PB8 as led output
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
// connect PC13 to EXTI controller
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);
// enable and configure EXTI controller
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line=EXTI_Line13;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
// enable IRQ
NVIC_EnableIRQ(EXTI15_10_IRQn);
NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);
// Configure NVIC
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
NVIC_Init(&NVIC_InitStructure);
// switch on led
GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
while(1);
return 0;
}
void EXTI15_10_IRQHandler(void){
// clear pending bit
if(EXTI_GetITStatus(EXTI_Line13)!=RESET){
EXTI_ClearITPendingBit(EXTI_Line13);
}
if(led==off){
GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
led=on;
}else{
GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET);
led=off;
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t * file,uint32_t line){
/* Infinite loop */
while (1);
}
#endif
I had this issue as well. I'm using a STM32F030.
The problem for me was not having the SYSCFG clock enabled, which is bit 0 of RCC APB2ENR register. I'm guessing this setting is enabled in debug, so that the software can debug? Otherwise the clock is disabled!
I finally found this by looking into the STM32F1 reference manual, which is slightly more comprehensive.
It is generally a very bad idea to use external interrupts for the buttons and keys. You should use the timer interrupt instead.
You can see simple implementation of the key in the timer interrupt (click, double click, long click events supported) here : https://www.diymat.co.uk/arm-three-function-click-double-and-long-click-button-library-timer-interrupt-driven/
I don't have knowledge about the mentioned controller, but I worked on STM32L4 series controllers. In STM32L4 push button is connected to the PC13 pin. I observed gpio debouncing when pressing the push button. In your EXTI15_10_IRQHandler() implement debouncing logic. Make sure the interrupt is reaching this function for only once per button press. May be the debugger is slowing down the processor(cpu running in lower frequency compared to free run) and you are getting the interrupts properly.
Do you use different build config for debug? If so, try making the led variable volatile and see if it helps.
If not: add some delay loop, i.e. voliatile unsigned i; for (i=0; i < 50000u; ++i); after clearing the EXTI bit in the ISR. This is generally a bad pratcice to use blocking delays in the interrupt service (if it's ever a good practice...) but might be helpful to see if it is related to debuncing not done properly. If it helps, then debouncing the switch is the most likely problem.
EDIT: consider using bit-banding (if possible) to access the output port, then you could do sth like bind_band_led_port ^= 1;, but that's just a side note.

Watchdog configuration on Stellaris Launchpad LM4F120

I try to configure the watchdog timer on Stellaris Launchpad LM4F120.
The code is the following:
void configure_watchdog(void) {
SYSCTL_RCGCWD_R = 0x1; /* Enabling Clock for WD0 */
WATCHDOG0_LOAD_R = 0xffffffff; /* Setting initial value */
WATCHDOG0_CTL_R = WDT_CTL_INTEN; /* Enabling interrupt generation */
}
This supposed to be enough in accordance to the datasheet.
The problem is that controller always falls to FaultISR and resets after it. I can't understand why.
What am I doing wrong?
EDIT: The controller does not reset. It just goes to FaultISR
Jumping to an ISR when the watchdog expires sounds like the correct behavior. What exactly are you doing inside your ISR code? If you are resetting the watchdog inside the ISR, then you shouldn't be seeing the microcontroller reset itself (based on your posted configuration code, at least). After you set up the watchdog, read the configuration register back out and make sure that it holds the value that you expect. Some of the bits in that register can only be set under certain circumstances, and it's possible that you're not running with the settings that you think you're using.
You mentioned that you were trying to use the watchdog timer as a generic downcounter. Could you use one of the general-purpose timers instead of the watchdog? You would still get an interrupt when time expired, but regular timers don't have the ability to reset the entire system.
You have to keep servicing the watchdog, otherwise it times out and calls whatever is setup for that exception. FaultISR would appear to be that in your case.
If you want the watchdog to do something else on the timeout you need to figure out how your particular toolchain connects functions to exception sources and map your new function correctly.
If you don't want the watchdog to expire (which is usually what it's there for, to catch errant code) then you need to service it regularly. The compiler vendor often provides a function or intrinsic to do this.

Programming ARM in C from scratch

I have a LPC3141 developers kit from Embeded artists and i have sucessfully created free IDE based on eclipse that can sucesfully compile for ARM. I tested my IDE using included blinker example. I have a startup code and a linker script which work and i will use them from now on.
Now i would like to learn how to start my own blinker program from nothing. What do i have to program first? Is it GPIO registers, timer registers, uart registers,... ??? What is the very first thing? Is the thing i need to write in fact a HAL? I allready ordered this book, what do you think?
Thank you.
Regards Ziga
These pages might be useful, same family, different chips.
http://lpcstuff.blogspot.com/2008/09/lpc-2148-blinker-1.html
http://lpcstuff.blogspot.com/2010/08/nxp-mbed-aint-so-bad-after-all.html
You wont need timers or interrupts or anything like that to get started. have a C loop count for a (long) while then change the state of the gpio. You will need to configure the gpio as an output. And careful not to have the C compiler optimize out your delay loop. Later you can get into polling the timer, then after that interrupts if you feel you really need to.
it is really easy to get started with arm microcontrollers. all you need to do is reading the datasheet and user manual of your microcontroller. you can find all documentation about peripherals and registers in the user manual
https://www.nxp.com/docs/en/user-guide/UM10362.pdf
for example, this code is for lpc2148 ():
#include <lpc214x.h> // this header file is provided by nxp and contains all register addresses
/* delay function is using only for loop to generate delay.
For accurate timing, use a hardware timer/counter (systick timer is recommended (because it is so easy and configurable via cmsis functions that are provided by ARM)) */
void delay_ms(unsigned int count)
{
unsigned int j=0,i=0;
for(j=0;j<count;j++)
{
for(i=0;i<3000;i++)
asm("nop");
}
}
/* main function */
int main()
{
PINSEL2 = 0x000000; //Configure the P1 Pins for GPIO;
IODIR1 = 0xffffffff; //Configure the P1 pins as OUTPUT;
while(1)
{
IOSET1 = 0xffffffff; // Make all the Port pins as high
delay_ms(1000);
IOCLR1 = 0xffffffff; // Make all the Port pins as low
delay_ms(1000);
}
return 0;
}

Resources