Хтось 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Прошу помощи у Клуба! Кто пользовался watchdog таймером в Xmega контроллерах? У меня watchdog нагло отказывается работать! Вот кусок программы: 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 36 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Что такое у вас "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 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Укладывается, я смотрел сгенерированный asm, там n назначен на r16 и присвоение идет двумя последовательными командами. К сожалению, до понедельника попробовать уже не смогу. Все осталось на работе. А Вы использовали WDT в Xmega_х? Мне не верится, что он там не работает вообще, но мало ли? Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 36 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба А Вы использовали WDT в Xmega_х? Мне не верится, что он там не работает вообще, но мало ли? Нет, я только Reset использовала по похожей схеме, вот так: __disable_interrupt(); CCP = CCP_IOREG_gc; RST.CTRL = RST_SWRST_bm; for(;;); И он нормально работает. Только после такого сброса нулевой байт UART'ом непонятно откуда принимается (при аппаратном ресете его нет). К сожалению, до понедельника попробовать уже не смогу. Все осталось на работе. А Вы использовали 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 Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Хорошо хоть у кого-то работает, значит проблема решается :) У меня определяется так же: #define WDT_PER_512CLK_gc (0x06<<2) // 512 cycles (0.5s at 3.3V) а можете показать асемблеровский кусок посмотреть? В понедельник еще возьму плату трехлетней давности, чтоб точно контроллер из другой партии был и проверю на ней. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 36 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба а можете показать асемблеровский кусок посмотреть? Не могу :), почему-то компилятор выложил код одним длинным куском, в котором нужного места я не нахожу. Выделила в отдельную функцию, чтобы посмотреть код: 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 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба WDT никогда не использовал ни в мегах ни в хмегах. Поэтому врядли чего подскажу. Но мне просто интересно зачем вам нужен WDT. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба вот сгенерированный код: ;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 36 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Если у Вас работает, то есть подозрения на битые контроллеры. Перечитайте мой предыдущий пост, он был отредактирован. По моему ваша проблема в том, что, не дождавшись истечения полусекуды, вы разрешаете WD снова. Потому у вас и нет сброса. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Но мне просто интересно зачем вам нужен WDT. Конкретно сейчас есть 3 причины: 1. При подаче питания с помощью искрящего контакта контроллер зависает где -то один раз из двадцати. (это при том, BOD включен на 2,4В при питании 3,3, а нормально работать контроллер начинает с 1,8В) 2. Плата работает в условии достаточно сильных помех от расположенных рядом двигателей + также рядом стоящие радиопередатчики ей здоровья не добавляют :twak: . 3. Использование WDT дает +2 к такому важному навыку разработчика, как "здоровый сон" :) Перечитайте мой предыдущий пост... Да, я читал, как доберусь до железа - обязательно попробую и сообщу о результатах. Еще раз спасибо за помощь! Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 4 октября, 2013 Опубликовано 4 октября, 2013 · Жалоба Конкретно сейчас есть 3 причины: 1. При подаче питания с помощью искрящего контакта контроллер зависает где -то один раз из двадцати. (это при том, BOD включен на 2,4В при питании 3,3, а нормально работать контроллер начинает с 1,8В) 2. Плата работает в условии достаточно сильных помех от расположенных рядом двигателей + также рядом стоящие радиопередатчики ей здоровья не добавляют :twak: . 3. Использование WDT дает +2 к такому важному навыку разработчика, как "здоровый сон" :) 1.Попробуйте внешний супервизор. 2.Борьба с зависаниями с помощью WDT абсурд. 3.Только с этим и согласен. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 6 октября, 2013 Опубликовано 6 октября, 2013 · Жалоба :bb-offtopic: Уважаемый zombi, на этом форуме уже есть не одна тема (и не без Вашего участия) с обсуждением стоит ли использовать WDT, с подобной "помощью" милости прошу туда! 1.Попробуйте внешний супервизор. Использование внешнего супервизора это абсурд, так как есть встроенный (BOD) который ничем не хуже, только дешевле. А от внешних мы отказались уже лет 8 назад, после того, как несколько штук сгорели и стали выдавать непериодический ресет просто так! (уж поверьте, сгорели именно супервизоры, а не питание сделалось плохим.) 2.Борьба с зависаниями с помощью WDT абсурд. Может мы говорим о разных вещах, но в документации от "атмел" написано, что ихний WDT именно для этого и предназначен! 3.Только с этим и согласен. Уже только этого и достаточно. P.S. Вы все равно не убедите меня, что WDT это зло, поэтому прошу по этому поводу в данной теме больше не писать. Кстати, некоторые убеждены, что ремень безопасности в машине это тоже зло, но я все равно им пользуюсь :) Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
IgorKossak 0 6 октября, 2013 Опубликовано 6 октября, 2013 · Жалоба Использование внешнего супервизора это абсурд, так как есть встроенный (BOD) который ничем не хуже, только дешевле. Таки бывают случаи, когда внешний необходим, но данной темы это не касается. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zombi 0 6 октября, 2013 Опубликовано 6 октября, 2013 · Жалоба прошу по этому поводу в данной теме больше не писать. Ой сорри. Больше не буду. Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Хтось 0 7 октября, 2013 Опубликовано 7 октября, 2013 · Жалоба Все! Я окончательно понял, что контроллеры делаются с помощью черной магии и их работоспособность сильно зависит от количества китайцев, на земле, фазы луны и еще от чего-то! В общем танцевал я с бубном вокруг WDT с утра и до обеда. Что только не пробовал на трех разных платах: и задержки и инициализации разные, по несколько раз через софт и через фьюзы, в конце вообще на ассемблер перешел прямо в АВР студии, чтоб компилятор был от производителя - ничего не помогает. Не работает и все! (Программный Reset, кстати, работал) Потом осенило посмотреть что в WDT.CTRL. Вывожу я его через UART наружу и - о чудо! Там 0x1A - в полном соответствии с симулятором! То есть WDT разрешён, и период 0,5сек. как я и устанавливаю. Получается - не работает сам модуль WDT в железе. Ну я и успокоился, решил что научились китайцы делать поддельные контроллеры, а нам повезло найти нужного поставщика - ну с кем не бывает :). Повытирал все свои эксперименты и сел дальше софт писать. Ближе к 5 часам вечера начинает коллега ругаться плохими словами - говорит программатор сдох ни с того ни с сего. Одолжил я ему свой (AVRISP mkII) на 5 мин., он свою плату перешил и программатор вернул. Прошиваю я сразу свою плату и вижу,что она уходит в ресет постоянный. И тут до меня доходит, что все "wdr" в программе закрыты, а watchdog в фьюзах остался включенным и он почему-то заработал. Беру другую плату - WDT не работает. Просто перешиваю программу (фьюзы не трогаю) и снова чудо - WDT заработал и на ней. Вот теперь даже не знаю - плакать :crying: или смеяться :08: , а главное - каких сюрпризов дальше ждать. :laughing: Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться