Advertisement
Guest User

Untitled

a guest
Apr 19th, 2018
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.87 KB | None | 0 0
  1. #include <iostream>
  2. #include <exception>
  3.  
  4. #include <sys/stat.h>   //system open() implementation
  5. #include <fcntl.h>      //flags for open()
  6. #include <sys/mman.h>   //system mmap() implementation
  7. #include <unistd.h>     //POSIX standard calls
  8.  
  9. #include "util.h"
  10. #include "conversion.h"
  11. #include "libaxidma.h"
  12.  
  13. class DMATransfer {
  14.  
  15.     private:
  16.         int rxChannel, memfd, fLength, rLength, rWidth;
  17.         volatile uint* fifoBufferUsed;
  18.         uint* outputBuffer;
  19.         bool bufferAllocated = false;
  20.         bool devMemOpen = false;
  21.         axidma_dev_t axidmaDevice;
  22.        
  23.         void deallocate_buffer();
  24.         void allocate_buffer();
  25.         void get_rx_channel();
  26.         void map_fifo_address(uint fifoAddress);
  27.         void init_device();
  28.  
  29.     public:
  30.         DMATransfer(uint fifoLength, uint readLength, uint readWidth, uint fifoAddress);
  31.         uint* perform_transfer();
  32.         void destroy();
  33. };
  34.  
  35.  
  36. /**********************
  37. *** PRIVATE METHODS ***
  38. **********************/
  39. void DMATransfer::deallocate_buffer(){
  40.     if(bufferAllocated) {
  41.         axidma_free(axidmaDevice, outputBuffer, (rLength*rWidth));
  42.     }
  43. }
  44.  
  45. void DMATransfer::allocate_buffer(){
  46.     deallocate_buffer();
  47.     outputBuffer = (uint*) axidma_malloc(axidmaDevice, (rLength*rWidth));
  48.     if(outputBuffer = NULL){
  49.         throw "Failed to allocate DMA buffer";
  50.     }
  51. }
  52.  
  53. void DMATransfer::get_rx_channel(){
  54.     const array_t *rxChannels;
  55.  
  56.     //List the available RX channels and default to the first
  57.     rxChannels = axidma_get_dma_rx(axidmaDevice);
  58.     if(rxChannels->len < 1){
  59.         destroy();
  60.         throw "No DMA Rx channels";
  61.     }
  62.     rxChannel = rxChannels->data[0];
  63. }
  64.  
  65. void DMATransfer::map_fifo_address(uint fifoAddress){
  66.     memfd = open("/dev/mem", O_RDWR|O_SYNC);
  67.     if(memfd < 0){
  68.         throw "Unable to open /dev/mem; require superuser privileges";
  69.     }
  70.     devMemOpen = true;
  71.     fifoBufferUsed = (uint*) mmap(0, 4096UL, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, fifoAddress);
  72. }
  73.  
  74. void DMATransfer::init_device(){
  75.     axidmaDevice = axidma_init();
  76.     if(axidmaDevice == NULL){
  77.         throw "DMA init error";
  78.     }
  79. }
  80.  
  81. /*********************
  82. *** PUBLIC METHODS ***
  83. *********************/
  84.  
  85. DMATransfer::DMATransfer(uint fifoLength, uint readLength, uint readWidth, uint fifoAddress){
  86.     fLength = fifoLength;
  87.     rLength = readLength;
  88.     rWidth = readWidth;
  89.  
  90.     init_device();
  91.     get_rx_channel();
  92.     allocate_buffer();
  93.  
  94. }
  95.  
  96. uint* DMATransfer::perform_transfer(){
  97.     int retVal = 0;
  98.     int fLen0 = 0;
  99.     int fLen1 = 0;
  100.  
  101.     //Check for buffer overrun
  102.     if(*fifoBufferUsed >= fLength){
  103.         printf("FIFO buffer overrun\n");
  104.     }
  105.  
  106.     //Perform the transfer
  107.     fLen0 = *fifoBufferUsed;
  108.     retVal = axidma_oneway_transfer(axidmaDevice, rxChannel, outputBuffer, (rLength*rWidth), true);
  109.     fLen1 = *fifoBufferUsed;
  110.     if(retVal < 0){
  111.         throw "DMA Transaction failed";
  112.     }
  113.     printf("DMA: %u / %u\n", fLen0, fLen1);
  114.  
  115.     return outputBuffer;
  116. }
  117.  
  118. void DMATransfer::destroy(){
  119.     axidma_destroy(axidmaDevice);
  120.     deallocate_buffer();
  121.     if(devMemOpen){
  122.         close(memfd);
  123.     }
  124. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement