Всем привет.
STM32F1xx, 72МГц, UART3 (тактируется от 36 МГц). Пытаюсь достичь высоких скоростей. И что-то не получается.
Отправляю блоки ~512 байт, через DMA.
Инициализация:
Код
RCC->APB1ENR |= RCC_APB1ENR_USART3EN;
USART3->BRR = 36000000 / BAUDRATE;
USART3->CR1 = USART_CR1_TE; // transmit enable
USART3->CR2 = 0;
USART3->CR3 = USART_CR3_DMAT; // no flow control, enable TX DMA
USART3->CR1 |= USART_CR1_UE; // enable USART
// UART interrupt
NVIC_SetPriority(USART3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 2, 2));
NVIC_EnableIRQ(USART3_IRQn);
// DMA
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
DMA1_Channel2->CPAR = (uint32_t)&USARTx->DR;
DMA1_Channel2->CCR = 0
| DMA_CCR1_MINC // Memory increment mode
| DMA_CCR1_DIR // Read from memory
| DMA_CCR1_PL_0 // Channel Priority level
;
Отправка блока:
Код
void sendBuf(const void* buf, size_t size)
{
// clear all interrupts on DMA TX channel
DMA1_Channel2->IFCR = DMA_ISR_GIF2;
// set memory address and size
DMA1_Channel2->CMAR = (uint32_t)buf;
DMA1_Channel2->CNDTR = size;
// Clear USART transmission complete flag:
USART3->SR &= ~USART_SR_TC;
// enable DMA channel
DMA1_Channel2->CCR |= DMA_CCR1_EN;;
// enable UART TC interrupt
USART3->CR1 |= USART_CR1_TCIE;
// wait for transfer complete
txDmaDone_.wait();
// disable DMA channel
DMA1_Channel2->CCR &= ~DMA_CCR1_EN;;
}
Ну и прерывание от UART:
Код
void USART3_IRQHandler()
{
uint16_t status = USART3->SR;
if (status & USART_SR_TC)
{
// clear interrupt
USART3->SR &= ~USART_SR_TC;
// disable it
USART3->CR1 &= ~USART_CR1_TCIE;
// and flag transmission done
txDmaDone_.signal_isr();
}
}
Вот. Всё весьма незамысловато. И до скоростей порядка 2МБит это замечательно работает. А вот после - начинается нечто странное. Чем больше скорость, тем больше время отправки блока. На скорости 3.6МБит отправка блока длится несколько (около 4х) секунд. При дальнейшем увеличении скорости отправка вообще перестаёт завершаться.

Такое впечатление, что обмен по DMA становится слишком интенсивным, и полностью забивает шину.
Поэтому у меня вопрос: это я натолкнулся на ограничения железа? Или я что-то делаю не так?
Кто-нибудь имел дело с такими скоростями UART, и насколько успешно?
Если бы я знал, что такое электричество...