Мінікомпютер з роутера з OpenWRT: розробляємо USB-відеокарту.

07.10.2015

Мінікомп’ютер з роутера з OpenWRT: розробляємо USB-відеокарту

Добрий день, шановні хабровчане. У цьому циклі статей ми з вами пройдемо досить довгий, але дуже цікавий шлях по перетворенню звичайного роутера в міні-комп’ютер з LCD-дисплеєм. Для цього ми розробимо спочатку USB-відеокарту на базі мікроконтролера STM32F103, потім тестовий драйвер, який дозволить нам виводити на нього графіком, і, нарешті повноцінний драйвер фреймбуффера, завдяки якому можна буде запустити справжні графічні додатки, такі як x-сервер. Заодно ми навчимося включати наш код у дерево исходников OpenWRT, допілівать його ядро і робити інші корисні речі.

Ну а в самому кінці ми отримаємо результат, який, я сподіваюся, викличе ностальгічну сльозу у багатьох читачів. Я постараюся викладати матеріал таким чином, щоб наприкінці кожного етапу ми отримували відчутний результат, не дає згаснути ентузіазму. Отже, почнемо.

Традиційно, подивимося, що з заліза нам буде потрібно. Тих, хто не любить паяти, я можу відразу заспокоїти — все що ми будемо робити – чисто фермварное і софтварное, так що власне паяти нам не доведеться. Але зате на знадобиться налагоджувальна на контролері STM32F103VE і QVGA дисплеєм, про яку я вже згадував у своїй статті .

Також нам знадобиться, власне, роутер, який я також згадував в іншій статті. але до нього ми повернемося пізніше. Зараз зосередимося на розробці самої USB-відеокарти на базі нашої налагоджувальної плати.

У STM32F103 є в складі два блоки, які нам дуже знадобляться. Перший з них – це, зрозуміло, апаратний USB-контролер, який відмінно підійде для організації з’єднання між відеокартою і хостом. Другий – FSMC – Flexible Static Memory Controller. Він являє собою контролер статичної пам’яті, який може бути налаштований для використання спільно з мікросхемами SRAM, NAND/NOR FLASH і тому подібними пристроями, причому ширина шини і таймінги в ньому піддаються налаштуванню. При цьому мікросхеми мапируются на адресний простір і, при зверненні за відповідною адресою, FSMC сам генерує необхідні сигнали на керуючих лініях і шинах адреси і даних, так що для програміста цей процес є повністю прозорим.

У випадку з дисплеєм це нам дуже допоможе, оскільки дисплеї такого роду забезпечені інтерфейсом, майже повністю збігається з інтерфейсом NOR-флешки і SRAM: 16-бітна шина даних, строби CS,

WR,

RD. З цими сигналами все просто – CS активізує дисплей, з нього починається цикл обміну даними.

WR або

RD активізуються при зверненні на читання або запис відповідно.

На жаль, дисплей не надає нам своєї шини адреси і даних для доступу до відеопам’яті, замість цього нам доступна єдина 16-бітна шина і додатковий сигнал RS, Register Select. При активному сигналі RS, значення, виставлене на цю шину, сприймається як адреса регістра (комірки RAM) контролера дисплея, до якого слід звернутися, а подальше читання або запис з неактивним RS – операцією з RAM дисплея.

Слід зазначити, що RAM в даному випадку не є відеопам’яттю, це пам’ять контролера дисплея, до якої відкритий доступ ззовні за допомогою описаного вище механізму. Відеопам’ять же фігурує в документації як GRAM, Graphics RAM, і її вміст доступно через «віконце» у вигляді одного з регістрів. При цьому логіка контролера дисплея сама инкрементирует/декрементирует внутрішній адреса відеопам’яті при послідовному читанні з одного і того ж регістра (CTR_WRITE_DATA, CTR_READ_DATA)

FSMC не має спеціалізованого сигналу RS, тому для цього застосовується один трюк: який-небудь з доступних сигналів шини адреси FSMC підключається до сигналу RS.

Припустимо, що ми підключили сигнал A0 до RS. Тоді при зверненні до адреси пам’яті 0х00000000 на запис (щодо базової адреси, на який мапирован даний банк FSMC) сигнал RS буде неактивний і дисплей сприйме це як установку адреси регістра.

При зверненні до 0х00000001 адресна лінія A0 буде активна, і читання або запис виконуватися вже для комірки RAM, тобто, для реєстру, адресу якого був заданий при зверненні за нульовим адресою.

Детальніше про це можна прочитати в апноуте від ВТМ, присвяченому даному питанню.

Опис регістрів контролера дисплея доступно його даташіте .

до Речі, з даташитами слід бути обережніше і уважно дивитися на його версію, тому що китайські товариші обожнюють спочатку копіювати саму мікросхему (не повністю, а як вийде), а потім – копіювати даташит від цієї мікросхеми. Тому в процесі читання даташита можна з подивом виявити регістри і функції, яких даний контролер ніколи не підтримував і які в наступної версії даташита вже подтерты.

Так, наприклад, ранні версії даташита на даний контролер повідомляють, що дисплей вміє робити апаратні побітові операції, включаючи апаратну маску для реалізації прозорості, однак, якщо покопатися глибше, то виявиться, що ця строчка потрапила в даташит на ILI9325 з даташита іншого, японського контролера дисплея, який китайці благополучно скопіювали і обізвали сумісним.

Так як дисплей вже підключений до Mini-STM32, все що нам потрібно – дізнатися, до якого із сигналів вибору чіпа він підключений і який з адресних ліній використовується в якості сигналу RS.

Згідно зі схемою, в якості сигналу CS використовується FSMC_NE1, а в якості RS – FSMC_A16.

дисплей має сигнал Reset, виведений на PE1 і сигнал управління підсвічуванням, з’єднаний з PD13.

Заодно подивимося, який з сигналів використовується для підключення підтяжки USB, про яку поговоримо пізніше – в даній схемі це PC13.

Отже, переходимо до коду.

Робота з LCD

Почнемо з розробки невеликий бібліотеки для роботи з дисплеєм. Працювати будемо в CooCox IDE. Винесемо в заголовковий файл усі адреси регістрів з даташита:

Оголошення регістрів LCD

Ми пам’ятаємо, що з точки зору коду, звернення до FSMC буде простий запис/читання з пам’яті, тому нам потрібно визначити з якою саме адресами звертатися. Дивимося в референс мануал на STM32, розділ FSMC, і бачимо, що для NOR/SRAM виділені адреси, що починаються з 0x60000000.

Під банками в широкому сенсі в мануалі маються на увазі великі регіони, виділені для пристроїв різного типу, так, банк #1 – це NOR/SRAM, банки #2 і #3 – NAND, банк #4 — PC Card.

У свою чергу банк #1 може бути використаний для доступу до цілих 4 чіпів пам’яті, кожен з яких може незалежно від інших бути NOR або SRAM. Так як дисплей підключений як NE1, нас цікавить банк, оголошений як FSMC_Bank1_NORSRAM1. Виходячи з базової адреси, можна відразу ж записати визначення

Адресою, активізує RS буде адреса, у якому активна лінія A16, тобто, приміром 0x60000000 + (2<<16), тобто 0x60020000, тому запишемо

І відразу ж визначимо відповідні макроси для запису значень в регістри дисплея і в його пам’ять:

Заодно визначимо дефайнами імена пінів та їх портів, що відповідають за скидання дисплея і за включення підсвічування:

Тепер напишемо код ініціалізації FSMC і супутньої периферії:

Код ініціалізації FSMC

Тут все досить просто – ми налаштовуємо системний таймер на інтервал в одну мілісекунду (що буде необхідно для організації затримок в процесі ініціалізації контролера дисплея), потім налаштовуємо всі сигнали, якими володіє FSMC як керовані «alternative functions», налаштовуємо піни Reset і Backlight як Output Push-Pull, після чого переходимо до налаштувань FSMC.

Короткий опис статті: usb відеокарта
Добрий день, шановні хабровчане. У цьому циклі статей ми з вами пройдемо досить довгий, але дуже цікавий шлях по перетворенню звичайного роутера в міні-комп’ютер з LCD-дисплеєм. Для цього… OpenWRT, Linux, LCD, STM32, мікроконтролери, драйвери, модулі ядра, kernel, stm32f103, USB, DIY

Джерело: Мінікомп’ютер з роутера з OpenWRT: розробляємо USB-відеокарту / Хабрахабр

Також ви можете прочитати