Доброго времени суток! Ситуация следующая: на AT90USB162 хочу сделать USB устройство. Точнее учусь этому делу. Для начала решил создать программу, которая просто подключала бы устройство к шине и обрабатывала управляющие запросы. Программу пишу поэтапно - написал блок, проверил работает ли он. Пишу в Atmel Studio 7. Пользуюсь книгой П. Агурова "Интерфейст USB практика использования и программирования", стандартным даташитом на данный контроллер и вот этим описанием регистров.
http://microsin.net/programming/avr-wor ... oller.htmlДело встало на создании 0 конечной точки. В даташите дан алгоритм как это сделать. Делаю. Но конечная точка не создается. Бит CFGOK принимает значение 1, если конечная точка настроена правильно (в даташите говорится о размере конечной точки, если он не превышает размер DPRAM, то всё ок). Но у меня он почему то никак не принимает значение 1. Пробовал сравнить свой код настройки конечной точки с кодом в примере Atmel (USB мышь), что и в какие регистры записывать - те же самые регистры, те же самые цифры, что и в моем коде.
Так же попробовал создать USB устройство в CodeVisionAVR и залить в контроллер - всё работает (сделал вывод, что дело не в плате, а то мало ли, самодельная всё таки, вдруг человеческий фактор какой...)
Если кто работал с данным контроллером, прошу подсказать в каком направлении двигаться, где искать решение проблемы. Код прилагаю.
#define F_CPU 16000000UL
#include <avr/io.h>
#include <math.h>
#include <util/delay.h>
int main(void)
{
CLKPR = (1 << CLKPCE); //разрешение перепрограммирования делителя
CLKPR = 0x00; //отключение делителя
/*---------Отключаем сторожевай таймер-----------------------------*/
asm volatile("cli"); // запрет глобальных прерываний
asm volatile("wdr"); // перезапуск сторожевого таймера
MCUSR &= ~(1<<WDRF);
WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = 0x00;
/*----------*/
/*-----Выбор коэффициента предделителя. Выбираем 2, т.к. в схеме кварц на 16МГц-----*/
PLLCSR |= (1<<PLLP0);
PLLCSR &= ~(1<<PLLP1);
PLLCSR &= ~(1<<PLLP2);
/*----------*/
/*-----Включаем генератор опорной частоты USB интерфейса------------*/
PLLCSR |= (1<<PLLE);
/*----------*/
/*-----Ждем, когда он запустится------------------------------------*/
while(PLLCSR & (1<<PLOCK));
/*----------*/
/*-----Разрешаем работу USB интерфейса------------------------------*/
USBCON |= (1<<USBE);
USBCON &= ~(1<<FRZCLK);
/*----------*/
/*-----Подключаем D+ к шине USB-------------------------------------*/
UDCON &= ~(1<<DETACH);
/*----------*/
/*-----Конфигурация 0 конечной точки.----------*/
while (((UESTA0X & (1<<CFGOK))!=1))
{
DDRC = (1<<PC4); //Для наглядности включаем светодиод на 26 ноге. Если конечная точка будет сконфигурирована правильно,
PORTC = (1<<PC4); //то бит CFGOK станет равным 1 и условие для выполнение цикла нарушится, выходим из цикла и для наглядности гасим светодиод.
/*-----Конфигурация 0 конечной точки. 000 - нулевая конечная точка.-*/
UENUM &= ~(1<<EPNUM0);
UENUM &= ~(1<<EPNUM1);
UENUM &= ~(1<<EPNUM2);
/*----------*/
/*-----Конфигурация 0 конечной точки. Разрешаем работу EP0----------*/
UECONX |= (1<<EPEN);
/*----------*/
/*-----Конфигурация 0 конечной точки. Выбираем тип EP0 (Control)----*/
UECFG0X &= ~(1<<EPTYPE0);
UECFG0X &= ~(1<<EPTYPE1);
/*----------*/
/*-----Конфигурация 0 конечной точки. Выбираем направление EP0 (OUT)-*/
UECFG0X &= ~(1<<EPDIR);
UECFG0X |= (1<<1); // NYET??? Взято из Atmel'овского примера USB мыши, но в описании регистра UECFG0X на это место вообще ничего не пишется.
/*----------*/
/*-----Конфигурация 0 конечной точки. Выбираем размер EP0 (32 байта)-*/
UECFG1X &= ~(1<<EPSIZE0);
UECFG1X |= (1<<EPSIZE1); //32 байта взято из ATMEL'овского примера
UECFG1X &= ~(1<<EPSIZE2);
/*----------*/
/*-----Конфигурация 0 конечной точки. Выбираем количество банков(1)-*/
UECFG1X &= ~(1<<EPBK0);
UECFG1X &= ~(1<<EPBK1);
/*----------*/
/*-----Конфигурация 0 конечной точки. Выдиление памяти для EP0.-----*/
UECFG1X |= (1<<ALLOC);
/*----------*/
}
DDRC = (1<<PC4); //Если 0 конечная точка сконфигурирована правильно, то значит мы вышли из цикла while, для наглядности гасим светодиод.
PORTC &= ~(1<<PC4);
}