Возможно, проблема в организации буфера в примере:
При получении SOF вычисляется длина данных, которые нужно отправить APP_Rx_length:
CODE
if (APP_Rx_ptr_out == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_out = 0;
}
if(APP_Rx_ptr_out == APP_Rx_ptr_in)
{
USB_Tx_State = 0;
return;
}
if(APP_Rx_ptr_out > APP_Rx_ptr_in) /* rollback */
{
APP_Rx_length = APP_RX_DATA_SIZE - APP_Rx_ptr_out;
}
else
{
APP_Rx_length = APP_Rx_ptr_in - APP_Rx_ptr_out;
}
APP_Rx_ptr_out - указатель на место, с которого начинать читать данные из буфера для отправки на ПК
APP_Rx_ptr_in - последние сохраненные данные в буфере
Я почему-то думал, что там должен быть кольцевой буфер, но там обычный буфер и в случае, если APP_Rx_ptr_out > APP_Rx_ptr_in, на отправку поступает только конец буфера, а уже записанные данные в начале буфера в данном кадре не передаются, а передадутся только уже в следующем. И тогда, если от APP_Rx_ptr_out до конца буфера будет мало данных, то и максимальная пропускная способность уменьшится.
Может проблема была где-то в этом. Хотя, исходя из того, что у меня буфер 32кБ и за кадр, допустим, передается по ~1кБ, то в случае описаном выше, была бы потеря в скорости не более 1/32, т.е. итоговая скорость была бы где-нибудь 970кБ/с.
UPD:
И еще, похоже где-то тормоза кроются в прерывании, т.к. если просто в цикле мэйна забивать данные в буфер без задержек на максимальной скорости, данные в буфере не перекрываются и на ПК принимается все последовательно. Для проверки записывал в цикле в буфер переменную uint32_t cnt с инкрементом.
Код
uint32_t cnt = 0;
while (1)
{
APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[3];
APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[2];
APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[1];
APP_Rx_Buffer[APP_Rx_ptr_in++] = ((uint8_t*)&(cnt))[0];
cnt++;
if(APP_Rx_ptr_in == APP_RX_DATA_SIZE)
{
APP_Rx_ptr_in = 0;
}
}
UPD2:
Измерил, 5мкс МК проводит в прерывании USB, 600нс проводит вне прерывания. Буду копать дальше.
UPD3:
У меня, похоже, какие-то проблемы с тактовой частотой.
Вывожу на пин частоту:
Код
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
while(1)
{
GPIOB->BSRRL = GPIO_Pin_12;
GPIOB->BSRRH = GPIO_Pin_12;
}
Вижу на выходе 10МГц. Непонятно, почему тактовая частота получается 20МГц, т.к. в system_stm32f2xx.c, который я использую по-умолчанию, настройка идет на 120МГц, кварц стоит 25МГц, питание 3,3В. Проверил SetSysClock(), PLL нормально настраивается на работу от HSE. Как так получается?
UPD4:
На кварце видна синусоида 25МГц.
UPD5:
Нашел причину этой проблемы, но не понимаю, почему она возникает.
При включении оптимизации по размеру, начала выводиться на пин нормальная частота.
Выключил оптимизацию - снова появляется эта проблема.
Компилятор Sourcery CodeBench Lite 2012.09-63.
Сообщение отредактировал BaN - Apr 29 2013, 13:17