Jump to content

    
Sign in to follow this  
xxxmatrixxx

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

Recommended Posts

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

 

Использовал стандартный 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 повторно???

 

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

 

Edited by xxxmatrixxx

Share this post


Link to post
Share on other sites

Решил проблему очисткой статусных регистров и контрольных(записью в низ 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С

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this