Не могу вылечить ватчдог на "голой" атмеге328р с внутр тактированием 8 МГц

b707
Offline
Зарегистрирован: 26.05.2017

Вроде и голый контроллер прошиваю не впервые, и загрузчик для "лечения" ватчдога приходилось менять - все было без проблем. Но ватчдог на "голом" МК запускаю первый раз. И ничего не выходит.

Выставляю фьюзы (рассчитаны по калькулятору для 8MHz internal), беру оптибут загрузчик, прошиваю в Ардуино ИДЕ через Arduino ISP - все прошивается без проблем. По диагностике avrdude видно, что фьюзы шьются правильные, файл буллоадера берется тот, что нужно. Заливаю тестовый скетч - тоже без ошибок.  Так как у контроллера нет обвязки USART, то подключил к МК OLED дисплей и смотрю вывод на нем. После включения ватчдога плата наглухо виснет. На РЕСЕТ не реагирует, только на отключение питания.

Прошерстил гугль - конкретно моего случая нет, у всех после замены бутлоадера на оптибут ватчдог работает. Оптибутовских загрузчиков попробовал 3 шт разных -

1) из  гитхабовского релиза оптибута файл optiboot_atmega328_pro_8MHz.hex

2) из проекта MiniCore = файл optiboot_flash_atmega328p_UART0_38400_8000000L.hex

3) и даже в одном месте вычитал, что можно брать бутлоадер и под 16МГЦ - взял стандартный оптибут optiboot_atmega328.hex

После прошивки любого из этих бутов никаких изменений в поведении контроллера не происходит - точно так же без проблем перешивается и так же виснет при запуске вотчдога.

Честно говоря. я в тупике. Больше идей нет. Такое впечатление, что не вижу чего-то прямо перед носом. Может кто что подскажет?

Для справки -

Фьюзы и параметры бутлоадера можно посмотреть в файле boards.txt:

##############################################################

atmega328bb.name=ATmega328 on BB (8 MHz internal optiboot)

atmega328bb.upload.tool=avrdude
atmega328bb.upload.protocol=arduino
atmega328bb.upload.maximum_size=32256
atmega328bb.upload.speed=57600

atmega328bb.bootloader.tool=avrdude
atmega328bb.bootloader.low_fuses=0xE2
atmega328bb.bootloader.high_fuses=0xDE
atmega328bb.bootloader.extended_fuses=0x05

atmega328bb.bootloader.file=optiboot/optiboot_atmega328_pro_8MHz.hex
atmega328bb.bootloader.unlock_bits=0x3F
atmega328bb.bootloader.lock_bits=0x0F

atmega328bb.build.board=ATMEGA328BB
atmega328bb.build.mcu=atmega328p
atmega328bb.build.f_cpu=8000000L
atmega328bb.build.core=arduino:arduino
atmega328bb.build.variant=arduino:standard

Тестовый скетч

#include <avr/wdt.h> 
#include "oled.h"

void setup()
 {
   wdt_disable(); 
   LEDPIN_Init();
   LED_Init();
   LED_P8x16Str(23,0,"wait");
   delay(16000);
   wdt_enable (WDTO_8S);
 } 
 
void loop()
 {
    //wdt_reset(); 
    
    LED_P8x16Str(23,0,"wdt on");
    delay(1000);
   
  }

 

b707
Offline
Зарегистрирован: 26.05.2017

Провел еще один тест - подключил к одному из пинов МК светодиод. Была мысль, что при ресете от ватчдога просто не стартует LED-экран, а все остальное - работает. Это уже просто от безисходности

Снова мимо. При первом старте платы светик загорается, гаснет при срабатывании ватчдога и больше не зажигается. То есть дело не в том, что просто не зажигается экран - плата реально зависает...

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

Попробуй поменять время собаке на меньшее.

b707
Offline
Зарегистрирован: 26.05.2017

Штирлиц пишет:

Попробуй поменять время собаке на меньшее.

Попробовал 1сек - без разницы.

 

Упростил тест до предела, чтобы эксперимент был максимально чистым:

1. Взял новую (еще ни разу не шитую) атмегу328р

2. Собрал на макетке классическую обвязку

3. Прошил оптибутовский загрузчик с фьзами 0xE2 0xDE 0x05

4. подключил к 7 пину светодиод

5. 3алил мега-простой скетч

#include <avr/wdt.h> 
int led =7;

void setup()
 {
   wdt_disable(); 
   pinMode(led,OUTPUT);
   digitalWrite(led,HIGH);
   delay(16000);
   wdt_enable (WDTO_1S);
 } 
 
void loop()
 {
    //wdt_reset(); 
    digitalWrite(led, ! digitalRead(led));
   
    delay(1000);
   
  
}
 

Итог - при включении светик горит 16сек, потом начинает мигать. После срабатывания ватчдога - мигает часто-часто - то есть типичный случай бесконечного ресета.

Этот же самый бутлоадер в Нано - работает!!!  ватчдог ресетится как положено.

Вывод - налицо несовместимость оптибута с атмегой328 с внутренним клоком 8МГц. Если это так = давно бы куча других ардуинщиков столкнулась бы с этим. Вопрос - почему я не вижу в гугле десятков подобных жалоб?

Варианты:

А) - я идиот. Уже готов согласится, при условии, что кто0нибудь обьяснит, в чем именно.

Б) - мне попалась бракованая партия контроллеров. Не исключено. Проверить просто - нужна другая папртия. Может кто-нибудь не пожалеет получаса, повторит перечисленные выше пп 1-5 и напишет свой результат?

В) - предлагайте свои варианты

 

Штирлиц
Штирлиц аватар
Offline
Зарегистрирован: 13.06.2015

С субботы на воскресенье всегда так. Все нормальные спят.

А по делу-я сча попробую проверить( пивко псле копоратива эсли позволит). Как ты сказал- "это где-то под носом"У мну была ппрблм с ватчдогом с мегой32. Но насколько могу вспомнить- проблема в Мега32.(Ватч от 2 ух сек и ниже только работал)

 

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

Вывод - налицо несовместимость оптибута с атмегой328 с внутренним клоком 8МГц. Если это так = давно бы куча других ардуинщиков столкнулась бы с этим. Вопрос - почему я не вижу в гугле десятков подобных жалоб?

Однозначно работает, ректификатор на нем пару лет пашет. Сам оптибут есть, а вот секцию с фузами потерял когда комп переустанавливал. Т.к. шил первый раз брал все с сайта. Поищи, это у Жеки_ТМ было, он ссылку где то на ЯД давал.

oleg_kazakof
Offline
Зарегистрирован: 24.04.2015

 

#include <avr/wdt.h> 
int led =7;

void setup()
 {
   wdt_disable(); 
   pinMode(led,OUTPUT);
   digitalWrite(led,HIGH);
   delay(16000);
   wdt_enable (WDTO_1S);
 } 
 
void loop()
 {
    //wdt_reset(); 
    digitalWrite(led, ! digitalRead(led));
   
    delay(1000);  
}

 

В) - предлагайте свои варианты

[/quote]

Собака настроена на 1сек и delay 1сек + обрабока пина => времени срабоки собаки

Почему закоментирован сброс собаки.

b707
Offline
Зарегистрирован: 26.05.2017

oleg_kazakof пишет:

Собака настроена на 1сек и delay 1сек + обрабока пина => времени срабоки собаки.

интервал собаки можно взять любой - ничего не меняется. Первоначально стояло 8сек, это я уже по совету Штирлица уменьшил.

oleg_kazakof пишет:
Почему закоментирован сброс собаки.

потому что! :) это вы не проснулись еще...

b707
Offline
Зарегистрирован: 26.05.2017

Народ, вынужден поднять ветку, так как очень нужно решение

Прошу тех, у кого есть под рукой атмега328 в DIP-корпусе - попробовать залить мой скетч и написать о результате.

bwn
Offline
Зарегистрирован: 25.08.2014

Попробуй отсюда, на 168 проминьку недавно делал, как раз для собаки, нормально пашет.

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Попробуй отсюда, на 168 проминьку недавно делал, как раз для собаки, нормально пашет.

да. спасибо, уже сам нашел эту ветку и прочитал все страницы.  Вечером попробую.

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Попробуй отсюда, на 168 проминьку недавно делал, как раз для собаки, нормально пашет.

сгенерил бутлоадер по ссылке, прошил - результат тот же.

Все больше прихожу к выводу. что причина во мне - не замечаю чего-то очевидного.

Может все ж-таки кто-то потратит 20 минут времени и попробует повторить мои тесты ?

sadman41
Offline
Зарегистрирован: 19.10.2016

У меня где-то есть 168-я в DIP, но она уже стояла в ардуине...

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

сорри, что поздно заметил!!!! Это лечится ОЧЕНЬ просто и об этом написано в документации:

Functions

static __inline__  __attribute__ ((__always_inline__)) void wdt_enable(const uint8_t value)
 

Detailed Description

#include <avr/wdt.h>

This header file declares the interface to some inline macros handling the watchdog timer present in many AVR devices. In order to prevent the watchdog timer configuration from being accidentally altered by a crashing application, a special timed sequence is required in order to change it. The macros within this header file handle the required sequence automatically before changing any value. Interrupts will be disabled during the manipulation.

Note
Depending on the fuse configuration of the particular device, further restrictions might apply, in particular it might be disallowed to turn off the watchdog timer.

Note that for newer devices (ATmega88 and newer, effectively any AVR that has the option to also generate interrupts), the watchdog timer remains active even after a system reset (except a power-on condition), using the fastest prescaler value (approximately 15 ms). It is therefore required to turn off the watchdog early during program startup, the datasheet recommends a sequence like the following:

#include <stdint.h>
#include <avr/wdt.h>
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
__attribute__((naked)) \
__attribute__((section(".init3")));
void get_mcusr(void)
{
mcusr_mirror = MCUSR;
MCUSR = 0;
wdt_disable();
}

Saving the value of MCUSR in mcusr_mirroris only needed if the application later wants to examine the reset source, but in particular, clearing the watchdog reset flag before disabling the watchdog is required, according to the datasheet.

==========================

вот пример кода, который я ТОЬКО ЧТО проверил на голом 328 в ДИП корпусе.

Вот видео, снял и кинул на Ютуб

Вот код:

#include <stdint.h>
#include <avr/wdt.h>
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
  __attribute__((naked)) \
  __attribute__((section(".init3")));
void get_mcusr(void)
{
  mcusr_mirror = MCUSR;
  MCUSR = 0;
  wdt_disable();
}

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27,16,2);

void setup() {
 
  pinMode(8,OUTPUT);
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Setup...");
  
  wdt_enable (WDTO_8S);
  lcd.print(" WDT on");
}

void loop(){
static int timer = 0;  
    if(!(millis()%1000)){
    timer++;
    lcd.setCursor(0,1);
    lcd.print("Count: ");
    lcd.print(timer);
    digitalWrite(8, !digitalRead(8));
  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula, спасибо огромное, вечером проверю. Думаю, что заработает :)

О необходимости этого кода я уже читал во многих местах. Но он, в принципе, должен быть встроен в оптибут - собственно, потому замена штатного бута на оптибут и "лечит" ватчдог.  Поэтому я не добавлял этот код в скетч, рассчитывая. что оптибут справится сам.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

wdrakula, спасибо огромное, вечером проверю. Думаю, что заработает :)

О необходимости этого кода я уже читал во многих местах. Но он, в принципе, должен быть встроен в оптибут - собственно, потому замена штатного бута на оптибут и "лечит" ватчдог.  Поэтому я не добавлял этот код в скетч, рассчитывая. что оптибут справится сам.

 

Перед тем, как писать, я проверил не только с оптибутом, но и вообще без бутлоадера. С разными фьюзами (и E2 DA и C2 DB - если понимаете, о чем я ).

Нет - работает ТОЛЬКО так.

Я всегда проверяю свои рекомендации (и софтовые и электронные) перед постингом, даже если ответ кажется очевидным.

Сперва я проверил вообще без бута, и добавив "wdr" в main() в ядре. Казалось, что это очевидное решение,  что еще хотеть? Ан нет, однако,  ответ написан выше ;) ;) ;)

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula,, твой код тоже не работает.

Зато если поместить сброс регистра ватчдога MCUSR в сетап - работает.

Рабочий код получился таким:

#include <avr/wdt.h> 
int led =7;

void setup()
 {
   MCUSR = 0;
   wdt_disable(); 
   
   pinMode(led,OUTPUT);
   digitalWrite(led,HIGH);
   delay(16000);
   wdt_enable (WDTO_1S);
 } 
 
void loop()
 {
    //wdt_reset(); 
    digitalWrite(led, ! digitalRead(led));
   
    delay(1000);
   
  }

Может ерунду предположу - но похоже на то, что при рестарте контроллера исполнение начинается прямо со скетча - без запуска бутлоадера и без пре-инит функций.

 

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

wdrakula,, твой код тоже не работает.

Выложен код и видео. Остальное - чушь какая-то.

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula пишет:

Выложен код и видео. Остальное - чушь какая-то.

Влад, погоди

Я не сказал, что твой код неверный. Просто на моей атмеге он не работает. Возможно, я там уже слишком намудрил с конфигами...

Сижу. читаю апноуты и даташиты, разбираюсь. Пока нашел только указание, что работоспособность этого решения зависит от опций компилятора.

 

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

на чистую ИДЕ поставь ЭТУ надстройку для бредбоард.

Сперва перезапускаешь ИДЕ и вызываешь "Записать загрузчик".

Потом компилируешь и загружаешь программу.

Больше НИЧЕГО не делаешь.

---------------------------

Я написал, что проверил много вариантов. В том числе и ВООБЩЕ без загрузчика.

Я делал вообще отдельное ядро с отдельными библиотеками, чтобы скетч грузился по кнопке, а не через "Загрузить через программатор", для "голого" 328, без бута.

Решение с кодом  в .init3 - самое простое и правильное. Работает с дефолтным бутлоадером и дефолтными фьюзами.

Твоя идея про загрузку - не  соответствует даташиту, если у тебя хоть что-то и как-то запустилось без кода в секции .init3, то значит этот код есть в загрузчике, что маловероятно, так как в оптибуте его нет. Может его добавили во что-то еще? Иначе никак... честное пионерское! ;)

Ради спортивного интереса, можешь указать свою надстройку для голого контроллера и версию среды - посмотрю на ней. Только Виндоус ставить не стану, даже для проверки ;) - это  "глубокая личная непереносимость", у меня есть древняя ХР на виртуалке  - этого для меня вполне хватает, если приползает что-то виндовое.

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula пишет:

на чистую ИДЕ поставь ЭТУ надстройку для бредбоард.

Сперва перезапускаешь ИДЕ и вызываешь "Записать загрузчик".

Потом компилируешь и загружаешь программу.

Больше НИЧЕГО не делаешь.

Ну я так и делаю. Моя настройка для голого контроллера есть в первом сообщении ветки (первый спойлер) - она практически идентична твоей.  Версия ИДЕ 1,8,3 Win7 x64

 

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

bwn пишет:

Попробуй отсюда, на 168 проминьку недавно делал, как раз для собаки, нормально пашет.

сгенерил бутлоадер по ссылке, прошил - результат тот же.

Все больше прихожу к выводу. что причина во мне - не замечаю чего-то очевидного.

Может все ж-таки кто-то потратит 20 минут времени и попробует повторить мои тесты ?

У меня еще хужее, начал тратить 20 минут и уперся в стену. Сформировал HEX, секцию подготовил, залил через IDE Ar..ISP, все нормально влилось. А от когда попытался залить блинк через преобразователь на ch340: "Нет синхронизации", если вставить в Ардуину (RT232), аналогично. (((( У Вас нормально с этим загрузчиком скетчи заливались? 
Вчера уже надоело, сегодня вернусь, фузы проверю и со скоростью поиграюсь. Для 168 на 16мГц все сразу взлетело. Загадка природы.((((

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

У меня еще хужее, начал тратить 20 минут и уперся в стену. Сформировал HEX, секцию подготовил, залил через IDE Ar..ISP, все нормально влилось. А от когда попытался залить блинк через преобразователь на ch340: "Нет синхронизации", если вставить в Ардуину (RT232), аналогично. (((( У Вас нормально с этим загрузчиком скетчи заливались?

Сорри, что втянул :)

Я заливаю скетчи через SPI - точно так же как загрузчик. После заливки загрузчика ничего не отсоединяете, можно вообще сразу же, как залился загрузчик - жмете "Скетч - Загрузить через программатор".

А через загрузчик я на голом контроллере не пробовал - везде написано, что без кварца UART может не работать.

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

wdrakula пишет:

на чистую ИДЕ поставь ЭТУ надстройку для бредбоард.

Сперва перезапускаешь ИДЕ и вызываешь "Записать загрузчик".

Потом компилируешь и загружаешь программу.

Больше НИЧЕГО не делаешь.

Ну я так и делаю. Моя настройка для голого контроллера есть в первом сообщении ветки (первый спойлер) - она практически идентична твоей.  Версия ИДЕ 1,8,3 Win7 x64

 

Я еще переделывал platform.txt

без него не работает, вот он:

name=Atmega328bb
version=0.22

# AVR compile variables
# --------------------- 

# Default "compiler.path" is correct, change only if you want to overidde the initial value
compiler.path={runtime.tools.avr-gcc.path}/bin/
compiler.c.cmd=avr-gcc
compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD
# -w flag added to avoid printing a wrong warning http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59396
# This is fixed in gcc 4.8.3 and will be removed as soon as we update the toolchain
compiler.c.elf.flags=-w -Os -Wl,--gc-sections
compiler.c.elf.cmd=avr-gcc
compiler.S.flags=-c -g -x assembler-with-cpp
compiler.cpp.cmd=avr-g++
compiler.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD
compiler.ar.cmd=avr-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=avr-objcopy
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
compiler.elf2hex.flags=-O ihex -R .eeprom
compiler.elf2hex.cmd=avr-objcopy
compiler.ldflags=
compiler.size.cmd=avr-size

# This can be overriden in boards.txt
build.extra_flags=

# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.S.extra_flags=
compiler.cpp.extra_flags=
compiler.ar.extra_flags=
compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=

# AVR compile patterns
# --------------------

## Compile c files
recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"

## Compile c++ files
recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"

## Compile S files
recipe.S.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.S.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.S.extra_flags} {build.extra_flags} {includes} "{source_file}" -o "{object_file}"

## Create archives
recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compiler.ar.extra_flags} "{archive_file_path}" "{object_file}"

## Combine gc-sections, archives, and objects
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm

## Create eeprom
recipe.objcopy.eep.pattern="{compiler.path}{compiler.objcopy.cmd}" {compiler.objcopy.eep.flags} {compiler.objcopy.eep.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.eep"

## Create hex
recipe.objcopy.hex.pattern="{compiler.path}{compiler.elf2hex.cmd}" {compiler.elf2hex.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.hex"

## Compute size
recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf"
recipe.size.regex=^(?:\.text|\.data|\.bootloader)\s+([0-9]+).*
recipe.size.regex.data=^(?:\.data|\.bss|\.noinit)\s+([0-9]+).*
recipe.size.regex.eeprom=^(?:\.eeprom)\s+([0-9]+).*


# AVR Uploader/Programmers tools
# ------------------------------

tools.avrdude.cmd.path={path}/bin/avrdude
tools.avrdude.config.path={path}/etc/avrdude.conf

tools.avrdude.upload.params.verbose=-v -v
tools.avrdude.upload.params.quiet=-q -q
tools.avrdude.upload.pattern="{cmd.path}" "-C{config.path}" {upload.verbose} -p{build.mcu} -c{upload.protocol} -P{serial.port} -b{upload.speed} -D "-Uflash:w:{build.path}/{build.project_name}.hex:i"

tools.avrdude.program.params.verbose=-v -v
tools.avrdude.program.params.quiet=-q -q
tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.hex:i"

tools.avrdude.erase.params.verbose=-v -v
tools.avrdude.erase.params.quiet=-q -q

tools.avrdude.erase.pattern="{cmd.path}" "-C{config.path}" {erase.verbose} -p{build.mcu} -c{protocol} {program.extra_params} -e -Uhfuse:w:{bootloader.high_fuses}:m -Ulfuse:w:{bootloader.low_fuses}:m

tools.avrdude.bootloader.params.verbose=-v -v
tools.avrdude.bootloader.params.quiet=-q -q
tools.avrdude.bootloader.pattern=
# "{cmd.path}" "-C{config.path}" {bootloader.verbose} -p{build.mcu} -c{protocol} {program.extra_params} 


# USB Default Flags
# Default blank usb manufacturer will be filled it at compile time
# - from numeric vendor ID, set to Unknown otherwise
build.usb_manufacturer=
build.usb_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}'

 

bwn
Offline
Зарегистрирован: 25.08.2014

b707 пишет:

Сорри, что втянул :)

Я заливаю скетчи через SPI - точно так же как загрузчик. После заливки загрузчика ничего не отсоединяете, можно вообще сразу же, как залился загрузчик - жмете "Скетч - Загрузить через программатор".

А через загрузчик я на голом контроллере не пробовал - везде написано, что без кварца UART может не работать.

Та чеж сорри то? Самому интересно стало, да возможно грабли миновал (плату разведешь и будешь репу чесать). Если через SPI, то нахрена тогда и загрузчик нужен.

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Если через SPI, то нахрена тогда и загрузчик нужен.

ну я ж не только по SPI гружу...

Тут уже тоже не только практический вопрос, но и просто интересно - почему загрузчик не работает?

А он, похоже, таки не работает... судя по результатам твоих и моих тестов.

 

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula пишет:

Я еще переделывал platform.txt

А что именно переделывал, не помнишь?

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

b707 пишет:

wdrakula пишет:

Я еще переделывал platform.txt

А что именно переделывал, не помнишь?

конечно помню!

-flto отключай или добавь

  __attribute__((used))

к описанию функции, что тебе проще. Сорри, все проверил, а этого тебе не рассказал. У меня -flto всегда отключено.

(это Линк Тайм Оптимизация, если знаешь... штука странная и не полезная)

bwn
Offline
Зарегистрирован: 25.08.2014

Мдя, вести с полей. После загрузки первый цикл отрабатывает, а потом вечный ребут.((((
Други, если добьете, манул для лохов вроде меня, плиз, а то я уже давно потерялся.((((

b707
Offline
Зарегистрирован: 26.05.2017

Пля....

" When you use Arduino as ISP (or any other ISP programmer) to program an AVR microcontroller, it takes out the bootloader. There is only one instruction available via ISP programming to erase flash, and that is the chip erase command, which wipes the whole flash (and the lockbits - this is part of their code security model ), including the bootloader section.

So - if you did "upload using programmer", that'll wipe out the bootloader on the target."

 

и на это я потратил 5 дней :))))

ПОЗОР

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

bwn пишет:

Мдя, вести с полей. После загрузки первый цикл отрабатывает, а потом вечный ребут.((((
Други, если добьете, манул для лохов вроде меня, плиз, а то я уже давно потерялся.((((

Я потерялся в ваших вопросах: у тебя что не работает? Если Вочдог, то вот такой код должен работать на любом камне: (обрати внимание на атрибут  "used")

#include <stdint.h>
#include <avr/wdt.h>
uint8_t mcusr_mirror __attribute__ ((section (".noinit")));
void get_mcusr(void) \
  __attribute__((naked)) \
  __attribute__((used)) \
  __attribute__((section(".init3")));
void get_mcusr(void)
{
  mcusr_mirror = MCUSR;
  MCUSR = 0;
  wdt_disable();
}

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x27,16,2);

void setup() {
 
  pinMode(8,OUTPUT);
  
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Setup...");
  
  wdt_enable (WDTO_8S);
  lcd.print(" WDT on");
}

void loop(){
static int timer = 0;  
    if(!(millis()%1000)){
    timer++;
    lcd.setCursor(0,1);
    lcd.print("Count: ");
    lcd.print(timer);
    digitalWrite(8, !digitalRead(8));
  }
}

 

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Мдя, вести с полей. После загрузки первый цикл отрабатывает, а потом вечный ребут.((((

bwn. так и должно быть, если ты загрузил скетч по SPI.  Оказывается, при этом удаляется бутлоадер... (см предыдущее сообщение).

Способ "вылечить" ватчдог в этом случае - от wdrakula в сообщении 13. Или мой код чуть дальше.

bwn
Offline
Зарегистрирован: 25.08.2014

Ну а я оптибут нашел, который с USB-UART дружит. Тот на который ссыль давал не синхронизируется.
Что по SPI загрузчик трет, знал, тока с собаком не смог это связать.))))
Всем спасибо за науку.

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Ну а я оптибут нашел, который с USB-UART дружит. Тот на который ссыль давал не синхронизируется.

а ссылку можно - какой синхронизируется, а какой нет.

bwn
Offline
Зарегистрирован: 25.08.2014

Ссыля нет, он у меня на диске валялся, Жека_ТМ давал. Если надо могу хекс скинуть.

b707
Offline
Зарегистрирован: 26.05.2017

bwn пишет:

Ссыля нет, он у меня на диске валялся, Жека_ТМ давал. Если надо могу хекс скинуть.

Хекс - это ж текстовой формат, выложи как код под спойлер

bwn
Offline
Зарегистрирован: 25.08.2014

ОК. 

:107E0000112484B714BE81FFF0D085E080938100F7
:107E100082E08093C00088E18093C10086E0809377
:107E2000C20089E18093C4008EE0C9D0259A84E025
:107E300028E13EEF91E0309385002093840096BBCB
:107E4000B09BFECF1D9AA8958150A9F7CC24DD24C4
:107E500088248394B5E0AB2EA1E19A2EF3E0BF2EE7
:107E6000A2D0813461F49FD0082FAFD0023811F036
:107E7000013811F484E001C083E08DD089C08234E0
:107E800011F484E103C0853419F485E0A6D080C0E4
:107E9000853579F488D0E82EFF2485D0082F10E0AE
:107EA000102F00270E291F29000F111F8ED06801E7
:107EB0006FC0863521F484E090D080E0DECF843638
:107EC00009F040C070D06FD0082F6DD080E0C81688
:107ED00080E7D80618F4F601B7BEE895C0E0D1E017
:107EE00062D089930C17E1F7F0E0CF16F0E7DF06D8
:107EF00018F0F601B7BEE89568D007B600FCFDCFD4
:107F0000A601A0E0B1E02C9130E011968C91119780
:107F100090E0982F8827822B932B1296FA010C0160
:107F200087BEE89511244E5F5F4FF1E0A038BF0790
:107F300051F7F601A7BEE89507B600FCFDCF97BE46
:107F4000E89526C08437B1F42ED02DD0F82E2BD052
:107F50003CD0F601EF2C8F010F5F1F4F84911BD097
:107F6000EA94F801C1F70894C11CD11CFA94CF0C13
:107F7000D11C0EC0853739F428D08EE10CD085E9AC
:107F80000AD08FE07ACF813511F488E018D01DD067
:107F900080E101D065CF982F8091C00085FFFCCF94
:107FA0009093C60008958091C00087FFFCCF809118
:107FB000C00084FD01C0A8958091C6000895E0E648
:107FC000F0E098E1908380830895EDDF803219F02E
:107FD00088E0F5DFFFCF84E1DECF1F93182FE3DFCA
:107FE0001150E9F7F2DF1F91089580E0E8DFEE27F6
:047FF000FF270994CA
:027FFE00040479
:0400000300007E007B
:00000001FF

Загрузочная:

##############################################################

a328p_8MHz.name=atmega328p (8 MHz)

a328p_8MHz.upload.tool=avrdude 
a328p_8MHz.upload.protocol=arduino 
a328p_8MHz.upload.maximum_size=32256 
a328p_8MHz.upload.speed=38400
 
a328p_8MHz.bootloader.tool=avrdude
a328p_8MHz.bootloader.low_fuses=0xe2 
a328p_8MHz.bootloader.high_fuses=0xd4 
a328p_8MHz.bootloader.extended_fuses=0x5  
a328p_8MHz.bootloader.unlock_bits=0x3F
a328p_8MHz.bootloader.lock_bits=0x0F
##a328p_8MHz.bootloader.file=optiboot/a328p_8MHz_e2_de_5.hex
a328p_8MHz.bootloader.file=optiboot/optiboot_a328_8mhz_e2_d4_38400.hex
 
a328p_8MHz.build.mcu=atmega328p
a328p_8MHz.build.f_cpu=8000000L 
a328p_8MHz.build.core=arduino 
a328p_8MHz.build.variant=standard 

 

b707
Offline
Зарегистрирован: 26.05.2017

ну понятно, в этом скорость UART задана 38400, а в том, что генерится по ссылке - 115200.  Я нашел старую ветку обсуждения того генератора - там автору многие указывали. что 115200 для 8МГц без кварца - это слишком быстро. Он, вроде, согласился, но так и не поправил.

Спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

wdrakula, код из сообщения №30 - РАБОТАЕТ (тот, который с атрибутом _used_)

Ну и вообще - полная победа! Проверил все варианты прошивки - и с бутлоадером, и без - все отлично работает!

Спасибо, мужики, огромное!!

wdrakula
wdrakula аватар
Offline
Зарегистрирован: 15.03.2016

Вот. С трудом нашел эту старую тему.

Выдалась пара часов на фоне чистки "снегопада века", починки китайского снегоочистителя, постоянной работы н\генератора, так как провода рвутся и электричество уходит! И ведь самогонка сама не выгоняется. Все сложно (с), короче.

====================================================================

Поправил бутлоадер, не "опти", а классику - она правда лучше. Теперь он раболтает на "голом" 328 на внутр. 8 МГц.

1. Makefile

 настраивать можно скорость компорта и время ожидания перед закачкой (то время, за которое нужно успеть нажать ресет) - настраивается в "попугаях" то есть в количестве циклов ожидания. сейчас стоит F_CPU >> 2, что равно 8млн/4=2млн циклов... ну где-то пара секунд.

avr-gcc и все эти вещи, предполагаются на путях - или пишите полные пути в мейкфайле. У меня Линух и стоит все для АВР. На Винде можно все настроить  - есть полные тулчейны, или пропишите путь к тому, что идет с АрдуиноИДЕ.


PROGRAM    = ATmegaBOOT_328only


MCU_TARGET = atmega168
LDSECTION  = --section-start=.text=0x3800


OBJ        = $(PROGRAM).o
OPTIMIZE   = -Os

DEFS       =
LIBS       =

CC         = avr-gcc

# Override is only needed by avr-lib build system.

override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) -DF_CPU=$(AVR_FREQ) $(DEFS)
override LDFLAGS       = -Wl,$(LDSECTION)
#override LDFLAGS       = -Wl,-Map,$(PROGRAM).map,$(LDSECTION)

OBJCOPY        = avr-objcopy
OBJDUMP        = avr-objdump

all:


atmega328bb: TARGET = atmega328
atmega328bb: MCU_TARGET = atmega328p
atmega328bb: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>2' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=19200
atmega328bb: AVR_FREQ = 8000000L
atmega328bb: LDSECTION  = --section-start=.text=0x7800
atmega328bb: $(PROGRAM)_atmega328bb.hex



%.elf: $(OBJ)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

clean:
	rm -rf *.o *.elf *.lst *.map *.sym *.lss *.eep *.srec *.bin *.hex

%.lst: %.elf
	$(OBJDUMP) -h -S $< > $@

%.hex: %.elf
	$(OBJCOPY) -j .text -j .data -O ihex $< $@

2. Сам бутлоадер. Там пара мест моих правок - ЛЕД не на той ноге. Мои места помечены //WLAD.  Чужие комментарии я частично стер частично оставил - мне они нахер не сдались, может кому-то полезны будут. ЕЩЕ РАЗ: "Мопед не мой" - в том смысле, что код не мой, а стандартный из ИДЕ, я причесал чуть чуть.

НАЗЫВАТЬ ЕГО НАДО: ATmegaBOOT_328only.c    И ТОЛЬКО ТАК. Ну или меняйте название в мейкфайле.


/* some includes */
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <util/delay.h>


#define MAX_ERROR_COUNT 5

#ifndef BAUD_RATE
#define BAUD_RATE   19200
#endif

/* SW_MAJOR and MINOR needs to be updated from time to time to avoid warning message from AVR Studio */
/* never allow AVR Studio to do an update !!!! */
#define HW_VER	 0x02
#define SW_MAJOR 0x01
#define SW_MINOR 0x10


#define BL_DDR  DDRD
#define BL_PORT PORTD
#define BL_PIN  PIND
#define BL      PIND6


#define LED_DDR  DDRB
#define LED_PORT PORTB
#define LED_PIN  PINB
#define LED      PINB1 //WLAD




/* manufacturer byte is always the same */
#define SIG1	0x1E	// Yep, Atmel is the only manufacturer of AVR micros.  Single source :(

#if defined __AVR_ATmega168__
#define SIG2	0x94
#define SIG3	0x06
#define PAGE_SIZE	0x40U	//64 words

#elif defined __AVR_ATmega328P__
#define SIG2	0x95
#define SIG3	0x0F
#define PAGE_SIZE	0x40U	//64 words

#elif defined __AVR_ATmega328__
#define SIG2	0x95
#define SIG3	0x14
#define PAGE_SIZE	0x40U	//64 words
#endif



/* function prototypes */
void putch(char);
char getch(void);
void getNch(uint8_t);
void byte_response(uint8_t);
void nothing_response(void);
char gethex(void);
void puthex(char);
void flash_led(uint8_t);

/* some variables */
union address_union {
	uint16_t word;
	uint8_t  byte[2];
} address;

union length_union {
	uint16_t word;
	uint8_t  byte[2];
} length;

struct flags_struct {
	unsigned eeprom : 1;
	unsigned rampz  : 1;
} flags;

uint8_t buff[256];
uint8_t address_high;

uint8_t pagesz=0x80;

uint8_t i;
uint8_t bootuart = 0;

uint8_t error_count = 0;

void (*app_start)(void) = 0x0000;


/* main program starts here */
int main(void)
{
	uint8_t ch,ch2;
	uint16_t w;

	ch = MCUSR;
	MCUSR = 0;
        //WLAD wdt Off!!!
	WDTCSR |= _BV(WDCE) | _BV(WDE);
	WDTCSR = 0;

	// Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
	// WLAD: Just comment this "if" to test. The bootloader will be restarting over and over again, and let you load your code through UART
	if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
		{
                 asm volatile("nop\n\t");
                 app_start();}  // skip bootloader


	/* check if flash is programmed already, if not start bootloader anyway */
	if(pgm_read_byte_near(0x0000) != 0xFF) {

	}



	/* initialize UART(s) depending on CPU defined */

#ifdef DOUBLE_SPEED
	UCSR0A = (1<<U2X0); //Double speed mode USART0
	UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*8L)-1);
	UBRR0H = (F_CPU/(BAUD_RATE*8L)-1) >> 8;
#else
	UBRR0L = (uint8_t)(F_CPU/(BAUD_RATE*16L)-1);
	UBRR0H = (F_CPU/(BAUD_RATE*16L)-1) >> 8;
#endif

	UCSR0B = (1<<RXEN0) | (1<<TXEN0);
	UCSR0C = (1<<UCSZ00) | (1<<UCSZ01);

	/* Enable internal pull-up resistor on pin D0 (RX), in order
	to supress line noise that prevents the bootloader from
	timing out (DAM: 20070509) */
	DDRD &= ~_BV(PIND0);
	PORTD |= _BV(PIND0);


	/* set LED pin as output */
	LED_DDR |= _BV(LED);


	/* flash onboard LED to signal entering of bootloader */
	flash_led(NUM_LED_FLASHES);

	/* 20050803: by DojoCorp, this is one of the parts provoking the
		 system to stop listening, cancelled from the original */
	//putch('\0');

	/* forever loop */
	for (;;) {

	/* get character from UART */
	ch = getch();

	/* A bunch of if...else if... gives smaller code than switch...case ! */

	/* Hello is anyone home ? */ 
	if(ch=='0') {
		nothing_response();
	}


	/* Request programmer ID */
	/* Not using PROGMEM string due to boot block in m128 being beyond 64kB boundry  */
	/* Would need to selectively manipulate RAMPZ, and it's only 9 characters anyway so who cares.  */
	else if(ch=='1') {
		if (getch() == ' ') {
			putch(0x14);
			putch('A');
			putch('V');
			putch('R');
			putch(' ');
			putch('I');
			putch('S');
			putch('P');
			putch(0x10);
		} else {
			if (++error_count == MAX_ERROR_COUNT)
				app_start();
		}
	}


	/* AVR ISP/STK500 board commands  DON'T CARE so default nothing_response */
	else if(ch=='@') {
		ch2 = getch();
		if (ch2>0x85) getch();
		nothing_response();
	}


	/* AVR ISP/STK500 board requests */
	else if(ch=='A') {
		ch2 = getch();
		if(ch2==0x80) byte_response(HW_VER);		// Hardware version
		else if(ch2==0x81) byte_response(SW_MAJOR);	// Software major version
		else if(ch2==0x82) byte_response(SW_MINOR);	// Software minor version
		else if(ch2==0x98) byte_response(0x03);		// Unknown but seems to be required by avr studio 3.56
		else byte_response(0x00);				// Covers various unnecessary responses we don't care about
	}


	/* Device Parameters  DON'T CARE, DEVICE IS FIXED  */
	else if(ch=='B') {
		getNch(20);
		nothing_response();
	}


	/* Parallel programming stuff  DON'T CARE  */
	else if(ch=='E') {
		getNch(5);
		nothing_response();
	}


	/* P: Enter programming mode  */
	/* R: Erase device, don't care as we will erase one page at a time anyway.  */
	else if(ch=='P' || ch=='R') {
		nothing_response();
	}


	/* Leave programming mode  */
	else if(ch=='Q') {
		nothing_response();
#ifdef WATCHDOG_MODS
		// autoreset via watchdog (sneaky!)
		WDTCSR = _BV(WDE);
		while (1); // 16 ms
#endif
	}


	/* Set address, little endian. EEPROM in bytes, FLASH in words  */
	/* Perhaps extra address bytes may be added in future to support > 128kB FLASH.  */
	/* This might explain why little endian was used here, big endian used everywhere else.  */
	else if(ch=='U') {
		address.byte[0] = getch();
		address.byte[1] = getch();
		nothing_response();
	}


	/* Universal SPI programming command, disabled.  Would be used for fuses and lock bits.  */
	else if(ch=='V') {
		if (getch() == 0x30) {
			getch();
			ch = getch();
			getch();
			if (ch == 0) {
				byte_response(SIG1);
			} else if (ch == 1) {
				byte_response(SIG2); 
			} else {
				byte_response(SIG3);
			} 
		} else {
			getNch(3);
			byte_response(0x00);
		}
	}


	/* Write memory, length is big endian and is in bytes  */
	else if(ch=='d') {
		length.byte[1] = getch();
		length.byte[0] = getch();
		flags.eeprom = 0;
		if (getch() == 'E') flags.eeprom = 1;
		for (w=0;w<length.word;w++) {
			buff[w] = getch();	                        // Store data in buffer, can't keep up with serial data stream whilst programming pages
		}
		if (getch() == ' ') {
			if (flags.eeprom) {		                //Write to EEPROM one byte at a time
				address.word <<= 1;
				for(w=0;w<length.word;w++) {
					while(EECR & (1<<EEPE));
					EEAR = (uint16_t)(void *)address.word;
					EEDR = buff[w];
					EECR |= (1<<EEMPE);
					EECR |= (1<<EEPE);
					address.word++;
				}			
			}
			else {					        //Write to FLASH one page at a time
				if (address.byte[1]>127) address_high = 0x01;	//Only possible with m128, m256 will need 3rd address byte. FIXME
				else address_high = 0x00;
				address.word = address.word << 1;	        //address * 2 -> byte location
				/* if ((length.byte[0] & 0x01) == 0x01) length.word++;	//Even up an odd number of bytes */
				if ((length.byte[0] & 0x01)) length.word++;	//Even up an odd number of bytes
				cli();					//Disable interrupts, just to be sure
				while(bit_is_set(EECR,EEPE));			//Wait for previous EEPROM writes to complete
				asm volatile(
					 "clr	r17		\n\t"	//page_word_count
					 "lds	r30,address	\n\t"	//Address of FLASH location (in bytes)
					 "lds	r31,address+1	\n\t"
					 "ldi	r28,lo8(buff)	\n\t"	//Start of buffer array in RAM
					 "ldi	r29,hi8(buff)	\n\t"
					 "lds	r24,length	\n\t"	//Length of data to be written (in bytes)
					 "lds	r25,length+1	\n\t"
					 "length_loop:		\n\t"	//Main loop, repeat for number of words in block							 							 
					 "cpi	r17,0x00	\n\t"	//If page_word_count=0 then erase page
					 "brne	no_page_erase	\n\t"						 
					 "wait_spm1:		\n\t"
					 "lds	r16,%0		\n\t"	//Wait for previous spm to complete
					 "andi	r16,1           \n\t"
					 "cpi	r16,1           \n\t"
					 "breq	wait_spm1       \n\t"
					 "ldi	r16,0x03	\n\t"	//Erase page pointed to by Z
					 "sts	%0,r16		\n\t"
					 "spm			\n\t"							 
					 "wait_spm2:		\n\t"
					 "lds	r16,%0		\n\t"	//Wait for previous spm to complete
					 "andi	r16,1           \n\t"
					 "cpi	r16,1           \n\t"
					 "breq	wait_spm2       \n\t"									 

					 "ldi	r16,0x11	\n\t"	//Re-enable RWW section
					 "sts	%0,r16		\n\t"						 			 
					 "spm			\n\t"
					 "no_page_erase:		\n\t"							 
					 "ld	r0,Y+		\n\t"	//Write 2 bytes into page buffer
					 "ld	r1,Y+		\n\t"							 
								 
					 "wait_spm3:		\n\t"
					 "lds	r16,%0		\n\t"	//Wait for previous spm to complete
					 "andi	r16,1           \n\t"
					 "cpi	r16,1           \n\t"
					 "breq	wait_spm3       \n\t"
					 "ldi	r16,0x01	\n\t"	//Load r0,r1 into FLASH page buffer
					 "sts	%0,r16		\n\t"
					 "spm			\n\t"
								 
					 "inc	r17		\n\t"	//page_word_count++
					 "cpi r17,%1	        \n\t"
					 "brlo	same_page	\n\t"	//Still same page in FLASH
					 "write_page:		\n\t"
					 "clr	r17		\n\t"	//New page, write current one first
					 "wait_spm4:		\n\t"
					 "lds	r16,%0		\n\t"	//Wait for previous spm to complete
					 "andi	r16,1           \n\t"
					 "cpi	r16,1           \n\t"
					 "breq	wait_spm4       \n\t"
					 "ldi	r16,0x05	\n\t"	//Write page pointed to by Z
					 "sts	%0,r16		\n\t"
					 "spm			\n\t"
					 "wait_spm5:		\n\t"
					 "lds	r16,%0		\n\t"	//Wait for previous spm to complete
					 "andi	r16,1           \n\t"
					 "cpi	r16,1           \n\t"
					 "breq	wait_spm5       \n\t"									 
					 "ldi	r16,0x11	\n\t"	//Re-enable RWW section
					 "sts	%0,r16		\n\t"						 			 
					 "spm			\n\t"					 		 
					 "same_page:		\n\t"							 
					 "adiw	r30,2		\n\t"	//Next word in FLASH
					 "sbiw	r24,2		\n\t"	//length-2
					 "breq	final_write	\n\t"	//Finished
					 "rjmp	length_loop	\n\t"
					 "final_write:		\n\t"
					 "cpi	r17,0		\n\t"
					 "breq	block_done	\n\t"
					 "adiw	r24,2		\n\t"	//length+2, fool above check on length after short page write
					 "rjmp	write_page	\n\t"
					 "block_done:		\n\t"
					 "clr	__zero_reg__	\n\t"	//restore zero register
					 : "=m" (SPMCSR) : "M" (PAGE_SIZE) : "r0","r16","r17","r24","r25","r28","r29","r30","r31"
					 );
				/* Should really add a wait for RWW section to be enabled, don't actually need it since we never */
				/* exit the bootloader without a power cycle anyhow */
			}
			putch(0x14);
			putch(0x10);
		} else {
			if (++error_count == MAX_ERROR_COUNT)
				app_start();
		}		
	}


	/* Read memory block mode, length is big endian.  */
	else if(ch=='t') {
		length.byte[1] = getch();
		length.byte[0] = getch();
		address.word = address.word << 1;	        // address * 2 -> byte location
		if (getch() == 'E') flags.eeprom = 1;
		else flags.eeprom = 0;
		if (getch() == ' ') {		                // Command terminator
			putch(0x14);
			for (w=0;w < length.word;w++) {		        // Can handle odd and even lengths okay
				if (flags.eeprom) {	                        // Byte access EEPROM read
					while(EECR & (1<<EEPE));
					EEAR = (uint16_t)(void *)address.word;
					EECR |= (1<<EERE);
					putch(EEDR);
					address.word++;
				}
				else {

					if (!flags.rampz) putch(pgm_read_byte_near(address.word));
					address.word++;
				}
			}
			putch(0x10);
		}
	}


	/* Get device signature bytes  */
	else if(ch=='u') {
		if (getch() == ' ') {
			putch(0x14);
			putch(SIG1);
			putch(SIG2);
			putch(SIG3);
			putch(0x10);
		} else {
			if (++error_count == MAX_ERROR_COUNT)
				app_start();
		}
	}


	/* Read oscillator calibration byte */
	else if(ch=='v') {
		byte_response(0x00);
	}


	else if (++error_count == MAX_ERROR_COUNT) {
		app_start();
	}
	} /* end of forever loop */

}


char gethexnib(void) {
	char a;
	a = getch(); putch(a);
	if(a >= 'a') {
		return (a - 'a' + 0x0a);
	} else if(a >= '0') {
		return(a - '0');
	}
	return a;
}


char gethex(void) {
	return (gethexnib() << 4) + gethexnib();
}


void puthex(char ch) {
	char ah;

	ah = ch >> 4;
	if(ah >= 0x0a) {
		ah = ah - 0x0a + 'a';
	} else {
		ah += '0';
	}
	
	ch &= 0x0f;
	if(ch >= 0x0a) {
		ch = ch - 0x0a + 'a';
	} else {
		ch += '0';
	}
	
	putch(ah);
	putch(ch);
}


void putch(char ch)
{
	while (!(UCSR0A & _BV(UDRE0)));
	UDR0 = ch;
}


char getch(void)
{
	uint32_t count = 0;
	while(!(UCSR0A & _BV(RXC0))){
		/* 20060803 DojoCorp:: Addon coming from the previous Bootloader*/               
		/* HACKME:: here is a good place to count times*/
		count++;
		if (count > MAX_TIME_COUNT){
//			flash_led(1); 
			app_start();
		}
	}
	return UDR0;
}


void getNch(uint8_t count)
{
	while(count--) {
		getch();
	}
}


void byte_response(uint8_t val)
{
	if (getch() == ' ') {
		putch(0x14);
		putch(val);
		putch(0x10);
	} else {
		if (++error_count == MAX_ERROR_COUNT)
			app_start();
	}
}


void nothing_response(void)
{
	if (getch() == ' ') {
		putch(0x14);
		putch(0x10);
	} else {
		if (++error_count == MAX_ERROR_COUNT)
			app_start();
	}
}

void flash_led(uint8_t count)
{
	while (count--) {
		LED_PORT |= _BV(LED);
		_delay_ms(100);
		LED_PORT &= ~_BV(LED);
		_delay_ms(100);
	}
}


/* end of file ATmegaBOOT.c */

3. ну и boards.txt к ним до кучи.

Скорость компорта тут и в мейкфайле должна совпадать.

##############################################################

atmega328bb1.name=ATmega328 on a breadboard1 (8 MHz internal clock)

atmega328bb1.upload.protocol=arduino
atmega328bb1.upload.maximum_size=28672
atmega328bb1.upload.speed=19200

atmega328bb1.bootloader.low_fuses=0xE2
#atmega328bb1.bootloader.high_fuses=0xD8
atmega328bb1.bootloader.high_fuses=0xD8
atmega328bb1.bootloader.extended_fuses=0xFD

atmega328bb1.bootloader.file=atmega/ATmegaBOOT_328only_atmega328bb.hex
#atmega328bb1.bootloader.file=atmega/optiboot_atmega328bb.hex
atmega328bb1.bootloader.unlock_bits=0x3F
atmega328bb1.bootloader.lock_bits=0x0F

atmega328bb1.build.board=ATMEGA328BB1
atmega328bb1.build.mcu=atmega328p
atmega328bb1.build.f_cpu=8000000L
atmega328bb1.build.core=arduino:arduino
atmega328bb1.build.variant=arduino:standard


atmega328bb1.bootloader.tool=arduino:avrdude
atmega328bb1.upload.tool=arduino:avrdude

=======================================

все это проверено в условиях:

Бутлоадер грузился через Нано с ArduinoISP из 1.8.5.

В качестве USB-UART использовалась Мега с закороченным на GND Ресетом.

В качестве тестового скетча был использован скетч из этой темы выше, мой вариант теста Вочдога. Только вывод был в Сериал, а не на дисплей.

Откомпилированный именно этот код, для тех, кого компилятор "не встает" на сборку бутлоадера ;) ;) ;)!!!.

:107800000C94343C0C94513C0C94513C0C94513CE1
:107810000C94513C0C94513C0C94513C0C94513CB4
:107820000C94513C0C94513C0C94513C0C94513CA4
:107830000C94513C0C94513C0C94513C0C94513C94
:107840000C94513C0C94513C0C94513C0C94513C84
:107850000C94513C0C94513C0C94513C0C94513C74
:107860000C94513C0C94513C11241FBECFEFD8E036
:10787000DEBFCDBF11E0A0E0B1E0E2EEFDE702C067
:1078800005900D92A230B107D9F712E0A2E0B1E065
:1078900001C01D92AD30B107E1F70E940B3D0C9481
:1078A000EF3E0C94003C9091C00095FFFCCF80937C
:1078B000C6000895CF93982F959595959595959594
:1078C000905D8F708A3014F0C7E501C0C0E3C80F27
:1078D000892F0E94533C8C2FCF910C94533CCF9214
:1078E000DF92EF92FF92C12CD12C76018091C000E3
:1078F00087FD13C08FEFC81AD80AE80AF80A81E892
:10790000C81684E8D8068EE1E806F10478F3E09121
:107910000201F09103010995E9CF8091C600FF9023
:10792000EF90DF90CF900895CF930E946F3CC82FC7
:107930000E94533CC13614F089EA03C0C0331CF0E6
:1079400080ED8C0F01C08C2FCF910895CF930E94B2
:10795000943CC82F0E94943C90E1C99F800D112453
:10796000CF910895CF93C82FCC2321F00E946F3C74
:10797000C150FACFCF910895CF93C82F0E946F3C8A
:10798000803251F484E10E94533C8C2F0E94533C7E
:1079900080E1CF910C94533C809104018F5F8093E0
:1079A0000401853031F4E0910201F0910301CF919F
:1079B0000994CF9108950E946F3C803231F484E1A4
:1079C0000E94533C80E10C94533C809104018F5FF2
:1079D00080930401853029F4E0910201F0910301C4
:1079E000099408958823B1F0299A2FEF30E792E0A7
:1079F000215030409040E1F700C0000029982FEF5F
:107A000030E792E0215030409040E1F700C00000A4
:107A10008150E8CF089594B714BE809160008861CA
:107A2000809360001092600091FD06C00000E0911C
:107A30000201F0910301099589E18093C40010923D
:107A4000C50088E18093C10086E08093C200509811
:107A5000589A219A81E00E94F23CFF24F3940E94FC
:107A60006F3C803309F442C08133E1F40E946F3CE3
:107A7000803209F0A6C184E10E94533C81E40E9457
:107A8000533C86E50E94533C82E50E94533C80E2D1
:107A90000E94533C89E40E94533C83E50E94533C7E
:107AA00080E586C1803439F40E946F3C8638F0F05E
:107AB0000E946F3C1BC08134A1F40E946F3C80384F
:107AC00011F482E003C0813821F481E00E94BC3CC3
:107AD000C6CF823811F480E1F9CF8839C9F583E047
:107AE000F5CF823431F484E10E94B23C0E94DB3C49
:107AF000B6CF853411F485E0F7CF982F9D7F903570
:107B0000A9F3813599F3853549F40E946F3C809340
:107B100006010E946F3C80930701E8CF8635D1F4BF
:107B20000E946F3C803389F40E946F3C0E946F3C3E
:107B3000182F0E946F3C111102C08EE1C7CF113087
:107B400011F485E9C3CF8FE0C1CF83E00E94B23C3E
:107B500080E0BCCF843609F0C6C00E946F3C8093A1
:107B600009020E946F3C8093080280910C028E7F74
:107B700080930C020E946F3C853429F480910C02A2
:107B8000816080930C0208E011E0809108029091DE
:107B900009029801285031402817390730F40E9413
:107BA0006F3CF80181938F01F0CF0E946F3C8032CF
:107BB00009F007C120910C02809106019091070104
:107BC00020FF29C0880F991F909307018093060119
:107BD000E8E0F1E080910802909109029F012850AD
:107BE00031402817390708F07CC0F999FECF809101
:107BF00006019091070192BD81BD819180BDFA9AE5
:107C0000F99A8091060190910701019690930701DE
:107C100080930601DFCF20910701220F220B2F2135
:107C200020930B02880F991F909307018093060100
:107C30008091080280FF09C080910802909109029A
:107C400001969093090280930802F894F999FECF67
:107C50001127E0910601F0910701C8E0D1E0809181
:107C6000080290910902103091F4009157000170C0
:107C70000130D9F303E000935700E89500915700D5
:107C800001700130D9F301E100935700E8950990A4
:107C900019900091570001700130D9F301E0009371
:107CA0005700E8951395103498F01127009157006C
:107CB00001700130D9F305E000935700E895009179
:107CC000570001700130D9F301E100935700E895A6
:107CD0003296029709F0C7CF103011F00296E5CF27
:107CE000112484E165C0843709F052C00E946F3CC2
:107CF000809309020E946F3C8093080280910601E4
:107D000090910701880F991F9093070180930601B6
:107D10000E946F3C90910C02853411F4916001C077
:107D20009E7F90930C020E946F3C803209F097CEA8
:107D300084E10E94533C00E010E0809108029091A1
:107D4000090208171907B0F580910C0280FF0BC0DB
:107D5000F999FECF809106019091070192BD81BDF6
:107D6000F89A80B507C081FD07C0E0910601F09147
:107D7000070184910E94533C809106019091070174
:107D8000019690930701809306010F5F1F4FD5CF97
:107D90008537A1F40E946F3C803299F484E10E94FF
:107DA000533C8EE10E94533C85E90E94533C8FE096
:107DB0000E94533C80E10E94533C51CE863709F427
:107DC000C7CE809104018F5F80930401853009F054
:107DD00046CEE0910201F0910301099540CEF8945E
:027DE000FFCFD3
:027DE20080001F
:040000030000780081
:00000001FF

 

кудрявый
Offline
Зарегистрирован: 14.12.2017

В продолжение темы бутлоадеров с работоспособным вотчдогом.

Прикупил ПроМини с 168P и кварцом 8 мгц (3,3в). Заливал загрузчик из пакета оптибута: optiboot_pro_8MHz.hex. (USBASP)

Пробовал залить из "Конструктор Bootloader`а" с конфигурацией 168 / 8.

В обеих случаях потом не могу загрузить сектч через uart.

         Using Port                    : COM3
         Using Programmer              : arduino
         Overriding Baud Rate          : 57600
avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_getsync() attempt 1 of 10: not in sync: resp=0xec

скорость порта менял от 9600 до 115200. результат тот же.

Фюзы - E:FC, H:DD, L:C6

Что делаю не так и где взять рабочий бутлоадер на 8мгц (маленький и с вотчдогом)

 

b707
Offline
Зарегистрирован: 26.05.2017

так через UART или через USBASP ? - это как бы принципиально разные вещи

кудрявый
Offline
Зарегистрирован: 14.12.2017

бутлоадер через USBASP, потом уже скетч пытался через UART.

lean_74
Offline
Зарегистрирован: 22.12.2015
кудрявый
Offline
Зарегистрирован: 14.12.2017

lean_74 пишет:

я брал отсюда: http://homes-smart.ru/index.php/oborudovanie/arduino/avr-zagruzchik

Брал и там тоже. Не работает. Если у вас работает, расскажите подробнее какая у вас конфигурация, какие фьюзы и на какой скорости заливаете скетчи, с помощью этого загрузчика. Вполне вероятно, я что-то сделал не так...

lean_74
Offline
Зарегистрирован: 22.12.2015
:103E0000F894112484B714BE81FFF0D085E080932C
:103E1000810082E08093C00088E18093C10086E049
:103E20008093C20088E08093C4008EE0C9D0259AB8
:103E300086E028E13EEF91E03093850020938400F6
:103E400096BBB09BFECF1D9AA8958150A9F7CC24B4
:103E5000DD2488248394B5E0AB2EA1E19A2EF3E013
:103E6000BF2EA2D0813461F49FD0082FAFD002388A
:103E700011F0013811F484E001C083E08DD089C0D5
:103E8000823411F484E103C0853419F485E0A6D0AE
:103E900080C0853579F488D0E82EFF2485D0082F9E
:103EA00010E0102F00270E291F29000F111F8ED0A0
:103EB00068016FC0863521F484E090D080E0DECFC9
:103EC000843609F040C070D06FD0082F6DD080E0EC
:103ED000C81688E3D80618F4F601B7BEE895C0E026
:103EE000D1E062D089930C17E1F7F0E0CF16F8E348
:103EF000DF0618F0F601B7BEE89568D007B600FCFB
:103F0000FDCFA601A0E0B1E02C9130E011968C919C
:103F1000119790E0982F8827822B932B1296FA0105
:103F20000C0187BEE89511244E5F5F4FF1E0A03889
:103F3000BF0751F7F601A7BEE89507B600FCFDCF15
:103F400097BEE89526C08437B1F42ED02DD0F82E38
:103F50002BD03CD0F601EF2C8F010F5F1F4F8491C7
:103F60001BD0EA94F801C1F70894C11CD11CFA9443
:103F7000CF0CD11C0EC0853739F428D08EE10CD07F
:103F800084E90AD086E07ACF813511F488E018D030
:103F90001DD080E101D065CF982F8091C00085FFB2
:103FA000FCCF9093C60008958091C00087FFFCCF9E
:103FB0008091C00084FD01C0A8958091C60008953D
:103FC000E0E6F0E098E1908380830895EDDF8032B1
:103FD00019F088E0F5DFFFCF84E1DECF1F93182FC3
:103FE000E3DF1150E9F7F2DF1F91089580E0E8DF89
:063FF000EE27FF270994F3
:0400000300003E00BB
:00000001FF
Блок файла boards.txt для Arduino IDE: 

a168_8MHz.name=atmega168 (8 MHz) 
a168_8MHz.upload.protocol=arduino 
a168_8MHz.upload.maximum_size=15872 
a168_8MHz.upload.speed=115200 
a168_8MHz.bootloader.low_fuses=0xff 
a168_8MHz.bootloader.high_fuses=0xde 
a168_8MHz.bootloader.extended_fuses=0x4 
a168_8MHz.bootloader.path=optiboot 
a168_8MHz.bootloader.file=a168_8MHz_ff_de_4.hex 
a168_8MHz.build.mcu=atmega168 
a168_8MHz.build.f_cpu=8000000L 
a168_8MHz.build.core=arduino 
a168_8MHz.build.variant=standard 

Прошивка через Arduino: avrdude -c avrisp -P COM1 -b 19200 -p atmega168 -U flash:w:a168_8MHz_ff_de_4.hex -U lfuse:w:0xff:m -U hfuse:w:0xde:m -U efuse:w:0x4:m
Прошивка через USBasp: avrdude -c usbasp -p atmega168 -U flash:w:a168_8MHz_ff_de_4.hex -U lfuse:w:0xff:m -U hfuse:w:0xde:m -U efuse:w:0x4:m

 

lean_74
Offline
Зарегистрирован: 22.12.2015

Как то так все работает, на 115200 шьется. Понятно, что верхний файлик переименовываешь в a168_8MHz_ff_de_4.hex и кладешь в паgку optiboot. в boards.txt добавляешь, что ниже. Далее перезагружаешь IDE, в списке видишь свою плату, Далее с помощью USBASP загрузить загрузчик, чтобы правильно прописались фьюзы. И пользуешься через UART.

 

кудрявый
Offline
Зарегистрирован: 14.12.2017

То что у меня 168P роли не играет? просто скорректировать 168 на 168Р в board.txt?

b707
Offline
Зарегистрирован: 26.05.2017

Несколько человек уже отписывались, что через USBASP не могут нормально бутлоадер прописать. Уж не знаю в чем дело, толи дешевые USBASP глячат, то ли в ИДЕ какие несовместимости.

Ардуиной через SPI скетчем "Ардуино-ИСП" записывается надежнее. 

кудрявый
Offline
Зарегистрирован: 14.12.2017

А коллективный разум уже решил что цеплять к входу ресет программируемой ProMini ?

А то я встречал от "ничего" до "электролит 47-100мкф"...

b707
Offline
Зарегистрирован: 26.05.2017

Я прошивал голый 328р на собственной плате через АрдуиноИСП, ресет посоединял напрямую к 10 пину программатора, без резисторов и кондеров.