ur5cuj 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Вам нужно DMA_Mode_Circular. DMA_Mode_Circular у меня работает, но это чисто для отладки Вч части, так как постоянно выдаётся таблица из флеши, а мне нужно готовить данные т.е. модулировать исходные данные процессором для подачи в ВЧ модулятор, где уже будет этот поток модулироваться несущей для излучения в антенну. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба DMA_Mode_Circular у меня работает, но это чисто для отладки Вч части, так как постоянно выдаётся таблица из флеши, а мне нужно готовить данные т.е. модулировать исходные данные процессором для подачи в ВЧ модулятор, где уже будет этот поток модулироваться несущей для излучения в антенну. Дык, сделайте обработчик прерываний HT и TC для этого DMA. Я делаю примерно так void DMA2_Stream7_IRQHandler(void) { if(DMA2->HISR & (1 << DMA_HISR_HTIF7)) { DMA2->HIFCR = (1 << DMA_HISR_HTIF7); dma_event = 1; } if(DMA2->HISR & (1 << DMA_HISR_TCIF7)) { DMA2->HIFCR = (1 << DMA_HISR_TCIF7); dma_event = 2; } } в idle if(dma_event == 1) { dma_event = 0; // заполняем первую половину кольца } if(dma_event == 2) { dma_event = 0; // заполняем вторую половину кольца } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Инит ДМА вот такой: void DMA_Config ( uint8_t * Memory0BaseAddr, uint16_t size ) { DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; // Сброс настроек DMA каналов DMA_DeInit ( SPI_DMA_MASTER_Tx_DMA_Stream ); RCC_AHB1PeriphClockCmd ( SPI_DMA_MASTER_DMA_CLK, ENABLE ); DMA_DeInit(SPIx_TX_DMA_STREAM); /* Configure DMA Initialization Structure */ DMA_InitStructure.DMA_BufferSize = size; DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; DMA_InitStructure.DMA_PeripheralBaseAddr =(uint32_t) (&(SPIx->DR)); DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStructure.DMA_Priority = DMA_Priority_High; /* Configure TX DMA */ DMA_InitStructure.DMA_Channel = SPIx_TX_DMA_CHANNEL; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStructure.DMA_Memory0BaseAddr =(uint32_t)Memory0BaseAddr; DMA_Init(SPIx_TX_DMA_STREAM, &DMA_InitStructure); // Configure the DMA interrupt priority NVIC_InitStructure.NVIC_IRQChannel = DMAx_Streamx_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = (uint8_t)(configKERNEL_INTERRUPT_PRIORITY >> 4); NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init ( &NVIC_InitStructure ); SPI_I2S_ITConfig ( SPIx, SPI_I2S_IT_TXE, ENABLE ); DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1[0], DMA_Memory_0); //первый массив для выдачи DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer2TX_SPI1[0], DMA_Memory_1); //второй массив для выдачи DMA_DoubleBufferModeCmd ( DMA2_Stream5, ENABLE ); SPI_I2S_DMACmd ( SPI_DMA_MASTER, SPI_I2S_DMAReq_Tx, ENABLE ); DMA_ITConfig ( SPI_DMA_MASTER_Tx_DMA_Stream, DMA_IT_TC, ENABLE ); } обработчик прерывания: void DMA2_Stream5_IRQHandler ( void ) { portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE; // Stream3 transfer complete interrupt? if(DMA_GetITStatus (SPIx_TX_DMA_STREAM,SPI_DMA_MASTER_Tx_DMA_IT)) { // clear pending interrupt DMA_ClearITPendingBit (SPIx_TX_DMA_STREAM,SPI_DMA_MASTER_Tx_DMA_IT); if(DMA_GetCurrentMemoryTarget (SPIx_TX_DMA_STREAM)) { // Memory 1 is current target DMA_MemoryTargetConfig (SPIx_TX_DMA_STREAM,Buffer2TX_SPI1[0],DMA_Memory_0); } else { // Memory 0 is current target DMA_MemoryTargetConfig(SPIx_TX_DMA_STREAM,Buffer1TX_SPI1[0],DMA_Memory_1); } } xSemaphoreGiveFromISR ( xSemaphore_spi1, &xHigherPriorityTaskWoken ); xTaskResumeFromISR (&xHandleSPI1); portEND_SWITCHING_ISR ( xHigherPriorityTaskWoken ); } ну а запускается всё вот так: ukladkabufTXSPI1 ( Buffer1TX_SPI1 );//заполнение первого массива инфой ukladkabufTXSPI1 ( Buffer2TX_SPI1 );//заполнение второго массива инфой DMA_Cmd ( SPI_DMA_MASTER_Tx_DMA_Stream, ENABLE ); и всё это Не работает, ЧЯДНТ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Hold 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Как минимум, в функцию DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1[0], DMA_Memory_0); необходимо давать адрес буфера, а него его первое значение. Функция то всё съест, на входе просто uint32_t. Улетает небось в hardFault, т.е. лезете в непонятную область данных. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Как минимум, в функцию DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1[0], DMA_Memory_0); необходимо давать адрес буфера, а него его первое значение. Функция то всё съест, на входе просто uint32_t. Улетает небось в hardFault, т.е. лезете в непонятную область данных. если прописать: DMA_DoubleBufferModeConfig(DMA2_Stream5, &Buffer1TX_SPI1, DMA_Memory_0); вываливает варнинг: warning: passing argument 2 of 'DMA_DoubleBufferModeConfig' makes integer from pointer without a cast [-Wint-conversion] Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба вываливает варнинг:Посылайте луч поноса авторам этой "библиотеки", которые передают указатель в виде целого (и даже не специально предназначенного для этого типа uintptr_t) и добавляйте явное приведение типа. Кстати, взятие адреса тут не требуется - имя массива автоматически преобразовывается к указателю на его нулевой элемент: DMA_DoubleBufferModeConfig(DMA2_Stream5, (uintptr_t)Buffer1TX_SPI1, DMA_Memory_0); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 (изменено) · Жалоба даже если прописать: DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1, DMA_Memory_0); что собственно не является ошибкой, получается такой же варнинг: warning: passing argument 2 of 'DMA_DoubleBufferModeConfig' makes integer from pointer without a cast [-Wint-conversion] так что только так передавать: Buffer1TX_SPI1[0] Изменено 5 сентября, 2017 пользователем Volldemar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Когда возился со SPI на F407 обратил внимание, что между посылками присутствуют паузы и ПДП тут никак не помогает. Паузы были даже на низкой скорости. Если Вы про паузы между словами, то их никак не убрать - в STM насколько помню нет такой возможности. Полклока каждые 8 или 16 бит. Они вставляются аппаратно контроллером SPI. Например в XMC4700 их можно убрать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 134 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба даже если прописать: DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1, DMA_Memory_0); что собственно не является ошибкой, получается такой же варнинг: warning: passing argument 2 of 'DMA_DoubleBufferModeConfig' makes integer from pointer without a cast [-Wint-conversion] Во-первых - да, формально это не является ошибкой, поэтому вы получаете не error, а только лишь warning. А теперь найдите 10 отличий: DMA_DoubleBufferModeConfig(DMA2_Stream5, (uintptr_t)Buffer1TX_SPI1, DMA_Memory_0); так что только так передавать: Buffer1TX_SPI1[0] Если вам все равно, что передавать - то да, можно и так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба Сергей Борщ - спасибо, внял вашему совету!!! (uintptr_t)Buffer1TX_SPI1 - полечило варнинг :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksandr Baranov 1 5 сентября, 2017 Опубликовано 5 сентября, 2017 · Жалоба так что только так передавать: Buffer1TX_SPI1[0] Buffer1TX_SPI1[0] - это не указатель. Его нельзя передавать. Можно так, например: &Buffer1TX_SPI1[0] или так Buffer1TX_SPI1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 6 сентября, 2017 Опубликовано 6 сентября, 2017 (изменено) · Жалоба Buffer1TX_SPI1[0] - это не указатель. Его нельзя передавать. Можно так, например: &Buffer1TX_SPI1[0] или так Buffer1TX_SPI1 Вопрос о правильной передаче параметра - решен! Изменено 6 сентября, 2017 пользователем Volldemar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ur5cuj 0 6 сентября, 2017 Опубликовано 6 сентября, 2017 · Жалоба Вроде зашевелилось!!! Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Aleksandr Baranov 1 6 сентября, 2017 Опубликовано 6 сентября, 2017 · Жалоба Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными? "Half transfer interrupt" никак не поможет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 235 7 сентября, 2017 Опубликовано 7 сентября, 2017 · Жалоба Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными? Если вопрос именно о непрерывной передаче, то когда "мнфа из одного из массивов уже ушла полностью", готовить 2-ой уже поздно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться