Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: USB своими руками для sam7x256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
e0000
Доброе время суток всем.
Имеем sam7x256, интерфейс USB, и небольшой опыт (3 проекта я не считаю опытом) работы с этим кристалом. С AVR и MC51 опыт достаточно большой, но с ARM-ом сталкнулся год назад. RS, CAN, ADC, SPI, TWI, AIC ну, в общем вся переферия кристалла поддалась о особых трудностей с этим не возникло.
Но, ниразу мне не приходилось делать что либо для USB. Однако интересовался, читал (и это форум в том числе), смотрел, слушал...
Я вообще долго не задаю вопросы пока уже совсем не упрусь в стенку. Понимаю, что те, кто разобрался в вопросе сечас могут закричать, что "там все просто" или "возьми примеры и не парься", но я человек дотошный и пытаюсь разобраться в каждой мелочи. При этом никогда не отказываю в объяснениях... Однако сейчас объяснить надо мне, да и другим думаю тоже будет интересно.
Я может буду задавать ламерские вопросы, но прошу отнестись ко мне с лояльной стороны и не судить за это строго.

И так.

1.
Судя из того, что я вычитал и прочитал. Работа UDP в background-е меня не устраивает и хотелось бы настроить работу через AIC. Но сталкнулся с такой проблемой: Как задать первоначальные настройки для UDP? Просто задали тактирование и все? А потом пытаемся ловить ENDBUSRES? или же надо запретить передатчик TXDIS перед настройкой?

2.
При простой подаче тактирования (ну, частоту я соблел sm.gif), UDP_ISR чистый (т.е. равен 0) как белый лист, какие бы "приседансы" не делались. и посему ENDBUSRES я просто не вижу. Ни включение ни выключение резисторя на D+ не приводят никчему. Хотя посылки от хоста осцилографом я вижу прекрасно. Пересброс питания, reset и включение выключения кабеля эфект нулевой.

3.
Несколько раз контроллер UDP таки запускался и я даже залетал по вектору прерывания в обработку прерываний от UDP, но ниодин из битов регистра UDP_ISR не детектируется. Создавалось впечатление, что я залетел туда случайно, но из прерывания он не выходит. Т.е. крутится там и все. Я принудительно в конце процедуры вставил очистку всех прерываний от UDP как в AIC так и в UDP_ICR.
А прерывание все равно вызывается и непонятно чем sad.gif

4.
Из-за всего этого я не могу идти дальше, посему вопросов связанных с самим протоколом я задать не смогу. Однако хочу задать вопрос по поводу отладки самого контроллера UDP. В keil нет ничего, что с ним связано. Для отладки другой переферии мне было достаточно keil debuger, а тут..? С UDP пришлось устанавливать "светодиодные метки" но, это жутко неудобно. Как и чем проверять работу кода для UDP в keil ?

Понимаю, что вопросы может быть даже немного к "стыду моему", но еще раз прошу отнестить снисходительно к ним.

PS
Я специально не привожу и не хочу, чтобы приводили куски кода, потому как хочу понять сам процесс и принцип.

kovigor
Цитата(e0000 @ Jan 28 2011, 11:54) *
потому как хочу понять сам процесс и принцип.


1, 2, 3. Вместе с Кейлом поставляются разные примеры для атмеловских АРМ. Годятся любые - как для ARM7, так и для ARM9. Они-то как раз и работают по прерываниям, а не по опросу. Попробуйте разобраться, ничего сверхсложного там нет. Ответы на 90% своих вопросов вы найдете там. Ну, и спецификацию на USB изучить придется, и книжку Гука почитать тоже будет совсем не лишним ...

4. а что вы хотели там увидеть ? Я в свои проекты вставляю вывод интересующий меня информации через Debug Port (UART). Ну и светодиоды + осциллограф подчас помогают лучше любого отладчика ...
e0000
Цитата(kovigor @ Jan 28 2011, 11:09) *
1, 2, 3. Вместе с Кейлом поставляются разные примеры для атмеловских АРМ. Годятся любые - как для ARM7, так и для ARM9. Они-то как раз и работают по прерываниям, а не по опросу. Попробуйте разобраться, ничего сверхсложного там нет. Ответы на 90% своих вопросов вы найдете там. Ну, и спецификацию на USB изучить придется, и книжку Гука почитать тоже будет совсем не лишним ...

4. а что вы хотели там увидеть ? Я в свои проекты вставляю вывод интересующий меня информации через Debug Port (UART). Ну и светодиоды + осциллограф подчас помогают лучше любого отладчика ...


1.2.3.
Знаете, может я совсем старомоден в принципах написания програмного обеспечения, но я не понимаю того, что пишут другие на СИ еще и сприменением каких-то там библиотек, каких-то макросов, которые кем-то когда-то были написаны и потм вылавливать в них глюки...
Я больше на ASM. Уж простите за столь старомодный подход. Посему и привык весь нижний уровень писать самостоятельно. Не то, чтобы СИ я не понимаю, а просто если взять кусок кода приведенного на СИ и попытаться разобраться то начинается, что нехватает *.h или других *.с файлов, чтобы понять от куда и как ростут ноги. Убивается куча времени а итог - 0.
Я могу вам "до битика"/"до милливольта" рассказать и объяснить работу CAN, RS(232/485/422/489) , ARING, и прочие. И до всего доходил сам слушая и читая (как тут выразились - "курю даташиты")...
Спецификация USB 2.0 "выкурена полностью" sm.gif
Но вопрос заключался не в Спецификации USB, а в контроллере UDP и его первичной инициализации... Этого к сожалению нигде не описано.

месный PS
Отправить дальше читать даташиты я и сам умею sm.gif

4.
Скажем для отладки собственно самого кода для ADC, CAN, TWI и пр в keil debuger есть соответсвующая переферия. И не надо 1000 раз перепрошиваться для отладки. А отладка через Debug Port меня уже пару раз наколола и очень жестко. Для медленных процессов - да, но для быстрых... sm.gif "сисилограф" (как говорят у нас на проходной) твой лучший друг и товарищ!
И все-таки. Есть ли какие либо стредства для отладки кода для UDP?
kovigor
1, 2, 3. А вы пробовали разобраться с примерами ? Нет там никаких библиотек. Вообще, ничего стороннего там не привлекается. Голый Си - код, работающий исключительно с ресурсами МК и не вызывающий и не использующий никакого постороннего кода. Хедеры ? Да, я их и сам не уважаю, когда их десятки и они ссылаются друг на друга. Но !!! Другого пути нет. Или по полгода или по году писать самому "нижний уровень", или за две-три недели разобрать готовый пример, поставляемый со средой. Лично мне больше по душе именно второе.

4. Хотите, расскажу вам одну штуку ? Я для отладки своих дивайсов сделал себе простой аппаратный USB - сниффер на FPGA и соотв софтик к нему на Делфи. Иногда он просто незаменим. Сделал давно, еще когда начинал разбираться с шиной. Но обычно хватает UART (ничего он не "врет", не выдумывайте), осциллограф и светодиоды.

P.S. Еще раз отправляю к первоисточникам - примерам от Кейла. Разбирайтесь. Другого выхода нет. Вы можете писать все что угодно и сколько угодно. Но все равно вы вынуждены будете вернуться к примерам.

P.P.S.
Чтобы вам не было так тоскливо, вот вам проект "мышки" для ARM9 (для ARM7 тоже подойдет). Сделан на основе примеров от Кейл, существенно переработан и "очеловечен". Пароль запросите личным сообщением ...

http://zalil.ru/30417880
e0000
Цитата(kovigor @ Jan 28 2011, 12:04) *
Чтобы вам не было так тоскливо, вот вам проект "мышки" для ARM9 (для ARM7 тоже подойдет). Сделан на основе примеров от Кейл, существенно переработан и "очеловечен". Пароль запросите личным сообщением ...

http://zalil.ru/30417880


Спасибо.
В личку отписать не могу. не дает пользоваться. говорит : Вам запрещено отправлять личные сообщения sad.gif
Попробуем поковыряться, но думаю, что буду задавать еще больше дурных вопросов sad.gif
kovigor
Цитата(e0000 @ Jan 28 2011, 13:10) *
Спасибо.
В личку отписать не могу. не дает пользоваться. говорит : Вам запрещено отправлять личные сообщения sad.gif
Попробуем поковыряться, но думаю, что буду задавать еще больше дурных вопросов sad.gif


kovigor@yahoo.com

Пишите ...
e0000
В принцияпе со стартом самого UDP разобрался.
Остался вопрос по поводу режима с которого стартуем.
Изначально UDP должно находиться в sleep mode?
kovigor
Цитата(e0000 @ Jan 28 2011, 15:21) *
В принцияпе со стартом самого UDP разобрался.
Остался вопрос по поводу режима с которого стартуем.
Изначально UDP должно находиться в sleep mode?


Почему ? Вы же подключаетесь к шине. Хост обязан начать энумерацию устройства, как только он такое подключение обнаружит. Если хост уснет, то МК перейдет в режим SUSPEND (а не SLLEP !). А вот что будет, если просто включить устройство и к шине его не подключать, я не знаю и раньше этим вопросом не задавался. Т.е., установится ли при этом бит UDP_ISR.RXSUSP ? Не знаю. Проверить сейчас не на чем. Думаю, это не слишком существенно ...

P.S.
Проверил в реальном устройстве. Да. Этот флажок установится если:
1. Просто включить устройство, но к шине его не подключать.
2. Включить устройство, подключить его к хосту и затем усыпить хост.
3. Включить устройство, подключить его к хосту, дать ему некоторое время поработать и затем вынуть вилку USB - разъема устройства из USB - розетки хоста.

Вот так ...
e0000
Цитата(kovigor @ Jan 28 2011, 14:38) *
Почему ? Вы же подключаетесь к шине. Хост обязан начать энумерацию устройства, как только он такое подключение обнаружит. Если хост уснет, то МК перейдет в режим SUSPEND (а не SLLEP !). А вот что будет, если просто включить устройство и к шине его не подключать, я не знаю и раньше этим вопросом не задавался. Т.е., установится ли при этом бит UDP_ISR.RXSUSP ? Не знаю. Проверить сейчас не на чем. Думаю, это не слишком существенно ...

P.S.
Проверил в реальном устройстве. Да. Этот флажок установится если:
1. Просто включить устройство, но к шине его не подключать.
2. Включить устройство, подключить его к хосту и затем усыпить хост.
3. Включить устройство, подключить его к хосту, дать ему некоторое время поработать и затем вынуть вилку USB - разъема устройства из USB - розетки хоста.

Вот так ...

ok!
Я так понял при старте нужно действовать по следующему алгоритму:

- Инициализации подлежит только AIC и UDP_IER
- Ждем прерывания от шины EDNBUSRES, включаем тактирование и конфигурируем EP0 как управляющую в режиме приема
- Ожидаем команды шины и отвечаем ей то, что она хочет (отдаем дискрипторы, проводим энумерацию и пр).
- "засыпаем" только по команде шины.

Правильно? 05.gif
kovigor
Цитата(e0000 @ Jan 28 2011, 17:32) *
Правильно? 05.gif


Последние два пункта - да. Первые - извините, я занимался этим весной и деталей не помню. Правильно (и работоспособно) так, как написано в примерах у Кейла и в том примере, что я вам дал.
aaarrr
Цитата(e0000 @ Jan 28 2011, 16:32) *
Я так понял при старте нужно действовать по следующему алгоритму:

- Инициализации подлежит только AIC и UDP_IER
- Ждем прерывания от шины EDNBUSRES, включаем тактирование и конфигурируем EP0 как управляющую в режиме приема

Тактирование все же надо включать до подключения, причем аж в двух местах:
Код
    AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
    AT91C_BASE_PMC->PMC_PCER = 1UL << AT91C_ID_UDP;


Атмеловские примеры на самом деле ужасно дурные. Лучше по возможности обойтись без них.
Помнится, когда первый раз запускал USB на этом процессоре, решил немного себя испытать
и оставил из средств отладки лишь один светодиод, а из документации только даташит.
И ничего, за вечер получилось.
e0000
Цитата(aaarrr @ Jan 28 2011, 22:40) *
Тактирование все же надо включать до подключения, причем аж в двух местах:
Код
    AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
    AT91C_BASE_PMC->PMC_PCER = 1UL << AT91C_ID_UDP;

Это я понял из даташита уже, что тактировать надо не только переферийно, а еще и системно... rolleyes.gif
Но спасибо, что ответили. Приятно, когда отвечают даже если дошел до этого самостоятельно.

Цитата(aaarrr @ Jan 28 2011, 22:40) *
Атмеловские примеры на самом деле ужасно дурные. Лучше по возможности обойтись без них.

С этим я могу согласиться. Тем более, что в СИ я не силен. Всю сознательную жизнь на ассемблере.
На AVR так я их даже asm примеры на дух не переносил sm.gif

Кстати ламерские вопросы: "1UL" это что?
Просто я пытаюсь перейти таки на СИ. Хотя много уже "нацарапано" на ASM-е.
1. "1UL" это что?
2. Можно ли использовать для СИ асмовый код, как скажем подпрограмму? Напрмер. У меня есть прерывание по таймеру (захват частоты) и обработчик прерывания уже написан на ASM. Как его вставить в СИ код?
Понимаю, что можно полазить и разобраться, но всеже rolleyes.gif

Цитата(aaarrr @ Jan 28 2011, 22:40) *
Помнится, когда первый раз запускал USB на этом процессоре, решил немного себя испытать
и оставил из средств отладки лишь один светодиод, а из документации только даташит.
И ничего, за вечер получилось.

Тут у меня похожая проблема за одним исключением. Мне еще надо было спецификацию USB изучить и светодиода нет crying.gif , но есть 2 реле и выход PWM biggrin.gif .
aaarrr
Цитата(e0000 @ Jan 29 2011, 15:18) *
1. "1UL" это что?

1 - это 1, UL указывает компилятору тип константы - unsigned long. Кстати, в тех же атмеловских хидерах сплошь и рядом встречаются записи типа (1 << 31), что заставляет компилятор выкидывать ворнинги.

Цитата(e0000 @ Jan 29 2011, 15:18) *
2. Можно ли использовать для СИ асмовый код, как скажем подпрограмму? Напрмер. У меня есть прерывание по таймеру (захват частоты) и обработчик прерывания уже написан на ASM. Как его вставить в СИ код?
Понимаю, что можно полазить и разобраться, но всеже rolleyes.gif

В C-код ничего вставлять не надо, все вместе соберет линкер. Если хотите использовать подпрограммы на ассемблере, то придется еще изучить стандарт AAPCS.

Цитата(e0000 @ Jan 29 2011, 15:18) *
Тут у меня похожая проблема за одним исключением. Мне еще надо было спецификацию USB изучить и светодиода нет crying.gif , но есть 2 реле и выход PWM biggrin.gif .

Тогда прикрутите UART для отладки.
e0000
Продолжение глупых вопросов sm.gif

У меня ситуация следующая:
Проиходит reset, потом wakeup, и почему-то, хост опять посылает мне reset sad.gif
Так и должно быть? Я что-то пропустил?
Что должно вызываться первым? reset или wakeup?
И должен ли вообще вызываться wakeup, если до этого был reset?



Цитата(aaarrr @ Jan 29 2011, 14:33) *
В C-код ничего вставлять не надо, все вместе соберет линкер. Если хотите использовать подпрограммы на ассемблере, то придется еще изучить стандарт AAPCS.

Спасибо. На досуге разберусь обязательно. Жалко неиспользовать наработки прошлого.

Цитата(aaarrr @ Jan 29 2011, 14:33) *
Тогда прикрутите UART для отладки.

Это и сделал. Правда пришлось смоим зрением паять к ногам LQFP-100 провода. Но получилось sm.gif
Больше ничего допаивать не хочу - и так глаза поломал пока припаялся.
Иногда правда UART отстает от событий, прийдется еще и FIFO сгородить небольшой...
aaarrr
Цитата(e0000 @ Jan 29 2011, 20:46) *
У меня ситуация следующая:
Проиходит reset, потом wakeup, и почему-то, хост опять посылает мне reset sad.gif
Так и должно быть? Я что-то пропустил?
Что должно вызываться первым? reset или wakeup?
И должен ли вообще вызываться wakeup, если до этого был reset?

Reset может приходить не один, это точно. А вот что с wakeup не помню. Обрабатывайте все спокойно, там разберетесь.
Chameleon
Сброс обязательно будет не один. При подключении устройства Windows первым делом дает сброс, а затем запрашивает дескриптор. После получения первых 8 байт дескриптора опять дается второй сброс, без завершения получения дескриптора. После второго сброса уже идет полная энумерация.

Вот, нашел.

Энумерация USB устройства в Windows включает следующие шаги:

1. Хост (или концентратор) распознает подключение нового устройства с помощью подтягивающего резистора на
линии данных. Хост ожидает по меньшей мере 100 мс, что бы процесс физического подключения был полностью завершен
и в подключаемом устройстве стабилизировалось питание.
2. Хост производит сброс устройства в состояние по умоланию. Устройство должно отвечать на нулевой адрес.
3. MS Windows запрашивает первые 64 байта дескриптора устройства.
4. После получения первых 8 байтов дескриптора устройства, хост сразу же генерирует второй сброс.
5. Хост выдает команду "Установить адрес", переводя устройство в адресуемое состояние.
6. Хост запрашивает 18 байт дескриптора устройства.
7. Затем он запрашивает 9 байт дескриптора конфигурации, чтобы определить общий размер дескрипторов.
8. Хост запрашивает 255 байт дескриптора конфигурации. (Но отвечать надо реальным количеством байт дескриптора).
9. Хост запрашивает все строковые дескрипторы, если они были указаны.
kichnamid
Здравствуйте,
а не встречались с такой проблеммой?:
при работе с отладочной платой при подключении USB в UDP_ISR выставляется ENDBUS, SUSPEND и RESUME, SOF и прерывание EP0. А при работе со своим устройством но темже самым проектом получаю только , SUSPEND и RESUME.
e0000
Сталкнулся с той-же проблемой...
Приходят только Reset, SOF, Suspend и больше ничего.
Хотя еще вчера все работало cranky.gif
Думаю, что после того как начал потреблять от шины перевалил за 100 мА...
Пытаюсь все вернуть назад.
e0000
Возврат к "только процессор на порту" результатов не дал.
Вопрос открыт
kichnamid
странно. у меня устройство запитывается от внешнего источника, а не от USB. но на EK плате я подключал тоже от внешнего, всё работало. надо проверить: если VSUB не доходит до GND на схеме(на моей только конденсатор к земле), то, может, хост не понимает, что надо сетупить устройство и не те пакеты шлёт => MK не выставляет прерывание конечной точки. я смотрел через отладчик: UDP_CSR[0] равен 0 в момент прерывания, а должен быть с битом RXSETUP.
e0000
Прошу прощения у всезнаеющего All-a, но я уже не знаю что делать и прошу, если кто знает, ответить.
Почему HOST не присылает SETUP запросов?
Наверное даже не так:
В каких случаях host их может не присылать?
kovigor
Цитата(e0000 @ Feb 16 2011, 21:46) *
Прошу прощения у всезнаеющего All-a, но я уже не знаю что делать и прошу, если кто знает, ответить.
Почему HOST не присылает SETUP запросов?
Наверное даже не так:
В каких случаях host их может не присылать?


Что, даже не пытается прочитать дескриптор устройства ? А может, он как раз и присылает запросы, да вы их своим устройством не видите ? Или вы забываете подключиться к шине (т.е., резистор, например, у вас одним выводом подключен на D+, в то время как другой его вывод никуда не подключен) ? BusHound что говорит ? А осциллограф (маркеры SOF идут) ?
e0000
Цитата(kovigor @ Feb 16 2011, 20:52) *
Что, даже не пытается прочитать дескриптор устройства ? А может, он как раз и присылает запросы, да вы их своим устройством не видите ? Или вы забываете подключиться к шине (т.е., резистор, например, у вас одним выводом подключен на D+, в то время как другой его вывод никуда не подключен) ? BusHound что говорит ? А осциллограф (маркеры SOF идут) ?

"Дословно":
Pull Up On (осцилографом вижу, что таки резистор подключен)
Suspend
Reset
Reset
Suspend
Timeout to Connect. Pull Up Off
Pull Up On
...

И далее все по новой.
Timeout - отсчитывает 20 сек после подключения резистора, если устойство не иннумеровано.

>>> BusHound что говорит ?
"Такой борьбы не знаю" (с) Гостья из будующего sm.gif
Что за софт/железо?

>>> А осциллограф (маркеры SOF идут) ?
нет sad.gif
Перезапуск машины и опробование на еще 3-х
результат тотже...
kovigor
Цитата(e0000 @ Feb 17 2011, 10:53) *
Что за софт/железо?


Это такая программа-сниффер. Иногда бывает очень полезной.

Скорее всего, ваше устройство просто не отвечает на SETUP - пакеты, адресованные к его EP0. Вот я и предлагаю воспользоваться сниффером, чтобы выяснить, посылает хост эти пакеты или же нет. Почему устройство не отвечает на запросы ? Например, вы подключаетесь к шине слишком рано, когда устройство еще не готово отвечать на запросы (не засинхронизирована PLL, не разрешены прерывания ...).
e0000
BusHound
Скачал, поставил...
SETUP пакетов именно для моего девайса не присылает smile3046.gif
Для других устройств все красиво и четко. wacko.gif

PS
К нему кряк какой нибудь есть? rolleyes.gif
Платить почти $800 за Full Version как-то... cranky.gif
kovigor
Цитата(e0000 @ Feb 17 2011, 13:19) *
К нему кряк какой нибудь есть? rolleyes.gif


Есть. Вы просто плохо искали ...
e0000
Цитата(kovigor @ Feb 17 2011, 15:12) *
Есть. Вы просто плохо искали ...

Большое спасибо за BusHound

Ситуация такова:
BusHound говорит, что после reset у меня нет ниодноuj EP sad.gif
Я четко прописал и вижу, что в UDP_CSR0 EPEDS взведен и только в нем. Остальное - нули...
kovigor
Цитата(e0000 @ Feb 17 2011, 20:42) *
Ситуация такова ...


Хорошо. Залейте заведомо рабочий проект и посмотрите, как проходит подключение к шине на нем и на вашем проекте ...
shrek
У меня сначала знакомства с USB "своими руками" были так же постоянные проблемы. (сейчас вроде норм... тьфу-тьфу-тьфу) fman.gif
У меня AT91SAM7A3. Рассматривал ATMELовские примеры... Но я их как то не вкурил или не докурил...
Писал все сам с поддержкой Агурова, спецификации USB 2.0 и гуру пользователя aaarrr и всех кто принимал участие (Большое Вам Спасибо! wink.gif ).
Обычно я сначала в инициализации периферии инициализировал сначала частоты
Код
//---Конфигурация контроллера питания-------------------------------------------
     AT91C_BASE_CKGR -> CKGR_MOR    = 0x00000F01;                                    //MOSCEN = 1, OSCBYPASS = 0, OSCOUNT = 0xF, конфигурация генератора (от кварца)
     AT91C_BASE_PMC  -> PMC_MCKR    = AT91C_PMC_CSS_MAIN_CLK | AT91C_PMC_PRES_CLK;   //источник тактовых импульсов кварц MCK 18.432 MHz
     while (!((AT91C_BASE_PMC -> PMC_SR) & AT91C_PMC_MCKRDY));                       //ждать пока не будет готова частота MCK
     AT91C_BASE_CKGR -> CKGR_PLLR   = 0x107C3F18;                                    //USBDIV = 0b01, MUL = 0x7C, OUT = 0b00, PLLCOUNT = 0x3F, DIV = 0x18 частота PLL 96 MHz
     while (!((AT91C_BASE_PMC -> PMC_SR) & AT91C_PMC_LOCK));                         //ждать пока не замкнется петля обратной связи
     AT91C_BASE_PMC  -> PMC_SCER    = AT91C_PMC_PCK | AT91C_PMC_UDP;                 //разрешение тактирования ядра и USB

не забывая включить пользовательски сброс.
Потом контроллер прерываний
Код
//---Конфигурация контроллера прерываний----------------------------------------
     AT91C_BASE_AIC  -> AIC_IDCR    = AT91C_ALL_INT;                            //запрещение всех прерываний
     AT91C_BASE_AIC  -> AIC_ICCR    = AT91C_ALL_INT;                            //сброс всех прерываний
     AT91C_BASE_AIC  -> AIC_EOICR   = 0xF1F1F1F1;                               //запись в регистр конца прерывания
     AT91C_BASE_AIC  -> AIC_SMR[AT91C_ID_N_UDP] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0;//режим прерывания IRQ от USB запуск высоким уровнем!!!
     AT91C_BASE_AIC  -> AIC_SVR[AT91C_ID_N_UDP] = (int) usb;                    //адрес обработчика прерывания IRQ от USB
     AT91C_BASE_AIC  -> AIC_IDCR    = AT91C_ALL_INT;                            //запрещение всех прерываний

Дальше иницилизировал сам контроллер USB
Код
//---Конфигурация USB-----------------------------------------------------------
     AT91C_BASE_PMC  -> PMC_PCER     = AT91C_ID_UDP;
     AT91C_BASE_UDP  -> UDP_GLBSTATE = 0;
     AT91C_BASE_UDP  -> UDP_ICR      = AT91C_UDP_CLEAR_INT;                      //Сброс прерываний
     AT91C_BASE_UDP  -> UDP_RSTEP    = AT91C_UDP_ALL_EP;                         //Сброс всех конечных точек
     AT91C_BASE_UDP  -> UDP_IDR      = AT91C_UDP_ALL_INT | AT91C_UDP_ALL_EP;     //Запрещаем все прерывания
     AT91C_BASE_UDP  -> UDP_IER      = AT91C_UDP_ALL_INT | AT91C_UDP_EPINT0;     //Разрешить прерывание от 0
     AT91C_BASE_UDP  -> UDP_CSR[AT91C_UDP_EP0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;//0 конечная контрольная точка

Я все (ну или почти все) проинициализировал. Можно прикрутить модуль UART для отладки что я и делал. Смотрел какие пакеты приходят и в каких прерываниях висит устройство. Сразу скажу что устройство после сброса будет постоянно вистеть в прерывании SOF(кадр каждую милисекунду приходит).
Так... далее
Код
AT91C_BASE_AIC  -> AIC_IECR = AT91C_ID_UDP;
AT91C_BASE_PIOB -> PIO_CODR = AT91C_PIO_PB1;

Включаем прерывания USB и подтягивающий резистор (в ките AT91SAM7A3-EK).
И понеслась...
Хост несколько раз сначала сбрасывает устройство...
Код
//---Обработчик прерываний USB--------------------------------------------------
void usb()
     {
//---Обработка прерываний от конечных точек-------------------------------------
     switch ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_ALL_EP)
          {
          case AT91C_UDP_EPINT0: {POINT = 0; USB_EP_INT(); break;}      //в зависимости от вызвавшей конечной точки прерывания присваиваем соответствующий индекс
          case AT91C_UDP_EPINT1: {POINT = 1; USB_EP_INT(); break;}
          case AT91C_UDP_EPINT2: {POINT = 2; USB_EP_INT(); break;}
          case AT91C_UDP_EPINT3: {POINT = 3; USB_EP_INT(); break;}
          case AT91C_UDP_EPINT4: {POINT = 4; USB_EP_INT(); break;}
          case AT91C_UDP_EPINT5: {POINT = 5; USB_EP_INT(); break;}
          default: break;
          }
//------------------------------------------------------------------------------
     if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_RXRSM)
          {
          AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_RXRSM;
          }
//------------------------------------------------------------------------------
     if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_RXSUSP)
          {
          AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_RXSUSP;
          }
//---Обработка прерывания по началу кадра---------------------------------------
     if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_SOFINT)
          {
          AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_SOFINT;
          }
//---Конфигурация USB при сбросе шины-------------------------------------------
     if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_ENDBUSRES)
          {
          AT91C_BASE_UDP  -> UDP_IDR = AT91C_UDP_ALL_INT | AT91C_UDP_ALL_EP;                  //Запрещаем все прерывания
          AT91C_BASE_UDP  -> UDP_IER = AT91C_UDP_ALL_INT | AT91C_UDP_EPINT0;                  //Разрешить прерывание от 0
          AT91C_BASE_UDP  -> UDP_CSR[AT91C_UDP_EP0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;//0 конечная контрольная точка
          AT91C_BASE_UDP  -> UDP_ICR = AT91C_UDP_ENDBUSRES;                                  //Сброс прерывания по сбросу шины
          }
//------------------------------------------------------------------------------
     if ((AT91C_BASE_UDP -> UDP_ISR) & AT91C_UDP_WAKEUP)
          {
          AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_WAKEUP;
          }
//---Прерывание обработано------------------------------------------------------
     AT91C_BASE_AIC -> AIC_EOICR = 0xF1F1F1F1;                                  //Сообщаем AIC прерывание обработал :-)
     }

После сброса устройство надо заново проинициализировать (по крайней мере по совету aaarrr мне это помогло), а так было как у вас. Кстати бит прерывания сброса надо очистить, чтобы устройство в нем не пребывало постоянно.
Как видно я обрабатываю только 2 прерывания, а остальные все сбрасываю. Обрабатываю прерывания по конечной точке и по сбросу шины (и в нем же сразу заново инициализирую устройство).
Мой первый пост про USB
Ну а дальше все по идее должно заработать. (должен прислать setup пакет вида 80 06 00 01 00 00 40 00)
kichnamid
"После сброса устройство надо заново проинициализировать " - это имеется в виду прерывание ENDBUS?

вообщем не помогло. всё так же нет прерывания конечной точки.
у меня конфигурация частоты вынесена в стартуп, может в основном теле программы повторить? глаза замылились, чувствую, что бьюсь о стенку. уже вторую плату сделали - тоже самоеsad.gif
shrek
Цитата
"После сброса устройство надо заново проинициализировать " - это имеется в виду прерывание ENDBUS?

вообщем не помогло. всё так же нет прерывания конечной точки.
у меня конфигурация частоты вынесена в стартуп, может в основном теле программы повторить? глаза замылились, чувствую, что бьюсь о стенку. уже вторую плату сделали - тоже самое

Да оно самое ENDBUSRES. Попробуйте в другой порт USB воткнуть или вообще в другой комп))) У меня была такая проблема на работе HID устройство (джостик) работало на всех компах корректно и не зависало (В Battlefield 2 пробовали biggrin.gif ). Дома подключаю, дрова поставились, но где-то через несколько минут девайс зависал не знаю почему... Точнее не исследовал почему зависает).
В стартупе я написал вход в прерывание и выход из него и инициализировал стек. Далее PC шел на инициализацию периферии и т.д., а затем на main().
С другой стороны возьмите и разрешите все прерывания (например по RS-232 можно послать состояние регистра UDP_ISR, все равно прерывания чистить надо вручную).
По порядку.
Инициализация частот. Настройка PLL. Разрешение тактирования UDP модуля где нужно 48 МГц отдельно!!! (AT91C_BASE_PMC -> PMC_SCER = AT91C_PMC_PCK | AT91C_PMC_UDP;)
Конфигурация контроллера прерываний.
Код
AT91C_BASE_AIC  -> AIC_IDCR    = AT91C_ALL_INT;                            //запрещение всех прерываний
     AT91C_BASE_AIC  -> AIC_ICCR    = AT91C_ALL_INT;                            //сброс всех прерываний
     AT91C_BASE_AIC  -> AIC_EOICR   = 0xF1F1F1F1;                               //запись в регистр конца прерывания
     AT91C_BASE_AIC  -> AIC_SMR[AT91C_ID_N_UDP] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 0;//режим прерывания IRQ от USB запуск высоким уровнем!!!
     AT91C_BASE_AIC  -> AIC_SVR[AT91C_ID_N_UDP] = (int) usb;                    //адрес обработчика прерывания IRQ от USB
     AT91C_BASE_AIC  -> AIC_IDCR    = AT91C_ALL_INT;                            //запрещение всех прерываний

Конфигурация USB. Разрешение его тактирования! (AT91C_BASE_PMC -> PMC_PCER = AT91C_ID_UDP;)
Разрешаем прерывание по USB. (AT91C_BASE_AIC -> AIC_IECR = AT91C_ID_UDP;)
Если у Вас отдельно как-то подключается резистор к шине (например транзистором) подключаем. Дальше должны пойти прерывания. Первые буду сброс шины ENDBUSRES у меня раза четыре шина сбрасывалась.После сброса надо заново инициализировать USB. Потом туча прерываний SOFINT. Потом должно быть прерывание от конечной точки. Причем только от НУЛЕВОЙ!!! И она должна быть КОНТРОЛЬНОЙ!!!
Проверте тактируете вы USB частотой 48 МГц, тактируете ли вы сам периферийный модуль USB, сконфигурировали ли вы модуль USB, разрешили ли вы в модуле прерывания от конечных точек, разрешили ли вы прерывания для модуля USB в контроллере прерываний?
kichnamid
к моей плате подходят только пару-тройку ENBUSRES, а потом несколько resume. тот же самый проект, но с другой конфигурацией частоты(от кварца) на отладочной плате почти сразу получает и SOF и EP0 прерывание в UDP_ISR.

выложите пожалуйста кто-нибудь вашу электрическую схему. кусочек только про USB интерфейс.

на своей плате проверил PLL через программируемы клок: вывел на ножку - нормально и 48MHz и 12MHz.

заново инициализировать USB после ENDBUSRES: может здесь я не догоняю что-то?

AT91C_BASE_UDP -> UDP_IDR = AT91C_UDP_ALL_INT | AT91C_UDP_ALL_EP; //Запрещаем все прерывания
AT91C_BASE_UDP -> UDP_IER = AT91C_UDP_ALL_INT | AT91C_UDP_EPINT0; //Разрешить прерывание от 0
AT91C_BASE_UDP -> UDP_CSR[AT91C_UDP_EP0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;//0 конечная контрольная точка
AT91C_BASE_UDP -> UDP_ICR = AT91C_UDP_ENDBUSRES; //Сброс прерывания по сбросу шины

так?

а как проверить возимело-ли это действие? атмеловцы советуют перепроверять запись флагов в UDP_CSR и в цикле долбить флаги пока не изменятся. это иногда к зависанию приводит, еще метод есть?
можно ли заставить UDP просто выдать что-нибудь на линию? может оба контроллера бракованные, у нас вообще были проблемы с их покупкой
aaarrr
Цитата(kichnamid @ Mar 1 2011, 14:44) *
атмеловцы советуют перепроверять запись флагов в UDP_CSR и в цикле долбить флаги пока не изменятся. это иногда к зависанию приводит, еще метод есть?

Иногда - это когда между записью и проверкой вклинивается прерывание. Правильный способ: запретить прерывания - установить/сбросить биты - дождаться изменения - восстановить прерывания. И проверка эта нужна далеко не во всех случаях, смотрите внимательно описание регистра CSR.
shrek
Цитата
к моей плате подходят только пару-тройку ENBUSRES, а потом несколько resume. тот же самый проект, но с другой конфигурацией частоты(от кварца) на отладочной плате почти сразу получает и SOF и EP0 прерывание в UDP_ISR.

А от чего у вас тогда ARM тактируется?... Атмелу для USB вроде нужна ТОЛЬКО 48 МГц. 12 МГц туда ни к сегу ни к городу. 48 МГц USB нужно чтобы частоту 12 МГц получить. У меня тоже "отладочная платка" AT91SAM7A3-EK. На ней все прекрасно. На тех платках, которые я проэктировал на основе ARMа, я перенес все с кита (обьвязку и цепочку PLL). Все запускалось и прекрасно работало кроме PLL. Не запускался... Наивно полагая, если склонирую с кита, что все заработает.
USB нужны 2 частоты 48 МГц для приемо-передающего устройства, которая получается только с PLL, и "любая" тактовая частота для модуля чтобы ядро общалось с USB.
48 МГц включатся командой:
Код
AT91C_BASE_PMC -> PMC_SCER = AT91C_PMC_UDP;

Перед этим 48 МГц надо получить (она еще делится в своем же спец делителе для USB).
Для "общения ядра с USB":
Код
AT91C_BASE_PMC -> PMC_PCER = AT91C_ID_UDP;
DmitryM
Цитата(shrek @ Mar 1 2011, 19:25) *
...


Не забываем про AT91C_BASE_PMC -> CKGR_PLLR USB_DIV
kichnamid
то, что было на PLL, я и проверял, выводя наружу, с разными делениями. поскольку 48MHz МК может получить из 96MHz PLL, я решил до UDP частота доходит в порядке.
CODE
Mode_USR EQU 0x10
Mode_FIQ EQU 0x11
Mode_IRQ EQU 0x12
Mode_SVC EQU 0x13
Mode_ABT EQU 0x17
Mode_UND EQU 0x1B
Mode_SYS EQU 0x1F

I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled


; Internal Memory Base Addresses
FLASH_BASE EQU 0x00100000
RAM_BASE EQU 0x00200000


;// <h> Stack Configuration (Stack Sizes in Bytes)
;// <o0> Undefined Mode <0x0-0xFFFFFFFF:8>
;// <o1> Supervisor Mode <0x0-0xFFFFFFFF:8>
;// <o2> Abort Mode <0x0-0xFFFFFFFF:8>
;// <o3> Fast Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o4> Interrupt Mode <0x0-0xFFFFFFFF:8>
;// <o5> User/System Mode <0x0-0xFFFFFFFF:8>
;// </h>

UND_Stack_Size EQU 0x00000000
SVC_Stack_Size EQU 0x00000008
ABT_Stack_Size EQU 0x00000000
FIQ_Stack_Size EQU 0x00000000
IRQ_Stack_Size EQU 0x00000080
USR_Stack_Size EQU 0x00000400

ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
FIQ_Stack_Size + IRQ_Stack_Size)

AREA STACK, NOINIT, READWRITE, ALIGN=3

Stack_Mem SPACE USR_Stack_Size
__initial_sp SPACE ISR_Stack_Size
Stack_Top


;// <h> Heap Configuration
;// <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF>
;// </h>

Heap_Size EQU 0x00000000

AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit


; Reset Controller (RSTC) definitions
RSTC_BASE EQU 0xFFFFFD00 ; RSTC Base Address
RSTC_MR EQU 0x08 ; RSTC_MR Offset

;/*
;// <e> Reset Controller (RSTC)
;// <o1.0> URSTEN: User Reset Enable
;// <i> Enables NRST Pin to generate Reset
;// <o1.8..11> ERSTL: External Reset Length <0-15>
;// <i> External Reset Time in 2^(ERSTL+1) Slow Clock Cycles
;// </e>
;*/
RSTC_SETUP EQU 1
RSTC_MR_Val EQU 0xA5000401


; Embedded Flash Controller (EFC) definitions
EFC_BASE EQU 0xFFFFFF00 ; EFC Base Address
EFC0_FMR EQU 0x60 ; EFC0_FMR Offset
EFC1_FMR EQU 0x70 ; EFC1_FMR Offset

;// <e> Embedded Flash Controller 0 (EFC0)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC0_SETUP EQU 1
EFC0_FMR_Val EQU 0x00320100

;// <e> Embedded Flash Controller 1 (EFC1)
;// <o1.16..23> FMCN: Flash Microsecond Cycle Number <0-255>
;// <i> Number of Master Clock Cycles in 1us
;// <o1.8..9> FWS: Flash Wait State
;// <0=> Read: 1 cycle / Write: 2 cycles
;// <1=> Read: 2 cycle / Write: 3 cycles
;// <2=> Read: 3 cycle / Write: 4 cycles
;// <3=> Read: 4 cycle / Write: 4 cycles
;// </e>
EFC1_SETUP EQU 0
EFC1_FMR_Val EQU 0x00320100


; Watchdog Timer (WDT) definitions
WDT_BASE EQU 0xFFFFFD40 ; WDT Base Address
WDT_MR EQU 0x04 ; WDT_MR Offset

;// <e> Watchdog Timer (WDT)
;// <o1.0..11> WDV: Watchdog Counter Value <0-4095>
;// <o1.16..27> WDD: Watchdog Delta Value <0-4095>
;// <o1.12> WDFIEN: Watchdog Fault Interrupt Enable
;// <o1.13> WDRSTEN: Watchdog Reset Enable
;// <o1.14> WDRPROC: Watchdog Reset Processor
;// <o1.28> WDDBGHLT: Watchdog Debug Halt
;// <o1.29> WDIDLEHLT: Watchdog Idle Halt
;// <o1.15> WDDIS: Watchdog Disable
;// </e>
WDT_SETUP EQU 1
WDT_MR_Val EQU 0x00008000


; Power Mangement Controller (PMC) definitions
PMC_BASE EQU 0xFFFFFC00 ; PMC Base Address
PMC_MOR EQU 0x20 ; PMC_MOR Offset
PMC_MCFR EQU 0x24 ; PMC_MCFR Offset
PMC_PLLR EQU 0x2C ; PMC_PLLR Offset
PMC_MCKR EQU 0x30 ; PMC_MCKR Offset
PMC_SR EQU 0x68 ; PMC_SR Offset
PMC_MOSCEN EQU (1<<0) ; Main Oscillator Enable
PMC_OSCBYPASS EQU (1<<1) ; Main Oscillator Bypass
PMC_OSCOUNT EQU (0xFF<<8) ; Main OScillator Start-up Time
PMC_DIV EQU (0xFF<<0) ; PLL Divider
PMC_PLLCOUNT EQU (0x3F<<8) ; PLL Lock Counter
PMC_OUT EQU (0x03<<14) ; PLL Clock Frequency Range
PMC_MUL EQU (0x7FF<<16) ; PLL Multiplier
PMC_USBDIV EQU (0x03<<28) ; USB Clock Divider
PMC_CSS EQU (3<<0) ; Clock Source Selection
PMC_PRES EQU (7<<2) ; Prescaler Selection
PMC_MOSCS EQU (1<<0) ; Main Oscillator Stable
PMC_LOCK EQU (1<<2) ; PLL Lock Status
PMC_MCKRDY EQU (1<<3) ; Master Clock Status

;// <e> Power Mangement Controller (PMC)
;// <h> Main Oscillator
;// <o1.0> MOSCEN: Main Oscillator Enable
;// <o1.1> OSCBYPASS: Oscillator Bypass
;// <o1.8..15> OSCCOUNT: Main Oscillator Startup Time <0-255>
;// </h>
;// <h> Phase Locked Loop (PLL)
;// <o2.0..7> DIV: PLL Divider <0-255>
;// <o2.16..26> MUL: PLL Multiplier <0-2047>
;// <i> PLL Output is multiplied by MUL+1
;// <o2.14..15> OUT: PLL Clock Frequency Range
;// <0=> 80..160MHz <1=> Reserved
;// <2=> 150..220MHz <3=> Reserved
;// <o2.8..13> PLLCOUNT: PLL Lock Counter <0-63>
;// <o2.28..29> USBDIV: USB Clock Divider
;// <0=> None <1=> 2 <2=> 4 <3=> Reserved
;// </h>
;// <o3.0..1> CSS: Clock Source Selection
;// <0=> Slow Clock
;// <1=> Main Clock
;// <2=> Reserved
;// <3=> PLL Clock
;// <o3.2..4> PRES: Prescaler
;// <0=> None
;// <1=> Clock / 2 <2=> Clock / 4
;// <3=> Clock / 8 <4=> Clock / 16
;// <5=> Clock / 32 <6=> Clock / 64
;// <7=> Reserved
;// </e>
PMC_SETUP EQU 1
PMC_MOR_Val EQU 0x00000602
PMC_PLLR_Val EQU 0x10053C01
PMC_MCKR_Val EQU 0x00000001


PRESERVE8


; Area Definition and Entry Point
; Startup Code must be linked first at Address at which it expects to run.

AREA RESET, CODE, READONLY
ARM


; Exception Vectors
; Mapped to Address 0.
; Absolute addressing mode must be used.
; Dummy Handlers are implemented as infinite loops which can be modified.

Vectors LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP ; Reserved Vector
; LDR PC,IRQ_Addr
LDR PC,[PC,#-0xF20] ; Vector From AIC_IVR
; LDR PC,FIQ_Addr
LDR PC,[PC,#-0xF20] ; Vector From AIC_FVR

Reset_Addr DCD Reset_Handler
Undef_Addr DCD Undef_Handler
SWI_Addr DCD SWI_Handler
PAbt_Addr DCD PAbt_Handler
DAbt_Addr DCD DAbt_Handler
DCD 0 ; Reserved Address
IRQ_Addr DCD IRQ_Handler
FIQ_Addr DCD FIQ_Handler

Undef_Handler B Undef_Handler
SWI_Handler B SWI_Handler
PAbt_Handler B PAbt_Handler
DAbt_Handler B DAbt_Handler
IRQ_Handler B IRQ_Handler
FIQ_Handler B FIQ_Handler


; Reset Handler

EXPORT Reset_Handler
Reset_Handler


; Setup RSTC
IF RSTC_SETUP != 0
LDR R0, =RSTC_BASE
LDR R1, =RSTC_MR_Val
STR R1, [R0, #RSTC_MR]
ENDIF


; Setup EFC0
IF EFC0_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC0_FMR_Val
STR R1, [R0, #EFC0_FMR]
ENDIF

; Setup EFC1
IF EFC1_SETUP != 0
LDR R0, =EFC_BASE
LDR R1, =EFC1_FMR_Val
STR R1, [R0, #EFC1_FMR]
ENDIF

; Setup WDT
IF WDT_SETUP != 0
LDR R0, =WDT_BASE
LDR R1, =WDT_MR_Val
STR R1, [R0, #WDT_MR]
ENDIF


; Setup PMC
IF PMC_SETUP != 0
LDR R0, =PMC_BASE

; Setup Main Oscillator
LDR R1, =PMC_MOR_Val
STR R1, [R0, #PMC_MOR]

; Wait until Main Oscillator is stablilized
IF (PMC_MOR_Val:AND:PMC_MOSCEN) != 0
MOSCS_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MOSCS
BEQ MOSCS_Loop
ENDIF

; Setup the PLL
IF (PMC_PLLR_Val:AND:PMC_MUL) != 0
LDR R1, =PMC_PLLR_Val
STR R1, [R0, #PMC_PLLR]

; Wait until PLL is stabilized
PLL_Loop LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_LOCK
BEQ PLL_Loop
ENDIF

; Select Clock
IF (PMC_MCKR_Val:AND:PMC_CSS) == 1 ; Main Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_CSS
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ELIF (PMC_MCKR_Val:AND:PMC_CSS) == 3 ; PLL Clock Selected
LDR R1, =PMC_MCKR_Val
AND R1, #PMC_PRES
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy1 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy1
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR]
WAIT_Rdy2 LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_MCKRDY
BEQ WAIT_Rdy2
ENDIF ; Select Clock
ENDIF ; PMC_SETUP


; Copy Exception Vectors to Internal RAM

IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF


; Remap on-chip RAM to address 0

MC_BASE EQU 0xFFFFFF00 ; MC Base Address
MC_RCR EQU 0x00 ; MC_RCR Offset

IF :DEF:REMAP
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR] ; Remap
ENDIF


; Setup Stack for each mode

LDR R0, =Stack_Top

; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size

; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size

; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size

; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size

; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size

; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB

EXPORT __initial_sp

ELSE

MOV SP, R0
SUB SL, SP, #USR_Stack_Size

ENDIF


; Enter the C code

IMPORT __main
LDR R0, =__main
BX R0


IF :DEF:__MICROLIB

EXPORT __heap_base
EXPORT __heap_limit

ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY

IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap

LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF


END

это стартап с установкой частоты

CODE

/* Enables the 48MHz USB Clock UDPCK and System Peripheral USB Clock */
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK |AT91C_PMC_UDP;
AT91C_BASE_AIC->AIC_IDCR=AT91C_ALL_INT; //zapr int
AT91C_BASE_AIC->AIC_ICCR=AT91C_ALL_INT; //sbros int
AT91C_BASE_AIC->AIC_EOICR=0xF1F1F1F1;

/* Global USB Interrupt: Mode and Vector with Highest Priority and Enable */
AT91C_BASE_AIC->AIC_SMR[AT91C_ID_UDP] = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL |0;
AT91C_BASE_AIC->AIC_SVR[AT91C_ID_UDP] = (unsigned long) USB_ISR;
AT91C_BASE_AIC->AIC_IDCR=AT91C_ALL_INT; //zapr int
AT91C_BASE_PMC->PMC_PCER = (1<<AT91C_ID_UDP);

AT91C_BASE_UDP->UDP_GLBSTATE=0;
AT91C_BASE_UDP->UDP_ICR=AT91C_UDP_CLEAR_INT;
AT91C_BASE_UDP->UDP_RSTEP=AT91C_UDP_ALL_EP;
AT91C_BASE_UDP->UDP_IDR = AT91C_UDP_ALL_INT | AT91C_UDP_ALL_EP;
AT91C_BASE_UDP->UDP_IER = AT91C_UDP_ALL_INT | AT91C_UDP_EPINT0;
AT91C_BASE_UDP->UDP_CSR[0] = (AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS);
AT91C_BASE_AIC->AIC_IECR = 0x0000FFFF;

это начальная инициализация UDP

CODE
void USB_ISR (void) __irq {
DWORD isr, csr, bkm, n;

while (isr = pUDP->UDP_ISR) {

;
/* End of Bus Reset Interrupt */
if (isr & AT91C_UDP_ENDBUSRES) {
AT91C_BASE_UDP -> UDP_IDR = AT91C_UDP_ALL_INT | AT91C_UDP_ALL_EP; //Запрещаем все прерывания
AT91C_BASE_UDP -> UDP_IER = AT91C_UDP_ALL_INT | AT91C_UDP_EPINT0; //Разрешить прерывание от 0
while ((pUDP->UDP_CSR[0]&(AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL))!=(AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL)) {
AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL;
}
AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
}

/* USB Suspend Interrupt */
if (isr & AT91C_UDP_RXSUSP) {
USB_Suspend();
#if USB_SUSPEND_EVENT
USB_Suspend_Event();
#endif
pUDP->UDP_ICR = AT91C_UDP_RXSUSP;
}

/* USB Resume Interrupt */
if (isr & AT91C_UDP_RXRSM) {
USB_Resume();
#if USB_RESUME_EVENT
USB_Resume_Event();
#endif
pUDP->UDP_ICR = AT91C_UDP_RXRSM;
}

/* External Resume Interrupt */
if (isr & AT91C_UDP_EXTRSM) {
USB_WakeUp();
#if USB_WAKEUP_EVENT
USB_WakeUp_Event();
#endif
pUDP->UDP_ICR = AT91C_UDP_EXTRSM;
}

/* Start of Frame Interrupt */
if (isr & AT91C_UDP_SOFINT) {
#if USB_SOF_EVENT
USB_SOF_Event();
#endif
pUDP->UDP_ICR = AT91C_UDP_SOFINT;
}

/* Endpoint Interrupts */
for (n = 0; n < USB_EP_NUM; n++) {
if (isr & (1 << n)) { //ВОТ СЮДА ПРОГРАММА НИКОГДА НЕ ПОПАДАЕТ!!!!!(((((

csr = pUDP->UDP_CSR[n];

/* Setup Packet Received Interrupt */
if (csr & AT91C_UDP_RXSETUP) {
if (USB_P_EP[n]) {
USB_P_EP[n](USB_EVT_SETUP);
}
/* Setup Flag is already cleared in USB_DirCtrlEP */
/* pUDP->UDP_CSR[n] &= ~AT91C_UDP_RXSETUP; */
}

/* Data Packet Received Interrupt */
bkm = RX_DATA_BK[RxDataBank[n]];
if (csr & bkm) {
if (USB_P_EP[n]) {
USB_P_EP[n](USB_EVT_OUT);
}
pUDP->UDP_CSR[n] &= ~bkm;
if (DualBankEP & (1 << n)) {
RxDataBank[n] ^= 1;
}
}

/* Data Packet Sent Interrupt */
if (csr & AT91C_UDP_TXCOMP) {
// pUDP->UDP_CSR[n] &= ~AT91C_UDP_TXCOMP;
if (TxDataBank[n]) {
pUDP->UDP_CSR[n] |= AT91C_UDP_TXPKTRDY;
TxDataBank[n] = 0;
}
if (USB_P_EP[n]) {
USB_P_EP[n](USB_EVT_IN);
}
pUDP->UDP_CSR[n] &= ~AT91C_UDP_TXCOMP;
}

/* STALL Packet Sent Interrupt */
if (csr & AT91C_UDP_STALLSENT) {
if ((csr & AT91C_UDP_EPTYPE) == AT91C_UDP_EPTYPE_CTRL) {
if (USB_P_EP[n]) {
USB_P_EP[n](USB_EVT_IN_STALL);
/* USB_P_EP[n](USB_EVT_OUT_STALL); */
}
}
pUDP->UDP_CSR[n] &= ~AT91C_UDP_STALLSENT;
}

}
}

}

*AT91C_AIC_EOICR = 0xF1F1F1F1; /* End of Interrupt */
}

это обработчик прерывания собсна.

я понимаю, что у многих результат труда это комерческая тайна, но если есть возможность выложите всёже кусок схемы сопряжения с USB разъёмом и PLL фильтр.
shrek
Цитата
я понимаю, что у многих результат труда это комерческая тайна, но если есть возможность выложите всёже кусок схемы сопряжения с USB разъёмом и PLL фильтр.


А че тут таить то? fman.gif
Кит AT91SAM7A3-EK
Вот его схемка со всеми кусками)
Нажмите для просмотра прикрепленного файла
Кстати одна маленькая деталь. Кварц я заменил с 18.432 МГц, на 8 МГц. Соответственно коэффициенты изменились (чтобы эта же цепочка PLL была работоспособна) DIV = 4, MUL = 47 (коэф. расчитывается как MUL + 1). Это все делалось чтобы вписаться в требования для PLL модуля. А то на родном 18.432 МГц получался коэф деления DIV = 24, по требованиям то нужно чтобы входная частота для PLL была больше 1 МГц. Можно поставить и на 16 МГц и подобрать свои коэф. и свою цепочку PLL по PLL калькулятору.
Нажмите для просмотра прикрепленного файла
sergeeff
Совет. Мы купили как-то отладочную плату, где во входных цепях USB стояли фильтрующие ферриты. Я над запуском USB протра...ся недели две, пока мы не закоротили эти долбаные ферриты. Резюме - проверьте номиналы RC на входе и внимательно посмотрите, так ли все у вас, как советует Atmel.
kichnamid
перепроверил схему, сверил с предлагаемой Atmel`ем - всё как у них. только я не отслеживаю VBUS, а просто завожу через 10кОм на землю. питание у мя от внешнего источника.

всё попрежнему не работает: только сбросы да resume приходит и всё.

ещё заметил, что после начальной инициализации что-то вызывает прерывание UDP, хотя USB кабель вообще не подключён. почему такое происходит? или это закономерный результат(код я запостил выше)
shrek
Вашу схему в студию! sm.gif
kichnamid
вот кусок схемы относительно интерфейса USB
aaarrr
А где, простите, земля у USB? И зачем эта непонятная RC цепочка на 5V?
kichnamid
извиняюсь, забыл дорисовать.

РЦ-цепочка у 5В - это у 1-ой ножки USB имеется в виду? Если да, то я пытался сделать так как на EK-плате: конденсатор на землю, так же там VSUB идёт на микроконтроллер (чтобы отловить момент подключения) и притянута к GND через резистор. у меня 1-ая ножка USB вообще не используется, но резистор я решил скопировать.
shrek
Под "USB" что в схеме понимается? Земля полюбому должна быть у USB и контроллера связана!
kichnamid
земля на моей плате общая для всего. под USB понимается разъём USB(тип В у меня)
e0000
Доброе время суток, всезнающий All!
Возвращаюсь к теме, так как своих мозгов уже не хватает:
Устойство ожило и работает вполне коректно.
Появилась следующая необходимость: гонять пакеты размерностью больше чем размер конечной точки...
И тут затык.
Влетаем по прерыванию в обработку приема конечной точки, считываем от дуда данные в количестве RXBYTECNT...
сбрасываем флаг соответвующего банка, через который этот пакет влетел. Но его размер принятых данных равен максимальному размеру конечной точки...
Ладно - делаем буферезацию и ждем следующего куска и... следующего прерывания не происходит sad.gif
Может кто сталкивался с подобной проблемой, может у кого-то есть опыД в подобных вещах...

В целом вопрос заключается в двух вопросах:
1. Как принять данные больше чем конечная точка?
2. Возникает ли рерывание, когда должен прилететь второй(третий, пятый) блок данных одного пакета данных?
kovigor
Цитата(e0000 @ Aug 29 2011, 15:05) *
В целом вопрос заключается в двух вопросах:
1. Как принять данные больше чем конечная точка?
2. Возникает ли рерывание, когда должен прилететь второй(третий, пятый) блок данных одного пакета данных?

Не помню, хоть расстреляйте. Делал весной. деталей не помню. Есть проект - отлаженный и рабочий, для AT91SAM9XE512 (mass-storage). Посмотрите, как там сделано. Дать ?

P.S. Насколько я помню, там с приходом каждого нового кусочка генерится прерывание, и по нему данные выбираются из буфера и добавляются к уже существующим. А вот как это выглядит в деталях ... см. выше
e0000
в том-то и дело, что прерывание не возникает sad.gif

Но если не сложно, то пришлите - гляну, может я что-то не так делаю...
(мейл отправил в личку)
kovigor
Цитата(e0000 @ Aug 29 2011, 17:47) *
Но если не сложно, то пришлите - гляну, может я что-то не так делаю...
(мейл отправил в личку)


Отправил. Очень прошу не распространять !
e0000
- Очень прошу не распространять!
умрет вместе со мной!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.