Спутниковое телевидение
Atmega fusebit doctor — исправляем микроконтроллер
Для исправления микроконтроллеров с неправильно прошитыми фьюзами собрал Atmega fusebit doctor. Как у большинства начинающих, программирование микроконтроллеров заканчивается залочиванием кристалла неправильно выставленными фьюзами. Не обошла и эта проблема меня, в результате, две Atmega8 и три Atmega328P в dip корпусе лежат у меня в коробке. Изучая в интернете вопрос «как разлочить микроконтроллер Atmega», попал на сайт getchip, где автор предложил свой вариант устройства Atmega fusebit doctor для исправления фьюзов до заводских. Единственным фактором являлась цена Atmega8. В городе в магазине радиодеталей Atmega8 стоит 320 рублей. Пришлось заказывать на площадке Aliexpress микроконтроллер, доставка составила 26 дней. За это время подготовил плату, и распаял детали.
Изготавливать плату с кучей dip панелей под разные микроконтроллеры не хотелось, так как в наличии Atmega8 и Atmega328P dip корпусе с неправильно прошитыми фьюзами. Решил оставить только один разъем к которому, есть возможность подключать переходники адаптеры под разные микроконтроллеры, если возникнит такая необходимость. Схема устройства взята с сайта автора и имеет версию 2h. Я ее немного изменил: резисторы smd тип 0805, транзисторы smd выпаял из старой материнской птаты. Перед установкой транзисторов проверил исправность с помощью ESR тестер. Стабилизатор напряжения +5V на чипе ams1117-5.0. Плату развел программой Sprint Layout под smd детали. Также заранее необходимо прошить микроконтроллер Atmega8 любым подходящим и имеющимся у вас в наличии программатором. Я рекомендую программатор USB ISP для прошивки кристала Atmega8. Стоит не забывать про правильно выставление фьюзы для прошивки микроконтроллера.
Переходник Atmega8 и Atmega328P dip корпусе
Изготовленная плата с распаянными деталями
После подачи постоянного напряжения +12В на плату устройство при правильной сборке и монтаже запустится сразу же о чем будет сигнализировать красный светодиод. Блок питания на 12V от старой телевизионной приставки. Этот блок питания использую для подачи напряжения на электромотор, для сверления отверстий в печатных платах.
Изготовленный переходник для Atmega8 и Atmega328P
Индикации готового устройства имеет два светодиода – красный и зеленый цвета.
Горит зеленый светодиод – микроконтроллер успешно вылечен, фьюз биты восстановлены до заводских. То есть если микроконтроллер «залочен» (LockBits включены), проверяются фьюз биты и если они совпадают с заводскими – загорается зеленый светодиод.
Горит красный светодиод – проблемы с сигнатурой микроконтроллера, невозможно прочитать микрокод, нет микроконтроллера в панельке или нет такого микрокода в кристале данных Atmega8.
Зеленый светодиод мигает – микрокод в порядке, фьюз биты с ошибкой, но исправить их невозможно, так как микроконтроллер «залочен» (LockBits включены), необходимо полное стирание данных микроконтроллера, для этого нужно установить перемычку для полного стирания кристала – «ALLOW ERASE».
Мигает красный светодиод – микрокод в порядке, микроконтроллер «не залочен», но, по какой-то причине, нет возможности восстановить фьюз биты.
На плате есть 3-х пиновый разъем UART, через который наше устройство Atmega fusebit doctor есть возможность подключить к компьютеру через соответствующий переходник и считывать данные о процессе восстановления микроконтроллера.
Список микроконтроллеров: успешно востановленных пользователями устройством Atmega fusebit doctor.
1kB:
AT90s1200, Attiny11, Attiny12, Attiny13/A, Attiny15
2kB:
Attiny2313/A, Attiny24/A, Attiny26, Attiny261/A, Attiny28, AT90s2333, Attiny22,Attiny25, AT90s2313, AT90s2323, AT90s2343
4kB:
Atmega48/A, Atmega48P/PA, Attiny461/A, Attiny43U, Attiny4313, Attiny44/A, Attiny48, AT90s4433, AT90s4414, AT90s4434, Attiny45
8kB:
Atmega8515, Atmega8535, Atmega8/A, Atmega88/A, Atmega88P/PA, AT90pwm1, AT90pwm2, AT90pwm2B, AT90pwm3, AT90pwm3B, AT90pwm81, AT90usb82, Attiny84, Attiny85, Attiny861/A, Attiny87, Attiny88, AT90s8515, AT90s8535
16kB:
Atmega16/A, Atmega16U2, Atmega16U4, Atmega16M1, Atmega161, Atmega162, Atmega163, Atmega164A, Atmega164P/PA, Atmega165A/P/PA, Atmega168/A, Atmega168P/PA, Atmega169A/PA, Attiny167, AT90pwm216, AT90pwm316, AT90usb162
32kB:
Atmega32/A, Atmega32C1, Atmega323/A, Atmega32U2, Atmega32U4, Atmega32U6, Atmega32M1, Atmega324A, Atmega324P, Atmega324PA, Atmega325, Atmega3250, Atmega325A/PA, Atmega3250A/PA, Atmega328, Atmega328P, Atmega329, Atmega3290, Atmega329A/PA, Atmega3290A/PA, AT90can32
64kB:
Atmega64/A, Atmega64C1, Atmega64M1, Atmega649, Atmega6490, Atmega649A/P, Atmega6490A/P, Atmega640, Atmega644/A, Atmega644P/PA, Atmega645, Atmega645A/P, Atmega6450, Atmega6450A/P, AT90usb646, AT90usb647, AT90can64
128kB:
Atmega103, Atmega128/A, Atmega1280, Atmega1281, Atmega1284, Atmega1284P, AT90usb1286, AT90usb1287, AT90can128
256kB:
Atmega2560, Atmega2561
Успешно вылечил свои микроконтроллеры.Теперь в программаторе USB ISP микроконтроллеры Atmega читаються и прошиваються.
Источник
Параллельный программатор / фьюз-бит доктор для контроллеров avr
Получив из Китая очередную партию чипов ATtiny2313 для изготовления шлюзов UART-to-I2C/SPI/1W я, вдруг, обнаружил, что эти чипы совершенно невозможно прошить последовательным внутрисхемным (ICSP) программатором. Чипы при этом были в заводской упаковке и без следов пайки. Ранее я уже сталкивался с ситуациями, когда китайцы продавали новые рабочие чипы, но заранее прошитые под какие-либо устройства (например, — вот). Такие чипы прошивают нужной прошивкой прямо на заводе, но, видимо, время от времени случаются накладки, заказчик не забирает партию и чипы попадают в открытую продажу.
Ситуация в общем-то обычная, сложность же конкретно с контроллерами AVR заключается в том, что при сбросе определённых фьюзов, прошить контроллер становится возможно только параллельным программатором в режиме высоковольтного программирования (с использованием напряжения +12 Вольт). Схемы фьюз-докторов для AVR можно найти в интернете, однако минус всех этих схем заключается в полном отсутствии описания их работы. Выложена просто готовая прошивка, которую нужно залить в управляющий схемой контроллер, включить, нажать кнопку и будет вам счастье. Ни исходников, ни подробностей, вообще никаких объяснений.
Для меня, как для радиохламера, такой подход совершенно невозможен и невыносим, поэтому решено было разработать свой собственный программатор / фьюз-бит доктор для микроконтроллеров AVR, описать как он работает и выложить в открытый доступ не только прошивку, но и исходники программы для микроконтроллера с комментариями. Итак, поехали:
В любом даташите на микроконтроллеры AVR есть глава «Memory Programming». Если микроконтроллер поддерживает параллельное программирование (здесь и далее в этой статье под этим термином понимается заливка прошивки в микроконтроллер), то в этой главе есть раздел «Parallel Programming». В этом разделе, во-первых, описано какие сигналы и ноги используются при параллельном программировании, во-вторых, описаны используемые при этом команды и алгоритмы и, в третьих, приводятся диаграммы сигналов. В общем, — всё, что нужно для успеха операции.
Для начала разберёмся с сигналами. Сигналы используются следующие:
- 8 сигналов для параллельного приёма/передачи байта данных DATA[7:0]. Сигналы передаются в обоих направлениях в зависимости от сигнала OE.
- 9 служебных сигналов:
- RDY/BSY — уровень на этой линии сигнализирует о готовности контроллера принимать новые команды. Данные передаются от контроллера к программатору
- OE — служит для переключения линий данных на вход (высокий уровень) или на выход (низкий уровень)
- WR — используется для старта выполнения каких-либо действий (стирание / запись …)
- BS2, BS1 — эти две линии используются для выбора старших или младших байт
- XA1, XA0 — по уровням на этих двух линиях определяется какое действие будет выполняться по наличию тактового импульса
- PAGEL — используется при программировании Flash/EEPROM
- XTAL1 — используется для подачи тактовых импульсов
Кроме этого нам потребуется напряжение +12 Вольт (для перехода в режим программирования), +5 Вольт — для питания контроллера, ну и естественно нужно будет подключить нулевой провод, относительно которого задаются +12 и +5 Вольт, к ноге GND.
В некоторых контроллерах какие-то сигналы могут быть объединены (например, в ATtiny2313 объединены ноги BS1 и PAGEL, а также XA1 и BS2), кроме того, могут отличаться номера ног, на которые заводятся эти сигналы (например, в ATmega8 для данных используются два младших бита порта C и 5 младших бит порта B, а в ATtiny2313 для данных используется только порт B целиком).
С алгоритмами тоже всё оказалось довольно просто, — вся задача сводится к выставлению нужных уровней на некоторые служебные линии (XA1, XA0, BS2, BS1, OE) и линии данных, а также к генерированию положительных или отрицательных импульсов на других служебных линиях (XTAL1, WR, PAGEL). Плюс нужно управлять питанием +5 Вольт (+1 линия) и напряжением +12 Вольт (ещё +1 линия). Управление всеми нужными линиями решено было сделать командами через UART (для этого нужно ещё 2 линии).
Исходя из всего выше описанного, для реализаци устройства нужно иметь 21 линию I/O (8 — данные + 9 — служебные сигналы + 2 — управление линиями +5 и +12 Вольт + 2 — uart), что, согласитесь, довольно много. Чтобы ног на всё хватило, в качестве управляющего контроллера была выбрана ATmega8 (для прототипа, естественно, в dip-корпусе), — у неё 23 линии I/O.
Справа на схеме нарисовано как подключать к ней микроконтроллеры ATtiny2313.
Места печатной платы для которых показаны связи, но отсутствуют медные дорожки, должны быть соединены изолированными проводами, навесным монтажом (ниже будет фото собранной платы). При разработке печатной платы прототипа основным параметром оптимизации было удобство изготовления и сборки, поэтому плата выглядит достаточно громоздко, имеет кучу навесных перемычек и откровенно уродливый вид. Как я уже говорил, плюсы этой платы заключаются в другом:
- разводка выполнена для одностороннего текстолита (не нужно совмещать разные стороны при переносе рисунка на плату)
- использован контроллер в dip-корпусе (возможность установки в кроватку + большие расстояния между ножками обеспечивают лёгкость пайки)
- все нужные контакты выведены на линейки с большим шагом (2,54 мм)
- есть разъём для внутрисхемного программирования управляющего контроллера (для отладки очень удобно прошивать контроллер прямо на плате, не вынимая из кроватки)
При разводке платы я также предусмотрел установку конденсаторов по линиям питания +5 и +12 Вольт (прямо рядом с разъёмом питания). Эти конденсаторы на схеме не нарисованы, но я решил их на всякий случай поставить. Большого тока схема не потребляет, поэтому будет достаточно конденсаторов на 10-47 мкФ, рассчитанных на максимальное напряжение 16-25 Вольт и выше.
После сборки устройство выглядит вот так:
В соответствии с приведёнными в даташитах алгоритмами и диаграммами наш программатор должен уметь делать следующие вещи:
- переходить в режим программирования
- устанавливать и считывать уровни на линиях DATA[7:0]
- выставлять правильные уровни на линиях XA1, XA0, BS2, BS1, OE
- генерировать импульсы заданной ширины на линиях WR, XTAL1, PAG
Учитывая, что переходить в режим программирования нужно из какого-то начального состояния, а также то, что линия PAG может быть совмещена с BS1, — для реализации заявленного выше функционала нам хватит всего 11-дцати UART-команд, которые я просто пронумеровал от 0x1 до 0xB:
- 0x01 — установить все используемые для программирования выводы (включая выводы, управляющие линиями +5 и +12 вольт) в начальное состояние
- 0x02 — выполнить алгоритм перехода в режим программирования
- 0x03 — выполнить алгоритм выхода из режима программирования
- 0x04 — установить нужное состояние на линиях XA1/XA0 и BS2/BS1
- 0x05 — установить нужное состояние на линии OE
- 0x06 — сформировать положительный импульс на линии BS1
- 0x07 — сформировать положительный импульс на линии PAG
- 0x08 — сформировать положительный импульс на линии XTAL1
- 0x09 — сформировать отрицательный импульс на линии WR
- 0x0A — установить нужные уровни на линиях Data[7:0]
- 0x0B — прочитать состояния линий Data[7:0]
Теперь некоторые моменты обсудим более детально:
Во-первых. В даташитах написано, что перед переходом в режим программирования нужно установить сигналы XA1, XA0, BS1 и WR (они называются Prog_enable) в ‘0000’. Поскольку сигнал на линии WR инвертирован (active low) и далее на всех диаграммах он начинается с высокого уровня, то логично было бы предположить, что его начальное состояние — это высокий уровень (именно он для него означает 0). На деле оказалось, что это работает только после подачи питания, а до подачи питания для всех ног 0 — это низкий уровень, и перед переходом в режим программирования все ноги, входящие в группу Prog_enable должны быть притянуты к низкому уровню.
Сам алгоритм перехода в режим программирования банален, — после того, как все линии Prog_enable притянуты к низкому уровню — нужно включить питание +5 Вольт и далее через 20-60 мкс включить напряжение +12 Вольт. Через 10 мкс после этого можно начинать переключать линии Prog_enable, а через 300 мкс — загружать каманды.
Выйти из режима программирования можно отключив от программируемого чипа +12 Вольт или +5 Вольт (или оба сразу).
Далее. Как можно заметить, для выполнения некоторых команд из приведённого выше списка нужны дополнительные данные. Например, команда «установить нужное состояние на линии OE» не позволяет сделать никаких выводов о том, что это за нужное состояние. Для таких команд мы будем устанавливать специальные флаги, которые будут означать, что следующий принимаемый по UART байт — это не новая команда, а те самые данные о «нужных состояниях» линий (состояния линий будут соответствовать определённым битам полученного байта).
Ну и, наконец, чтобы как-то сообщить компьютеру о том, что предыдущий принятый байт обработан и можно посылать следующий — будем отсылать обратно на компьютер 0x00 в случае успешной обработки очередного принятого байта или 0xFF в случае его неуспешной обработки. Вот, собственно, и вся концепция.
Исходя из всего вышеописанного получилась следующая программа:
;— radiohlam.ru — .device ATmega8 .include «m8def.inc» .list ;— по-умолчанию фьюзы CSEL = 0001 (1 МГц), нужно поставить CSEL = 0100 (8 МГц) ;— определяем свои переменные (и раздаём под них регистры) .def w=r16 ; аккумулятор (обменник) .def wait_flags=r17 ; флаги ожидания данных (0 — XA1/XA0/BS2/BS1, 1 — OE, 2 — Data) .def fd_reg=r19 ; счётчик для организации быстрых (маленьких) задержек (шаг 1 мкс) .def ld_reg=r20 ; счётчик для организации медленных (больших) задержек (шаг 200 мкс) .def w2=r21 ; ещё одна переменная для временного хранения всякой фигни ;— определяем названия выводов и портов .equ Data_Out = 0x18 ; порт B — вывод данных (линии данных на выход) .equ Data_In = 0x16 ; порт B — ввод данных (линии данных на вход) .equ RDY = 0 ; PC0 .equ BS1 = 1 ; PC1 .equ BS2 = 2 ; PC2 .equ XA0 = 3 ; PC3 .equ XA1 = 4 ; PC4 .equ PAG = 5 ; PC5 .equ OE = 2 ; PD2 .equ XTAL1 = 3 ; PD3 .equ WR = 4 ; PD4 .equ Ctrl_12 = 6 ; PD6 .equ Ctrl_5 = 7 ; PD7 .equ RxD = 0 ; PD0 .equ TxD = 1 ; PD1 .equ MinCommandNumber = 0x1 ; минимальный номер команды .equ MaxCommandNumber = 0xB ; максимальный номер команды ;—————————————— ;— начало программного кода .cseg .org 0 rjmp Init ; переход на начало программы (вектор сброса) ;— дальше идут вектора прерываний ;— если не используем — reti, иначе — переход на начало обработчика reti ; внешнее прерывание INT0 reti ; внешнее прерывание INT1 reti ; Timer2 COMP reti ; Timer2 OVF reti ; Timer1 CAPT reti ; Timer1 COMPA reti ; Timer1 COMPB reti ; Timer1 OVF reti ; Timer0 OVF reti ; SPI, STC rjmp RX_INT ; USART, Rx complete reti ; USART, DataRegister Empty reti ; USART, Tx complete reti ; ADC conversion complete reti ; EEPROM ready reti ; Analog comparator reti ; TWI (two-wire serial interface) reti ; Store Program Memory Ready ;— начало программы Init: ;— устанавливаем указатель вершины стека на старший байт RAM ldi w,Low(RAMEND) out SPL,w ; младший байт адреса ldi w,High(RAMEND) out SPH,w ; старший байт адреса ;— отключаем лишнее sbi ACSR,ACD ; выключаем компаратор ;— инициализируем порты ;— DDR — направление работы (0 — вход, 1 — выход) ;— PORT — состояние защёлок / подтяжек (0 — низкий уровень / нет подтяжки, 1 — высокий уровень / есть подтяжка) ;— настраиваем PORTD (состояние — все, кроме PD2(OE), PD4(WR), PD7(+5) — нули, направление — все на выход) ldi w,0b10000000 out PORTD,w ldi w,0b11111111 out DDRD,w ;— настраиваем PORTC (состояние — все нули, направление — все на выход, кроме PC0(RDY)) clr w out PORTC,w ldi w, 0b11111110 out DDRC,w ;— настраиваем PORTB (состояние — все нули, направление — все на выход) clr w out PORTB,w ser w out DDRB,w ;— инициализируем UART clr w out UBRRH,w ; UBRR (для кварца 8 МГц и скорости 38400) ldi w,12 ; равен 12, т.е. UBRRH = 0, UBRRL = 12 out UBRRL,w ldi w,0b10001110 ; поднимаем биты USBS, UCSZ1:0 + старший бит (URSEL) должен быть 1 при записи в UCSRC ; в примере из оф.доки на мегу — косяк, они просто скопировали пример из 2313 ; (в 2313 старший бит был не важен) out UCSRC,w ; формат: 1 старт, 8 данные, 2 стоп ldi w, (1
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.
Источник