Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Не работает Watchdog в AtXmega
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Хтось
Прошу помощи у Клуба!

Кто пользовался watchdog таймером в Xmega контроллерах?
У меня watchdog нагло отказывается работать!
Вот кусок программы:

CODE
void watchdog_init(void)
{unsigned char s,n;
// Сгенерировано через Code Wisard AVR и проверено по атмеловскому даташиту
#pragma optsize-
s = SREG; // Save interrupts enabled/disabled state
#asm("cli") // Disable interrupts
n = WDT_PER_512CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; // Watchdog Timer: On. Period: 500 ms
CCP = CCP_IOREG_gc;
WDT.CTRL = n;

n = (WDT.WINCTRL & (~WDT_WEN_bm)) | WDT_WCEN_bm; // Watchdog window mode: Off
CCP = CCP_IOREG_gc;
WDT.WINCTRL = n;

SREG = s; // Restore interrupts enabled/disabled state
}

#define SetGreenLed PORTC.OUTCLR = 0x40
#define ClrGreenLed PORTC.OUTSET = 0x40
#define SetRedLed PORTC.OUTCLR = 0x80
#define ClrRedLed PORTC.OUTSET = 0x80

void main(void)
{
watchdog_init();
InitPins(); //Инициализация ножек, куча строк типа "PORTA.DIR = 0b00110110;" и ничего больше
SetGreenLed; //
InitSystemClock(); //переключиться на внешний генератор 33 МГц
delay_ms(400); //
ClrGreenLed; //
delay_ms(5000); //
while(1) //
{delay_ms(250); //
SetRedLed; //
delay_ms(250); //
ClrRedLed; //
} //
//... //Дальше шла программа, которую WDT должен был защищать и оберегать


После рестарта мигает зеленый светодиод, а затем навсегда начинает мигать красный. То есть контроллер не сбрасывается.
Пробовал включить WDT через Fuse биты (устанавливал WDP и WDLOCK) - не помогает, все равно Watchdog не работает.
Пробовал на двух контроллерах AtXmega128A1 AtXmega32A4. не работает ни там ни там.
Как заставить его работать? Может я что-то упускаю? Кто то вообще использовал WDT в Xmega_х?
Xenia
Что такое у вас "n"?
Попробуйте прямо записать константу в WDT.CTRL, без промежуточной перевалки. Вдруг в 4 такта, резервируемых CCP, вы не уложились?
Код
CCP = CCP_IOREG_gc;
WDT.CTRL = WDT_PER_512CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;  // Watchdog Timer: On. Period: 500 ms
Хтось
Укладывается, я смотрел сгенерированный asm, там n назначен на r16 и присвоение идет двумя последовательными командами. К сожалению, до понедельника попробовать уже не смогу. Все осталось на работе. А Вы использовали WDT в Xmega_х? Мне не верится, что он там не работает вообще, но мало ли?

Xenia
Цитата(Хтось @ Oct 4 2013, 21:17) *
А Вы использовали WDT в Xmega_х? Мне не верится, что он там не работает вообще, но мало ли?

Нет, я только Reset использовала по похожей схеме, вот так:
Код
  __disable_interrupt();
  CCP = CCP_IOREG_gc;
  RST.CTRL = RST_SWRST_bm;
  for(;;);

И он нормально работает. Только после такого сброса нулевой байт UART'ом непонятно откуда принимается (при аппаратном ресете его нет).

Цитата(Хтось @ Oct 4 2013, 21:17) *
К сожалению, до понедельника попробовать уже не смогу. Все осталось на работе. А Вы использовали WDT в Xmega_х? Мне не верится, что он там не работает вообще, но мало ли?

Проверила на своем. Вот так работает, сброс есть:
Код
  __disable_interrupt();
  CCP = CCP_IOREG_gc;
  WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;  // Watchdog Timer: On. Period: 500 ms
  for(;;);

Только у меня маска называется WDT_PER_500CLK_gc, а не WDT_PER_512CLK_gc. Определена в хидере так:
WDT_PER_500CLK_gc = (0x06<<2), ///< 500 cycles (0.5s @ 3.3V)

Контроллер ATxmega128A1 (rev.H), компилятор EWAVR 6.21.2
Хтось
Хорошо хоть у кого-то работает, значит проблема решается sm.gif
У меня определяется так же:
#define WDT_PER_512CLK_gc (0x06<<2) // 512 cycles (0.5s at 3.3V)

а можете показать асемблеровский кусок посмотреть?

В понедельник еще возьму плату трехлетней давности, чтоб точно контроллер из другой партии был и проверю на ней.
Xenia
Цитата(Хтось @ Oct 4 2013, 22:36) *
а можете показать асемблеровский кусок посмотреть?

Не могу sm.gif, почему-то компилятор выложил код одним длинным куском, в котором нужного места я не нахожу.

Выделила в отдельную функцию, чтобы посмотреть код:
Код
void WatchDogStart()
{
WatchDogStart:
   CCP = CCP_IOREG_gc;  // 0xD8 - protected IO register
00000000   ED08            LDI     R16, 216
00000002   BF04            OUT     0x34, R16
   WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;  // Watchdog Timer: On. Period: 500 ms
00000004   E10B            LDI     R16, 27
00000006   93000080        STS     128, R16
}
0000000A   9508            RET

Еще совет. Попробуйте после установки WDT подождать. Вот так:

Код
  CCP = CCP_IOREG_gc;                       // 0xD8 - Снятие защиты от записи на 4 цикла
  WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;  // Включение WDT в нормальном режиме, период выдержки 500 мс
  while( WDT.STATUS & WDT_SYNCBUSY_bm);     // Ожидание синхронизации
zombi
WDT никогда не использовал ни в мегах ни в хмегах.
Поэтому врядли чего подскажу.
Но мне просто интересно зачем вам нужен WDT.
Хтось
вот сгенерированный код:
CODE
;void watchdog_init(void)
; 0000 0056 {unsigned char s,n;
_watchdog_init:
; 0000 0057 // Сгенерировано через Code Wisard AVR и проверено по атмеловскому даташиту
; 0000 0058 #pragma optsize-
; 0000 0059 s = SREG; // Save interrupts enabled/disabled state
ST -Y,R17
ST -Y,R16
; s -> R17
; n -> R16
IN R17,63
; 0000 005A #asm("cli") // Disable interrupts
cli
; 0000 005B n = WDT_PER_512CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm; // Watchdog Timer: On. Period: 500 ms
LDI R16,LOW(27)
; 0000 005C CCP = CCP_IOREG_gc;
LDI R30,LOW(216)
OUT 0x34,R30
; 0000 005D WDT.CTRL = n;
STS 128,R16
; 0000 005E
; 0000 005F n = (WDT.WINCTRL & (~WDT_WEN_bm)) | WDT_WCEN_bm; // Watchdog window mode: Off
LDS R30,129
ANDI R30,0xFD
ORI R30,1
MOV R16,R30
; 0000 0060 CCP = CCP_IOREG_gc;
LDI R30,LOW(216)
OUT 0x34,R30
; 0000 0061 WDT.WINCTRL = n;
STS 129,R16
; 0000 0062
; 0000 0063 SREG = s; // Restore interrupts enabled/disabled state
OUT 0x3F,R17
; 0000 0064 }
LD R16,Y+
LD R17,Y+
RET
;


Вроде все нормально. Да и я включал WDT через Fuse биты - все равно не работал!!!
Если у Вас работает, то есть подозрения на битые контроллеры. Тем более, что у меня уже есть горький опыт именно с Xmega32A4. (внутреннее АЦП в беззнаковом режиме выдавало на некоторых участках битый код. Пришлось запустить в знаковый режим, потерял 1 бит точности, но все стало работать. ) В общем в понедельник буду испытывать на других платах. и спасибо за помощь.
Xenia
Цитата(Хтось @ Oct 4 2013, 23:01) *
Если у Вас работает, то есть подозрения на битые контроллеры.


Перечитайте мой предыдущий пост, он был отредактирован.

По моему ваша проблема в том, что, не дождавшись истечения полусекуды, вы разрешаете WD снова. Потому у вас и нет сброса.
Хтось
Цитата(zombi @ Oct 4 2013, 21:53) *
Но мне просто интересно зачем вам нужен WDT.

Конкретно сейчас есть 3 причины:
1. При подаче питания с помощью искрящего контакта контроллер зависает где -то один раз из двадцати. (это при том, BOD включен на 2,4В при питании 3,3, а нормально работать контроллер начинает с 1,8В)
2. Плата работает в условии достаточно сильных помех от расположенных рядом двигателей + также рядом стоящие радиопередатчики ей здоровья не добавляют twak.gif .
3. Использование WDT дает +2 к такому важному навыку разработчика, как "здоровый сон" sm.gif

Цитата(Xenia @ Oct 4 2013, 22:08) *
Перечитайте мой предыдущий пост...

Да, я читал, как доберусь до железа - обязательно попробую и сообщу о результатах.
Еще раз спасибо за помощь!
zombi
Цитата(Хтось @ Oct 4 2013, 22:21) *
Конкретно сейчас есть 3 причины:
1. При подаче питания с помощью искрящего контакта контроллер зависает где -то один раз из двадцати. (это при том, BOD включен на 2,4В при питании 3,3, а нормально работать контроллер начинает с 1,8В)
2. Плата работает в условии достаточно сильных помех от расположенных рядом двигателей + также рядом стоящие радиопередатчики ей здоровья не добавляют twak.gif .
3. Использование WDT дает +2 к такому важному навыку разработчика, как "здоровый сон" sm.gif

1.Попробуйте внешний супервизор.
2.Борьба с зависаниями с помощью WDT абсурд.
3.Только с этим и согласен.

Хтось
bb-offtopic.gif Уважаемый zombi, на этом форуме уже есть не одна тема (и не без Вашего участия) с обсуждением стоит ли использовать WDT, с подобной "помощью" милости прошу туда!

Цитата(zombi @ Oct 5 2013, 00:09) *
1.Попробуйте внешний супервизор.

Использование внешнего супервизора это абсурд, так как есть встроенный (BOD) который ничем не хуже, только дешевле. А от внешних мы отказались уже лет 8 назад, после того, как несколько штук сгорели и стали выдавать непериодический ресет просто так! (уж поверьте, сгорели именно супервизоры, а не питание сделалось плохим.)
Цитата(zombi @ Oct 5 2013, 00:09) *
2.Борьба с зависаниями с помощью WDT абсурд.

Может мы говорим о разных вещах, но в документации от "атмел" написано, что ихний WDT именно для этого и предназначен!
Цитата(zombi @ Oct 5 2013, 00:09) *
3.Только с этим и согласен.

Уже только этого и достаточно.

P.S. Вы все равно не убедите меня, что WDT это зло, поэтому прошу по этому поводу в данной теме больше не писать.
Кстати, некоторые убеждены, что ремень безопасности в машине это тоже зло, но я все равно им пользуюсь sm.gif
IgorKossak
Цитата(Хтось @ Oct 6 2013, 14:38) *
Использование внешнего супервизора это абсурд, так как есть встроенный (BOD) который ничем не хуже, только дешевле.

Таки бывают случаи, когда внешний необходим, но данной темы это не касается.
zombi
Цитата(Хтось @ Oct 6 2013, 14:38) *
прошу по этому поводу в данной теме больше не писать.

Ой сорри. Больше не буду.
Хтось
Все! Я окончательно понял, что контроллеры делаются с помощью черной магии и их работоспособность сильно зависит от количества китайцев, на земле, фазы луны и еще от чего-то! wacko.gif
В общем танцевал я с бубном вокруг WDT с утра и до обеда. Что только не пробовал на трех разных платах: и задержки и инициализации разные, по несколько раз через софт и через фьюзы, в конце вообще на ассемблер перешел прямо в АВР студии, чтоб компилятор был от производителя - ничего не помогает. Не работает и все! (Программный Reset, кстати, работал) Потом осенило посмотреть что в WDT.CTRL. Вывожу я его через UART наружу и - о чудо! Там 0x1A - в полном соответствии с симулятором! То есть WDT разрешён, и период 0,5сек. как я и устанавливаю. Получается - не работает сам модуль WDT в железе. Ну я и успокоился, решил что научились китайцы делать поддельные контроллеры, а нам повезло найти нужного поставщика - ну с кем не бывает sm.gif. Повытирал все свои эксперименты и сел дальше софт писать. Ближе к 5 часам вечера начинает коллега ругаться плохими словами - говорит программатор сдох ни с того ни с сего. Одолжил я ему свой (AVRISP mkII) на 5 мин., он свою плату перешил и программатор вернул. Прошиваю я сразу свою плату и вижу,что она уходит в ресет постоянный. И тут до меня доходит, что все "wdr" в программе закрыты, а watchdog в фьюзах остался включенным и он почему-то заработал. Беру другую плату - WDT не работает. Просто перешиваю программу (фьюзы не трогаю) и снова чудо - WDT заработал и на ней. Вот теперь даже не знаю - плакать crying.gif или смеяться 08.gif , а главное - каких сюрпризов дальше ждать. laughing.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.