Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <exception>
- #include <sys/stat.h> //system open() implementation
- #include <fcntl.h> //flags for open()
- #include <sys/mman.h> //system mmap() implementation
- #include <unistd.h> //POSIX standard calls
- #include "util.h"
- #include "conversion.h"
- #include "libaxidma.h"
- class DMATransfer {
- private:
- int rxChannel, memfd, fLength, rLength, rWidth;
- volatile uint* fifoBufferUsed;
- uint* outputBuffer;
- bool bufferAllocated = false;
- bool devMemOpen = false;
- axidma_dev_t axidmaDevice;
- void deallocate_buffer();
- void allocate_buffer();
- void get_rx_channel();
- void map_fifo_address(uint fifoAddress);
- void init_device();
- public:
- DMATransfer(uint fifoLength, uint readLength, uint readWidth, uint fifoAddress);
- uint* perform_transfer();
- void destroy();
- };
- /**********************
- *** PRIVATE METHODS ***
- **********************/
- void DMATransfer::deallocate_buffer(){
- if(bufferAllocated) {
- axidma_free(axidmaDevice, outputBuffer, (rLength*rWidth));
- }
- }
- void DMATransfer::allocate_buffer(){
- deallocate_buffer();
- outputBuffer = (uint*) axidma_malloc(axidmaDevice, (rLength*rWidth));
- if(outputBuffer = NULL){
- throw "Failed to allocate DMA buffer";
- }
- }
- void DMATransfer::get_rx_channel(){
- const array_t *rxChannels;
- //List the available RX channels and default to the first
- rxChannels = axidma_get_dma_rx(axidmaDevice);
- if(rxChannels->len < 1){
- destroy();
- throw "No DMA Rx channels";
- }
- rxChannel = rxChannels->data[0];
- }
- void DMATransfer::map_fifo_address(uint fifoAddress){
- memfd = open("/dev/mem", O_RDWR|O_SYNC);
- if(memfd < 0){
- throw "Unable to open /dev/mem; require superuser privileges";
- }
- devMemOpen = true;
- fifoBufferUsed = (uint*) mmap(0, 4096UL, PROT_READ | PROT_WRITE, MAP_SHARED, memfd, fifoAddress);
- }
- void DMATransfer::init_device(){
- axidmaDevice = axidma_init();
- if(axidmaDevice == NULL){
- throw "DMA init error";
- }
- }
- /*********************
- *** PUBLIC METHODS ***
- *********************/
- DMATransfer::DMATransfer(uint fifoLength, uint readLength, uint readWidth, uint fifoAddress){
- fLength = fifoLength;
- rLength = readLength;
- rWidth = readWidth;
- init_device();
- get_rx_channel();
- allocate_buffer();
- }
- uint* DMATransfer::perform_transfer(){
- int retVal = 0;
- int fLen0 = 0;
- int fLen1 = 0;
- //Check for buffer overrun
- if(*fifoBufferUsed >= fLength){
- printf("FIFO buffer overrun\n");
- }
- //Perform the transfer
- fLen0 = *fifoBufferUsed;
- retVal = axidma_oneway_transfer(axidmaDevice, rxChannel, outputBuffer, (rLength*rWidth), true);
- fLen1 = *fifoBufferUsed;
- if(retVal < 0){
- throw "DMA Transaction failed";
- }
- printf("DMA: %u / %u\n", fLen0, fLen1);
- return outputBuffer;
- }
- void DMATransfer::destroy(){
- axidma_destroy(axidmaDevice);
- deallocate_buffer();
- if(devMemOpen){
- close(memfd);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement