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

Вам нужно DMA_Mode_Circular.

DMA_Mode_Circular у меня работает, но это чисто для отладки Вч части, так как постоянно выдаётся таблица из флеши, а мне нужно готовить данные т.е. модулировать исходные данные процессором для подачи в ВЧ модулятор, где уже будет этот поток модулироваться несущей для излучения в антенну.

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


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

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;
  // заполняем вторую половину кольца
}

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


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

Инит ДМА вот такой:

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 );

и всё это Не работает, ЧЯДНТ?

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


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

Как минимум, в функцию DMA_DoubleBufferModeConfig(DMA2_Stream5, Buffer1TX_SPI1[0], DMA_Memory_0); необходимо давать адрес буфера, а него его первое значение. Функция то всё съест, на входе просто uint32_t. Улетает небось в hardFault, т.е. лезете в непонятную область данных.

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


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

Как минимум, в функцию 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]

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


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

вываливает варнинг:
Посылайте луч поноса авторам этой "библиотеки", которые передают указатель в виде целого (и даже не специально предназначенного для этого типа uintptr_t) и добавляйте явное приведение типа. Кстати, взятие адреса тут не требуется - имя массива автоматически преобразовывается к указателю на его нулевой элемент:

DMA_DoubleBufferModeConfig(DMA2_Stream5, (uintptr_t)Buffer1TX_SPI1, DMA_Memory_0);

 

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


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

даже если прописать:

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]

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

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


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

Когда возился со SPI на F407 обратил внимание, что между посылками присутствуют паузы и ПДП тут никак не помогает. Паузы были даже на низкой скорости.

Если Вы про паузы между словами, то их никак не убрать - в STM насколько помню нет такой возможности. Полклока каждые 8 или 16 бит.

Они вставляются аппаратно контроллером SPI.

Например в XMC4700 их можно убрать.

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


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

даже если прописать:

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]

Если вам все равно, что передавать - то да, можно и так.

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


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

Сергей Борщ - спасибо, внял вашему совету!!!

(uintptr_t)Buffer1TX_SPI1 - полечило варнинг :)

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


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

так что только так передавать: Buffer1TX_SPI1[0]

 

Buffer1TX_SPI1[0] - это не указатель. Его нельзя передавать. Можно так, например: &Buffer1TX_SPI1[0] или так Buffer1TX_SPI1

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


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

Buffer1TX_SPI1[0] - это не указатель. Его нельзя передавать. Можно так, например: &Buffer1TX_SPI1[0] или так Buffer1TX_SPI1

Вопрос о правильной передаче параметра - решен!

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

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


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

Вроде зашевелилось!!!

Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными?

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


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

Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными?

"Half transfer interrupt" никак не поможет?

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


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

Появилась выдача в SPI, но тут подкралось НО! как теперь определять, что мнфа из одного из массивов уже ушла полностью и пора готовить второй массив с данными?

Если вопрос именно о непрерывной передаче, то когда "мнфа из одного из массивов уже ушла полностью", готовить 2-ой уже поздно.

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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