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

STM32F3xx, USB, “1 x 16 bits/word” access scheme

Читаю 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.

Допустим, понять еще... ладно, и понять не могу :biggrin: И узнать, какому 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...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Откуда они узнали не знаю, а Вы можете это посмотреть в разделе 32.3 Table 176.

 

Все эти странности по одной простой причине: буферная память у них 16-разрядная и её по-разному отображают в адресное пространство процессора.

512-байтный буфер виден кусочками по 16 бит в каждом 32-битном слове, а в девайсах с буфером 1024 байта эти 16-битные слова упакованы по две штуки в слово. Но читать их по-прежнему можно только полусловами, по 16 бит за раз.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И то, что на 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И то, что на 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-модуль контроллера, да прикрутили по-быстрому.

 

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

В результате имеем массу не нужных программисту подробностей об аппаратной реализации, да ещё и пропущенных через "популяризационный фильтр".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Да, похоже, что разную периферию делали разного уровня специалисты. Надо было ARM-у еще и USB разработать и присобачить к Cortex-у. :lol:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...