Ви не увійшли.
Blue pill? Так в ньому інша система команд повинна бути
і gpio трохи інакше влаштовано мабуть.
Нє, Blue Pill - то ж наче STM32.
Колись попалась в руки "атмега", корпус явно перемаркований, таймінги дивні, не відповідають даташиту. Деякі фʼюзи не шились, ще якісь дивності з периферією були. Міряв споживання в різних режимах - на атмегу зовсім не схоже, і пульсації струму 72 МГц. Хоча шилась по-AVRівськи і AVRівський байткод виконувала. Потім перестала по ISP відповідати. Думав, може SPIEN фʼюз злетів. Вирішив 12-вольтовим програматором до неї достукатись, вона і згоріла нафіг.
Можна подивитися як влаштована ліба для адресних світлодіодів, там досить швидко біти виводяться.
Для довільних даних швидше як 2 такта на біт все одно не отримати. А якщо чисто програмно, не використовуючи SPI чи UART, то ще час на завантаження саміх даних в регістри.
Мені вдавалось колись генерувати зображення на атмезі, і VGA, і PAL. Але фіксовані фрагменти по пікселю за такт, або довільні дані по 2 такта. При тактовій 20 МГц це було щось біля 300 з чимось пікселів по горизонталі.
І на форумі був пост про генерацію відео, але там було stm32.
Там була генерація апаратним LTDC.
Ще може бути, що ваш компілятор виявився розумніший, і згенерував щось типу
ldi r24,lo8(1)
out 0x5,r24
out 0x5,__zero_reg__
out 0x5,r24
out 0x5,__zero_reg__
out 0x5,r24
out 0x5,__zero_reg__
out 0x5,r24
out 0x5,__zero_reg__
Це 8 біт за 0.5 мкс. Але ж це константні дані. Для знакогенерації чи інших фіксованих картинок ок, для довільного зображення вже так не буде.
Там виводиться байт 0b01010101 молодшим бітом вперед
При константному значенні цей код компілиться в пари ldi/out. Кожна з цих інструкцій на atmega328p виконується за один такт. При 16 МГц один біт за 125 нс, 8 біт за 1 мкс за 937.5 нс.
Як давно осцилограф калібрували?
Або може у вас якийсь китайський емулятор атмеги на 32-бітному ядрі та 72 МГц, таке теж трапляється.
не знаю, як вставити фото екрана осциллографа
Внизу під вікном редагування "Завантаження". Там "Upload a file". Потім відкриваєте завантажений файл, копіюєте його адресу і вставляєте в текст.
Саме так. Я не розумію, як таке може бути, але засоби об'єктивного контролю підтверджують.
А можете показати код (тільки той, що виводить байт) та опції компіляції? Або дизасембльований код. Бо чудес не буває.
Звичайнісінький 16 МГц UNO. Я ж казав "Сам у шоці"
Тобто 1 біт за 1 такт на atmega328p? Щось тут не те.
(Я маю на увазі довільні дані, а не фіксований патерн)
А чому б не використати якийсь штатний регістр, що не використовується за призначенням (напр. OCRxA/B якогось таймера)?
Для чого, для оптимізації? Не плутайте регістри процесора з регістрами ввода-вивода. AVR не вміє бітові зсуви чи іншу арифметику над регістрами ввода-вивода, тільки set/clear bit.
А для "загального використання" є три I/O регістра GPIOR0-GPIOR2. Їх зручно використовувати для бітових флагів, що виставляються в обробниках переривань.
A, якщо вдається 8 біт за 0.5 мкс, то там явно не атмега. Або розігнана до 32 МГц
Так то через SPI теж можна 1 байт дуже швидко вигрузити.
Більше того, поки один вигружається, можна вже підготувати наступний. Але з атмеговим SPI-контролером "розриви" все одно будуть, бо регістр даних не буферизований. А якщо використати USART в режимі SPI, то можна практично без розривів.
Формую відеосигнал зсувом байтової змінної. Якщо змінна в регістрі, то через однобітовий порт виводжу послідовно 8 бітів за 0,5 мікросекунди (сам у шоці). Якщо змінна не в регістрі - 1 біт за той же час. Різниця катастрофічна
Для такої задачі inline assembler - саме воно. Не обовʼязково inline, можна і в окремому source файлі.
В avr-gcc можна об'явити глобальну змінну:
register uint8_t myregvar asm("r16");
Це не специфічно для avr-gcc, для інших платформ теж так можна.
вона гарантовано буде в r16, але код на C не буде з нею працювати оптимально.
Якщо точніше, гарантованим буде сайд-ефект у вигляді доступу до регістру при доступі до змінної. Саме значення може зберігатись в іншому регістрі, даючи деоптимізацію:
register uint8_t x asm("r16");
void foo(void)
{
for (x = 0; x < 100; x++)
GPIOR0 = x;
}
foo:
.L__stack_usage = 0
ldi r24,0
.L2:
mov r16,r24
cpi r24,lo8(100)
brlo .L3
ret
.L3:
out 0x1e,r24
subi r24,lo8(-(1))
rjmp .L2
https://godbolt.org/z/n4Kx4frGe
А якщо раптом помилково використати call-clobbered register і не побачити попередження від компілятора, то ловити баг можна буде дуже довго
Чи відомі комусь ВЛАСНОРУЧ ПЕРЕВІРЕНІ засоби змусити компілятор використовувати для змінної регістр.
Стандартних таких засобів у мовах C та C++ немає.
Навіщо це вам потрібно? У більшості випадків (але не завжди) компілятор знає краще за програміста, де розміщувати змінну. Краще напишіть, яку саме проблему намагаєтесь вирішити використанням регістру для змінної.
Якщо таки потрібно, є власноруч перевірений GCC Inline Assembly.
Ключове слово "register" не працює, принаймні у мене.
register - це лише підказка компілятору, причому давно застаріла (deprecated).
Вимкнути оптимізацію - цікава ідея. Куди треба лізти для цього
Не треба. Примусове вимкнення оптимізації в сучасних компіляторах не має практичного сенсу. До того ж, це скоріш змусить НЕ використовувати регістр, ніж навпаки.
2dimich якщо можете накидайте мені скетч ..для роботи тріума з бібліотекою PCD8544 та PCF8812 ...не виходить ...нема зображення
Щоб "накидувати скетч", необхідно:
а) розуміти, який результат очікується від його виконання
б) бажано мати на руках екземпляр цього контролера для перевірки
в) мати якусь мотивацію
з бібліотекою PCD8544 та PCF8812
Що це за бібліотека? І що ви від неї хочете?
В своїй професійній діяльності я взагалі не використовую фреймворк ардуіно, не кажучи вже про якісь бібліотеки.
...не виходить ...нема зображення
Ви ж наче ініціалізацію вже написали, "графіку виводить чотко", а тут "нема зображення".
Показуйте свій код, опишіть, який результат від нього очікуєте, покажіть фактичний результат. Тоді можна буде щось радити.
Camera DFU Device -- так в менеж не камера...
Та хто знає, під якою назвою такий девайс в базі. Який у нього VID:PID? Може у вас встановлено драйвер для якоїсь камери, який асоційовано з таким же ідентифікатором.
Воно раніше на цьому компі працювало, а тепер перестало, чи ні разу ще не прошивали?
При підключенні контроллера пише що
https://forum.arduino.ua/img/members/1477/1111111.jpg
При підключенні зʼявляються обидва девайса, "Camera DFU Device" та це "Неизвестное устройство"? Не дуже зрозуміло, чому воно в одному списку з хабами.
Зазвичай неможливість прочитати дескриптор означає апаратну проблему з USB: кабель, розʼєм, живлення, електромагнітні наводки і т.п.
Не можу підключитися в режимі ВООТ, контроллер визначається як відеокамера ...
Але зараз треба залити нову прошивку на плату
Хіба "DFU" в "Camera DFU Device" не означає "Device Firmware Upgrade"? Тобто девайс якраз і очікує на прошивку.
Що STLink каже при спробі прошити?
Якщо маєте нормальні фонти для монохромних диспів з кирилицею ,прошу поділитися
Доречі, майте на увазі, що у вашій програмі шрифт у форматі "вертикальних байтів". Такий формат зручніше виводити на дисплеї з горизонтальними банками, просто передаючи байти послідовно. У більшості стандартних форматів шрифти у вигляді "горизонтальних байтів". Щоб виводити їх на дисплей з горизонтальними банками потрібно транспонувати гліфи, або заздалегідь, або в рантаймі.
Серйозний підхід. Особливо в топіку про програмування ардуїни
)
Цей топік скоріш про програмування LCD-контролерів
Що у вас за задачі, які вимагають аж підпилювання ядерних модулів?
Це не задача, це бажання отримати підключені пристрої доступними всій системі. Тобто взаємодіяти з ними на рівні системи, а не на рівні окремої програми. Наприклад, виводити зображення на LCD через /dev/fb, бачити термодатчик у /sys/class/thermal/ чи підключену SPI флешку як /dev/mtd.
На платформах з ARM це зазвичай не проблема, бо драйвери конфігуруються через Device Tree. А на x86 не все так просто.
Доречі, колись виводив зображення через /dev/fb і на x86 (давно це було):
https://www.youtube.com/watch?v=ROVGhcR0g_M
https://www.youtube.com/watch?v=r9iUEkEgs0Y
Але це в userspace: один процес пише у /dev/fb, інший паралельно читає з нього і передає зображення через FTDI на LCD.
Дуже часто бачив, як одні програмісти рахують координати в пікселях, інші - в гліфах.
Більше того, у таких двокольорових дисплеїв (1 bit per pixel) зображення складається зі смужок ("сторінки" або "банки") висотою 8 пікселів. Або шириною, дивлячись як повернути. Одна з координат обирає сторінку, тобто задається в знакомісцях, а інша - зміщення на сторінці, тобто в пікселях.
setPosition() в коді вище так і реалізована.
Дисплей на Trium Mars монохромний 96x65 pix Буфер 102x72 pix
Контролер LPH7690
Такий стоїть на NOKIA 6210
На форумах пишуть,що подібний до PCD8544 та PCF8812
Ну він же адекватно реагує на інструкції для PCD8544/PCF8812? Бітмапи, які в нього передаєте, відображає коректно? Значить, як мінімум, сумісний.
Запишіть в нього по нульовій адресі бітмап, що легко вгадується, наприклад:
0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f
Зрозумієте, де у нього початок координат і в якому порядку йде автоінкремент.
Взагалі, там же в даташитах все намальовано: PCF8812.pdf, стр.8, PCD8544.pdf, стр.8.
дисплей на телефоні шлейфом униз,
Відображаю графіку та текст шлейфом наверх ...побороти не зміг
Не схоже, щоб у цих контролерів був якийсь апаратний MADCTL (як у ST7735) або row/col remap (як у SSD1306).
Якщо хочете перевернути зображення - реалізуйте це програмно.
Якщо маєте нормальні фонти для монохромних диспів з кирилицею ,прошу поділитися
Я зазвичай беру лінуксові consolefonts, там є і з кирилицею. Коли не вистачає якихось символів, то домальовую сам.
Є різні тулзи для маніпуляцій зі шрифтами, наприклад Monobit.
Але зазвичай для генерації коду зі шрифтом я пишу свою програмку, що виконує необхідні маніпуляції для конкретної задачі.
Ви ж, сподіваюсь, розумієте, що кодування літералів у програмі має відповідати кодуванню символів у шрифті? Якщо вихідний код в однобайтовому кодуванні, наприклад cp1251, то можна просто відсортувати гліфи в шрифті для cp1251. Але якщо в UTF-8, то потрібно перед компіляцією конвертувати літерали в однобайтне кодування. Для цього зручно зберігати текст повідомлень в окремому файлі, і генерувати вихідний код з повідомленнями автоматично при збірці.
Забув пояснити: w1-uart реалізований через serdev.
Так отож. Тому і потрібно модифікувати таблицю ACPI, щоб відвʼязати UART від tty та прибіндити до serdev.
А що там не так з ch341, що він працює максимум на 250000 BAUD, а далі таке враження, що в нього там буфер на читання лише 32 байти?
Так, max packet size у ендпоінта 32 байта. Хоча один раз попався екземпляр, що рапортував 64. Ще й у різних версій різна розрядність дільника.
В режим UART я не дуже лазив, для нього є драйвер в mainline. CH341A - це, по суті, три різних девайса на одному чіпі, для кожного потрібен свій драйвер.
В режимі EPP/MEM ще й фіксований clock. Може він насправді й не фіксований, але документації нема.
Подивіться ось тут ідею, як використовуючи другий CS керувати DATA/COMM та отримати додаткові бонуси від двох SPI.
Цей пост уже бачив, але за пораду дякую.
Щоб використовувати другий CS, потрібно у софті верхнього рівня додавати ще один окремий SPI slave. Не завжди це зручно.
А по-факту, припускаю, що в самому контролері воно так і реалізовано, DATA/COMM мультиплексує CS на різні підмодулі.
Доречі, вам не вдавалось піднімати w1-uart на x86? У мене з наскоку не вийшло, схоже, потрібно патчити таблицю ACPI. Поки що не розібрався, як це правильно зробити.
Може і необхідність правити відпаде)
Та її наразі і нема) Драйвер для CH341A я тільки підтримую, щоб компілювався для сучасних ядер.
Що потрібно, робиться через gpio-mpsse з FT232H. До нього теоретично можна і spi-bitbang прикрутити на x86, але знову ж таки, потрібно патчити таблицю ACPI.
-кирилиця не працює
Так у вас у шрифті тільки великі латинські літери та цифри. Навіть знаків пунктуації нема, не то що кирилиці.
-текст виводить де попало
А де попало? Я маю на увазі, як співвідносяться координати, які передаєте, з тими, де виводиться насправді?
-пробував більший шрифт ..не працює
В якому форматі той інший шрифт? Ви модифікували getChar() та drawText() відповідно до нього?
-дзеркалить по Y
Який точно у вас контролер LCD, для которого ця програма? Є на нього даташит? Бо тут уже згадувалось декілька різних контролерів, і незрозуміло, на якому з них проблема з текстом.
Наскільки бачу, ви виводите байти гліфів з шрифта "як є". Якщо це 1-бітний LCD (піксель on/off), то правильно. Якщо ж це кольоровий дисплей, то так не буде працювати. Потрібно відповідно до кожного біта в гліфі виводити піксель (байт або декілька, в залежності від режиму) кольору текста або фона.
Дзеркалить по Y - це ліво з право переплутане, чи верх з низом? Одна картинка з результатом роботи програми допомогла би розібратись.
Потрібно дивитись, які режими автоінкремента у цього контролера. А далі або змінити напрямок автоінкременту, або біти в шрифті перевертати, або бітмап виводити задом наперед, від останнього байта до першого.
наприклад, CH341A
Доречі, у CH341A ще є режим IEEE-1284, тобто емуляція LPT-порта. Можна реалізувати SPI bitbang через parport API -> CH341A -> SPI/GPIO -> дисплей. Але з цим режимом я колись побавився, світлодіодами поблимав, і забив.
зараз не можу зробити нормальний вивід тексту на Trium Mars та Siemens LPH9135
В якому він у вас режимі кольорів? Ви ж враховуєте, що при 12bpp непарні пікселі попадають на середину байта? Хоча, якщо пікселі виводяться правильно, то, мабуть, враховуєте. Тоді покажіть, як виглядає "ненормальний" вивід тексту. Ну і код покажіть, яким виводите.
А можна якийсь приклад, зрозумілий колгоспникам?
Приклад чого, як працювати з spidev, як реалізувати SPI на GPIO, чи як дригати GPIO-пінами?
Якщо у вас адаптер, для якого є драйвер ядра, що реалізує SPI-контролер (наприклад, CH341A), то прибіндити його до spidev. Зʼявиться /dev/spiN.*, працювати з ним через SPI userspace API. Тільки для SPI-дисплеїв все одно доведеться задіяти GPIO, бо як мінімум ще DATA/COMM треба смикати.
Якщо для адаптера є драйвер, що реалізує GPIO-контролер, то працювати з ним через libgpiod.
Звісно, це під лінуксом. Як там під віндою - не маю жодного уявлення.
Я подивився на приклади, як тим ft232h управляти, і мені здалось що це не сильно простіше ніж без нього.
Вже нема необхідності управляти самою FT232H з userspace, gpio-mpsse більше як півроку в mainline. Прибіндити FT232H до gpio-mpsse, зʼявляється gpiochipN з 16 лініями.
Але якщо дуже хочеться, то можна і з userspace, через libftdi. Та й протокол MPSSE досить простий.
Бачив, є для пайтона всякі pyftdi та python-adafruit-blinka. Але ними користуватись не доводилось, то не знаю, в якому вони там стані.
ch341a ще гірший
З CH341A проблема в тому, що за замовчуванням три піна використовуються як CS, і для GPIO залишається два, один з яких тільки input. Якщо потрібно смикати тільки DATA/COMM, то цього достатньо. Якщо хочеться ще GPIO, наприклад, для RST, то треба поправити таблицю в коді та перезібрати драйвер. Все руки не дійдуть реалізувати цю конфігурацію у вигляді параметра.
Ну і CH341A повільний, навіть в апаратно реалізованому SPI mode 0. Програмна емуляція mode 1-3 ще повільніша. Але для тестів та експериментів достатньо.