У меня подключена flash AT45DBxxx на SPI1, соответственно читаю из нее я по DMA1 (канал 2 на прием, 3 - на передачу). Так вот, если выставляю частоту шины 72МГц (SPI - 36 соответственно). Как бы передача по DMA работает, но только какое то время. После чего задача повисает в ожидании флага TCIF2, смотрю, а в DMA регистрах счетчиках на передачу - 0, а в приеме - 1, это значит, что 1 байт где то потерялся,
как такое возможно в принципе!? Пробовал синхронизоваться по прерыванию от 3 канала (TX) - ничего хорошего не дало, действительно в приемнике были не корректные данные.
При чем, эта ситуация возникает тогда, когда другая задача начинает активно работать с шиной (хоть с APB1 хоть с APB2 - разницы нет), у меня конкретно в другом потоке постоянно производилась запись в USART, при чем сама запись в регистр на шине не влияла а портило все чтение _SR регистра в ожидании когда опустеет буфет на передачу .
Понижаю частоту APB2 с 72 до 36МГц и косяк вроде бы перестает наблюдаться.В ERRATA такой глюк не описан, подскажите кто встречался с подобным или я что не так делаю?
кусок кода обмена по DMA
Код
unsigned char DFSPI1_DMARecceiveBlock (unsigned char * buff, unsigned long count)
{
DMA1_Channel2->CMAR = (uint32_t)buff;
DMA1_Channel2->CNDTR = count;
DMA1_Channel3->CNDTR = count;
DMA_ClearITPendingBit(DMA1_IT_TC2);
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, ENABLE); // Enable Interrupt on transmition compleet
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, ENABLE); // Enable Rx DMA
DMA_Cmd(DMA1_Channel2, ENABLE); // Start Rx DMA
DMA_Cmd(DMA1_Channel3, ENABLE); // Start Tx DMA
xSemaphoreTake( xSemaphoreSPI1, portMAX_DELAY );
SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx | SPI_I2S_DMAReq_Rx, DISABLE); // Enable Rx DMA
DMA_ITConfig(DMA1_Channel2, DMA_IT_TC, DISABLE);
DMA_Cmd(DMA1_Channel2, DISABLE);
DMA_Cmd(DMA1_Channel3, DISABLE);
return 1;
}
void DFSPI1_DMARecceiveISR (void)
{
static signed portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if (xSemaphoreSPI1)
xSemaphoreGiveFromISR( xSemaphoreSPI1, &xHigherPriorityTaskWoken );
//vPortYieldFromISR( );
}
PS: FreeRtos