Перейти к содержанию
    

billidean

Свой
  • Постов

    245
  • Зарегистрирован

  • Посещение

Весь контент billidean


  1. Добрый день всем. Работаю в квартусе 14.1. Пару дней назад перестала генериться QSys. Процесс генерации запускается, производится генерация нескольких субмодулей, генератор доходит до генерации контроллера ddr3 и на этом моменте висит, якобы генерит. Но этот процесс не завершается. Я ждал два часа. Причем никаких ошибок нет. Ранее генерация занимала минут 15. Сначала я думал, что проект немного сломал. Удалил его. Развернул сохраненный проект, который генерился и корректно работал в железе. Но проблема не исчезла. С чем может быть связано такое поведение?? Поможет ли переустановка квартуса??
  2. Я так уже делал, но почему-то не прокатило. Уже разобрался. Тему можно закрывать.
  3. Я немного не понял вопроса. Я сейчас вообще никак не могу создать полноценный проект для моделсима, поэтому и прошу помощи в создании его. Думаю, что делжен быть некий автоматизированный механизм его создания, типа того, о котором я писал при работе с квартусом 9.1. Какой-нибудь скрипт должен генериться для этого, но пока не разобрался в этом.
  4. Добрый день. Нужно промоделировать проект с НИОСом. Проект создан в Квартусе 14.1 (для других Квартусов не нужно). Система QSys состоит из НИОС(classic), памяти и портов. Подобный проект я спокойно моделировал в Квартусе 9.1. Но там все было довольно просто: создал систему, создал .hex-файл для инициализации памяти, подменил его в проекте для компиляции, скомпилил, указал в СОПЦ'настройках расположение МоделСима, запустил (из СОПЦ'а), загрузил .do-файл...и все, моделируй. Здесь же столкнулся с проблемами. Создал QSys... есть два варианта генерации модели: просто как система для симуляции и система для симуляции с тестбенчем сразу. Причем это будут две разные папки со своими наборами всех субмодулей. Сгенерил оба варианта. А как теперь создать проект для МоделСима...не понимаю. Модели системы содержат кучу модулей и файлов, подцеплять их вручную...при этом можно наткнуться на неправильную последовательность (очередь) компиляции. Мне кажется в Квартусе 14.1 не все так плохо должно быть, не должно быть хуже чем в старых версиях. поэтому прошу подсказать "правильную" последовательность действий для того, чтобы создать проект для МоделСима. UPD: Версию МоделСима использую "Altera Starter Edition 6.5b". Пробовал по мануалам делать, запускать моделирование из Еклипса...так и не получилось...лезут всякие ошибки.
  5. Спасибо Maverick за ссылку. Пробежался по статье, пока нет времени плотно поразбираться, но на первый взгляд статья подробная.
  6. Добрый день всем. На вход ПЛИС поступает некая тактовая по ЛВДС: PORT MAP ( i => comp_in_p, ibar => comp_in_n, o => cry_lane_clk ); Эта тактовая поступает в модуль переопределения рабочих частот: PORT MAP ( -- clock area lane_clk_in => cry_lane_clk, lane_clk_out => cry_lane_clk_selected, gen_clk => quartz_clk, lane_div_out => lane_div, ... ); Далее, что происходит в этом модуле: 1. lane_clk_out <= lane_clk_inner; lane_div_out <= lane_div_clk_p; 2. lane_clk_inner <= pll_160_lane_clk WHEN command_osc_oe = '1' ELSE lane_clk_in WHEN pll2_status_locked = '1' ELSE pll_160_lane_clk WHEN pll_160_status_locked = '1' ELSE '0'; т.е. исходя из условий, тактовая lane_clk_inner может быть pll_160_lane_clk или lane_clk_in или 0. 3. этот модуль содержит 2 ФАПЧа: gen_pll_lane : gen_pll2 PORT MAP ( inclk0 => lane_clk_in, -- 160 c0 => pll2_sdi_clk, -- 300 c1 => pll2_serial_clkh, -- 20 c2 => pll2_core_clk, -- 100 c3 => pll2_serial_clkl, -- 3 locked => pll2_status_locked ); gen_pll_160_quartz : gen_pll_160 PORT map ( inclk0 => gen_clk, -- 80 c0 => pll_160_lane_clk, -- 160 locked => pll_160_status_locked ); исходя из состояний этих ФАПЧей и происходит выбор тактовой, которая коммутируется на сигнал lane_clk_inner. 4. Также в этом модуле есть деление этой тактовой lane_clk_inner на 10, этот сигнал называется lane_div_clk_p. В SDC-файле описал следующее: 1. create_clock -period 6.25 -name comp_in_p [ get_ports comp_in_p ] т.е. описал входную тактовую comp_in_p (160 МГц) 2. create_clock -period 12.50 -name quartz_clk [ get_ports quartz_clk ] т.е. описал входную тактовую quartz_clk (80 МГц) 3. create_clock -name {altera_reserved_tck} -period 33.333 -waveform { 0.000 16.666 } [get_ports {altera_reserved_tck}] derive_pll_clocks derive_clock_uncertainty set_clock_groups -asynchronous \ -group {altera_reserved_tck} \ -group {comp_in_p} \ -group {quartz_clk} т.е. указал асинхронные группы без их взаимного анализа. altera_reserved_tck - из-за использования СигналТапа. Проект компилится без замечаний ТаймКвеста, т.е. типа все норм. И вот здесь начинается... Вроде проект заработал, можно тестировать... НО!... немного изменишь проект, добавишь отладочные сигналы или изменишь наполнение СигналТапа (уберешь пару сигналов из захвата)... и все, проект перестает полноценно работать. При подробном анализе ТаймКвеста увидел не описанную тактовую lane_div_clk_p, т.е. которая lane_clk_inner/10. В-общем по разному пытался её описать, но ничего не получается, постоянно появляется варнинг: "Node: gen_logic:gen_logic_unit|lane_div_clk_p was determined to be a clock but was found without an associated clock assignment." Думаю, что сначала надо описать тактовую lane_clk_inner, но не знаю как, т.к. она является мультиплексированной, после этого уже описывать lane_div_clk_p. Большая просьба, подскажите нормальную литературу по времнному анализу ТаймКвест для ОЧЕНЬ начинающих, где можно постичь тонкости описания таких сложных ситуаций. Можно даже попытаться объяснить прямо здесь. Заранее признателен за помощь.
  7. В-общем, используя настройку таймера через регистры, добился генерации тактовой на MCLK высокой частоты. Звуковой драйвер работает, транслирует сигнал с ЦАПа на выход наушников. Теперь проблема другого плана. Я в проекте еще не дошел до работы с SD-картой. Поэтому для вывода звука нашел в инете некий массив (около 360 слов), в котором расположены отсчеты звука, некая мелодия. Настроив таймер управления ДМА, выдающего эти отсчеты в ЦАП, на определенную частоту, слышу эти самые отсчеты. И складывается ощущение, что чего-то не хватает, звук какой-то недоделанный. Меняя частоту работы ДМА изменяется только тональность всей мелодии в целом. Нашел еще несколько массивов звуков. Эффект или такой же, или еще хуже. По задаче мне нужно сделать вывод какой-нибудь музыки или речи (в конце-концов это будет определенная фраза), но чтобы звучание было более-менее правдоподобным. При этом мне не нужно воспроизведение mp3-файлов, это должен быть некий зашитый/статичный массив отсчетов. Может проблема в том, что при моей реализации нужен массив в определенном формате. Можете посоветовать, в каком направлении покопать. З.Ы.: с обработкой звуковых файлов пока дело не имел и с кодеками не знаком, поэтому решил пойти таким вот путем вывода звука через встроенный ЦАП без всякой обработки.
  8. Да в том-то и дело, что из документации ясно, что это должно работать, как Вы и говорите - счет до 1 и сброс, т.е. делитель частоты на два. Но почему-то не работает. Может проблема связана с Осью. ChibiOS имеет в себе драйвера для периферии (hal), и проект я делал используя их. Я ChibiOS недавно использую, может и я где-то что-то не увидел. А может лучше все на регистрах сделать.
  9. Да.нет. я прерывание не использую. Я настроил таймер чтобы он сразу на ногу выводил свой сигнал. Задействовал режим Toggle в регистре управления таймером.
  10. Получилось запустить работу этой микросхемы, была проблема с выдачей частоты на РС7. Но частота эта довольно маленькая получается - 350кГц. Выше поднять не получается, проект не апускается. Делаю так: таймер использую третий, настроил на частоту 42МГц, настроил выход на Toggle, АRR делаю 60, вывод настроил как высокоскоростной. В таком исполнении работает. Как только делаю ARR 50 и меньше, проект вываливается на первом же прерывании от таймера. Не знаю пока, как победить. В доке о таком ограничении, да и вообще об ограничении на таймеры, ничего не нашел. Но если бы поднять частоту, то звук получше бы стал. Подскажите кто-нибудь как выдать на ногу бОльшую частоту.
  11. Может проблема в том, что Вы в обработчике прерывания запускаете "тяжелые функции" типа SendCommandFromISR(CMD_LUX, CurrentCmd), я не знаю на счет именно этой ф-ции. что она делает, но может её выполнение длительное. И еще "в эту же струю" - ф-ция taskYIELD (); не поток ли запускает? Может в обработчике прерывания не стоит запускать потоки? З.Ы.: с контроллерами работаю недавно, поэтому возможно моё мнение не особо верное.
  12. Добрый день всем. Имеется у меня плата stm32f4-Discovery. Делаю всякие мелкие проекты по реализации имеющихся в проце возможностей (SPI, USART, USB-CDC, USB-HID, LCD, EXT). Использую ОС ChibiOS и среду ChibiStudio. Сейчас пытаюсь реализовать вывод звука на разъем для наушников. Проект веду следующим путем: данные для воспроизведения гоню с помощью ДМА на встроенный в проце ЦАП, далее с ноги РА4 аналоговый сигнал должен проходить через звуковой драйвер-микросхему CS43L22, и уже с выхода этой микросхемы на наушники. В-общем, на данный момент я на ноге РА4 имею звуковой поток. По схеме вывод РА4 с проца подключен к входам AIN1A,AIN1B микросхемы CS43L22. Но на выходе этой микросхемы ничего нет. Для реализации моей задумки микросхему CS43L22 по интерфейсу I2C нужно перевести в режим Analog Passthrough, при котором аналоговые данные со входа идут на выход, т.е. транслируется. Но при этом можно управлять громкостью (уровнем) выводимого звука. Сколько ни пытался инициализировать эту микросхему на нужный мне режим работы, никак не получается, на выходе вообще ничего нет. В инете натыкался на процедуры инициализации для режима воспроизведения цифрового потока, подаваемого по I2S. Но мне этот режим не нужен. Кто-нибудь может что-нибудь подсказать по данному вопросу, даже без привязки к ОС, просто алгоритм (рабочий) инициализации этой микросхемы CS43L22? Заранее благодарю за ответы.
  13. Всем привет. Посмотрев на автомат ТС мне представилась следующая возможная конструкция этого-же автомата: package x_types is type x_array is array (0 to NUM_REGISTERS) of integer; end x_types; ---------------------------- entity xxx is port ( ... a : in x_array; -- каждый элемент массива подключается к своему источнику данных (к своему тактовому домену) ... ); end xxx; ---------------------------- EMIFD <= a(EMIFA); Это всё, конечно же, на вскидку, без проработки мелочей. Но хотелось бы услышать мнение знатоков: возможна ли такая конструкция мультиплексора (возможно и не асинхронная)? Или же это полная ...?
  14. TSerg Спасибо огромное! Сравнил результат этой проги по уже сделанному фильтру Баттерворта - коэффициенты совпали. => Значит можно верить программе.
  15. Спасибо всем за помощь, с этим фильтром разобрался, его реализация в ПЛИС работает достойно. Теперь еще одна просьба: Помогите найти расчет коэффициентов для фильтра ФНЧ Бесселя 6-го порядка. В Матлабе в fdatool для такого фильтра расчета нет. В инете тоже не могу найти. Саму функцию фильтра я имею, а вот где взять коэффициенты, ума не приложу.
  16. Открыл отдельную тему http://electronix.ru/forum/index.php?showtopic=124926
  17. Используя Си я пытаюсь преобразовать математику из плав. в фикс.точку. Вместо int использовал везде long. int b0 = 0.0001*MM; -- это чтобы не пересчитывать на калькуляторе каждый коэффициент, это место можно не анализировать, расчет ведется правильно, проверил отладчиком. На счет: (int)((float)(b0*s0 + b1*s1 + b2*s2 + b3*s3 + b4*s4 + b5*s5 + b6*s6 - a1*y1 - a2*y2 - a3*y3 - a4*y4 - a5*y5 - a6*y6)/(float)MM); - когда буду реализовывать на VHDL, как мне преобразовывать в тип float? Да и на результат эти преобразования не повлияют. Сами данные будут поступать с АЦП в виде 14-разрядов. В тип float я их не смогу преобразовать в ПЛИС. Я их сдвигаю на 14 рр и считаю, что эти 14-разрядов представляют целую часть числа в фиксированной точке. Думается, что где-то кардинальная ошибка. Может обратная связь при фиксированной точке дает некоторую ЗНАЧИМУЮ погрешность?? В-общем дошел до какого-то варианта решения: все типы заменил на long long и получил такой график: Это конечно извращение - такими типами манипулировать, но.. Теперь не знаю, как это все в VHDL буду перекидывать...
  18. Решил попробовать написать на Си этот фильтр. Вот две функции: Вычисления с плавающей точкой: void MainWindow::butter(float s) { float b0 = 0.0001; float b1 = 0.0006; float b2 = 0.0016; float b3 = 0.0021; float b4 = 0.0016; float b5 = 0.0006; float b6 = 0.0001; float a0 = 1; float a1 = -4.0616; float a2 = 7.0995; float a3 = -6.7850; float a4 = 3.7230; float a5 = -1.1087; float a6 = 0.1397; static float s0; static float s1; static float s2; static float s3; static float s4; static float s5; static float s6; static float y0; static float y1; static float y2; static float y3; static float y4; static float y5; static float y6; float t = 0.0; s6 = s5; s5 = s4; s4 = s3; s3 = s2; s2 = s1; s1 = s0; y6 = y5; y5 = y4; y4 = y3; y3 = y2; y2 = y1; y1 = y0; s0 = s; y0 = b0*s0 + b1*s1 + b2*s2 + b3*s3 + b4*s4 + b5*s5 + b6*s6 - a1*y1 - a2*y2 - a3*y3 - a4*y4 - a5*y5 - a6*y6; qDebug() << y0; } Вычисления с фиксированной точкой: #define MM 16384 // 2^14 void MainWindow::butter_i(int s) { int b0 = 0.0001*MM; int b1 = 0.0006*MM; int b2 = 0.0016*MM; int b3 = 0.0021*MM; int b4 = 0.0016*MM; int b5 = 0.0006*MM; int b6 = 0.0001*MM; int a0 = 1; int a1 = -4.0616*MM; int a2 = 7.0995*MM; int a3 = -6.7850*MM; int a4 = 3.7230*MM; int a5 = -1.1087*MM; int a6 = 0.1397*MM; static int s0; static int s1; static int s2; static int s3; static int s4; static int s5; static int s6; static int y0; static int y1; static int y2; static int y3; static int y4; static int y5; static int y6; s6 = s5; s5 = s4; s4 = s3; s3 = s2; s2 = s1; s1 = s0; y6 = y5; y5 = y4; y4 = y3; y3 = y2; y2 = y1; y1 = y0; s0 = s*MM; y0 = (b0*s0 + b1*s1 + b2*s2 + b3*s3 + b4*s4 + b5*s5 + b6*s6 - a1*y1 - a2*y2 - a3*y3 - a4*y4 - a5*y5 - a6*y6)/MM; qDebug() << (int)(y0); } На вход подал постоянку (10). Первая ф-ция дает такой результат: Вторая: Где мой косяк, подскажите, плз. Второй день голову ломаю.
  19. Я бы рад, но я с Матлабом не особо работал. А с симулинком вообще не знаком. Как-то не было нужды до этих пор. Но я чувствую, что выходная картинка должна быть другой. Может быть входной сигнал какой-нибудь другой загнать, чтобы получить на выходе какой-нибудь заранее известный сигнал? Чота я как-то вообще не могу вникнуть.
  20. Помогите плизз. Раньше с фильтрами почти не работал. Необходимо написать код vhdl фильтра ФНЧ Баттерворта 6 порядка. Частота среза = 40 кГц. Частота дискретизации = 500 кГц. Данные от АЦП - 14-разрядные. Покопавшись в Матлабе сгенерил коэффициенты, и накидал такой код: -- Формула фильтра Баттерворта 6-го порядка: -- y = 1/a0 * ( b0*x + b1*x(-1) + b2*x(-2) + b3*x(-3) + b4*x(-4) + b5*x(-5) + b6*x(-6) - -- - a1*y(-1) - a2*y(-2) - a3*y(-3) - a4*y(-4) - a5*y(-5) - a6*y(-6) ) -- Полоса среза ФНЧ = 40 кГц -- Порядок фильтра = 6 -- Частота дискретизации = 500 кГц -- Из Матлаба получил следующие коэффициенты: -- b0 = 1.0707e-004 -- b1 = 6.4241e-004 -- b2 = 1.6060e-003 -- b3 = 2.1414e-003 -- b4 = 1.6060e-003 -- b5 = 6.4241e-004 -- b6 = 1.0707e-004 -- a0 = 1.0000e+000 -- a1 = -4.0616e+000 -- a2 = 7.0995e+000 -- a3 = -6.7850e+000 -- a4 = 3.7230e+000 -- a5 = -1.1087e+000 -- a6 = 1.3966e-001 -- -- Для перехода от плавающей математики к целочисленной использую -- масштабирующий коэффициент 2^14=16384 -- Т.к. а0=1, то 1/а0=1, и я просто убираю эту операцию из формулы -- После умножения весовых коэффициентов на масштабирующий коэффициент и перенеся знак "-" в саму формулу получаю: -- b0 = 1,75423488 -- b1 = 10,52524544 -- b2 = 26,312704 -- b3 = 35,0846976 -- b4 = 26,312704 -- b5 = 10,52524544 -- b6 = 1,75423488 -- a1 = -66545,2544 -- a2 = 116318,208 -- a3 = -111165,44 -- a4 = 60997,632 -- a5 = -18164,9408 -- a6 = 22881,8944 signal b0 : integer := 2; signal b1 : integer := 11; signal b2 : integer := 26; signal b3 : integer := 35; signal b4 : integer := 26; signal b5 : integer := 11; signal b6 : integer := 2; --signal a0 : integer := 16384; signal a1 : integer := 66545; signal a2 : integer := 116318; signal a3 : integer := 111165; signal a4 : integer := 60998; signal a5 : integer := 18165; signal a6 : integer := 22882; signal input : integer := 0; signal xv_0 : integer := 0; signal xv_1 : integer := 0; signal xv_2 : integer := 0; signal xv_3 : integer := 0; signal xv_4 : integer := 0; signal xv_5 : integer := 0; signal xv_6 : integer := 0; signal yv_0 : integer := 0; signal yv_1 : integer := 0; signal yv_2 : integer := 0; signal yv_3 : integer := 0; signal yv_4 : integer := 0; signal yv_5 : integer := 0; signal yv_6 : integer := 0; process(rst_n, clk) begin if rst_n = '0' then input <= 0; else if clk'event and clk = '1' then input <= conv_integer(unsigned(din)); end if; end if; end process; process(rst_n, clk) variable y_temp : integer := 1; begin if rst_n = '0' then xv_0 <= 0; xv_1 <= 0; xv_2 <= 0; xv_3 <= 0; xv_4 <= 0; xv_5 <= 0; xv_6 <= 0; y_temp := 0; yv_0 <= 0; yv_1 <= 0; yv_2 <= 0; yv_3 <= 0; yv_4 <= 0; yv_5 <= 0; yv_6 <= 0; else if clk'event and clk = '1' then xv_0 <= input; xv_1 <= xv_0; xv_2 <= xv_1; xv_3 <= xv_2; xv_4 <= xv_3; xv_5 <= xv_4; xv_6 <= xv_5; y_temp := b0*xv_0 + b1*xv_1 + b2*xv_2 + b3*xv_3 + b4*xv_4 + b5*xv_5 + b6*xv_6 + a1*yv_1 - a2*yv_2 + a3*yv_3 - a4*yv_4 + a5*yv_5 - a6*yv_6; -- Делим получившийся результат на масштабирующий коэффициент yv_0 <= y_temp/16384; yv_1 <= yv_0; yv_2 <= yv_1; yv_3 <= yv_2; yv_4 <= yv_3; yv_5 <= yv_4; yv_6 <= yv_5; -- Переводим из типа integer в тип std_logic_vector на 14 разрядов -- для записи в ФИФО fifo_din <= CONV_STD_LOGIC_VECTOR((yv_0), 14); end if; end if; end process; В Моделсиме получаю такую картину: Частота T_clk=500 кГц. Период входной пилы = 46 мкс, т.е. частота входного сигнала = 21,7 кГц. Исходя из этого я думаю, что сигнал почти весь должен пройти через фильтр без изменения. НО на картинке какая-то ересь. Что мне делать, куда смотреть?
  21. Добрый день. Кто-нибудь может помочь: нужна линейная формула с коэффициентами ФНЧ Баттерворта 6-го порядка с полосой 40 кГц. Далее я её буду реализовывать в ПЛИС на vhdl, поэтому она должна быть линейной с операциями +, - и *. Заранее спасибо.
  22. Может кто-нибудь поделится рабочим проектиком с подобным функционалом, если не жалко :help:
  23. Сегодня все просмотрел, адресация не сломана, она проходит нормально. Глянул изначальные файлы проекта с CDC+Shell. В файле serial_usb.c есть такие вещи: 1. void sduObjectInit(SerialUSBDriver *sdup) { ... chIQInit(&sdup->iqueue, sdup->ib, SERIAL_USB_BUFFERS_SIZE, inotify, sdup); chOQInit(&sdup->oqueue, sdup->ob, SERIAL_USB_BUFFERS_SIZE, onotify, sdup); } , где, как я понял, происходит инициализация очередей &sdup->iqueue &sdup->oqueue. 2. В файле usbcfg.c при обработке запроса SET_CONFIG (USB_EVENT_CONFIGURED) происходит вызов функции sduConfigureHookI, где опять происходит сброс и подготовка очередей &sdup->iqueue и &sdup->oqueue. И вообще далее весь интерфейс в проекте CDC+Shell крутится вокруг этих очередей. Я при переделке просто удалил вызов функции sduConfigureHookI при обработке запроса SET_CONFIG (USB_EVENT_CONFIGURED). И видимо из-за этого у меня получается не настроена система приема и обработки данных. Это получается, что нужно описать такие же процедуры инициализации, сброса и работы с очередями, как и в проекте примера? Или все может быть намного проще?
  24. ChibiOS :: USB HID Device (stm32f4DISCOVERY)

    Добрый день. Пытаюсь сделать HID-устройство из платы stm32f4DISCOVERY. За основу взят девайс (тоже HID) на AT89C5131, который работает стабильно и для которого есть прога на ПК. Проект делаю в ЧибиСтудии. При разработке проекта решил перепилить пример с использованием CDC+Shell, путем избавления от Serialхх-интерфейсов. На данный момент добился завершения энумерации без ошибок, т.е. винда видит устройство как HID с нужными параметрами (такими же как и для устройства на AT89C5131). Долго мучался с этим моментом, пока не поправил обработчик в файле usb.c: static bool_t default_handler(USBDriver *usbp) { ... case USB_RTYPE_RECIPIENT_DEVICE | (USB_REQ_GET_DESCRIPTOR << 8): case USB_RTYPE_RECIPIENT_INTERFACE | (USB_REQ_GET_DESCRIPTOR << 8): case USB_RTYPE_RECIPIENT_ENDPOINT| (USB_REQ_GET_DESCRIPTOR << 8): /* !!добавил эту строчку!! */ /* Handling descriptor requests from the host.*/ dp = usbp->config->get_descriptor_cb( usbp, usbp->setup[3], usbp->setup[2], usbFetchWord(&usbp->setup[4])); if (dp == NULL) return FALSE; usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); return TRUE; ... } до этого запрос дескриптора HID и его конечной точки игнорировался. Сейчас уперся в проблему обработки OUT-транзакции. Не могу понять, что где подкрутить, чтобы принять о обработать данные. Используя программу BusHound наблюдаю следующее (работаю со "старым" девайсом на AT89C5131 и с "новым"): - инициализация завершается нормально для "старого" и "нового" устройств; - при отправке OUT-данных на "старое" устройство, на экране проги BusHound вижу OUT-данные; - при отправке OUT-данных на "новое" устройство, на экран BusHound ничего не выводится, а программа ПК, из которой производится передача данных, вообще зависает, до тех пор, пока не отключишь девайс. Я понимаю. что где-то в СТМке не отрабатывается этот OUT-запрос, но вот ГДЕ, не могу найти уже несколько дней. Вот основной файл с описанием дескрипторов (и попыткой навешивания какого-то обработчика приема данных): #include "ch.h" #include "hal.h" bool_t myRequestsHook(USBDriver *usbp) { if ((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) { switch (usbp->setup[1]) { case 1: usbSetupTransfer(usbp, NULL, 0, NULL); return TRUE; default: return FALSE; } } return FALSE; } void myEP1Transmitter(USBDriver *usbp, usbep_t ep) { (void)usbp; (void)ep; } void myEP1Receiver(USBDriver *usbp, usbep_t ep) { size_t n, maxsize; // SerialUSBDriver *sdup = usbp->out_params[ep - 1]; // if (sdup == NULL) // return; chSysLockFromIsr(); // chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE); /* Writes to the input queue can only happen when there is enough space to hold at least one packet.*/ maxsize = usbp->epc[ep]->out_maxsize; // if ((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize) { /* The endpoint cannot be busy, we are in the context of the callback, so a packet is in the buffer for sure.*/ chSysUnlockFromIsr(); n = (n / maxsize) * maxsize; // usbPrepareQueuedReceive(usbp, ep, &sdup->iqueue, n); chSysLockFromIsr(); usbStartReceiveI(usbp, ep); // } chSysUnlockFromIsr(); } /* * USB Device Descriptor. */ static const uint8_t vcom_device_descriptor_data[18] = { USB_DESC_DEVICE (0x0001, /* bcdUSB (1.0). */ 0x00, /* bDeviceClass (HID). */ 0x00, /* bDeviceSubClass. */ 0x00, /* bDeviceProtocol. */ 0x40, /* bMaxPacketSize for ep0. */ 0x03EB, /* idVendor (Atmel vendor ID = 03EBh). */ 0x5703, /* idProduct. */ 0x0000, /* bcdDevice. */ 1, /* iManufacturer. */ 2, /* iProduct. */ 3, /* iSerialNumber. */ 1) /* bNumConfigurations. */ }; /* * Device Descriptor wrapper. */ static const USBDescriptor vcom_device_descriptor = { sizeof(vcom_device_descriptor_data), vcom_device_descriptor_data }; /* Configuration Descriptor tree for a CDC.*/ static const uint8_t vcom_configuration_descriptor_data[41] = { /* Configuration Descriptor.*/ USB_DESC_CONFIGURATION(41, /* wTotalLength. */ 0x01, /* bNumInterfaces. */ 0x01, /* bConfigurationValue. */ 0, /* iConfiguration. */ 0xC0, /* bmAttributes (self powered). */ 50), /* bMaxPower (100mA). */ /* Interface Descriptor.*/ USB_DESC_INTERFACE (0x00, /* bInterfaceNumber. */ 0x00, /* bAlternateSetting. */ 0x01, /* bNumEndpoints. */ 0x03, /* bInterfaceClass (HID). */ 0xff, /* bInterfaceSubClass (xx). */ 0xff, /* bInterfaceProtocol (xx). */ 0x00), /* iInterface. */ /* Дескриптор HID */ USB_DESC_BYTE (9), USB_DESC_BYTE (0x21), /* дескриптор HID */ USB_DESC_BYTE (0x00), USB_DESC_BYTE(0x01), /* версия HID */ USB_DESC_BYTE (0), /* числовой код страны для локальных устройств */ USB_DESC_BYTE (1), /* число дескрипторов репорта */ USB_DESC_BYTE (0x22), /* номер дескриптора репорта */ USB_DESC_WORD (47), /* размер дескриптора репорта */ /* Дескриптор первой конечной точки */ USB_DESC_BYTE (7), USB_DESC_BYTE (0x05), /* дескриптор ENDPOINT */ USB_DESC_BYTE (0x01), /* номер конечной точки OUT */ USB_DESC_BYTE (0x03), /* аттрибуты конечной точки */ // !!!! INTERRUPT !!!! USB_DESC_WORD (0x0040), /* максимальный размер пакета(32) */ // USB_DESC_WORD (0x0008), /* максимальный размер пакета(32) */ USB_DESC_BYTE (10), /* Дескриптор второй конечной точки */ USB_DESC_BYTE (7), USB_DESC_BYTE (0x05), /* дескриптор ENDPOINT */ USB_DESC_BYTE (0x01|0x80), /* номер конечной точки IN */ USB_DESC_BYTE (0x03), /* аттрибуты конечной точки */ // !!!! INTERRUPT !!!! USB_DESC_WORD (0x0040), /* максимальный размер пакета(32) */ // USB_DESC_WORD (0x0008), /* максимальный размер пакета(32) */ USB_DESC_BYTE (10) }; /* * Configuration Descriptor wrapper. */ static const USBDescriptor vcom_configuration_descriptor = { sizeof(vcom_configuration_descriptor_data), vcom_configuration_descriptor_data }; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! static const uint8_t vcom_HID_descriptor_data[8] = { /* Дескриптор HID */ USB_DESC_BYTE (0x21), /* дескриптор HID */ USB_DESC_BYTE (0x00), USB_DESC_BYTE(0x01), /* версия HID */ USB_DESC_BYTE (0), /* числовой код страны для локальных устройств */ USB_DESC_BYTE (1), /* число дескрипторов репорта */ USB_DESC_BYTE (0x22), /* номер дескриптора репорта */ USB_DESC_WORD (47) /* размер дескриптора репорта */ }; /* * Configuration Descriptor wrapper. */ static const USBDescriptor vcom_HID_descriptor = { sizeof(vcom_HID_descriptor_data), vcom_HID_descriptor_data }; static const uint8_t vcom_HID_report_descriptor_data[47] = { USB_DESC_BYTE(0x06), USB_DESC_BYTE(0x00), USB_DESC_BYTE(0xff), /* USAGE_PAGE (Generic Desktop) */ USB_DESC_BYTE(0x09), USB_DESC_BYTE(0x01), /* USAGE (Vendor Usage 1) */ USB_DESC_BYTE(0xa1), USB_DESC_BYTE(0x01), /* COLLECTION (Application) */ USB_DESC_BYTE(0x19), USB_DESC_BYTE(0x01), /* USAGE_MINIMUM (Vendor Usage 1) */ USB_DESC_BYTE(0x29), USB_DESC_BYTE(0x01), /* USAGE_MAXIMUM (Vendor Usage 1) */ USB_DESC_BYTE(0x15), USB_DESC_BYTE(0x00), /* LOGICAL_MINIMUM (0) */ USB_DESC_BYTE(0x26), USB_DESC_BYTE(0xff), USB_DESC_BYTE(0x00), /* LOGICAL_MAXIMUM (255) */ USB_DESC_BYTE(0x85), USB_DESC_BYTE(0x01), /* REPORT_ID (1) */ USB_DESC_BYTE(0x75), USB_DESC_BYTE(0x20), /* REPORT_SIZE (32) МОЁ НОВШЕСТВО */ USB_DESC_BYTE(0x95), USB_DESC_BYTE(0x08), /* REPORT_COUNT(8) */ USB_DESC_BYTE(0xB1), USB_DESC_BYTE(0x02), /* FEATURE (Data,Var,Abs) МОЁ НОВШЕСТВО */ USB_DESC_BYTE(0xc0), /* END_COLLECTION */ USB_DESC_BYTE(0x09), USB_DESC_BYTE(0x01), /* USAGE (Vendor Usage 1) */ USB_DESC_BYTE(0xa1), USB_DESC_BYTE(0x01), /* COLLECTION (Application) */ USB_DESC_BYTE(0x19), USB_DESC_BYTE(0x01), /* USAGE_MINIMUM (Vendor Usage 1) */ USB_DESC_BYTE(0x29), USB_DESC_BYTE(0x01), /* USAGE_MAXIMUM (Vendor Usage 1) */ USB_DESC_BYTE(0x15), USB_DESC_BYTE(0x00), /* LOGICAL_MINIMUM (0) */ USB_DESC_BYTE(0x26), USB_DESC_BYTE(0xff), USB_DESC_BYTE(0x00), /* LOGICAL_MAXIMUM (255) */ USB_DESC_BYTE(0x85), USB_DESC_BYTE(0x02), /* REPORT_ID (2) */ USB_DESC_BYTE(0x75), USB_DESC_BYTE(0x0f), /* REPORT_SIZE (15) */ USB_DESC_BYTE(0x95), USB_DESC_BYTE(0x08), /* REPORT_COUNT(8) */ USB_DESC_BYTE(0x91), USB_DESC_BYTE(0x02), /* OUTPUT (Data,Var,Abs) */ USB_DESC_BYTE(0xc0) /* END_COLLECTION */ }; /* * Configuration Descriptor wrapper. */ static const USBDescriptor vcom_HID_report_descriptor = { sizeof(vcom_HID_report_descriptor_data), vcom_HID_report_descriptor_data }; // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! /* * U.S. English language identifier. */ static const uint8_t vcom_string0[] = { USB_DESC_BYTE(4), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ USB_DESC_WORD(0x0409) /* wLANGID (U.S. English). */ }; /* * Vendor string. */ static const uint8_t vcom_string1[] = { USB_DESC_BYTE(38), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0, 'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0, 'c', 0, 's', 0 }; /* * Device Description string. */ static const uint8_t vcom_string2[] = { USB_DESC_BYTE(56), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ 'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0, 'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0, 'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0 }; /* * Serial Number string. */ static const uint8_t vcom_string3[] = { USB_DESC_BYTE(8), /* bLength. */ USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ '0' + CH_KERNEL_MAJOR, 0, '0' + CH_KERNEL_MINOR, 0, '0' + CH_KERNEL_PATCH, 0 }; /* * Strings wrappers array. */ static const USBDescriptor vcom_strings[] = { {sizeof(vcom_string0), vcom_string0}, {sizeof(vcom_string1), vcom_string1}, {sizeof(vcom_string2), vcom_string2}, {sizeof(vcom_string3), vcom_string3} }; /* * Handles the GET_DESCRIPTOR callback. All required descriptors must be * handled here. */ static const USBDescriptor *get_descriptor(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) { (void)usbp; (void)lang; switch (dtype) { case USB_DESCRIPTOR_DEVICE: return &vcom_device_descriptor; case USB_DESCRIPTOR_CONFIGURATION: return &vcom_configuration_descriptor; case USB_DESCRIPTOR_STRING: if (dindex < 4) return &vcom_strings[dindex]; // HID-дескриптор case 0x21: return &vcom_HID_descriptor; // дескриптор репорта case 0x22: return &vcom_HID_report_descriptor; } return NULL; } /** * @brief IN EP1 state. */ static USBInEndpointState ep1instate; /** * @brief OUT EP1 state. */ static USBOutEndpointState ep1outstate; /** * @brief EP1 initialization structure (OUT). */ static const USBEndpointConfig ep1config = { USB_EP_MODE_TYPE_INTR, NULL, myEP1Transmitter, myEP1Receiver, 0x0040, 0x0040, &ep1instate, &ep1outstate, 2, NULL }; /** * @brief IN EP2 state. */ static USBInEndpointState ep2instate; /** * @brief EP2 initialization structure (IN only). */ static const USBEndpointConfig ep2config = { USB_EP_MODE_TYPE_INTR, NULL, myEP1Transmitter, NULL, 0x0040, 0x0000, &ep2instate, NULL, 1, NULL }; /* * Handles the USB driver global events. */ static void usb_event(USBDriver *usbp, usbevent_t event) { // extern SerialUSBDriver SDU1; switch (event) { case USB_EVENT_RESET: return; case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: chSysLockFromIsr(); /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions must be used.*/ usbInitEndpointI(usbp, 1, &ep1config); // usbInitEndpointI(usbp, 2, &ep2config); /* Resetting the state of the CDC subsystem.*/ // sduConfigureHookI(&SDU1); chSysUnlockFromIsr(); return; case USB_EVENT_SUSPEND: return; case USB_EVENT_WAKEUP: return; case USB_EVENT_STALLED: return; } return; } /* * USB driver configuration. */ const USBConfig usbcfg = { usb_event, get_descriptor, myRequestsHook, NULL }; Файлы проекта прикладываю ниже. hid_bad.rar
  25. USB монитор

    Поработал с BusHound. В-принципе, нормально, но эта прога выдает на экран информацию о транзакции только при условии прохождения этой самой транзакции в полной мере. В данный момент у меня проблемка в том, что устройство не реагирует на OUT-передачу, и при этом BusHound не показывает вообще, что в линию USB что-то ушло. В то же время при подключении рабочего устройства к USB прога BusHound нормально отображает эту транзакцию. Т.е. что-то не доработано в этой проге, или просто нельзя ТОЛЬКО программно анализировать незавершенные транзакции. Да.. мне бы аппаратный анализатор.. :( Может кто в курсе, какой-нибудь китайский девайс реально недорого приобрести, за пару КРуб?
×
×
  • Создать...