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

GD32F450 искажаются данные в приемном USB FIFO

Может быть у кого встречалось, и кто подскажет решение. В микроконтроллере GD32F450 при интенсивном обмене через USBFS наблюдается следующее:  после OUT транзакции, если во время чтения RX FIFO, происходит IN транзакция, то возможна ситуация когда при чтении RX FIFO будет однократно прочитано значение из TX FIFO.

Искажается одно 32bit слово, равное размеру  чтения из FIFO, в произвольном месте приемного буфера. Может повредится  первое статусное слово (GRSTATP), расположенное в начале каждого блока данных.

И чем дальше во времени после OUT транзакции происходит чтение, тем вероятнее проявляется ошибка. Если в системе повысить уровень приоритета прерывания USB до максимального, то вероятность ошибки будет минимальной.

Такое поведение наблюдается как в USBFS, так и в USBHS (режим FS) блоке. Если в USBHS (режим FS) включить чтение буферов  через DMA, то  ошибок не будет.

Компилятор GCC и родные китайские библиотеки.

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


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

В распределении FIFO - посмотрите есть ли разница с тем как оно работает при DMA и без DMA. Если отличия есть - распределяйте как для режима с DMA.
Это на основании разбирательств с STM32... МОжет и тут поможет?

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


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

On 10/31/2022 at 1:30 PM, deni said:

Если в системе повысить уровень приоритета прерывания USB до максимального, то вероятность ошибки будет минимальной.

Если размер флеша превысит Code Area, то ... ничего не поможет.

gd450.jpg

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


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

12 часов назад, GenaSPB сказал:

В распределении FIFO - посмотрите есть ли разница с тем как оно работает при DMA и без DMA. Если отличия есть - распределяйте как для режима с DMA.
Это на основании разбирательств с STM32... МОжет и тут поможет?

В HS блоке они одинаково распределены, что для режима с DMA, что для режима без DMA. Для всего что копируется в/из FIFO выровнены адреса по 4 байта, что для режима DMA обязательно.

3 часа назад, vit496 сказал:

Если размер флеша превысит Code Area, то ... ничего не поможет.

gd450.jpg

Ну я столько кода ещё не написал ).

 

Мне ещё не понятно как такое может получиться, я попробовал (в качестве эксперимента) программно записать по адресу RXFIFO, запись туда не возможна, только чтение. Похоже что когда при чтении буфера из RXFIFO процесс прерывается, в этот момент приходит IN транзакция, и во внутренней памяти USB адрес переключается на TXFIFO, и при продолжении чтения выдается одно слово из TXFIFO, далее уже нормально. 

У компилятора одно чтение 32b, одна запись 32b:     

 *(uint32_t *)dest_buf = *fifo;
 800a090:    69bb          ldr    r3, [r7, #24]
 800a092:    681a          ldr    r2, [r3, #0]
 800a094:    68bb          ldr    r3, [r7, #8]
 800a096:    601a          str    r2, [r3, #0]

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


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

Распределение памяти fifo... попробуйте накинуть 1..3 четырехбайтных ячейки...

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


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

9 минут назад, GenaSPB сказал:

Распределение памяти fifo... попробуйте накинуть 1..3 четырехбайтных ячейки...

Сейчас нарезано вот так:

#ifdef USB_FS_CORE
    #define RX_FIFO_FS_SIZE                         128
    #define TX0_FIFO_FS_SIZE                        64
    #define TX1_FIFO_FS_SIZE                        64
    #define TX2_FIFO_FS_SIZE                        64
    #define TX3_FIFO_FS_SIZE                        0

#ifdef USB_HS_CORE
    #define RX_FIFO_HS_SIZE                          512
    #define TX0_FIFO_HS_SIZE                         128
    #define TX1_FIFO_HS_SIZE                         128
    #define TX2_FIFO_HS_SIZE                         128
    #define TX3_FIFO_HS_SIZE                         0
    #define TX4_FIFO_HS_SIZE                         0
    #define TX5_FIFO_HS_SIZE                         0

 завтра попробую, что-нибудь не кратное 64байт.

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


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

В FIFO попробуйте дополнительно больше байт на 8..12 чем в дескрипторе ендпоинта

 

 

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


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

6 часов назад, GenaSPB сказал:

В FIFO попробуйте дополнительно больше байт на 8..12 чем в дескрипторе ендпоинта

 

 

Попробовал, можно крутить размеры FIFO по всякому, не влияет никак. Влияет только время которое прошло от момента получения до начала чтения из FIFO, чем дольше тем больше вероятность ошибки.

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


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

On 10/31/2022 at 2:30 PM, deni said:

Может быть у кого встречалось, и кто подскажет решение. В микроконтроллере GD32F450 при интенсивном обмене через USBFS наблюдается следующее:  после OUT транзакции, если во время чтения RX FIFO, происходит IN транзакция, то возможна ситуация когда при чтении RX FIFO будет однократно прочитано значение из TX FIFO.

Искажается одно 32bit слово, равное размеру  чтения из FIFO, в произвольном месте приемного буфера. Может повредится  первое статусное слово (GRSTATP), расположенное в начале каждого блока данных.

И чем дальше во времени после OUT транзакции происходит чтение, тем вероятнее проявляется ошибка. Если в системе повысить уровень приоритета прерывания USB до максимального, то вероятность ошибки будет минимальной.

Такое поведение наблюдается как в USBFS, так и в USBHS (режим FS) блоке. Если в USBHS (режим FS) включить чтение буферов  через DMA, то  ошибок не будет.

Компилятор GCC и родные китайские библиотеки.

а в каком регистре включается чтение через ДМА?

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


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

Посмотрел даташит... Полностью опущены детали, которые в аналогичном месте привели ST. Как вы крутили... Полагаю что это и есть причина.
Еще раз - размер памяти должен быть больше чем в endpoint.

On 11/2/2022 at 4:37 PM, deni said:

можно крутить размеры FIFO по всякому

Не надо по всякому, а надо увеличить. В аналогичном месте у ST есть зависимость и от количества ендопинтов всего и от типа DMA/NON DMA. И то что жолжно быть по нулевому смещению в fifo и что дальше.

Изменено пользователем GenaSPB

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


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

19 часов назад, 0men сказал:

а в каком регистре включается чтение через ДМА?

В библиотеке включается наличием #define USB_HS_INTERNAL_DMA_ENABLED в usb_conf.h, у USB_HS собственный DMA контроллер.

 

17 часов назад, GenaSPB сказал:

Посмотрел даташит... Полностью опущены детали, которые в аналогичном месте привели ST. Как вы крутили... Полагаю что это и есть причина.
Еще раз - размер памяти должен быть больше чем в endpoint.

Не надо по всякому, а надо увеличить. В аналогичном месте у ST есть зависимость и от количества ендопинтов всего и от типа DMA/NON DMA. И то что жолжно быть по нулевому смещению в fifo и что дальше.

 

Ну куда уже больше, для RX 512 * 4 = 2048 байт, для TX 128 *4 = 512 байт, для режима FS максимальный размер EP = 64 байта. Сейчас прием и передача происходит размером в один пакет (64 байта), там FIFO и так пустые по большей части. 

Размер FIFO конфигурируется через библиотеку, если смотреть регистры USB блока в работе, то делает она это верно. Организация RXFIFO такая же как в ST, при получении данных сначала в буфер FIFO кладется статус слово, за ним данные.

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


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

Еще погонял тесты, не всегда происходит прерывание по окончанию транзакции OUT. Прерывание RXFNEIF (Rx FIFO non-empty interrupt flag) вызывается всегда после получения OUT, один или несколько раз если общий размер больше передачи EP. А вот OEPIF (OUT endpoint interrupt flag), который должен быть вызван по окончанию получению всех данных иногда пропускается.

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


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

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

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

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

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

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

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

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

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

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