Jump to content

    

billidean

Свой
  • Content Count

    245
  • Joined

  • Last visited

Everything posted by billidean


  1. Цитата(Flip-fl0p @ Feb 22 2017, 13:43) В общем, порывшись немного в интернете вопрос свой не решил. Но нашел несколько сайтов которые умеют генерировать тетбенч. А есть ли какая софтина простенькая, которая может этот тест сгенерировать ? При большом желании можно самому написать некую программу-генератор шаблонов... Можно всё это сделать параметризируемое.
  2. Добрый день всем. Работаю в квартусе 14.1. Пару дней назад перестала генериться QSys. Процесс генерации запускается, производится генерация нескольких субмодулей, генератор доходит до генерации контроллера ddr3 и на этом моменте висит, якобы генерит. Но этот процесс не завершается. Я ждал два часа. Причем никаких ошибок нет. Ранее генерация занимала минут 15. Сначала я думал, что проект немного сломал. Удалил его. Развернул сохраненный проект, который генерился и корректно работал в железе. Но проблема не исчезла. С чем может быть связано такое поведение?? Поможет ли переустановка квартуса??
  3. Все некогда было написать...сори... В-общем, проблема решилась сама собой. После перезапуска компа и очистки системных временных файлов и т.п. все стало работать ровно. Даже не знаю, с чем это было связано, но это уже второй подобный большой и непонятный косяк со стороны квартуса за время моей работы с ним, причем первая проблема было еще с версией 9.1. В первый раз была проблема в том, что не проходила компиляция проекта и выдавалась какая-то, уже не помню какая, ошибка, смысл которой был вообще левый...И решилось это только пересозданием проекта с подключением ВСЕХ тех же файлов. Так что нужно предусматривать и подвохи со стороны квартуса )
  4. Цитата(novartis @ Dec 15 2016, 23:16) https://www.altera.co.jp/content/dam/altera...re/an/an351.pdf По аналогии с симуляцией всяких трансиверов, сделать нужно следующее: в моделсиме нажми File -> Load -> Macro File, выбери msim_setup.tcl (где-то в тех сгенеренных папках валяется). Затем выполни команду ld_debug. Затем File -> Load -> Macro File -> wave.do. Ну дальше run 2ms Я так уже делал, но почему-то не прокатило. Уже разобрался. Тему можно закрывать.
  5. Цитата(AVR @ Dec 15 2016, 13:50) А есть варианты с задержками и без таковых? Запуск Modelsim осуществляется из под Quartus или отдельно? Я немного не понял вопроса. Я сейчас вообще никак не могу создать полноценный проект для моделсима, поэтому и прошу помощи в создании его. Думаю, что делжен быть некий автоматизированный механизм его создания, типа того, о котором я писал при работе с квартусом 9.1. Какой-нибудь скрипт должен генериться для этого, но пока не разобрался в этом.
  6. Спасибо Maverick за ссылку. Пробежался по статье, пока нет времени плотно поразбираться, но на первый взгляд статья подробная.
  7. Добрый день всем. На вход ПЛИС поступает некая тактовая по ЛВДС: Код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. Большая просьба, подскажите нормальную литературу по времнному анализу ТаймКвест для ОЧЕНЬ начинающих, где можно постичь тонкости описания таких сложных ситуаций. Можно даже попытаться объяснить прямо здесь. Заранее признателен за помощь.
  8. Помогите плизз. Раньше с фильтрами почти не работал. Необходимо написать код vhdl фильтра ФНЧ Баттерворта 6 порядка. Частота среза = 40 кГц. Частота дискретизации = 500 кГц. Данные от АЦП - 14-разрядные. Покопавшись в Матлабе сгенерил коэффициенты, и накидал такой код: CODE-- Формула фильтра Баттерворта 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; В Моделсиме получаю такую картину: [attachment=88782:__________.png] Частота T_clk=500 кГц. Период входной пилы = 46 мкс, т.е. частота входного сигнала = 21,7 кГц. Исходя из этого я думаю, что сигнал почти весь должен пройти через фильтр без изменения. НО на картинке какая-то ересь. Что мне делать, куда смотреть?
  9. Создал систему Qsys в квартусе 11.1: 1. НИОС 2. on_chip_RAM - озу для НИОСа 3. сис.таймер 4. PIO - выходы, подключенные к лампочкам RAM инициализирую hex-файлом по-умолчанию. Компилю проект, получаю .sof-файл. В NIOS II IDE создаю проект с использованием uC/OS, компилю, все ок. Программирую квартусовским программером кристалл, заливаю из NIOS II IDE в НИОС программу, все тоже хорошо, лампочки мигают. Задача: получить такой .sof-файл, чтобы не нужно было запускать программу НИОСа из NIOS II IDE. Из доки "Developing NiosII Software" вычитал, что нужно расставить галочки в BSP Settings определенным образом, используя скрипт "elf2hex <myapp>.elf <start_addr> <end_addr> --width=<data_width> <hex_filename>.hex" получить .hex-файл из .elf-файла, в Qsys выставить инициализацию RAM своим сгенеренным .hex-ом, скомпилить, получить .sof-файл, и вроде как все. Сделал все как там сказано, НО НИОС не заработал, лампочки не мигают. <start_addr> и <end_addr> взял из Qsys, как begin и end для RAM-а. Если после всех этих манипуляций я пытаюсь компилить проект в NIOS II IDE, то вылезает ошибка типа "multiple target ..." в файле mem_init.mk. И тут я ваще ни.. не понимаю, что делать. Кто занимался такими вещами ПЛЗЗЗ подскажите, в чем может быть мой косяк?
  10. stm32f4discovery проблема настройки cs43l22

    В-общем, используя настройку таймера через регистры, добился генерации тактовой на MCLK высокой частоты. Звуковой драйвер работает, транслирует сигнал с ЦАПа на выход наушников. Теперь проблема другого плана. Я в проекте еще не дошел до работы с SD-картой. Поэтому для вывода звука нашел в инете некий массив (около 360 слов), в котором расположены отсчеты звука, некая мелодия. Настроив таймер управления ДМА, выдающего эти отсчеты в ЦАП, на определенную частоту, слышу эти самые отсчеты. И складывается ощущение, что чего-то не хватает, звук какой-то недоделанный. Меняя частоту работы ДМА изменяется только тональность всей мелодии в целом. Нашел еще несколько массивов звуков. Эффект или такой же, или еще хуже. По задаче мне нужно сделать вывод какой-нибудь музыки или речи (в конце-концов это будет определенная фраза), но чтобы звучание было более-менее правдоподобным. При этом мне не нужно воспроизведение mp3-файлов, это должен быть некий зашитый/статичный массив отсчетов. Может проблема в том, что при моей реализации нужен массив в определенном формате. Можете посоветовать, в каком направлении покопать. З.Ы.: с обработкой звуковых файлов пока дело не имел и с кодеками не знаком, поэтому решил пойти таким вот путем вывода звука через встроенный ЦАП без всякой обработки.
  11. stm32f4discovery проблема настройки cs43l22

    Да в том-то и дело, что из документации ясно, что это должно работать, как Вы и говорите - счет до 1 и сброс, т.е. делитель частоты на два. Но почему-то не работает. Может проблема связана с Осью. ChibiOS имеет в себе драйвера для периферии (hal), и проект я делал используя их. Я ChibiOS недавно использую, может и я где-то что-то не увидел. А может лучше все на регистрах сделать.
  12. stm32f4discovery проблема настройки cs43l22

    Да.нет. я прерывание не использую. Я настроил таймер чтобы он сразу на ногу выводил свой сигнал. Задействовал режим Toggle в регистре управления таймером.
  13. stm32f4discovery проблема настройки cs43l22

    Получилось запустить работу этой микросхемы, была проблема с выдачей частоты на РС7. Но частота эта довольно маленькая получается - 350кГц. Выше поднять не получается, проект не апускается. Делаю так: таймер использую третий, настроил на частоту 42МГц, настроил выход на Toggle, АRR делаю 60, вывод настроил как высокоскоростной. В таком исполнении работает. Как только делаю ARR 50 и меньше, проект вываливается на первом же прерывании от таймера. Не знаю пока, как победить. В доке о таком ограничении, да и вообще об ограничении на таймеры, ничего не нашел. Но если бы поднять частоту, то звук получше бы стал. Подскажите кто-нибудь как выдать на ногу бОльшую частоту.
  14. STM32F072CB PC13 в режиме EXTI

    Может проблема в том, что Вы в обработчике прерывания запускаете "тяжелые функции" типа SendCommandFromISR(CMD_LUX, CurrentCmd), я не знаю на счет именно этой ф-ции. что она делает, но может её выполнение длительное. И еще "в эту же струю" - ф-ция taskYIELD (); не поток ли запускает? Может в обработчике прерывания не стоит запускать потоки? З.Ы.: с контроллерами работаю недавно, поэтому возможно моё мнение не особо верное.
  15. Всем привет. Посмотрев на автомат ТС мне представилась следующая возможная конструкция этого-же автомата: Код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); Это всё, конечно же, на вскидку, без проработки мелочей. Но хотелось бы услышать мнение знатоков: возможна ли такая конструкция мультиплексора (возможно и не асинхронная)? Или же это полная ...?
  16. TSerg Спасибо огромное! Сравнил результат этой проги по уже сделанному фильтру Баттерворта - коэффициенты совпали. => Значит можно верить программе.
  17. Спасибо всем за помощь, с этим фильтром разобрался, его реализация в ПЛИС работает достойно. Теперь еще одна просьба: Помогите найти расчет коэффициентов для фильтра ФНЧ Бесселя 6-го порядка. В Матлабе в fdatool для такого фильтра расчета нет. В инете тоже не могу найти. Саму функцию фильтра я имею, а вот где взять коэффициенты, ума не приложу.
  18. ФВЧ 2-го порядка

    Открыл отдельную тему http://electronix.ru/forum/index.php?showtopic=124926
  19. Используя Си я пытаюсь преобразовать математику из плав. в фикс.точку. Вместо 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? Да и на результат эти преобразования не повлияют. Цитатаvoid MainWindow::butter_i(int s) не int должен быть, а флоат, если вы его умножаете в функции ... Сами данные будут поступать с АЦП в виде 14-разрядов. В тип float я их не смогу преобразовать в ПЛИС. Я их сдвигаю на 14 рр и считаю, что эти 14-разрядов представляют целую часть числа в фиксированной точке. Думается, что где-то кардинальная ошибка. Может обратная связь при фиксированной точке дает некоторую ЗНАЧИМУЮ погрешность?? В-общем дошел до какого-то варианта решения: все типы заменил на long long и получил такой график: [attachment=88796:fixed_1.png] Это конечно извращение - такими типами манипулировать, но.. Теперь не знаю, как это все в VHDL буду перекидывать...
  20. Решил попробовать написать на Си этот фильтр. Вот две функции: Вычисления с плавающей точкой: Код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). Первая ф-ция дает такой результат: [attachment=88790:float.png] Вторая: [attachment=88791:fixed.png] Где мой косяк, подскажите, плз. Второй день голову ломаю.
  21. Я бы рад, но я с Матлабом не особо работал. А с симулинком вообще не знаком. Как-то не было нужды до этих пор. Но я чувствую, что выходная картинка должна быть другой. Может быть входной сигнал какой-нибудь другой загнать, чтобы получить на выходе какой-нибудь заранее известный сигнал? Чота я как-то вообще не могу вникнуть.
  22. ФВЧ 2-го порядка

    Добрый день. Кто-нибудь может помочь: нужна линейная формула с коэффициентами ФНЧ Баттерворта 6-го порядка с полосой 40 кГц. Далее я её буду реализовывать в ПЛИС на vhdl, поэтому она должна быть линейной с операциями +, - и *. Заранее спасибо.
  23. ChibiOS :: USB HID Device (stm32f4DISCOVERY)

    Может кто-нибудь поделится рабочим проектиком с подобным функционалом, если не жалко
  24. Добрый день. Пытаюсь сделать 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-запрос, но вот ГДЕ, не могу найти уже несколько дней. Вот основной файл с описанием дескрипторов (и попыткой навешивания какого-то обработчика приема данных): CODE#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 }; Файлы проекта прикладываю ниже. [attachment=87905:hid_bad.rar]
  25. ChibiOS :: USB HID Device (stm32f4DISCOVERY)

    Цитата(Timmy @ Nov 1 2014, 11:47) Может быть, вы сломали функцию смены адреса. Она происходит как раз после энумерации, и если адрес не сменить, то протокол работать дальше не будет. Сегодня все просмотрел, адресация не сломана, она проходит нормально. Глянул изначальные файлы проекта с 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). И видимо из-за этого у меня получается не настроена система приема и обработки данных. Это получается, что нужно описать такие же процедуры инициализации, сброса и работы с очередями, как и в проекте примера? Или все может быть намного проще?