ViKo 1 17 июня, 2015 Опубликовано 17 июня, 2015 · Жалоба Читаю RM0316, раздел USB, 32.6.3 Buffer descriptor table: In the following pages, two address locations are reported for devices with “1 x 16 bits/word” access scheme: the one to be used by application software while accessing the packet memory, and the local one relative to USB peripheral access. To obtain the correct memory address value to be used in the application software while accessing the packet memory, the actual memory location address must be multiplied by two. On devices with “2 x 16 bits/word” access scheme, the address location to be used by application software is the same as the local one relative to USB peripheral access. The packet memory on these devices should be accessed only by byte (8-bit) or half-word (16- bit) accesses. Word (32-bit) accesses are not allowed. Допустим, понять еще... ладно, и понять не могу И узнать, какому MCU какая схема соответствует. Кубописатели в stm32f3xx_hal_pcd_ex.h предлагают такое решение: /** * @brief Gets address in an endpoint register. * @param USBx: USB peripheral instance register address. * @param bEpNum: Endpoint Number. * @retval None */ #if defined(STM32F302xC) || defined(STM32F303xC) || \ defined(STM32F373xC) #define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint32_t *)((USBx->BTABLE+bEpNum*8)*2+ ((uint32_t)USBx + 0x400))) #define PCD_EP_TX_CNT(USBx, bEpNum) ((uint32_t *)((USBx->BTABLE+bEpNum*8+2)*2+ ((uint32_t)USBx + 0x400))) #define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint32_t *)((USBx->BTABLE+bEpNum*8+4)*2+ ((uint32_t)USBx + 0x400))) #define PCD_EP_RX_CNT(USBx, bEpNum) ((uint32_t *)((USBx->BTABLE+bEpNum*8+6)*2+ ((uint32_t)USBx + 0x400))) #define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) {\ uint32_t *pdwReg = PCD_EP_RX_CNT(USBx, bEpNum); \ PCD_SET_EP_CNT_RX_REG(pdwReg, wCount);\ } #endif /* STM32F302xC || STM32F303xC || */ /* STM32F373xC */ #if defined(STM32F302xE) || defined(STM32F303xE) || \ defined(STM32F302x8) #define PCD_EP_TX_ADDRESS(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8)+ ((uint32_t)USBx + 0x400))) #define PCD_EP_TX_CNT(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8+2)+ ((uint32_t)USBx + 0x400))) #define PCD_EP_RX_ADDRESS(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8+4)+ ((uint32_t)USBx + 0x400))) #define PCD_EP_RX_CNT(USBx, bEpNum) ((uint16_t *)((USBx->BTABLE+bEpNum*8+6)+ ((uint32_t)USBx + 0x400))) #define PCD_SET_EP_RX_CNT(USBx, bEpNum,wCount) {\ uint16_t *pdwReg = PCD_EP_RX_CNT(USBx, bEpNum); \ PCD_SET_EP_CNT_RX_REG(pdwReg, wCount);\ } Но откуда они узнали? Где написано? Что-то я впадаю в депрессию при попытках разобраться с USB в STM32... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 6 18 июня, 2015 Опубликовано 18 июня, 2015 · Жалоба Откуда они узнали не знаю, а Вы можете это посмотреть в разделе 32.3 Table 176. Все эти странности по одной простой причине: буферная память у них 16-разрядная и её по-разному отображают в адресное пространство процессора. 512-байтный буфер виден кусочками по 16 бит в каждом 32-битном слове, а в девайсах с буфером 1024 байта эти 16-битные слова упакованы по две штуки в слово. Но читать их по-прежнему можно только полусловами, по 16 бит за раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 18 июня, 2015 Опубликовано 18 июня, 2015 · Жалоба И то, что на Figure 400 слева показано - это номера (индексы) 8-битовых элементов таблицы? 00-01 - ADDR0_TX, 02-03 - COUNT0-TX, и т.д. А реальные адреса, видимые процессором, для 1x16 bits/word: 00-01, 04-05, для 2x16 bits/word: 00-01, 02-03. Так? Регистр BTABLE задает адрес таблицы распределения памяти буферов конечных точек. И находится эта таблица сама внутри этой же памяти. Спрашивается, зачем ее не сделали по фиксированному адресу, например, в начале этой памяти? В разделе 32.6 (в начале) явно недокорректировали текст: All register addresses are expressed as offsets with respect to the USB peripheral registers base address 0x4000 5C00, except the buffer descriptor table locations, which starts at the address specified by the USB_BTABLE register. All register addresses are aligned to 32-bit word boundaries although they are 16-bit wide. The same address alignment is used to access packet buffer memory locations, which are located starting from 0x4000 6000.All register addresses are aligned to 32-bit word boundaries although they are 16-bit wide. On devices with ”1 x 16 bits/word” access scheme, the same address alignment is used to access packet buffer memory locations, which are located starting from 0x4000 6000. В разделе 32.6.3 тоже недоредактировали: Address offset: [uSB_BTABLE] + n*16 USB local address: [uSB_BTABLE] + n*8 Address offset (”1 x 16 bits/word” access scheme): [uSB_BTABLE] + n*16 Address offset (”2 x 16 bits/word” access scheme): [uSB_BTABLE] + n*8 USB local address: [uSB_BTABLE] + n*8 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 6 19 июня, 2015 Опубликовано 19 июня, 2015 · Жалоба И то, что на Figure 400 слева показано - это номера (индексы) 8-битовых элементов таблицы? 00-01 - ADDR0_TX, 02-03 - COUNT0-TX, и т.д. Таблица в буферной памяти - это информация для контроллера USB, поэтому там все адреса есть адреса относительно начала буферной памяти. Не исключено, что на самом деле доступ к этой памяти производится только словами, а в буферной памяти эти адреса хранятся сдвинутыми на один бит, "для удобства". Впрочем нам это не видно, а потому не важно. А реальные адреса, видимые процессором, для 1x16 bits/word: 00-01, 04-05, для 2x16 bits/word: 00-01, 02-03. Так? ага. Собственно, есть простая формула (даже две формулы, для разных реализаций) для преобразования адресов в буферной памяти в адреса на шине процессора, а вся остальная писанина - применение этих формул к конкретному случаю доступа к тому или иному параметру. Регистр BTABLE задает адрес таблицы распределения памяти буферов конечных точек. И находится эта таблица сама внутри этой же памяти. Спрашивается, зачем ее не сделали по фиксированному адресу, например, в начале этой памяти? Ну, например, чтобы можно было иметь две таблицы и быстро переключаться между ними при смене конфигурации. Есть и проще объяснение, взяли готовый IP-модуль контроллера, да прикрутили по-быстрому. По моему опыту - такие заумные описания железа появляются в результате стратегической ошибки: разработчики железа без злого умысла рассказывают "писателю" как оно всё устроено с подробностями, а уж потом он что понял переносит на бумагу. В результате имеем массу не нужных программисту подробностей об аппаратной реализации, да ещё и пропущенных через "популяризационный фильтр". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 19 июня, 2015 Опубликовано 19 июня, 2015 · Жалоба Спасибо. Да, похоже, что разную периферию делали разного уровня специалисты. Надо было ARM-у еще и USB разработать и присобачить к Cortex-у. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться