Контроллер USB STM32 серий STM32F103xx и STM32F102xx
Добавил(а) microsin
Этот документ (перевод раздела "Universal serial bus full-speed device interface (USB)" из даташита [1]) относится к периферии USB микроконтроллеров семейств STM32F103xx и STM32F102xx. Все непонятные термины и сокращения см. Словарике [4].
Периферийное устройство USB реализует интерфейс между шиной full-speed USB 2.0 и шиной APB1 процессора. Поддерживаются сигналы USB suspend/resume, которые позволяют остановить тактирование устройства для снижения энергопотребления.
Основные поддерживаемые функции и возможности:
• Совместимость со спецификацией USB 2.0 full-speed. • Конфигурируемое количество конечных точек от 1 до 8. • Генерация/проверка CRC, кодирование сигнала с использованием NRZI и bit-stuffing. • Поддержка изохронных (isochronous) транзакций. • Поддержка двойной буферизации конечных точек bulk/isochronous. • Операции USB Suspend/Resume. • Генерация импульсов синхронизации по фрейму (Frame locked clock pulse generation).
Примечание: в MCU классов low-density, medium-density, high-density и XL-density, контроллеры USB и CAN используют общую память SRAM размером 512 байт для передачи и приема, поэтому эти интерфейсы не могут использоваться одновременно (к этой общей RAM осуществляется эксклюзивный доступ как со стороны CAN, так и USB). Поэтому USB и CAN могут использоваться в одном приложении, но не одновременно.
Это условная классификация MCU от компании ST по размеру памяти.
Low-density это MCU STM32F101xx, STM32F102xx и STM32F103xx, у которых размер Flash-памяти в диапазоне от 16 до 32 килобайт.
Medium-density это MCU STM32F101xx, STM32F102xx и STM32F103xx, у которых размер Flash-памяти в диапазоне от 64 до 128 килобайт.
High-density это MCU STM32F101xx и STM32F103xx, у которых размер Flash-памяти в диапазоне от 256 до 512 килобайт.
XL-density это MCU STM32F101xx и STM32F103xx, у которых размер Flash-памяти в диапазоне от 768 до 1 мегабайта.
Connectivity line это MCU STM32F105xx и STM32F107xx.
Здесь xx это дополнительные буквенные обозначения, показывающих модификацию MCU (тип корпуса, температурный диапазон и т. п.).
На рис. 220 показана блок-схема периферийного устройства (контроллера) USB.
Рис. 220. Блок-схема контроллера USB для MCU семейств STM32F103xx и STM32F102xx.
Контроллер USB предоставляет USB-совместимое соединение между хостом PC (хостом PC называют главное устройство на шине USB, это обычно компьютер) и функцией (устройством USB одного из классов), реализованной в MCU. Перемещение данных между хостом PC и системной памятью MCU осуществляется через выделенную буферную память пакета, к которой непосредственно получает доступ контроллер USB. Размер этой выделенной буферной памяти должен соответствовать количеству используемых конечных точек и максимальному размеру пакета. Эта выделенная память имеет размер 512 байт, и может обслуживать до 16 однонаправленных конечных точек, или до 8 двунаправленных. Контроллер USB детектирует токены пакетов, обрабатывает передачу/прием данных и пакеты рукопожатия (handshake packet), как того требует стандарт USB. Форматирование транзакций происходит аппаратно, включая генерацию и проверку CRC.
Каждая конечная точка связана с блоком описания буфера (buffer description block), показывающим, какая область памяти выделена конечной точке - её начальный адрес и размер, т. е. сколько байт должно быть передано. Когда контроллером USB обнаружена допустимая пара функция/конечная точка, осуществляется соответствующая транзакция данных (если это необходимо, и если конечная точка сконфигурирована). Данные, буферизированные контроллером USB, загружаются во внутренний 16-битный регистр, и выполняется доступ к выделенному буферу. Когда перемещены все данные, то при необходимости генерируется handshake-пакет по шине USB, или ожидается появление такого пакета - в зависимости от направления транзакции.
По окончании транзакции генерируется прерывание, относящееся к конечной точке, происходит чтение регистров состояний и/или используются разные подпрограммы обработки прерываний. MCU может определить:
• Обслуживаемую конечную точку. • Тип произошедшей транзакции, произошли ли ошибки (такие как ошибки bit-stuffing, format, CRC, протокола, отсутствие ACK, over/underrun).
Для изохронных и высокоскоростных bulk-транзакций предоставляется специальная поддержка в виде двойной буферизации, что позволяет всегда иметь доступный буфер для контроллера USB, в то время как MCU обрабатывает другой буфер.
Когда это необходимо, блок может быть переведен в режим пониженного энергопотребления (SUSPEND mode) путем записи в регистр управления. Тогда избегается любое статическое потребление энергии, и тактирование USB замедляется или останавливается. При определении активности на входах USB, когда устройство находится в low-power mode, асинхронно выведет устройство из сна. К сигналу пробуждения (wakeup line) может быть подключен специальный источник прерывания, чтобы позволить системе немедленно перезапуститься с нормальной генерацией тактов и/или поддержки непосредственного запуска/остановки тактирования.
[Описание блоков USB]
Периферийное устройство USB реализует все функции, связанные с интерфейсом USB, которые включают следующие блоки:
• Serial Interface Engine (SIE): функции в этом блоке включают распознавание последовательностей синхронизации, bit-stuffing, генерацию и проверку CRC, проверку и генерацию PID, вычисление handshake. Это должно реализовать интерфейс с трансиверами USB и использует виртуальные буферы, предоставляемые интерфейсом к локальному хранилищу данных. Этот блок также генерирует сигналы в соответствии с событиями периферии USB, такими как Start of Frame (SOF), USB_Reset, Data errors и т. д., и для событий, связанных с событиями конечной точки наподобие окончания передачи или корректного окончания приема пакета; эти сигналы затем используются для генерации прерываний.
• Таймер: этот блок генерирует импульс, синхронизируемый по сигналу начала фрейма (start-of-frame, SOF), и детектирует глобальную приостановку (global suspend, генерируется хостом), когда не было трафика в течение времени 3 мс и более.
• Packet Buffer Interface (интерфейс буфера пакета): этот блок управляет локальной памятью, гибко реализуя набор буферов как для передачи, так и для приема. Он выбирает правильный буфер в соответствии с запросами, приходящими от SIE, и размещает их в памяти, адресованной регистрами конечной точки. Он инкрементирует адрес после прохождения каждого слова обмена до окончания пакета, отслеживая количество прошедших буферов и предотвращая переполнение буфера сверх его емкости.
• Регистры конечных точек: у каждой конечной точки есть связанные с ней регистры, где содержится тип конечной точки и её текущее состояние. Для однонаправленных конечных точек с одним буфером для реализации двух разных конечных точек может использоваться один регистр. Всего регистров 8, что дает возможность реализовать до 16 однонаправленных конечных точек с одним буфером, или до 7 конечных точек с двойным буфером в любой комбинации. Например, периферийное устройство USB может быть запрограммировано для 4 конечных точек с двойной буферизацией и 8 однонаправленных конечных точек с одним буфером.
• Регистры управления: это регистры, содержащие информацию о состоянии всего периферийного устройства USB, используемые для отслеживания некоторых событий USB, таких как resume (возобновление работы) и power-down (выключение).
• Регистры прерываний: содержат маски прерываний и записывают события. Они могут использоваться для определения причины прерывания, состояния прерывания или очистки состояния прерывания, ожидающего обработки.
Периферийное устройство USB подключено к шине APB1 через интерфейс APB1, содержащий следующие блоки:
• Память пакетов (Packet Memory): это локальная память, где физически содержатся буферы пакетов (Packet Buffers). Она может использоваться интерфейсом буфера пакетов, который создает структуру данных и к которому можно напрямую получить доступ из программы приложения. Размер Packet Memory составляет 512 байт, что структурировано как 256 слов по 16 бит.
• Арбитр: этот блок получает запросы к памяти, поступающие от шины APB1 и от интерфейса USB. Он разрешает конфликты давая приоритет доступа к APB1, при этом всегда резервируется половина полосы пропускания памяти для завершения всех транзакций USB. Эта временная дуплексная схема реализует виртуальную двухпортовую SRAM, позволяющую доступ к памяти во время осуществления транзакции USB. По этой схеме также позволяются многословные транзакции APB1 любой длины.
• Система привязки регистров (Register Mapper): этот блок собирает различные байтовые и битовые регистры периферии USB в структурированные набор 16-битных слов, адресуемых по шине APB1.
• APB1 Wrapper: предоставляет интерфейс к APB1 для памяти и регистра. Он также отображает все периферийное устройство USB на адресное пространство APB1.
• Interrupt Mapper: этот блок используется для выбора, какие возможные события USB могут генерировать прерывания, и привязывает их к трем разным линиям NVIC:
– низкоприоритетное прерывание USB (канал 20): вызывается всеми событиями USB (корректная транзакция, сброс USB, и т. д.). Firmware должно проверить источник прерывания перед обслуживанием прерывания. – высокоприоритетное прерывание USB (канал 19): вызывается событием корректной изохронной транзакции и bulk-транзакции с двойной буферизацией, чтобы достичь самых высоких возможных скоростей передачи. – USB wakeup interrupt (канал 42): срабатывает от события пробуждения (wakeup event) из режима приостановки USB (USB Suspend).
В следующих секциях рассматриваются способы взаимодействия между периферийным устройством USB и программой приложения, чтобы упростить разработку firmware микроконтроллера.
[Общее программирование устройства USB]
В этой секции описаны основные задачи программы приложения, требуемые для получения USB-совместимого поведения. К этим действиям относятся обработка основных событий USB и специальные случаи конечных точек с двойной буферизацией и изохронные транзакции. Кроме системного сброса, действие всегда инициируется периферийным устройством USB, управляемым одним из событий USB, описанных ниже.
System reset и power-on reset. При системном сбросе и сбросе при включении питания первое, что должна сделать программа - настроить все требуемые сигналы тактов для периферийного устройства USB, и затем снять его сигнал reset, чтобы можно было получить доступ к регистрам USB. После этого выполняется вся последовательность инициализации (см. далее).
Первый шаг, который должно предпринять приложение - активация тактов регистра макроячейки и снять ее специальный сигнал сброса, используя соответствующие биты управления логики управления тактированием.
После этого аналоговая часть устройства, связанная с трансивером USB, должна быть включена с помощью бита PDWN в регистре CNTR, который требует специальной обработки. Этот бит предназначен для включения внутренних источников опорного напряжения, которые питают порт трансивера. У этой схемы есть определенное время включения (startup time, определяемое параметром tSTARTUP из даташита), в течение которого поведение трансивера USB не определено. Поэтому следует подождать это время после установки бита PDWN в регистре CNTR перед тем, как снять сигнал reset с аппаратуры USB (путем очистки бита FRES в регистре CNTR ). Затем очистка бита ISTR очищает любые случайные ожидающие прерывания перед тем, как разрешается любая другая операция макроячейки.
При системном сбросе микроконтроллер должен инициализировать все требуемые регистры и таблицу описания буфера пакета, чтобы периферийное устройство USB могло правильно генерировать прерывания и транзакции данных. Все регистры, не относящиеся к определенной конечной точке, должны быть инициализированы в соответствии с нуждами программы приложения (выбор разрешенных прерываний, выбор адреса буферов пакета и т. д.). Затем процесс продолжается как для случая сброса по шине USB (USB reset).
USB reset (RESET interrupt). Когда происходит событие сброса по шине USB, периферийное устройство USB переводится в то же самое состояние, которое получается после инициализации, описанной в предыдущих абзацах: обмен запрещен, и запрещены все регистры конечных точек (периферийное устройство USB не будет отвечать на любой пакет). Как ответ на событие USB, должна быть разрешена функция USB, у которой USB-адрес 0, реализующая только конечную точку управления по умолчанию (default control endpoint, конечная точка 0). Это осуществляется установкой бита Enable Function (EF) в регистре USB_DADDR и инициализацией регистра EP0R и соответствующих буферов пакета. Во время процесса энумерации USB хост назначает уникальный адрес этому устройству, который должен быть записан в биты ADD[6:0] регистра USB_DADDR, и конфигурируется любая другая необходимая конечная точка.
Когда принято прерывание RESET, программа приложения отвечает за то, чтобы снова разрешить default endpoint USB-функции 0 в течение 10 мс от конца последовательности сброса, которая вызвала прерывание.
Структура буферов пакета и их использование. Каждая двунаправленная конечная точка может принимать или передавать данные от хоста и к хосту. Принятые данные сохраняются в выделенном буфере памяти, зарезервированном для этой конечной точки, в то время как другой буфер памяти содержит данные для передачи из конечной точки. Доступ к этой памяти выполняется через блок интерфейса буфера пакета, которая передает запрос на доступ к памяти и ожидает подтверждения на него. Поскольку к памяти буфера пакета должен также получать доступ и микроконтроллер, логика арбитража разрешает конфликты доступа, используя половину цикла APB1 для доступа микроконтроллера, и остальную половину полосы для доступа со стороны периферии USB. Таким способом оба этих агента могут работать так, как если бы память пакета была бы двухпортовой SRAM, и не нужно беспокоиться о любом конфликте, даже если микроконтроллер выполняет операцию чтение-модификация-запись (back-to-back access). Логика периферии USB использует выделенное тактирование. Частота этих выделенных тактов фиксирована на 48 МГц в соответствии с требованиями стандарта USB, и эта частота может отличаться от тактовой частоты, используемой для интерфейса к шине APB1. Возможные разные конфигурации тактов, где частота APB1 может быть выше или ниже частоты тактов периферии USB.
Примечание: из-за скорости данных USB и требований к интерфейсу памяти, частота APB1 должна быть выше 8 МГц, чтобы избежать проблем переполнения/недогрузки (overrun/underrun).
Каждая конечная точка связана с двумя буферами пакета (обычно один для передачи, другой для приема). Буферы могут быть размещены в любом месте памяти пакетов, потому что их размещение и размер указываются в таблице описания буферов, которая также находится в памяти пакетов по адресу, который задает регистр USB_BTABLE. Каждая запись в таблице связана с регистром конечной точки, и она состоит из четырех 16-битных слов таким образом, что начальный адрес таблицы всегда выровнен по 8-байтной границе (три младшие бита регистра USB_BTABLE всегда равны 000). Записи в таблице дескрипторов буферов описаны ниже в секции "Таблица дескрипторов буферов (BDT)". Если конечная точка однонаправленная, и она не изохронная и не типа bulk с двойной буферизацией, то требуется только один буфер пакета (он связан с поддерживаемым направлением передачи). Другие места в таблице доступны для пользователя, которые относятся к не поддерживаемым направлениям передачи или не используемым конечным точкам. Изохронные и bulk конечные точки с двойной буферизацией имеют специальную обработку буферов пакета (см. секцию "Изохронные передачи" и секцию "Конечные точки с двойной буферизацией" соответственно). Взаимодействие между записями в таблице описания буферов и областями буфера пакета показано на рис. 221.
Рис. 221. Области буфера пакета с примерами ячеек таблицы описания буферов.
Каждый буфер пакета используется либо во время приема, либо передачи, начиная с нижней части буфера. Периферийное устройство USB никогда не будет менять области памяти, соседние с выделенными буферами памяти; если буфер пакета больше, чем принятая длина буфера (событие переполнения буфера, buffer overrun), то данные будут копироваться в память только до последней допустимой ячейки.
Инициализация конечной точки. Первый шаг инициализации конечной точки - записать подходящие значения в регистры ADDRn_TX/ADDRn_RX, чтобы периферийное устройство USB нашло уже готовые передаваемые данные, и принятые данные могли быть буферизированы. Биты EP_TYPE в регистре USB_EPnR должны быть установлены в соответствии с типом конечной точки, иногда используется бит EP_KIND для разрешения специальной необходимой функции. На стороне передачи конечная точка должна быть разрешена битами STAT_TX в регистре USB_EPnR, и должен быть инициализирован COUNTn_TX. Для приема биты STAT_RX должны быть установлены для разрешения приема, и в COUNTn_RX должен быть записан размер выделенного буфера с помощью полей BL_SIZE и NUM_BLOCK. Однонаправленные конечные точки, кроме изохронных и bulk-точек с двойной буферизацией, нуждаются только в инициализации бит и регистров, связанных с поддерживаемым направлением данных. Как только передача и/или прием разрешены, регистр USB_EPnR и ячейки ADDRn_TX/ADDRn_RX, COUNTn_TX/COUNTn_RX (соответственно) не должны быть модифицированы программой приложения, поскольку аппаратура может поменять их значения на лету. Когда операция перемещения данных завершена, о чем оповещает событие прерывания CTR, к ним можно снова обратиться для разрешения новой операции.
Пакеты IN (передача данных). Когда принимается токен IN в пакете, если принятый адрес совпадает и сконфигурирована допустимая конечная точка, периферия USB осуществляет доступ к содержимому ячеек ADDRn_TX и COUNTn_TX внутри записи таблицы дескриптора буфера, относящейся к адресованной конечной точке. Содержимое этих ячеек сохраняется в их внутренние 16-битные регистры ADDR и COUNT (недоступные для программы). К памяти пакетов обращаются снова для чтения первого слова для передачи (см. "Структура буферов пакета и их использование"), н начинается отправка DATA0 или DATA1 PID в соответствии с битом DTOG_TX регистра USB_EPnR. Когда PID завершен, первый байт из слова читается из памяти буфера, загружается в выходной регистр сдвига для передачи по шине USB. После того, как передан последний байт, отправляется автоматически вычисленная CRC. Если адресованная конечная точка недопустима, отправляется handshake-пакет NAK или STALL вместо пакета данных, в соответствии с битами STAT_TX в регистре USB_EPnR.
Внутренний регистр ADDR используется как указатель на место в памяти текущего буфера, в то время как COUNT используется для количества оставшихся байт для передачи. Каждое слово, прочитанное из памяти буфера пакета, передается по шине USB, начиная с самого младшего значащего байта. Чтение передаваемого буфера в памяти начинается с адреса, указываемого ADDRn_TX для COUNTn_TX/2 слов. Если передаваемый пакет составлен из нечетного количества байт, то будет использована только младшая половина последнего слова, к которому осуществляется доступ.
При получении ACK-подтверждения хоста регистр USB_EPnR обновится следующим образом: переключится бит DTOG_TX, конечная точка делается недоступной установкой STAT_TX=10 (NAK) и установится бит CTR_TX. Программа приложения должна сначала идентифицировать конечную точку, которая запрашивает внимание микроконтроллера, путем оценки бит EP_ID и DIR в регистре USB_ISTR. Обслуживание события CTR_TX начинается с очистки бита прерывания; затем программа приложения подготавливает другой буфер заполнением отправляемых данных, обновляет COUNTn_TX в таблице количеством передаваемых данных следующей передачи, и наконец устанавливается STAT_TX в 11 (VALID), для нового разрешения передачи. Пока биты STAT_TX в состоянии 10 (NAK), любой IN-запрос, адресованный в эту конечную точку, завершится отказом NAK, показывая условие управления потоком (flow control): хост USB будет пытаться повторить транзакцию до её завершения. Важно выполнить последовательность операций, показанных выше, чтобы избежать потери оповещения второй адресованной на той же конечной точке IN транзакции, которая немедленно последует за срабатыванием прерывания CTR.
Пакеты OUT и SETUP (прием данных). Эти два токена обрабатываются периферийным устройством USB более или менее таким же образом; отличия в обработке пакетов SETUP подробнее показан в следующем параграфе, описывающем передачи управления (control transfer). Когда принимается OUT/SETUP PID, если адрес совпадает с правильной конечной точкой, периферия USB обращается к содержимому ячеек ADDRn_RX и COUNTn_RX внутри записи таблицы дескрипторов буферов, относящейся к адресованной конечной точке. Содержимое ADDRn_RX сохраняется непосредственно во внутренний регистр ADDR. Хотя COUNT сейчас сброшен, и значения битовых полей BL_SIZE и NUM_BLOCK, которые прочитаны из содержимого COUNTn_RX, используются для инициализации BUF_COUNT, внутреннего 16-битного счетчика, который используется для проверки события переполнения буфера - buffer overrun condition (все эти внутренние регистры недоступны для программного обеспечения). Байты данных, последовательно принятые периферией USB, упаковываются в слова (первый принятый байт сохраняется в самый младший значащий байт) и затем перемещаются в буфер пакета, начиная с адреса, содержащегося во внутреннем регистре ADDR, в то время как BUF_COUNT декрементируется, и COUNT инкрементируется с каждым принятым байтом. Когда будет определен конец пакета DATA, проверена корректность принятой CRC, и только если нет ошибок при приеме, передающему хосту обратно отправится handshake-пакет ACK.
В случае неправильной CRC или другого рода ошибок (нарушения bit-stuff, ошибки фрейма и т. д.), байты данных все еще копируются в память буфера пакета, как минимум до точки определения ошибки, однако ACK-пакет не отправляется, и установится бит ERR в регистре USB_ISTR. Однако в таком случае здесь обычно не требуется действий от программы: периферия USB восстановится из ошибок приема и останется готовой к поступлению следующей транзакции. Если адресованная конечная точка не допустима (not valid), вместо ACK будет отправлен handshake-пакет NAK или STALL, в соответствии с битами STAT_RX в регистре USB_EPnR и никакие данные не записываются в память буферов приема.
Ячейки буфера приема записываются, начиная с адреса, содержащегося в ADDRn_RX для количества байт, соответствующего длине принятого пакета данных, включая CRC (т. е. длина полезной нагрузки + 2), или до последней выделенной ячейке памяти, как определено BL_SIZE и NUM_BLOCK, которые поступают первыми. При таком способе обработки периферия USB при записи никогда не выйдет за пределы области памяти, выделенной под буфер. Если длина пакета полезной нагрузки данных (реальное количество данных, используемого приложением) больше, чем выделенный буфер, периферия USB определяет событие переполнения буфера (buffer overrun condition). В этом случае отправится STALL handshake вместо обычного ACK, чтобы оповестить хост о проблеме, прерывание не генерируется и транзакция считается неудачной.
Когда транзакция корректно завершится путем отправки handshake-пакета ACK, внутренний регистр COUNT копируется обратно в ячейку COUNTn_RX, находящуюся в записи таблицы описания буферов, оставляя не измененными поля BL_SIZE и NUM_BLOCK, которые обычно не требуется перезаписывать, и регистр USB_EPnR обновляется следующим образом: переключается бит DTOG_RX, конечная точка делается "invalid" путем установки STAT_RX = 10 (NAK), и установится бит CTR_RX. Если транзакция была неудачной из-за ошибок или переполнения буфера, то никакие из ранее упомянутых действий не выполняются. Программа приложения должна сначала должна идентифицировать конечную точку, которая запрашивает внимание микроконтроллера, путем оценки бит EP_ID и DIR в регистре USB_ISTR. Событие CTR_RX обрабатывается так, что сначала определяется тип транзакции (бит SETUP в регистре USB_EPnR); программа приложения должна очистить бит прерывания бит флага прерывания и получить количество принятых байт чтением ячейки COUNTn_RX внутри записи таблицы описания буферов, относящейся к обрабатываемой конечной точке. После того, как принятые данные обработаны, программа приложения должна установить биты STAT_RX в 11 (Valid) в регистре USB_EPnR, тем самым разрешая будущие транзакции. Пока биты STAT_RX равны 10 (NAK), любые запросы OUT к этой адресованной конечной точке будут отклоняться пакетом NAK, показывая условие управления потоком: хост USB будет делать повторные попытки выполнить транзакцию до её успешного завершения. Важно выполнить последовательность операций, упомянутых выше, чтобы избежать потери оповещения второй OUT-транзакции, адресованной в ту же самую конечную точку, которая немедленно следует за сработавшим прерыванием CTR.
Передачи управления. Управляющая передача осуществляется транзакцией SETUP, за которой идут 0 или большее количество стадий данных, все в том же направлении, за которыми идет стадия статуса (передача нулевого количества байт в обратном направлении). Транзакции SETUP обрабатываются только конечными точками управления (control endpoint) очень похоже на конечные точки OUT (прием данных), за исключением того, что значения бит DTOG_TX и DTOG_RX регистров адресованной конечной точки установятся в 1 и 0 соответственно для инициализации управляющей передачи, и оба поля STAT_TX и STAT_RX устанавливаются в 10 (NAK), чтобы позволить программе решить, должны ли последующие транзакции быть IN или OUT, в зависимости от содержимого SETUP. Управляющая конечная точка должна проверить бит SETUP в регистре USB_EPnR на каждом событии CTR_RX, чтобы отделить обычные транзакции OUT от транзакций SETUP. Устройство USB может определить количество и направление стадий данных путем интерпретации данных, переданных на стадии SETUP, и требуется приостановка (STALL) транзакции в случае ошибок. Чтобы это сделать, все стадии данных до последней в неиспользуемом направлении должны быть установлены в STALL, так что если хост поменяет направление передачи слишком быстро, то получит STALL как состояние стадии.
Когда разрешается последняя стадия данных, обратное направление должно быть установлено в NAK для того, что если хост немедленно поменяет направление передачи (для выполнения стадии статуса), он останется в ожидании завершения операции управления. Если операция управления завершилась успешно, программа поменяет NAK на VALID, иначе в STALL. В то же время, если стадия статуса будет OUT, то должен быть установлен бит STATUS_OUT (EP_KIND в регистре USB_EPnR), чтобы генерировалась ошибка, если транзакция статуса выполнилась с не нулевыми данными. Когда обслуживается транзакция статуса, приложение очищает бит STATUS_OUT bit и устанавливает STAT_RX в VALID (чтобы принять новую команду) и STAT_TX в NAK (чтобы отложить возможную стадию статуса последующей настройки, выполненной немедленно).
Поскольку спецификация USB устанавливает, что на пакет SETUP не должно быть handshake, отличающегося от ACK, то иногда обрывается ранее выданная команда для запуска новой, логика USB не должна позволить управляющей конечной точке ответить пакетом NAK или STALL на токен SETUP, принятый от хоста.
Когда биты STAT_RX установлены в 01 (STALL) или 10 (NAK), и принят токен SETUP, USB принимает данные, выполняет требуемые перемещения данных и отправляет обратно ACK handshake. Если эта конечная точка получила ранее выданный запрос CTR_RX, но это пока не подтверждено приложением (например бит CTR_RX все еще установлен ранее завершенным приемом), то USB отбрасывает транзакцию SETUP и не отвечает любым handshake-пакетом не зависимо от своего состояния, симулируя ошибку приема, и принуждая хост снова отправить токен SETUP. Это делается с целью избежать потери оповещения о транзакции SETUP, адресованной в ту же конечную точку, непосредственно следующей за транзакцией, которая вызвала срабатывание прерывания CTR_RX.
Конечные точки с двойной буферизацией. Все другие типы конечных точек, определенные стандартом USB, представляют различные модели трафика, и описывают типовые требования операций передачи различного вида данных. Когда между хостом и функцией USB передаются большие порции данных, тип bulk конечной точки - наиболее подходящая модель. Причина в том, что хост планирует bulk-транзакции так, чтобы заполнить всю доступную полосу пропускания фрейма шины, максимально увеличивая скорость передачи данных, пока функция USB готова обрабатывать адресованную её bulk-транзакцию. Если функция USB все еще занята предыдущей транзакцией, когда уже поступает следующая, то на неё будет выдана в ответ NAK handshake, и хост PC снова выдаст ту же самую транзакцию, пока USB функция не станет готовой к её обработке, снижая реальную скорость передачи из-за полосы, занимаемой повторными передачами. По этой причине с bulk-конечными точками может использоваться специальная возможность двойной буферизации.
Когда активирована двойная буферизация, используется последовательность переключения данных для выбора, какой буфер используется периферией USB для выполнения требуемых передач данных, используя области памяти как для передачи, так и для приема, чтобы обработать переключение буферов при каждой успешной транзакции, чтобы всегда иметь заполненный буфер, используемый приложением, пока периферия USB заполняет другой буфер. Например, во время транзакции OUT, направленной на прием через bulk-конечную точку с двойной буферизацией, пока один буфер заполняется новыми приходящими через USB от хоста данными, другой буфер доступен для программного обеспечения микроконтроллера (то же самое происходит с передающей bulk-конечной точкой транзакции IN).
Поскольку управление переключением буферов требует использования всех четырех записей таблицы описания буферов для адресов буферов в памяти и их длины, то регистры USB_EPnR, используемые для реализации bulk-конечных точек с двойной буферизацией, приходится использовать целиком только для одного направления передачи. Таким образом, только одна пара бит STAT должна быть установлено в значение, отличающееся от 00 (Disabled): STAT_RX, если это bulk конечная точка с двойной буферизацией для приема, или STAT_TX, если это bulk конечная точка с двойной буферизацией, разрешенная для передачи. В случае, если требуются конечные точки bulk с двойной буферизацией в обоих направлениях - и приема, и передачи, то должны быть использованы два регистра USB_EPnR.
Чтобы задействовать функцию двойной буферизации и достичь максимально возможной скорости передачи по шине, должна быть модифицирована структура управления потоком конечной точки, описанная в предыдущих секциях, чтобы переключать статус конечной точки в NAK только когда происходит конфликт за доступ к буферу между периферией USB и программой приложения, вместо того, чтобы делать это по окончанию каждой успешной транзакции. Буфер памяти, который в настоящий момент используется периферией USB, определяется по биту DTOG, относящемуся к направлению конечной точки: DTOG_RX (бит 14 регистра USB_EPnR) для приемной bulk-конечной точки с двойной буферизацией, или DTOG_TX (бит 6 регистра USB_EPnR) для передающей bulk-конечной точки с двойной буферизацией. Для реализации новой схемы управления потоком периферия USB должна знать, какой буфер пакета в настоящее время используется программой приложения, чтобы избежать любого конфликта. Поскольку в регистре USB_EPnR есть два бита DTOG, но только один используется периферией USB для данных и последовательности буферов (из-за ограничения однонаправленности, требуемого для функции двойной буферизации), другой может использоваться программой приложения, чтобы показать, какой буфер в настоящий момент используется. Этот новый флаг буфера называется SW_BUF. В следующей таблице объясняется соответствие между битами регистра USB_EPnR и определениями DTOG/SW_BUF для случаев передачи и приема у bulk-конечных точек с двойной буферизацией.
Таблица 169. Определение флага двойной буферизации.
Флаг буфера
Передающая конечная точка
Принимающая конечная точка
DTOG
DTOG_TX (USB_EPnR, бит 6)
DTOG_RX (USB_EPnR, бит 14)
SW_BUF
USB_EPnR, бит 14
USB_EPnR, бит 6
Буфер памяти, который в настоящий момент используется периферией USB, определяет флаг буфера DTOG, в то время как буфер, используемый программой приложения, идентифицируется флагом SW_BUF. Взаимодействие между значением буфера флага и используемым буфером пакета то же самое в обоих случаях, как это показано в следующей таблице.
Таблица 170. Использование bulk буферов с двойной буферизацией.
Тип конечной точки
DTOG
SW_BUF
Буфер пакета, используемый периферией USB
Буфер пакета, используемый программой
IN
0
1
ADDRn_TX_0 / COUNTn_TX_0 записи BDT
ADDRn_TX_1 / COUNTn_TX_1 записи BDT
1
0
ADDRn_TX_1 / COUNTn_TX_1 записи BDT
ADDRn_TX_0 / COUNTn_TX_0 записи BDT
0
0
Не используется(1)
ADDRn_TX_0 / COUNTn_TX_0 ячейки BDT
1
1
OUT
0
1
ADDRn_RX_0 / COUNTn_RX_0 записи BDT
ADDRn_RX_1 / COUNTn_RX_1 записи BDT
1
0
ADDRn_RX_1 / COUNTn_RX_1 записи BDT
ADDRn_RX_0 / COUNTn_RX_0 записи BDT
0
0
Не используется(1)
ADDRn_RX_0 / COUNTn_RX_0 записи BDT
1
1
ADDRn_RX_1 / COUNTn_RX_1 записи BDT
Примечание (1): конечная точка в состоянии NAK.
Функция двойной буферизации для bulk конечной точки активируется:
• записью поля бит EP_TYPE в 00 регистра USB_EPnR, чтобы определить конечную точку как bulk, и • установкой бита EP_KIND в 1 (DBL_BUF) того же регистра.
Программа приложения отвечает за инициализацию бит DTOG и SW_BUF в соответствии с первым используемым буфером; это учитывает специальное свойство "только переключение", которое имеют эти два бита. Окончание первой транзакции, произошедшей после установки DBL_BUF, вызывает срабатывание специального управления потоком для bulk конечных точек с двойной буферизацией, что используется для всех транзакций, адресованных этой конечной точке, пока бит DBL_BUF остается установленным. По окончании каждой транзакции установится бит CTR_RX или CTR_TX bit регистра USB_EPnR адресованной конечной точки, в зависимости от разрешенного направления. В то же время соответствующий бит DTOG в регистре USB_EPnR переключается аппаратно, делая переключение буферов полностью независимым от программы. В отличие от общих транзакции, и первой после установки DBL_BUF, на пару бит STAT не влияет завершение транзакции, и их значение остается в состоянии 11 (Valid). Однако как только принят пакет токена новой транзакции, актуальный статус конечной точки будет маскирован как 10 (NAK), когда обнаружен конфликт между периферией USB и программой приложения (это состояние идентифицируется одинаковым значением DTOG и SW_BUF, см. таблицу 170). Программа приложения отвечает за обработку оповещения о событии CTR путем очистки флага прерывания и запуска любой требуемой обработки завершенной транзакции. Когда заканчивается работа приложения над буфером пакета, программа переключает бит SW_BUF путем записи в него 1, чтобы оповестить периферию USB о доступности этого буфера. Таким способом количество транзакций с NAK ограничивается только приложением, что связано со скоростью обработки данных: если время обработки короче, чем время, необходимое для завершения транзакции по шине USB, то не потребуются повторные передачи из-за управления потоком, и реальная скорость передачи будет ограничена только хостом PC.
Программа приложения всегда может отменить специальное управление потоком, реализованное для bulk конечных точек с двойной буферизацией, путем записи явного статуса, отличающегося от 11 (Valid), в пару бит STAT регистра USB_EPnR. В этом случае периферия USB будет всегда использовать запрограммированный статус конечной точки, независимо от состояния использования буфера.
Изохронные передачи. Стандарт USB поддерживает полноскоростные периферийные устройства, требующие фиксированной и точной частоты генерации/потребления данных, такой вид трафика определен как "изохронный". Типичные примеры таких данных: выборки звука, потоки сжатого видео и любой вид оцифрованных данных, у которых есть жесткое ограничение для точности передаваемой частоты передачи. Когда конечная точка определена как "изохронная" во время фазы энумерации, хост выделяет в фрейме требуемую полосу и передает точно один пакет IN или OUT в каждом фрейме, в зависимости от направления конечной точки. Из-за ограничения требований к полосе для изохронного трафика невозможны повторные передачи ошибочных транзакций; это приводит к тому, что фактически изохронные транзакции не имеют фазы handshake, и не ожидается пакет ACK или его отправка после пакета данных. По той же причине изохронные транзакции не поддерживают последовательность переключения данных, и всегда используют DATA0 PID для запуска любого пакета данных.
Изохронное поведение для конечной точки выбирается установкой бит EP_TYPE в 10 (находятся в регистре USB_EPnR). Поскольку фаза handshake отсутствует, то для пар бит STAT_RX/STAT_TX легальные значения только 00 (Disabled) и 11 (Valid), любое другое значение приведет к результатам, не совместимым со стандартом USB. Изохронные конечные точки реализуют двойную буферизацию для упрощения разработки программы приложения, используя при этом обе области памяти "передачи" и "приема", чтобы обеспечить переключение буферов для каждой успешной транзакции. Это обеспечит в доступность одного буфера для приложения, в то время как периферия USB работает с другим буфером.
Память буфера, которая в настоящий момент используется периферией USB, определяется битом DTOG, связанным с направлением конечной точки (DTOG_RX для принимающих изохронных конечных точек, DTOG_TX для передающих изохронных конечных точек, оба в соответствующем регистре USB_EPnR), как показано в таблице 171.
Таблица 171. Использование памяти изохронных буферов.
Тип конечной точки
DTOG
Буфер пакета, используемый периферией USB
Буфер пакета, используемый программой
IN
0
ADDRn_TX_0 / COUNTn_TX_0 записи BDT
ADDRn_TX_1 / COUNTn_TX_1 записи BDT
1
ADDRn_TX_1 / COUNTn_TX_1 записи BDT
ADDRn_TX_0 / COUNTn_TX_0 записи BDT
OUT
0
ADDRn_RX_0 / COUNTn_RX_0 записи BDT
ADDRn_RX_1 / COUNTn_RX_1 записи BDT
1
ADDRn_RX_1 / COUNTn_RX_1 записи BDT
ADDRn_RX_0 / COUNTn_RX_0 записи BDT
Как это происходит и у bulk-конечных точек с двойной буферизацией, регистры USB_EPnR, используемые для реализации изохронных конечных точек, принудительно используются для однонаправленного потока данных. Если требуется разрешить изохронные конечные точки для обоих направлений данных - приема и передачи, то должны использоваться два регистра USB_EPnR.
Программа приложения отвечает за инициализацию бита DTOG в соответствии с первым используемым буфером; это должно быть сделано с учетом свойства "только переключение", которое имеют эти два бита. По окончании каждой транзакции установится бит CTR_RX или CTR_TX в регистре USB_EPnR адресованной конечной точки, в зависимости от направления передачи. В то же самое время соответствующий бит DTOG в регистре USB_EPnR аппаратно переключится, переключая буфер полностью независимо от программного обеспечения. На пару бит STAT не повлияет завершение транзакции; поскольку для изохронных передач невозможно управление потоком (flow control), так как у нет фазы handshake, конечная точка всегда остается в состоянии 11 (Valid). Изохронные OUT-транзакции, где есть ошибки CRC, или ситуации переполнения буфера (buffer-overrun condition), всегда считаются корректными транзакциями, они всегда вызывают срабатывание события CTR_RX. Однако ошибки CRC все равно устанавливают бит ERR в регистре USB_ISTR, чтобы оповестить программу о возможных повреждениях данных.
События Suspend/Resume. Стандарт USB определяет специальное состояние периферийного устройства, так называемое SUSPEND (приостановка), в котором средний ток потребления от шины USB не должен превышать 2.5 мА. Это требование фундаментальное для устройств USB, получающих питание от шины (bus-powered device), поскольку устройства USB с собственным питанием (self-powered device) не требуют тока шины, и для них необязательно соблюдать это ограничение. В режиме приостановки хост PC отправляет оповещение, когда не посылает никакой трафик по шине USB в течение времени больше 3 мс. Поскольку SOF пакета обязательно должен проходить каждую 1 мс во время нормального функционирования, периферийное устройство определяет пропадание 3 следующих друг за другом пакетов SOF, и трактует это как запрос приостановки от хоста. Это устанавливает бит SUSP регистра USB_ISTR в 1 и вызывает срабатывание прерывания, если оно разрешено. Как только устройство приостановило свою работу, его нормальная работоспособность может быть восстановлено так называемой последовательностью RESUME (возобновление), которую может начать хост PC или непосредственно по сигналу периферийного устройства, или по своему собственному сигналу. Приостановленное периферийное устройство USB всегда должно быть способно детектировать последовательность RESET на шине USB, реагируя на это событие как нормальное событие сброса USB (USB reset event).
Реальная процедура, используемая для приостановки периферии USB, зависит от устройства и его потребления тока, и для снижения потребления могут понадобиться различные действия.
Ниже представлено краткое описание типовой процедуры приостановки, сфокусированное на связанных с USB аспектах программы приложения, отвечающей на оповещение SUSP периферии USB:
1. Установите бит FSUSP регистра USB_CNTR в 1. Это действие активирует режим suspend для периферии USB. Как только режим suspend активировался, проверьте, что прием mode SOF запрещен, чтобы избежать будущих прерываний SUSP, которые могут произойти, когда USB приостанавливается.
2. Отключите или снизьте любое статическое потребление тока в других блоках, не относящихся к USB.
3. Установите в 1 бит LP_MODE регистра USB_CNTR, чтобы устранить статическое потребление мощности аналоговых трансиверов USB, но сохраняйте их в состоянии, когда возможно определение активности resume.
4. Опционально выключите внешний генератор и PLL, чтобы остановить любую активность внутри устройства.
Когда произойдет событие USB, если все устройство находится в режиме SUSPEND, должна быть вовлечена процедура RESUME, чтобы восстановить нормальное тактирование и восстановить обычное поведение устройства USB. Особенное внимание нужно уделить гарантии, что этот процесс не займет по длительность больше 10 мс, когда событием пробуждения является последовательность USB reset (подробнее см. описание стандарта USB [2]). Начало resume или последовательности USB reset, когда периферия USB приостановлена, асинхронно очистит бит LP_MODE регистра USB_CNTR. Даже если это событие может вызвать срабатывание прерывания WKUP, если оно разрешено, использовать ответ процедурой прерывания должно быть выполнено осторожно, чтобы не вызывать долгой латентности на перезапуск системных тактов. Чтобы снизить латентность перед возобновлением номинального тактирования, рекомендуется поместить процедуру восстановления сразу после процедуры приостановки, чтобы код возобновления сразу начал выполняться, как только перезапустятся системные такты. Чтобы предотвратить разряды ESD или любые другие виды помех из-за пробуждения системы (выход из режима suspend это асинхронное событие), во время пробуждения активируется подходящий аналоговый фильтр на состоянии линии данных. Полоса среза фильтра составляет около 70 нс.
Список действий для resume-процедуры:
1. Опционально включите внешний генератор и/или PLL (если они выключены).
2. Очистите бит FSUSP регистра USB_CNTR.
3. Если идентифицировано событие resume, биты RXDP и RXDM в регистре USB_FNR могут использоваться по таблице 172, которая также перечисляет необходимые действия программы во всех случаях. Если необходимо, окончание resume или последовательности reset может быть определено путем мониторинга статуса вышеупомянутых бит путем проверки, когда они достигнут конфигурации 10, что представляет состояние ожидание шины USB (Idle bus state). Кроме того, по окончанию последовательности reset установится в 1 бит RESET в регистре USB_ISTR. При этом сработает прерывание, если оно разрешено, и это прерывание должно быть обработано обычным образом.
Таблица 172. Детектирование события resume.
Состояние бит [RXDP,RXDM]
Wakeup event (событие пробуждения)
Действие программы, необходимое для resume (возобновления работы)
00
Root reset (сброс)
Нет действий
10
None (ничего, шум на шине)
Переход обратно в режим приостановки (Suspend mode)
01
Root resume (возобновление)
Нет действий
11
Недопустимое состояние (шум на шине)
Переход обратно в режим приостановки (Suspend mode)
Устройству может потребоваться выйти из режима suspend в ответ на отдельные события, не относящиеся напрямую к протоколу USB (например перемещение мыши вызывает пробуждение всей системы). В этом случае последовательность resume может начинаться установкой в 1 бита RESUME регистра USB_CNTR и сбросом его в 0 после интервала между 1 мс и 15 мс (этот интервал может отслеживаться с помощью прерывания ESOF, которые происходят каждые 1 мс, когда такты системы работают на номинальной частоте). Как только бит RESUME очищен, последовательность resume будет завершена хостом PC, и его окончание снова отслеживается битами RXDP и RXDM в регистре USB_FNR.
Примечание: бит RESUME должен быть всегда использоваться только после того, как периферия USB переведена в режим suspend установкой в 1 бита FSUSP в регистре USB_CNTR.
Регистры USB. Регистры периферии USB можно поделить на следующие группы:
• Общие регистры: регистры прерывания и управления. • Регистры конечных точек: конфигурация и статус конечной точки. • Таблица описания буферов (Buffer Descriptor Table, BDT): место в буфере пакетов, используемое для размещения буферов данных.
Все адреса регистров выражаются как смещения по отношению к базовому регистров периферии USB 0x40005C00, за исключением ячеек BDT, которая начинается по адресу, указанному в регистре USB_BTABLE. Из-за общего ограничения мостов APB1 на адресацию слов, все адреса регистров выровнены на границы 32-битных слов, хотя эти регистры длиной 16 бит. То же самое выравнивание адреса используется для доступа к ячейками буфера пакетов, который размещается начиная с адреса 0x40006000.
Примечание: в описании регистров используются аббревиатуры для обозначения способа доступа к битам регистров (rw, r, w, rc_w1 и т. д.). См. врезку ниже.
read/write (rw) Программа может читать и записывать эти биты.
read-only (r) Программа может только читать эти биты.
write-only (w) Программа может только записывать этот бит. Чтение бита вернет значение сброса.
read/clear (rc_w1) Программа может читать, а также очищать этот бит путем записи в него лог. 1. Запись лог. 0 не дает никакого эффекта. Биты с таким видом доступа также иногда называют W1C (write-1-clear).
read/clear (rc_w0) Программа может читать, а также очищать этот бит путем записи в него лог. 0. Запись лог. 1 не дает никакого эффекта.
read/clear by read (rc_r) Программа может читать этот бит, причем чтение автоматически очистит бит в лог. 0. Запись лог. 0 никак не влияет на этот бит.
read/set (rs) Программа может прочитать этот бит, а также может установить этот бит. Запись лог. 0 никак не влияет на этот бит.
read-only write trigger (rt_w) Программа может прочитать этот бит. Запись 0 или 1 вызовет срабатывание события, но не окажет никакого влияния на значение этого бита.
toggle (t) Программа может только переключить этот бит путем записи в него лог. 1. Запись лог. 0 не дает никакого эффекта.
Reserved (Res.) Зарезервированный бит, его состояние должно сохраняться на значении сброса.
К регистрам периферии может осуществляться доступ через половину слова (16-битный доступ) или доступ к полному слову (32 бита).
[Общие регистры]
Эти регистры влияют на основное поведение периферии USB - определяется рабочий режим, обработка прерываний, адрес устройства. Также они дают доступ к текущему номеру фрейма, обновляемому хостом PC.
0: прерывание корректной передачи (Correct Transfer, CTR) запрещено. 1: прерывание CTR разрешено, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
PMAOVRM: Packet memory area over / underrun interrupt mask
0: прерывание PMAOVR запрещено. 1: разрешено прерывание PMAOVR, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
ERRM: Error interrupt mask
0: прерывание ERR запрещено. 1: разрешено прерывание ERR, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
WKUPM: Wakeup interrupt mask
0: прерывание WKUP запрещено. 1: разрешено прерывание WKUP, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
SUSPM: Suspend mode interrupt mask
0: прерывание запроса входа в режим приостановки (Suspend Mode Request, SUSP) запрещено. 1: разрешено прерывание SUSP, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
RESETM: USB reset interrupt mask
0: прерывание RESET запрещено. 1: разрешено прерывание RESET, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
SOFM: Start of frame interrupt mask
0: прерывание SOF запрещено. 1: разрешено прерывание SOF, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
ESOFM: Expected start of frame interrupt mask
0: прерывание ожидаемого начала фрейма (Expected Start of Frame, ESOF) запрещено. 1: разрешено прерывание ESOF, генерируется запрос прерывания, когда установится соответствующий бит в регистре USB_ISTR.
7:5 эти биты зарезервированы.
RESUME: Resume request
Запрос возобновления работы. Микроконтроллер может установить этот бит для отправки сигнала Resume хосту. По спецификации USB это должно быть активировано в интервале не меньше 1 мс и не больше 15 мс, после чего хост до конца готов управлять последовательностью возобновления работы.
FSUSP: Force suspend
Программа должна установить этот бит, когда принято прерывание SUSP, которое выдается, когда трафик USB пропал на 3 мс.
0: никакого эффекта. 1: вход в режим приостановки (suspend mode). Это не влияет на тактирование и статическое потребление мощности в аналоговом трансивере. Если есть требования к низкому потреблению мощности (bus-powered device, устройство USB получает питание от шины USB), то программа приложения должна установить бит LP_MODE после FSUSP, как это описано ниже.
LP_MODE: Low-power mode
Режим низкого энергопотребления - этот режим используется, когда ограничение потребляемой мощности режима приостановки требует, чтобы не было статического потребления тока за исключением источника питания внешнего pull-up резистора. В это состояние должен произойти вход, когда приложение готово остановить все системные такты, или настолько снизить частоту тактов, чтобы удовлетворить низкому потреблению тока от шины USB в состоянии приостановки (suspend condition). Активность на шине USB во время режима suspend (событие пробуждения, WKUP event) асинхронно сбросит этот бит (он также может быть сброшен программно).
0: нет режима низкого потребления энергии, нормальный рабочий режим (No Low-power mode). 1: вход в режим низкого энергопотребления.
PDWN: Power down
Выключение питания - этот бит используется для полного выключения всех связанных с USB аналоговых частей, если по какой-то причине требуется полный запрет периферии USB. Когда этот бит установлен, периферия USB отключается от трансиверов и не может использоваться.
0: выход из режима выключения (Exit Power Down). 1: вход в режим Power down.
FRES: Force USB Reset
0: очистка USB reset. 1: принудительный сброс периферии USB, точно так же, как это происходит по сигналу RESET по шине USB. Периферия USB удерживается в состоянии RESET, пока программа приложения не очистит этот бит. Если это разрешено, то генерируется прерывание "USB-RESET".
Этот регистр содержит состояние (статус) всех источников прерывания, которые может определить программа, и которые могут вызывать запрос на прерывание.
Старшая часть этого регистра содержит одиночные биты, каждый из которых представляет определенное событие. Эти биты устанавливаются аппаратно, когда возникает соответствующее событие; если соответствующий бит в регистре USB_CNTR установлен, то генерируется стандартный запрос на прерывание. Обработчик прерывания, проверяя каждый бит USB_ISTR, будет выполнять все необходимые действия, и в конце очистит все обработанные биты USB_ISTR. Если какой-то из бит не будет очищен, то считается, что прерывание все еще ожидает своей обработки, и линия прерывания все еще будет удерживаться в активном состоянии лог. 1 (прерывание возникнет снова). Если несколько бит установятся одновременно, то возникнет только один запрос на прерывание.
Для снижения латентности обработки прерываний событие завершения транзакции конечной точки может быть обработано другим способом. Бит CTR устанавливается аппаратно, как только конечная точка успешно завершит транзакцию, генерируя стандартный запрос на прерывание, если установлен соответствующий бит в регистре USB_CNTR. Выделенное состояние прерывания конечной точки активируется независимо от бита CTRM в регистре USB_CNTR. Оба этих состояния прерывания остаются активными, пока программа не очистит бит ожидающей обработки в соответствующем регистре USB_EPnR (бит CTR в действительности бит только для чтения, read only bit). Для прерываний, относящихся к конечной точке, программа может использовать read-only биты направления транзакции (Direction of Transaction, DIR) и EP_ID, чтобы идентифицировать, какая конечная точка вызвала последний запрос прерывания, и вызывает соответствующий обработчик прерывания (interrupt service routine, ISR).
Пользователь может выбрать относительный приоритет одновременно ожидающих обработки событий USB_ISTR путем указания порядка, в котором программа проверяет биты USB_ISTR в обработчике прерывания (ISR). Очищаются только те биты событий, которые обслужены. По окончании ISR будет запрошено другое прерывание для обработки оставшихся событий.
Чтобы избежать случайной очистки некоторых бит, рекомендуется очищать их с инструкцией загрузки, где все биты, которые не должны быть изменены, записываются в лог. 1, и все очищаемые биты записываются в лог. 0 (только записываемые в 0 биты могут быть очищены программой). Циклов Read-modify-write (чтение-модификация-запись) следует избегать, потому что между операциями чтения и записи может быть аппаратно установлен другой бит, и следующая запись очистит его перед тем, как у микроконтроллера появится время для его обработки.
CTR: Correct transfer
Этот бит установится аппаратно, чтобы показать, что конечная точка успешно завершила транзакцию; с помощью бит DIR и EP_ID программа может определить, какая конечная точка запросила прерывание. Этот бит только для чтения.
PMAOVR: Packet memory area over / underrun
Этот бит установится, если микроконтроллер не смог ответить в нужное время на запрос к памяти USB. Периферия USB обрабатывает это событие следующим образом: во время приема handshake-пакет ACK не отправляется, во время передачи ошибка bit-stuff принудительно вставляется в передаваемый поток; в обоих случаях хост повторит передачу. Прерывание PMAOVR никогда не должно случаться при нормальном функционировании. Поскольку ошибочная транзакция повторяется хостом, у программы приложения есть шанс ускорить обработку и попытаться правильно обработать следующую попытку транзакции; однако это не происходит во время изохронной транзакции (такие транзакции никогда не повторяются, даже если они ошибочные), что приведет к потере данных. Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
ERR: Error
Этот флаг установится всякий раз, когда произойдет одна из перечисленных ниже ошибок:
NANS: No ANSwer (нет ответа). Истек таймаут для ответа хоста. CRC: Cyclic Redundancy Check error. Одна из принятых CRC была с ошибкой, либо в токене, либо в данных. BST: Bit Stuffing error. Была определена ошибка вставки стафф-бита в любом месте - PID, данные и/или CRC. FVIO: Framing format Violation. Принят нестандартный фрейм (EOP в неправильном месте, неправильная последовательность токена, и т. п.).
Программа USB обычно может игнорировать эти ошибки, поскольку периферия USB и хост PC совершенно прозрачно управляют повторными передачами в случае ошибок. Это прерывание может быть полезно на этапе разработки, или чтобы отслеживать качество передач по шине USB, чтобы показать для пользователя возможные проблемы (например неисправный коннектор, слишком шумное рабочее окружение, плохое соединение в кабеле и т. д.). Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
WKUP: Wakeup
Этот бит устанавливается в 1 аппаратно, когда во время режима suspend была определена активность на шине, которая разбудила периферию USB. Это событие асинхронно очистит бит LP_MODE в регистре CTLR, и активирует линию USB_WAKEUP, которая может использоваться для оповещения остальной части устройства (например, блок пробуждения) о начале процесса возобновления работы (resume). Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
SUSP: Suspend mode request
Этот бит установится аппаратно, когда на шине USB нет трафика в течение 3 мс и более, показывая тем самым наличие на шине USB запроса приостановки (suspend mode request). Проверка состояния suspend разрешена немедленно после USB reset и запрещается аппаратно, когда активизируется suspend mode (FSUSP=1) до окончания последовательности возобновления (resume sequence). Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
RESET: USB reset request
Устанавливается, когда периферия USB детектирует активный сигнал USB RESET на своих входах. Периферия USB в ответ на RESET просто сбрасывает внутреннюю машину состояний протокола, генерируя прерывание, если установлен бит RESETM в регистре USB_CNTR. Прием и передача запрещены до тех пор, пока не будет очищен бит RESET. Все конфигурационные регистры не сбрасываются: микроконтроллер должен явно очистить эти регистры (это сделано для гарантии, чтобы прерывание RESET могло быть безопасно доставлено, и могла быть завершена транзакция, за которой немедленно последовал RESET). Адрес функции и регистры конечной точки сбрасываются событием USB reset. Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
SOF: Start of frame
Этот бит сигнализирует о начале нового фрейма USB, и он устанавливается, когда по шине USB пришел пакет начала фрейма (SOF). ISR может мониторить события SOF, чтобы получить событие синхронизации с хостом USB, которое происходит каждую 1 мс. Это позволяет безопасно прочитать регистр USB_FNR, который обновляется при каждом приеме пакета SOF (это полезно для изохронных приложений). Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
ESOF: Expected start of frame
Этот бит установится аппаратно, когда ожидается пакет SOF, но он не принят. Хост отправляет пакет SOF каждую миллисекунду, но если хаб не принял его корректно, то Suspend Timer выдает это прерывание. Если генерируются три следующих друг за другом прерывания ESOF (т. е. не было трех пакетов SOF) без какого-либо трафика между ними, генерируется прерывание SUSP. Этот бит установится даже когда произошла потеря пакета SOF, когда Suspend Timer пока не заблокирован. Этот бит можно читать и записывать, однако можно записать только 0, запись 1 не дает эффекта.
7:5 эти биты зарезервированы.
DIR: Direction of transaction
Этот бит записывается аппаратно в соответствии с направлением успешной транзакции, которая сгенерирована запросом на прерывание. Если бит DIR = 0, то в регистре USB_EPnR установится CTR_TX, относящийся к этой конечной точке. Транзакция прерывания имеет тип IN (данные передаются от периферии USB до хоста PC). Если бит DIR = 1, то в регистре USB_EPnR установится бит CTR_RX или оба бита CTR_TX/CTR_RX, относящиеся к этой конечной точке, вызвавшей прерывание. Транзакция прерывания имеет тип OUT (данные были переданы от хоста PC и приняты периферией USB), или ожидают обработки две транзакции. Эта информация может использоваться программой приложения для доступа к битам USB_EPnR, относящихся к сработавшей транзакции, поскольку она представляет направление имеющегося прерывания, ожидающего обработки. Этот бит только для чтения.
EP_ID[3:0]: Endpoint Identifier
Идентификатор конечной точки. Эти биты записываются аппаратурой в соответствии с номером конечной точки, которая сгенерировала запрос прерывания. Если ожидает обработки несколько транзакций, то аппаратура запишет идентификатор конечной точки, относящийся к конечной точки, у который самый высокий приоритет. Этот приоритет определен следующим способом. Определены два набора конечных точке, в порядке приоритета: изохронные и bulk-конечные точки считаются первыми, и после них проверяются другие конечные точки. Если больше одной конечной точки из одного набора запрашивают прерывание, то биты EP_ID в регистре USB_ISTR назначаются в соответствии с самым младшим запрашиваемым регистром конечной точки, у EP0R самый высокий приоритет, за ним идет EP1R, и так далее. Программа приложения может назначить регистр для каждой конечной точки по этой схеме приоритета, чтобы подходящим способом определить порядок конкурирующих запросов конечной точки. Эти биты только для чтения.
Значение после сброса: 0x0XXX (X обозначает неопределенные значения).
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
RXDP
RXDM
LCK
LSOF[1:0]
FN[10:0]
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
r
RXDP: Receive data + line status
Этот бит может использоваться, чтобы определить состояние принятых данных плюсовой линии данных upstream-порта. Может использоваться в подпрограммах окончания режима приостановки (end-of-suspend), чтобы помочь определить событие пробуждения (wakeup event).
RXDM: Receive data - line status
Этот бит может использоваться, чтобы определить состояние принятых данных минусовой линии данных upstream-порта. Может использоваться в подпрограммах окончания режима приостановки (end-of-suspend), чтобы помочь определить событие пробуждения (wakeup event).
LCK: Locked
Захват. Этот бит устанавливается аппаратно, когда приняты как минимум два следующих друг за другом пакета SOF после окончания состояния USB reset, или после окончания последовательности возобновления работы (USB resume sequence). После захвата таймер фрейма остается в этом состоянии до тех пор, пока не произойдет событие USB reset или USB suspend.
LSOF[1:0]: Lost SOF
Эти биты записываются аппаратно, когда генерируется прерывание ESOF, подсчитывая количество пропавших следующих друг за другом пакетов SOF. При приеме пакета SOF эти биты очищаются.
FN[10:0]: Frame number
Это 11-битное поле содержит номер фрейма, содержащегося в последнем принятом пакете SOF. Номер фрейма инкрементируется при каждом фрейме, отправленном хостом, и это полезно для изохронных передач. Это битовое поле обновляется при генерации прерывания SOF.
Этот бит устанавливается программой, чтобы разрешить работу устройства USB. Адрес этого устройства содержится в следующих битах ADD[6:0]. Если этот бит в лог. 0, то никакие транзакции не обрабатываются, независимо от настроек регистров USB_EPnR.
ADD[6:0]: Device address
Эти биты содержат адрес функции USB, назначенный хостом PC во время процесса энумерации. Это поле и поле адреса конечной точки (Endpoint Address, EA) в связанном регистре USB_EPnR, оба должны совпадать с информацией, содержащейся в токене USB, чтобы обработать транзакцию требуемой конечной точки.
Эти биты содержат начальный адрес таблицы выделения буфера в выделенной памяти пакетов. Эта таблица описывает каждое размещение буфера конечной точки и его размер, и адрес должен быть выровнен по границе 8 байт (три младших бита всегда равны 0). В начале каждой транзакции, адресованной этому устройству, периферия USB читает элемент из этой таблицы, относящийся к адресованной конечной точке, чтобы получить начальное положение её буфера и размер этого буфера (см. выше "Структура буферов пакета и их использование").
2:0 эти биты зарезервированы, принудительно установлены аппаратурой в 0.
[Регистры конечных точек]
Количество этих регистров меняется в зависимости о количества конечных точек, которое может обрабатывать периферия USB. Всего периферия USB поддерживает до 8 двунаправленных конечных точек. Каждое устройство USB должно поддерживать управляющую конечную точку (control endpoint, у которой адрес (номер конечной точки, биты EA) должен быть установлен в 0. Периферия USB ведет себя непредсказуемо, если разрешено несколько конечных точек с одинаковым адресом (номером конечной точки). Для каждой конечной точки доступен регистр USB_EPnR для сохранения специфической для этой конечной точки информации.
У каждой конечной точки есть свой регистр USB_EPnR, где n это идентификатор конечной точки.
Смещение адреса: от 0x00 до 0x1C
Значение после сброса: 0x0000
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
CTR_RX
DTOG_RX
STAT_RX[1:0]
SETUP
EP_TYPE[1:0]
EP_KIND
CTR_TX
DTOG_TX
STAT_TX[1:0]
EA[3:0]
rc_w0
t
t
t
r
rw
rw
rw
rc_w0
t
t
t
rw
rw
rw
rw
Биты регистра USB_EPnR, кроме бит CTR_RX и CTR_TX, сбрасываются, когда по шине USB принят сигнал USB reset, или сброс может быть принудительно задан битом FRES в регистре CTLR. Биты CTR_RX и CTR_TX остаются неизменными, чтобы не пропустить корректное оповещение пакета, за которым немедленно следует событие сброса по шине (USB reset event).
Следует избегать циклов read-modify-write с этими регистрами, потому что между операциями чтения и записи может произойти аппаратное изменение каких-либо бит, и следующая запись может изменить их до того, как у CPU может быть время для определения изменения этих бит. С этой целью все биты, которых касается такая проблема, имеют "инвариантное" значение, которое должно использоваться всякий раз, когда модификация этих бит не требуется. Рекомендуется изменять эти биты инструкцией load, где все биты, которые могут быть изменены только аппаратно, записываются в свое "инвариантное" значение.
CTR_RX: Correct Transfer for reception
Этот бит устанавливается аппаратурой, когда для этой конечной точки успешно завершена транзакция OUT/SETUP; программа может только очистить этот бит. Если бит CTRM в регистре USB_CNTR установлен соответствующим образом, то генерируется стандартное прерывание вместе с прерыванием соответствующей конечной точки, которое всегда активируется. Тип произошедшей транзакции, OUT или SETUP, можно определить по биту SETUP, описанному ниже.
Транзакция, которая заканчивается NAK или STALL handshake, не установит этот бит, поскольку в действительности данные не были переданы, как происходит в случае ошибок протокола или переключения буферов данных (Data Toggle). Этот бит можно читать и записывать, однако записать можно только 0, запись 1 не дает эффекта.
DTOG_RX: Data Toggle, для транзакций приема
Если конечная точка не изохронная, то этот бит хранит ожидаемое значение бита переключения данных (0=DATA0, 1=DATA1) для следующего пакета данных, который будет получен. Аппаратура переключит этот бит, когда хостом отправлен ACK handshake после приема пакета данных, имеющего соответствующее значение PID данных; если конечная точка определена как управляющая, то аппаратура очищает этот бит при приеме SETUP PID, адресованного на эту конечную точку.
Если конечная точка использует функцию двойной буферизации, то этот бит также используется для поддержки переключения буферов данных (см. "Конечные точки с двойной буферизацией"). Если конечная точка изохронная, то этот бит используется только для поддержки переключения буфера, поскольку для такого вида конечных точек не используется переключение данных, и передается только пакет DATA0 (см. "Изохронные передачи"). Аппаратура переключает этот бит сразу после окончания приема пакета данных, поскольку для изохронных передач не используется handshake.
Этот бит также можно переключить аппаратно, чтобы инициализировать его значение (это обязательное действие, когда конечная точка не управляющая), или принудительно установить использование определенного переключения данных / буфера пакетов. Когда программа приложения записывает 0, то значение DTOG_RX не изменяется, в то время как запись 1 приведет к переключению значения этого бита на противоположное. Этот бит можно читать и записывать, однако его можно лишь с помощью записи переключить в противоположное значение, если записать 1.
STAT_RX [1:0]: биты статуса для транзакций приема
Эти биты содержат информацию о состоянии конечной точки, которые перечислены в таблице 173. Эти биты можно переключить программно для инициализации их значения. Когда программа приложения записывает 0, значение остается неизменным, в то время как запись 1 приводит к переключению бита. Аппаратура устанавливает биты STAT_RX в состояние NAK, когда произошла корректная транзакция (CTR_RX=1), соответствующая OUT или SETUP (только управление), чтобы у программы было время на обработку транзакции до поступления новой, и программа могла подтвердить пакетом ACK успешную обработку транзакции (программное управление потоком).
Таблица 173. Кодирование статуса приема.
STAT_RX[1:0]
Что означает
00
DISABLED: все запросы приема, адресованные этой конечной точке, игнорируются.
01
STALL: конечная точка остановлена (stalled) и на все запросы приема будет выдан STALL handshake.
10
NAK: на все входящие запросы будет выдан NAK handshake.
11
VALID: эта конечная точка разрешена для приема.
Bulk конечные точки с двойной буферизацией реализуют специальную схему управления потоком транзакций, где управление статусом основывается на доступности буфера (см. "Конечные точки с двойной буферизацией"). Если конечная точка определена как изохронная, то её статус может быть только VALID или DISABLED, так как аппаратура не может поменять статус изохронной конечной точки после успешной транзакции. Если программа установит биты STAT_RX в состояние STALL или NAK для изохронной конечной точки, то поведение периферии USB не определено. Эти биты можно читать и записывать, однако их можно лишь с помощью записи переключить в противоположное значение, если записать 1.
SETUP: Setup transaction completed
Этот бит только для чтения, и он устанавливается аппаратурой, когда последняя завершенная транзакция была SETUP. Этот бит меняет свое значение только для управляющих конечных точек. Он должен быть проверен в случае успешной принимающей транзакции (событие CTR_RX), чтобы определить тип произошедшей транзакции. Чтобы защитить ISR от изменений в битах SETUP из-за следующих приходящих токенов, этот бит удерживается замороженным, пока бит CTR_RX в состоянии 1; его состояние меняется, когда CTR_RX в состоянии 0.
EP_TYPE[1:0]: Endpoint type
Эти биты конфигурируют основное поведение конечной точки, как описано в таблице 174. Конечная точка 0 должна быть всегда управляющей (control endpoint), и каждая функция USB должна иметь как минимум одну управляющую конечную точку с адресом 0, однако могут быть и другие управляющие точки, если это необходимо. Только управляющие конечные точки обслуживают транзакции SETUP, которые игнорируются конечными точками других видов. На транзакцию SETUP нельзя ответить пакетом NAK или STALL. Если управляющая конечная точка определена как NAK, то периферия USB не отвечает, симулируя ошибку в направлении приема, когда приходит транзакция SETUP. Если управляющая конечная точка определена как STALL в направлении приема, то пакет SETUP все равно будет принят, с перемещением данных и срабатыванием прерывания CTR. Прием OUT-транзакция обрабатывается обычным образом, даже если конечная точка управляющая.
Таблица 174. Кодирование типов конечной точки.
EP_TYPE[1:0]
Что означает
00
BULK (пакетные ускоренные передачи)
01
CONTROL (управление)
10
ISO (изохронные передачи)
11
INTERRUPT
У конечных точек bulk и interrupt поведение очень похожее, и они отличаются только специальной функцией, доступной при использовании бита конфигурации EP_KIND. Использование изохронных конечных точек см. в секции "Изохронные передачи".
EP_KIND: Endpoint kind
Значение этого бита зависит от типа конечной точке, сконфигурированного битами EP_TYPE, что показано в таблице 175.
Таблица 175. Назначение Endpoint kind.
EP_TYPE[1:0]
Смысл EP_KIND
00
BULK
DBL_BUF
01
CONTROL
STATUS_OUT
10
ISO
Не используется
11
INTERRUPT
DBL_BUF: этот бит устанавливается программой для разрешения функции двойной буферизации для этой bulk конечной точки.
STATUS_OUT: этот бит устанавливается программой, чтобы показать, какой ожидается статус out-транзакции. В этом случае на все OUT-транзакции, содержащие ненулевое количество байт данных, будет дан ответ STALL вместо ACK. Этот бит может использоваться для увеличения надежности приложения по отношению к ошибкам протокола во время управляющих передач, и использование этого бита предназначено только для управляющих конечных точек. Когда STATUS_OUT сбрасывается, OUT-транзакции могут иметь любое необходимое количество байт.
CTR_TX: Correct Transfer for transmission
Этот бит установится аппаратно, когда на этой конечной точке успешно завершена транзакция IN; программа может только очистить этот бит. Если бит CTRM в регистре USB_CNTR установлен соответствующим образом, то генерируется обычное прерывание вместе с прерыванием, относящимся к конечной точке, которое активируется всегда.
Транзакция, которая закончится на NAK или STALL handshake, не установит этот бит, поскольку в реальности не были переданы данные, как происходит при ошибках протокола или не совпадении переключения данных.
Этот бит можно читать и записывать, однако записать можно только 0.
DTOG_TX: Data Toggle, для транзакций передачи
Если конечная точка не изохронная, то этот бит содержит требуемое значение бита переключения данных (0=DATA0, 1=DATA1) для следующего передаваемого пакета. Аппаратура переключит этот бит, когда от хоста USB будет получено ACK handshake, которое идет за передачей пакета данных. Если конечная точка определена как управляющая, то аппаратура установит этот бит в 1 при приеме SETUP PID, адресованного этой конечной точке.
Если конечная точка использует двойную буферизацию, то это бит также используется для поддержки смены буфера пакета (см. "Конечные точки с двойной буферизацией"). Если конечная точка изохронная, то этот бит используется для поддержки смены буфера, поскольку для конечных точек такого вида нет переключения данных, и передается только пакет DATA0 (см. "Изохронные передачи"). Аппаратура переключает этот бит сразу после окончания передачи пакета данных, поскольку для изохронных передач не используется handshake.
Этот бит также можно переключить программно для инициализации его значения (что обязательно, когда конечная точка не управляющая), или для принудительного использования специфического переключения данных / буфера пакета. Когда приложение записывает 0, значение DTOG_TX остается неизменным, в то время как запись 1 приводит к переключению значения бита на противоположное. Таки образом, этот бит можно читать и записывать, однако его можно только переключить записью 1.
STAT_TX [1:0]: биты статуса для передач
Эти биты содержат информацию о состоянии конечной точки, что перечислено в таблице 176. Эти биты можно переключить программно для инициализации их значения. Когда программа приложения записывает 0, значение бита не изменяется, в то время как запись 1 приводит к переключению бита в противоположное значение. Аппаратура установит биты STAT_TX в NAK, когда произошла корректная передача (CTR_TX=1), соответствующая транзакции IN или SETUP (только управление), адресованной в эту конечную точку. И затем ждет программу на предмет подготовки следующего передаваемого набора данных.
Таблица 176. Кодирование статуса передачи.
STAT_TX[1:0]
Что означает
00
DISABLED: все запросы передачи, адресованные этой конечной точке, игнорируются.
01
STALL: конечная точка остановлена (stalled) и на все запросы передачи будет выдан STALL handshake.
10
NAK: на все запросы передачи будет выдан NAK handshake.
11
VALID: эта конечная точка разрешена для передачи.
Конечные точки bulk с двойной буферизацией реализуют для управления потоком специальную транзакцию, которая управляет статусом на основе доступности буфера (см. "Конечные точки с двойной буферизацией"). Если конечная точка определена как изохронная, то этот статус будет только VALID или DISABLED. Таким образом, аппаратура не может поменять статус конечной точки после успешной транзакции. Если программа установит биты STAT_TX в STALL или NAK для изохронной конечной точки, то поведение периферии USB не определено. Эти биты можно читать и записывать, однако их можно только переключить записью 1.
EA[3:0]: Endpoint address
Программа должна записать в это поле 4-битный адрес для идентификации транзакций, направленных в эту конечную точку. Значение должно быть записано перед разрешением конечной точки.
[Таблица дескрипторов буферов (BDT)]
Хотя BDT находится внутри памяти буферов пакетов, её записи можно считать дополнительными регистрами, используемыми для конфигурирования размещения и размера буферов пакетов, используемых для обмена данными между макроячейками USB и STM32F10xxx. Из-за общего ограничения APB на адресацию слов, ко всем ячейкам памяти пакетов через APB осуществляется доступ по адресу, выровненному на 32 бита (4 байта), вместо реальных адресов памяти, используемых периферией USB для регистра USB_BTABLE и ячеек таблицы BDT.
Есть два адреса, один использует программа приложения при доступе к памяти пакетов, и еще один локальный относительно доступа к периферии USB. Для получения корректного значения адреса памяти STM32F10xxx для использования в программе приложения при доступе к памяти пакетов, реальный адрес ячейки памяти должен быть умножен на 2. Первая ячейка памяти пакетов находится по адресу 0x40006000. Ниже описана запись таблицы BDT, связанная с регистрами USB_EPnR.
Полное объяснение буферов пакета и BDT можно найти выше в секции "Структура буферов пакета и их использование".
Эти биты указывают на начальный адрес буфера пакета, передаваемого конечной точкой, связанной с регистром USB_EPnR на следующем токене IN, адресованном в эту конечную точку.
Бит 0 всегда должен быть записан как 0, поскольку память пакетов имеет ширину слова, и все буферы пакетов должны быть выровнены на размер слова.
15:10 эти биты не используются, поскольку размер пакета ограничен спецификацией USB на 1023 байтах. Значение этих бит не учитывается периферией USB.
COUNTn_TX[9:0]: Transmission byte count
Эти биты содержат количество байт, передаваемых конечной точкой, связанной с регистром USB_EPnR на следующем токене IN, адресованном в эту конечную точку.
Замечание: конечные точки IN с двойной буферизацией и изохронные конечные точки имеют два регистра USB_COUNTn_TX с именами USB_COUNTn_TX_1 и USB_COUNTn_TX_0, со следующим содержимым:
Эти биты указывают на начальный адрес буфера пакета, который будет содержать данные, принятые конечной точкой, связанной с регистром USB_EPnR на следующем токене OUT/SETUP, адресованном в эту конечную точку.
Бит 0 всегда должен быть записан в 0, поскольку память пакетов имеет ширину данных слова, и все буферы пакета должны быть выровнены на границу слова.
Эта ячейка таблицы используется для сохранения двух разных значений, оба требуются при приеме пакета. Старшие биты содержат определение выделенного размера буфера, чтобы можно было определить переполнение буфера, в то время как младшая часть этой ячейки записывается обратно периферией USB по окончании приема, чтобы дать реальное количество принятых данных. Из-за ограничения на количество доступных бит размер буфера представлен с использованием количества выделенных блоков памяти, где размер блока может быть выбран как компромисс между точной гранулярностью / малым буфером и грубой гранулярностью / большим буфером. Размер выделенного буфера является частью дескриптора конечной точки, и он обычно определяется во время процесса энумерации в соответствии со значением параметра maxPacketSize (см. описание стандарта USB [2]).
BL_SIZE: BLock size
Этот бит выбирает размер блока памяти, используемого для определения выделенной области буфера.
– если BL_SIZE=0, то блок памяти имеет размер 2 байта, это минимально допустимый размер блока в памяти шириной в слово. С этим размером блока размер буфера может быть в диапазоне от 2 до 62 байт.
– Если BL_SIZE=1, то размер блока памяти 32 байта, что позволяет достичь максимального размера пакета, определенного спецификацией USB. С этим размером блока выделенный размер буфера может быть в диапазоне от 32 до 1024 байт, последнее значение соответствует самому большому пакету, который допускает спецификация стандарта USB.
NUM_BLOCK[4:0]: Number of blocks
Эти биты задают количество блоков памяти, выделенных под этот буфер пакетов. Реальное количество выделенной памяти зависит от значения BL_SIZE, что показано в таблице 177.
Таблица 177. Определение выделенной под буфер памяти.
Значение NUM_BLOCK[4:0]
Память, выделенная при BL_SIZE=0
Память, выделенная при BL_SIZE=1
0 (00000b)
Не допускается
32 байта
1 (00000b)
2 байта
64 байта
2 (00010b)
4 байта
96 байт
3 (00011b)
6 байт
128 байт
...
...
...
15 (01111b)
30 байт
512 байт
16 (10000b)
32 байта
Недоступно
17 (10001b)
34 байта
18 (10010b)
36 байт
...
...
...
30 (11110b)
60 байт
Недоступно
31 (11111n)
62 байта
COUNTn_RX[9:0]: Reception byte count
Эти биты содержат количество байт, принятых конечной точкой, связанной с регистром USB_EPnR во время последней транзакции OUT/SETUP, адресованной в эту конечную точку.
Замечание: конечные точки IN с двойной буферизацией и изохронные конечные точки имеют два регистра USB_COUNTn_TX с именами USB_COUNTn_TX_1 и USB_COUNTn_TX_0, со следующим содержимым:
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
BLSIZE_1
NUM_BLOCK_1[4:0]
COUNTn_RX1[9:0]
rw
rw
rw
rw
rw
rw
r
r
r
r
r
r
r
r
r
r
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
BLSIZE_0
NUM_BLOCK_0[4:0]
COUNTn_RX0[9:0]
rw
rw
rw
rw
rw
rw
r
r
r
r
r
r
r
r
r
r
Таблица 178. Карта памяти регистров USB и их значения после сброса (Reset value).