Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 07:09:02

ПростоНуб писал(а):доступа к памяти
К какой памяти ?
У меня ДМА читает по FMC из SDRAM и кидает по FSMC в дисплей. Где тут оперативка нарисовалась ? :)))

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 07:32:48

ПростоНуб писал(а):доступа к памяти
К какой памяти ?
У меня ДМА читает по FMC из SDRAM и кидает по FSMC в дисплей. Где тут оперативка нарисовалась ? :)))

А где-то указано, что bus matrix может пропускать одновременно несколько потоков?
The bus matrix implements round-robin scheduling, thus ensuring at least half of the system bus bandwidth (both to memory and peripheral) for the CPU.

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 07:50:19

Откуда я знаю, где и что указано :) Я вижу то, что я вижу. А вижу я костыльную работу DMA.
Иначе, для чего он вообще нужен, если не умеет нормально отрабатывать что обязан ?
Тут ему освободи, там дай дорогу, ... :facepalm:

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 10:05:20

Да.

Попробуй Burst для SDRAM включить, хотя можно попробовать включить его и для DMA, на 4 непрерывные передачи, т.к. FIFO чтения у SDRAM 6x32-бит. И еще, не знаю как там у тебя сделано, но на F4 DMA может читать по 32 бита и два раза писать по 16, это должно меньше загружать шину.

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 10:14:03

Burst для SDRAM включен. FIFO пробовал подрубать - без изменений.

Добавлено after 1 minute 25 seconds:
Reflector писал(а):на F4 DMA может читать по 32 бита и два раза писать по 16, это должно меньше загружать шину.
Хм.. Интересно...
Дома буду - поколупаю на эту тему.

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 10:21:38

Burst для SDRAM включен. FIFO пробовал подрубать - без изменений.

Для самого DMA Burst включал?

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 10:31:55

Сейчас трудно сказать, что я включал, а что нет. Доберусь до дома, гляну код - может вспомню.
Помню что-то с FIFO было.

Re: На какой частоте работает DMA? STM32

Сб мар 02, 2019 21:58:10

Такс... Добрался я до компа, наконец то.
Выкладываю код напоказ :)
DMA:
Спойлер
Код:

static DMA_InitTypeDef          dma;
static __IO    int32_t        dma_cnt;
static __IO      uint8_t         * p_dist;
static __IO      uint8_t         * p_sourse;
static __IO    uint8_t       inc_dist=0;
static __IO    uint8_t       inc_sourse=0;

/*********************************************************************************/
void dma_m2m_init(){
   //----------
   RCC->AHB1ENR |= RCC_AHB1Periph_DMA2;
   //----------
   dma.DMA_Channel = DMA_Channel_0;
   //    dma.DMA_PeripheralBaseAddr = (uint32_t)lcd_buf;
//   dma.DMA_Memory0BaseAddr = (uint32_t)FMC_DATA_ADDRR;
   dma.DMA_DIR = DMA_DIR_MemoryToMemory;
   //    dma.DMA_BufferSize = (size);
   dma.DMA_PeripheralInc = DMA_PeripheralInc_Enable;
   dma.DMA_MemoryInc = DMA_MemoryInc_Disable;
   dma.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord;
   dma.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
   dma.DMA_Mode = DMA_Mode_Normal;
   dma.DMA_Priority = DMA_Priority_VeryHigh;      // DMA_Priority_Low;
   dma.DMA_FIFOMode = DMA_FIFOMode_Enable;         // DMA_FIFOMode_Disable;
   dma.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;   // DMA_FIFOThreshold_1QuarterFull;
   dma.DMA_MemoryBurst = DMA_MemoryBurst_Single;
   dma.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
   DMA_Init(DMA2_Stream0, &dma);
   NVIC_EnableIRQ(DMA2_Stream0_IRQn);
   DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
}
/*********************************************************************************/

/*********************************************************************************/
void DMA2_Stream0_IRQHandler(void){
if (DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0) == SET){
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
    DMA_Out();
}
}
/*********************************************************************************/


/*********************************************************************************/
static void DMA_Out(){
static uint32_t       dma_size_out=0;

    if(dma_cnt<=0){
         DMA_End();
         return;
    }
    if(dma_cnt<=50000)          dma_size_out = dma_cnt;
    else                        dma_size_out = 50000;
    dma_cnt -= dma_size_out;
    //----------
    DMA2_Stream0->M0AR =(__IO uint32_t)p_sourse ;
    DMA2_Stream0->PAR =(__IO uint32_t)p_dist ;
    DMA2_Stream0->NDTR = dma_size_out;
    DMA2_Stream0->CR |= DMA_SxCR_EN;
    if(inc_dist)   p_dist+=dma_size_out;
    if(inc_sourse)   p_sourse+=dma_size_out;
}
/*********************************************************************************/

/*********************************************************************************/
void dma_m2m_send(void *dist, uint8_t dist_inc, void *sourse, uint8_t sourse_inc, uint32_t size){
   p_dist = (uint8_t*)dist;
   p_sourse = (uint8_t*)sourse;
   dma_cnt = size;
   inc_dist = dist_inc;
   if(dist_inc)         DMA2_Stream0->CR |= DMA_SxCR_PINC;
   else               DMA2_Stream0->CR &= ~DMA_SxCR_PINC;
   inc_sourse = sourse_inc;
   if(sourse_inc)         DMA2_Stream0->CR |= DMA_SxCR_MINC;
   else               DMA2_Stream0->CR &= ~DMA_SxCR_MINC;
    DMA_Out();
}
/*********************************************************************************/



Инит SDRAM :
Спойлер
Код:
void SDRAM_Init(void)
{
  FMC_SDRAMInitTypeDef  FMC_SDRAMInitStructure;
  FMC_SDRAMTimingInitTypeDef  FMC_SDRAMTimingInitStructure;
 
  /* GPIO configuration for FMC SDRAM bank */
  SDRAM_GPIOConfig();
 
  /* Enable FMC clock */
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
 
/* FMC Configuration ----------*/
/* FMC SDRAM Bank configuration */   
  /* Timing configuration for 90 Mhz of SD clock frequency (180Mhz/2) */
  /* TMRD: 2 Clock cycles */
  FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay    = 2;   //2;
  /* TXSR: min=70ns (7x11.11ns) */
  FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;   //7;
  /* TRAS: min=42ns (4x11.11ns) max=120k (ns) */
  FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime      = 4;
  /* TRC:  min=70 (7x11.11ns) */       
  FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay        = 7;        // 7;
  /* TWR:  min=1+ 7ns (1+1x11.11ns) */
  FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime    = 2;        // 2;
  /* TRP:  20ns => 2x11.11ns */
  FMC_SDRAMTimingInitStructure.FMC_RPDelay              = 2;        // 2;
  /* TRCD: 20ns => 2x11.11ns */
  FMC_SDRAMTimingInitStructure.FMC_RCDDelay             = 2;        // 2;

/* FMC SDRAM control configuration */
  FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM;
  /* Row addressing: [7:0] */
  FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_8b;
  /* Column addressing: [11:0] */
  FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_12b;
  FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = SDRAM_MEMORY_WIDTH;
  FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;
  FMC_SDRAMInitStructure.FMC_CASLatency = SDRAM_CAS_LATENCY;
  FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;
  FMC_SDRAMInitStructure.FMC_SDClockPeriod = SDCLOCK_PERIOD; 
  FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Enable;
  FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_0;
  FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
 
  /* FMC SDRAM bank initialization */
  FMC_SDRAMInit(&FMC_SDRAMInitStructure);
 
  /* FMC SDRAM device initialization sequence */
  SDRAM_InitSequence();
 
}


Кусок основного кода :
Спойлер
Код:
static uint16_t   SDRAM   buf_sdram[384000];

/*********************************************************************************/
void Main_Task(void *pvParameters) {
    OS_Delay(100 Ms);

    LCD_SetArea(0,0,799,479);

    uint16_t rgb = RGB565CONVERT(200, 100, 100);

    while(1){
        OS_Delay(100 Ms);
        //----------
        GPIO_SetBits(GPIOG, GPIO_Pin_14);
        //----------
        //dma_m2m_send(rgb, 0, buf_sdram, 1, 384000*2);
        //wait_dma();
        for(uint32_t i=0; i<384000;i++)      buf_sdram[i]=rgb;
        //----------
        GPIO_ResetBits(GPIOG, GPIO_Pin_14);
        //----------
        GPIO_SetBits(GPIOG, GPIO_Pin_13);
        //----------
        LCD_MemStart();
        //dma_m2m_send(buf_sdram, 1, (void*)0x60020000, 0, sizeof(buf_sdram));
        //wait_dma();
        for(uint32_t i=0; i<384000;i++)   *(uint16_t*)0x60020000 = buf_sdram[i];
        //----------
        GPIO_ResetBits(GPIOG, GPIO_Pin_13);


    }
}
/*********************************************************************************/


Вот, как то так... :roll:

Добавлено after 1 hour 12 minutes 54 seconds:

Вот такие настройки
Код:
   dma.DMA_MemoryBurst = DMA_MemoryBurst_INC8;      //DMA_MemoryBurst_Single ;
   dma.DMA_PeripheralBurst = DMA_PeripheralBurst_INC8;      // DMA_PeripheralBurst_Single;
сделали время обновления = 18 мс. Это потрясающий результат :shock:

Reflector, спасибо большое за наводки. Вы спасли мою надежду :beer:

Re: На какой частоте работает DMA? STM32

Пн мар 04, 2019 12:53:47

Продолжаю эксперименты.
Подрубил DMA2D, сделал вывод в экран через него. На удивление, он это делает ещё быстрее, порядка 12 ms. Не знаю ка кон это делает, но сдаётся мне периферия уже на пределе.
Это получается ~30 ns на одну итерацию (чтение слова с SDRAM + запись его в дисплей).
Останусь, пожалуй, на этом варианте. Это избавит меня от дополнительного буфера, т.к. он уже имеется в SSD1963, и смысла создавать ещё один нет. Буду рисовать прямиком в него. Тем более, DMA2D имеет ещё бонусом всякие плюшки, типа смешивание цветов с прозрачностью, заливка областей, аппаратное преобразование из ARGB8888 в RGB565, и т.д...
Ответить