Bit-Banging I2C (TWI) Software slave AVR
Apr. 17th, 2011 07:26 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Простенькая задачка, но ковырял я её недели две, наверное.
Дело в том, что значительная часть модулей "Большого уха" имеет свои собственные набортные мозги в виде милипиздрических контроллерчиков ATtiny84. Оные чипы хоть и имеют внутри себя некий USI (universal serial interface), но после вдумчивого осмотра этого чуда я пришёл к выводу, что выигрыш от его использования незначителен. И понадеялся, что необходимые мне для работы интерфейсы я реализую чисто программными методами.
Например, для связи с чипами DDS и PLL используется старый-добрый SPI, в режиме мастера. Нет ничего проще - сдвиговый регистр и формирование такта делается в несколько строк.
Но вот понадобилось связать все модули в единую "сеть". Первоначально планировалось использовать шину I2C, так и спроектировано - трёхвольтовая шина обходит все-все платы, заходит в центральный контроллер, кой всеми ими и командует.
И с узлами I2C, реализованными аппаратно (микросхемы часов, перепрограммируемой ПЗУ, 16-битного порта), всё прекрасно работает. А с софтварной реализацией вот не склеилось.
Перепробовал несколько разных вариантов реализации, скачал образец с сайта Atmel (он не подходит под задачу, т.к. использует всё-таки некоторые аппаратные возможности контроллера - а у меня на всех платах ничего из используемого не выведено), прочитал пару веток специализированных форумов... где меня обрадовали, что чисто программную реализацию I2C сделать "очень сложно" и без поддержки со стороны железа почти невозможно добиться скоростей выше десятка кбит/с при частоте процессора 8МГц (у меня именно так - все "тиньки" тактируются от внутреннего RC-генератора... так проще, хоть и не очень стабильно).
Я уже почти отчаялся. Но потом осенило... Вощем, таки сделал я правильный finite state machine, даже с обработкой ошибок и всего такого - и удалось получить максимальную задержку реакции контроллера примерно в 5.5 мкс. То есть шина спокойно работает на скорости 100 кбит/с и ещё чуть запаса есть.
Прям даже настроение улучшилось. А то я жуть как не люблю такие ситуации, когда простая с виду задачка ставит в тупик.
Проект "Большое ухо" ещё на чуть-чуть приблизился к релизу.
P.S. Надо бы выложить код, хотя бы на AVRFreaks
P.P.S. И никакого ассемблера, если не считать за него вставки типа
Дело в том, что значительная часть модулей "Большого уха" имеет свои собственные набортные мозги в виде милипиздрических контроллерчиков ATtiny84. Оные чипы хоть и имеют внутри себя некий USI (universal serial interface), но после вдумчивого осмотра этого чуда я пришёл к выводу, что выигрыш от его использования незначителен. И понадеялся, что необходимые мне для работы интерфейсы я реализую чисто программными методами.
Например, для связи с чипами DDS и PLL используется старый-добрый SPI, в режиме мастера. Нет ничего проще - сдвиговый регистр и формирование такта делается в несколько строк.
Но вот понадобилось связать все модули в единую "сеть". Первоначально планировалось использовать шину I2C, так и спроектировано - трёхвольтовая шина обходит все-все платы, заходит в центральный контроллер, кой всеми ими и командует.
И с узлами I2C, реализованными аппаратно (микросхемы часов, перепрограммируемой ПЗУ, 16-битного порта), всё прекрасно работает. А с софтварной реализацией вот не склеилось.
Перепробовал несколько разных вариантов реализации, скачал образец с сайта Atmel (он не подходит под задачу, т.к. использует всё-таки некоторые аппаратные возможности контроллера - а у меня на всех платах ничего из используемого не выведено), прочитал пару веток специализированных форумов... где меня обрадовали, что чисто программную реализацию I2C сделать "очень сложно" и без поддержки со стороны железа почти невозможно добиться скоростей выше десятка кбит/с при частоте процессора 8МГц (у меня именно так - все "тиньки" тактируются от внутреннего RC-генератора... так проще, хоть и не очень стабильно).
Я уже почти отчаялся. Но потом осенило... Вощем, таки сделал я правильный finite state machine, даже с обработкой ошибок и всего такого - и удалось получить максимальную задержку реакции контроллера примерно в 5.5 мкс. То есть шина спокойно работает на скорости 100 кбит/с и ещё чуть запаса есть.
Прям даже настроение улучшилось. А то я жуть как не люблю такие ситуации, когда простая с виду задачка ставит в тупик.
Проект "Большое ухо" ещё на чуть-чуть приблизился к релизу.
P.S. Надо бы выложить код, хотя бы на AVRFreaks
P.P.S. И никакого ассемблера, если не считать за него вставки типа
asm("nop");
no subject
Date: 2011-04-17 06:04 pm (UTC)no subject
Date: 2011-04-17 07:36 pm (UTC)no subject
Date: 2011-04-17 10:39 pm (UTC)http://kincajou.livejournal.com/2446092.html
no subject
Date: 2011-04-17 11:04 pm (UTC)no subject
Date: 2011-04-18 03:31 am (UTC)no subject
Date: 2011-04-18 03:52 am (UTC)Одно плохо - задающий там извращенческий, просто так коммутацию контуров не организовать, без лишнего интвертора от внешнего гетеродина не запитать.
2450 - тоже хорошо, там и тракт передачи есть. Надо пробовать.
no subject
Date: 2011-04-18 07:39 am (UTC)no subject
Date: 2011-04-18 11:56 am (UTC)no subject
Date: 2011-04-18 03:35 pm (UTC)no subject
Date: 2011-04-18 06:58 am (UTC)А можно поподробнее остановиться на тех причинах, которые привели тебя к такому выводу?
no subject
Date: 2011-04-18 07:40 am (UTC)