Jump to content

    
Sign in to follow this  
afad

Программный USB на ATMEGA8

Recommended Posts

Если кому интересно, в журнале "Радио" N1 2007г, c.28 описано устройство (подключение джойстиков к РС) с программной реализацией USB Low Speed на ATMEGA8, использует стандартный HID-драйвер. Там же ссылки на исходники.

Share this post


Link to post
Share on other sites
Если кому интересно, в журнале "Радио" N1 2007г, c.28 описано устройство (подключение джойстиков к РС) с программной реализацией USB-1.0 на ATMEGA8, использует стандартный HID-драйвер. Там же ссылки на исходники.

:bb-offtopic: Гм, информативно) А у меня журнала нет...

Может быть Вы ссылочки впечатаете?

Share this post


Link to post
Share on other sites

Этот проект появился раньше, чем драйвер от ObDev. Но на данный момент в качестве референс-проекта он утратил актуальность, так как USB драйвер от ObDev на голову превосходит чисто ассемблерную реализацию в названном проекте по всем параметрам (компактность, переносимость, эффективность, документированность, совместимость).

 

Названный тут проект интересен только для повторения конкретного устройства: джойстика с автокалибровкой и т.п. сервисными функциями.

Share this post


Link to post
Share on other sites

Кстати использовал код из Радио для "оживления" старого ждойстика от соньки. Так вот когд там никуда не годиться, он только как пример и описание ХИД. Во всём остальном просто уджас, пришлось практически полностью его переписать.

Кстати о ObDev. У меня так и не получилось изменить код для переноса D- c ножки PD0 на другую. Менял маски и прочее. С чем это связано?

Edited by Alexey Belyaev

Share this post


Link to post
Share on other sites

У меня тоже не получилось. мне кажется, что хотя и декларировано помещение на любую 0 (или 7 ) ножку, но код жестко привязан к 0.

Share this post


Link to post
Share on other sites
У меня тоже не получилось. мне кажется, что хотя и декларировано помещение на любую 0 (или 7 ) ножку, но код жестко привязан к 0.

#define USB_CFG_IOPORT          PORTD
#define USB_CFG_DMINUS_BIT      PD0
#define USB_CFG_DPLUS_BIT       PD2

Вот это всё полная чушь. смотрим далее

usbdrv.h

/* I/O definitions for assembler module */
#define USBOUT          USB_CFG_IOPORT          /* output port for USB bits */
#define USB_PULLUP_OUT  USB_CFG_PULLUP_IOPORT
#ifdef __ASSEMBLER__
/* the following two lines must start in column 0 for IAR assembler */
USBIN = (USB_CFG_IOPORT - 2)                /* input port for USB bits */
USBDDR = (USB_CFG_IOPORT - 1)               /* data direction for USB bits */
#else
#define USBIN           (*(&USB_CFG_IOPORT - 2))    /* input port for USB bits */
#define USBDDR          (*(&USB_CFG_IOPORT - 1))    /* data direction for USB bits */
#define USB_PULLUP_DDR  (*(&USB_CFG_PULLUP_IOPORT - 1))
#endif
#if USB_CFG_DMINUS_BIT != PD0
#   error "USB_CFG_DMINUS_BIT MUST be PD0!"
#endif
#define USBMINUS    USB_CFG_DMINUS_BIT       /* D- MUST be on bit 0 */
#define USBIDLE     0x01                     /* value representing J state */
#define USBMASK     ((1<<USB_CFG_DPLUS_BIT) | USBIDLE)    /* mask for USB I/O bits */

Видно, что USBIDLE никак не соотносится с объявлением выше. Ну ладно меняем его на

#define USBIDLE  (1<<USB_CFG_DMINUS_BIT)

и убираем нафиг проверку на PD0 несколькими строками выше.

По идее всё. Но кто гарантирует что такого нет прям в коде? В смысле что в коде 100% идёт ссылка на эти объявления. И кстати как к таким дефайнам относится АСМ?

    cbr     x1, USBMASK    ;1 mask out data bits
    ori     x1, USBIDLE    ;1 idle

Фактически код выше выглядит как:

    cbr     x1, ((1<<USB_CFG_DPLUS_BIT) | (1<<USB_CFG_DMINUS_BIT))    ;1 mask out data bits
    ori     x1, (1<<USB_CFG_DMINUS_BIT)    ;1 idle

Мне кажеться это не есть правильно... Но на удивление это собирается. Но не работает. Не работает если D- != PD0.

Share this post


Link to post
Share on other sites

У меня тоже не получилось. мне кажется, что хотя и декларировано помещение на любую 0 (или 7 ) ножку, но код жестко привязан к 0.

#define USB_CFG_IOPORT          PORTD
#define USB_CFG_DMINUS_BIT      PD0
#define USB_CFG_DPLUS_BIT       PD2

...

#if USB_CFG_DMINUS_BIT != PD0

# error "USB_CFG_DMINUS_BIT MUST be PD0!"

#endif

Судя по приведенным фрагментам, использована старая версия драйвера. Рекомендую взять свежую для всех новых разработок, так как в ней даже с нарушением совместимости на уровне исходников (хотя автор AVR-USB крайне неохотно шел на такие вещи) были исправлены существеные недочеты и значительно расширена функциональность.

 

В новой версии приведенный фрагмент выглядит так:

 

#define USB_CFG_IOPORTNAME      D
/* This is the port where the USB bus is connected. When you configure it to
* "B", the registers PORTB, PINB and DDRB will be used.
*/
#define USB_CFG_DMINUS_BIT      0
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
* This may be any bit in the port.
*/
#define USB_CFG_DPLUS_BIT       2
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
* This may be any bit in the port. Please note that D+ must also be connected
* to interrupt pin INT0!
*/

И я могу гарантировать, что в этой версии действительно назначение D+ и D- произвольно. Требования остаются лишь те, что они должны быть в пределах одного порта, и один из них должен быть соединен с INT0 (или другим, если исправить в конфигурации, где это теперь тоже предусмотрено).

 

Актуальная версия драйвера содержится в reference-проекте PowerSwitch на странице AVR-USB.

 

Альтернативно в качестве примера HID джойстика с использованием этого драйвера могу посоветовать посмотреть проект "PPM RC to USB Interface" на этой странице. Я не уверен, что там использована последняя версия драйвера. И, в отличие от статьи в Радио, в нем не реализовано подключение нескольких устройств по одному интерфейсу (не ставилось такой задачи). Однако, простейший HID джойстик с осями и кнопками можно сделать, взяв за основу этот проект, выбрав в нем в качестве входного интерфейса IN_ADC (см. options.h), а в качестве выходного - OUT_JOYSTICK_BTN. Это даст 8 осей с АЦП и 8 кнопок, дублирующих аналоговые значения. Заменив кусок

 

            // prepare buttons
            int *dp = &channelData[0];
            char buttons = 0x00;
            char mask    = 0x01;

            for (i = 0; i < 8; i++)
            {
                // ensure atomic operation
                cli();
                data = *dp++;
                sei();

                if (data > 1500) buttons |= mask;
                mask <<= 1;
            }

            *rp = buttons;

 

на нечто вроде

 

            *rp = PINA;

(конечно, не забыв проинициализировать порт на ввод с включенными pull-up'ами), получится то, что нужно. Ну, а переписать дескрипторы, добавить дополнительные устройства и так далее, уже вопрос необходимости.

 

О коде RC USB... На данный момент все это переписано, реализована возможность динамической смены дескрипторов на уровне run-time (а не только при компиляции), и введен ряд других изменений. Однако, эта версия для публикации не готовилась и нигде не опубликована. А динамическое формирование дескрипторов текущая версия USB драйвера поддерживает out-of-the-box.

Share this post


Link to post
Share on other sites

Собрал на макетке схему из Радио-2007-01 джойстика USB для Соньки. Заработало под WinXP с первого раза (только проводок оборвавшийся припаял)! Брал две прошивки – для одного и двух джойстиков, норма. Попробовал по-быстрому запустить сеговский эмулятор Fussion и побаловался в игрушки от Megadrive-2. Ощущения абсолютно новые, когда играешь в них на джойстике от PlayStation.

 

Подключал еще два разных джойстика от первой и второй Соньки, убирал и ставил диод VD4 по питанию. Результаты экспериментов - на китайском джойстике с диодом VD4 и с прошивкой psx1.hex наблюдалось залипание кнопок, заменил диод перемычкой, все стало в норме. В принципе об этом в статье говорилось.

 

Откомпилировал через WinAVR-20060421 исходный проект PSX_Usb.pnproj и получил точно такой же по длине HEX-файл 13166 байтов, как и в скачанном архиве, только под названием main_psx.hex (так было прописано в авторском makefile). Зашил откомпилированный файл в контроллер, работает на ура. Значит на сайте выложена не липа, а рабочие исходники программы, пользуйтесь на здоровье. Метровый сэнкс автору публикации.

Share this post


Link to post
Share on other sites
Собрал на макетке схему из Радио-2007-01 джойстика USB для Соньки. .....

Я тоже опирался на это дело, мне не понравилась хардварная реализация SPI. Я переделал всё на софтварь и поправил кое код дабы он мне не понравился совсем по стилю. В итоге получил почти в двое меньший НЕХ и более быстрый опрос клавиш с детекцеей типа джойстика (от первой соньки нужно гораздо меньше делать длину опроса чем от джойстика с аналоговыми осями). После всего этого утрамбовал плату внутрь джойстика родной провод упрости, а вывел тока ЮСБ. Надеюсь скоро на радиокоте появится всё что я успел наработать на эту тему.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this