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

Стандартный Altera Dma Controller не производит 2ю транзакцию

Здравствуйте, уважаемые форумчане

 

Использовал стандартный DMA Controller, именно стандартный(https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_embedded_ip.pdf, пункт 29), а не msgdma... 

с одной стороны он связан с флэш памятью Max10, с другой OnChipMemory - служит для передачи данных из памяти во флэш и наоборот

я написал модуль на verilog, который конфигурирует DMA Controller и запускает транзакцию пересылки данных через DMA

 

image.thumb.png.f038de87fe65f264344b8b6e42725f7e.png

 

модуль MCU реализует инструкции, которые заданы в массиве значений, и выдает их на шину Avalon через avm_master

 

typedef struct packed {
  t_operation  operation;
  logic [31:0] address;
  logic [7:0]  register;
  logic [31:0] data;
} t_op_array;

t_op_array init_array[21];
t_op_array work_array[25];

 // Write from Flash to Memory                                                                                                             
  init_array[7]=  { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_RD_ADDRESS[7:0],   FLASH_DATA_AMM_ADDRESS[31:0] };                   // write Read address
  init_array[8]=  { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_WR_ADDRESS[7:0],   MEMORY_AMM_ADDRESS[31:0]};                        // write Write address 
  init_array[9]=  { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_LENGTH[7:0],       MEM_FLASH_SIZE[31:0] };                           // write Lenght
  init_array[10]= { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_CONTROL[7:0],      INTEL_DMA_CTRL_SET_LEEN_WORD_GO_IEN[31:0] };      // write control register (start DMA)
  init_array[11]= { OP_READ,  DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_STATUS[7:0],       32'h00};                                          // read status register (wait DMA Done)
   // Set Address and Lenght to Write from Memory to Flash                                                                                  
  init_array[12]= { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_RD_ADDRESS[7:0],   MEMORY_AMM_ADDRESS[31:0] };                       // write Read address
  init_array[13]= { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_WR_ADDRESS[7:0],   FLASH_DATA_AMM_ADDRESS[31:0]};                    // write Write address 
  init_array[14]= { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],     INTEL_DMA_LENGTH[7:0],       MEM_FLASH_SIZE[31:0] };                           // write Lenght
       
  
   // MEM_FLASH                                                                                                                
  work_array[10]= { OP_READ,  DMA_CSR_AMM_ADDRESS[31:0],       INTEL_DMA_STATUS[7:0],     32'h00};                                          // read status register (wait DMA Done)
  work_array[11]= { OP_WRITE, FLASH_CSR_AMM_ADDRESS[31:0],     MAX_FLASH_CONTROL[7:0],    MAX_FLASH_CTRL_SET_SE_CLR_WP_SECTOR_ID1[31:0] };  // enable write to Sector ID1 and erase Sector ID1
  work_array[12]= { OP_READ,  FLASH_CSR_AMM_ADDRESS[31:0],     MAX_FLASH_STATUS[7:0],     32'h00};                                          // read status register (wait erase Sector ID1)
  work_array[13]= { OP_WRITE, DMA_CSR_AMM_ADDRESS[31:0],       INTEL_DMA_CONTROL[7:0],    INTEL_DMA_CTRL_SET_LEEN_WORD_GO_IEN[31:0] };      // write control register (start DMA)             
                   

 

при старте пробегаюсь по массиву инициализации(init_array), как видно из него, я записываю адреса чтения, записи и длину пакета, равную 128, и стартую DMA транзакцию на 128 слов, причем у меня поставлена галочка Burst режим

При инициализации данные передаются из FLASH -> MEMORY, и транзакция проходит успешно

 

image.png.c59749a9f588af051d09f10237d2ca5e.png

 

INTEL_DMA_CTRL_SET_LEEN_WORD_GO_IEN  = INTEL_DMA_CTRL_WORD_MSK | INTEL_DMA_CTRL_GO_MSK | INTEL_DMA_CTRL_I_EN_MSK | INTEL_DMA_CTRL_LEEN_MSK = 0х9С

жду окончания транзакции DMA и записываю рабочие адреса записи и чтения, а также длину

затем в рабочем цикле(массив work_array) я запускаю DMA транзакцию, проверяя перед этим, что предыдущая транзакция по DMA завершена, когда выставлен контрольный бит в моем контрольном регистре, но DMA не запускается

 

В итоге получается:

1. при инициализации(массив init_array) DMA  отрабатывает нормально(правда 1 раз)

2. в рабочем цикле при запуске DMA, я не вижу по сигналтабу, что транзакция DMA стартует вообще, хотя все значения адресов, длины и контрольный регистр записаны

 

т.к. я адреса записи и чтения, а также длину выставил заранее, а потом только запускал DMA, надо ли их каждый раз перезаписывать, либо может стирать или записывать какие-то другие надо регистры, чтобы запустить DMA повторно???

 

спасибо, жду вашего ответа

 

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

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


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

Решил проблему очисткой статусных регистров и контрольных(записью в низ 0х0), а так же перезаписью на каждую транзакцию длины, адресов чтения и записи, ну и записи в контрольный регистр 

INTEL_DMA_CTRL_SET_LEEN_WORD_GO_IEN  = INTEL_DMA_CTRL_WORD_MSK | INTEL_DMA_CTRL_GO_MSK | INTEL_DMA_CTRL_I_EN_MSK | INTEL_DMA_CTRL_LEEN_MSK = 0х9С

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


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

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

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

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

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

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

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

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

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

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