forked from Sepanta/pcie-driver
h-4nd-h
4 years ago
10 changed files with 355 additions and 0 deletions
@ -0,0 +1,12 @@ |
|||||
|
#ifndef BUFFER_H |
||||
|
#define BUFFER_H |
||||
|
|
||||
|
#include <stdint.h> |
||||
|
|
||||
|
struct Buffer_t |
||||
|
{ |
||||
|
uint32_t size; |
||||
|
void* ptr; |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,22 @@ |
|||||
|
#ifndef SONO_EXCEPTION_H |
||||
|
#define SONO_EXCEPTION_H |
||||
|
|
||||
|
#include <exception> |
||||
|
|
||||
|
class SonoException : public std::exception |
||||
|
{ |
||||
|
private: |
||||
|
std::string _message; |
||||
|
public: |
||||
|
explicit SonoException(const std::string& message) |
||||
|
{ |
||||
|
_message = message; |
||||
|
} |
||||
|
|
||||
|
const char* what() const noexcept override |
||||
|
{ |
||||
|
return _message.c_str(); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,106 @@ |
|||||
|
#include "SonoPcieDevice.h" |
||||
|
|
||||
|
#include <sys/mman.h> |
||||
|
#include <fcntl.h> |
||||
|
|
||||
|
SonoPcieDevice::SonoPcieDevice() |
||||
|
{ |
||||
|
bars[0].size = 32 MB; |
||||
|
bars[1].size = 16 MB; |
||||
|
bars[2].size = 16 KB; |
||||
|
|
||||
|
for(auto i = 0; i < TOTAL_DMA_BUFFER_NUM; i++) |
||||
|
{ |
||||
|
dmaBuffers[i].size = DMA_SIZE; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::init() |
||||
|
{ |
||||
|
initBars(); |
||||
|
|
||||
|
initDmaBuffers(); |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::initBars() |
||||
|
{ |
||||
|
int fd = open("/proc/sono_bars", O_RDWR | O_SYNC); |
||||
|
if(fd == -1) |
||||
|
{ |
||||
|
SonoException exp("Could not open bar proc file"); |
||||
|
throw exp; |
||||
|
} |
||||
|
|
||||
|
for(auto i = 0; i < TOTAL_BAR_NUM; i++) |
||||
|
{ |
||||
|
bars[i].ptr = mmap(0, bars[i].size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, i << 12); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::initDmaBuffers() |
||||
|
{ |
||||
|
int fd = open("/proc/sono_buffers", O_RDWR | O_SYNC); |
||||
|
if(fd == -1) |
||||
|
{ |
||||
|
SonoException exp("Could not open buffers proc file"); |
||||
|
throw exp; |
||||
|
} |
||||
|
|
||||
|
for(auto i = 0; i < TOTAL_DMA_BUFFER_NUM; i++) |
||||
|
{ |
||||
|
dmaBuffers[i].ptr = mmap(0, dmaBuffers[i].size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, i << 12); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::writeByte(uint32_t bar, uint8_t data, uint32_t offset) |
||||
|
{ |
||||
|
uint8_t* temp = (uint8_t*)bars[bar].ptr; |
||||
|
temp[offset] = data; |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::writeShort(uint32_t bar, uint16_t data, uint32_t offset) |
||||
|
{ |
||||
|
uint16_t* temp = (uint16_t*)bars[bar].ptr; |
||||
|
temp[offset / 2] = data; |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::writeWord(uint32_t bar, uint32_t data, uint32_t offset) |
||||
|
{ |
||||
|
uint32_t* temp = (uint32_t*)bars[bar].ptr; |
||||
|
temp[offset / 4] = data; |
||||
|
} |
||||
|
|
||||
|
void SonoPcieDevice::writeLong(uint32_t bar, uint64_t data, uint32_t offset) |
||||
|
{ |
||||
|
uint64_t* temp = (uint64_t*)bars[bar].ptr; |
||||
|
temp[offset / 8] = data; |
||||
|
} |
||||
|
|
||||
|
uint8_t SonoPcieDevice::readByte(uint32_t bar, uint32_t offset) |
||||
|
{ |
||||
|
uint8_t* temp = (uint8_t*)bars[bar].ptr; |
||||
|
return temp[offset]; |
||||
|
} |
||||
|
|
||||
|
uint16_t SonoPcieDevice::readShort(uint32_t bar, uint32_t offset) |
||||
|
{ |
||||
|
uint16_t* temp = (uint16_t*)bars[bar].ptr; |
||||
|
return temp[offset / 2]; |
||||
|
} |
||||
|
|
||||
|
uint32_t SonoPcieDevice::readWord(uint32_t bar, uint32_t offset) |
||||
|
{ |
||||
|
uint32_t* temp = (uint32_t*)bars[bar].ptr; |
||||
|
return temp[offset / 4]; |
||||
|
} |
||||
|
|
||||
|
uint64_t SonoPcieDevice::readLong(uint32_t bar, uint32_t offset) |
||||
|
{ |
||||
|
uint64_t* temp = (uint64_t*)bars[bar].ptr; |
||||
|
return temp[offset / 8]; |
||||
|
} |
||||
|
|
||||
|
uint8_t* SonoPcieDevice::getBufferPtr(uint32_t buffer) |
||||
|
{ |
||||
|
return (uint8_t*)dmaBuffers[buffer].ptr; |
||||
|
} |
@ -0,0 +1,42 @@ |
|||||
|
#ifndef SONOPCIEDEVICE_H |
||||
|
#define SONOPCIEDEVICE_H |
||||
|
|
||||
|
#include <iostream> |
||||
|
|
||||
|
#include "SonoException.h" |
||||
|
#include "Buffer.h" |
||||
|
|
||||
|
#define KB * 1024 |
||||
|
#define MB KB KB |
||||
|
#define TOTAL_BAR_NUM 3 |
||||
|
#define TOTAL_DMA_BUFFER_NUM 16 |
||||
|
#define DMA_SIZE 4 MB |
||||
|
|
||||
|
class SonoPcieDevice |
||||
|
{ |
||||
|
private: |
||||
|
Buffer_t bars[TOTAL_BAR_NUM]; |
||||
|
Buffer_t dmaBuffers[TOTAL_DMA_BUFFER_NUM]; |
||||
|
|
||||
|
void initBars(); |
||||
|
void initDmaBuffers(); |
||||
|
|
||||
|
public: |
||||
|
SonoPcieDevice(); |
||||
|
|
||||
|
void init(); |
||||
|
|
||||
|
void writeByte(uint32_t bar, uint8_t data, uint32_t offset); |
||||
|
void writeShort(uint32_t bar, uint16_t data, uint32_t offset); |
||||
|
void writeWord(uint32_t bar, uint32_t data, uint32_t offset); |
||||
|
void writeLong(uint32_t bar, uint64_t data, uint32_t offset); |
||||
|
|
||||
|
uint8_t readByte(uint32_t bar, uint32_t offset); |
||||
|
uint16_t readShort(uint32_t bar, uint32_t offset); |
||||
|
uint32_t readWord(uint32_t bar, uint32_t offset); |
||||
|
uint64_t readLong(uint32_t bar, uint32_t offset); |
||||
|
|
||||
|
uint8_t* getBufferPtr(uint32_t buffer); |
||||
|
}; |
||||
|
|
||||
|
#endif |
@ -0,0 +1,73 @@ |
|||||
|
# This file is used to ignore files which are generated |
||||
|
# ---------------------------------------------------------------------------- |
||||
|
|
||||
|
*~ |
||||
|
*.autosave |
||||
|
*.a |
||||
|
*.core |
||||
|
*.moc |
||||
|
*.o |
||||
|
*.obj |
||||
|
*.orig |
||||
|
*.rej |
||||
|
*.so |
||||
|
*.so.* |
||||
|
*_pch.h.cpp |
||||
|
*_resource.rc |
||||
|
*.qm |
||||
|
.#* |
||||
|
*.*# |
||||
|
core |
||||
|
!core/ |
||||
|
tags |
||||
|
.DS_Store |
||||
|
.directory |
||||
|
*.debug |
||||
|
Makefile* |
||||
|
*.prl |
||||
|
*.app |
||||
|
moc_*.cpp |
||||
|
ui_*.h |
||||
|
qrc_*.cpp |
||||
|
Thumbs.db |
||||
|
*.res |
||||
|
*.rc |
||||
|
/.qmake.cache |
||||
|
/.qmake.stash |
||||
|
|
||||
|
# qtcreator generated files |
||||
|
*.pro.user* |
||||
|
|
||||
|
# xemacs temporary files |
||||
|
*.flc |
||||
|
|
||||
|
# Vim temporary files |
||||
|
.*.swp |
||||
|
|
||||
|
# Visual Studio generated files |
||||
|
*.ib_pdb_index |
||||
|
*.idb |
||||
|
*.ilk |
||||
|
*.pdb |
||||
|
*.sln |
||||
|
*.suo |
||||
|
*.vcproj |
||||
|
*vcproj.*.*.user |
||||
|
*.ncb |
||||
|
*.sdf |
||||
|
*.opensdf |
||||
|
*.vcxproj |
||||
|
*vcxproj.* |
||||
|
|
||||
|
# MinGW generated files |
||||
|
*.Debug |
||||
|
*.Release |
||||
|
|
||||
|
# Python byte code |
||||
|
*.pyc |
||||
|
|
||||
|
# Binaries |
||||
|
# -------- |
||||
|
*.dll |
||||
|
*.exe |
||||
|
|
@ -0,0 +1,15 @@ |
|||||
|
#include "MainWindow.h" |
||||
|
#include "ui_MainWindow.h" |
||||
|
|
||||
|
MainWindow::MainWindow(QWidget *parent) |
||||
|
: QMainWindow(parent) |
||||
|
, ui(new Ui::MainWindow) |
||||
|
{ |
||||
|
ui->setupUi(this); |
||||
|
} |
||||
|
|
||||
|
MainWindow::~MainWindow() |
||||
|
{ |
||||
|
delete ui; |
||||
|
} |
||||
|
|
@ -0,0 +1,21 @@ |
|||||
|
#ifndef MAINWINDOW_H |
||||
|
#define MAINWINDOW_H |
||||
|
|
||||
|
#include <QMainWindow> |
||||
|
|
||||
|
QT_BEGIN_NAMESPACE |
||||
|
namespace Ui { class MainWindow; } |
||||
|
QT_END_NAMESPACE |
||||
|
|
||||
|
class MainWindow : public QMainWindow |
||||
|
{ |
||||
|
Q_OBJECT |
||||
|
|
||||
|
public: |
||||
|
MainWindow(QWidget *parent = nullptr); |
||||
|
~MainWindow(); |
||||
|
|
||||
|
private: |
||||
|
Ui::MainWindow *ui; |
||||
|
}; |
||||
|
#endif // MAINWINDOW_H
|
@ -0,0 +1,22 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<ui version="4.0"> |
||||
|
<class>MainWindow</class> |
||||
|
<widget class="QMainWindow" name="MainWindow"> |
||||
|
<property name="geometry"> |
||||
|
<rect> |
||||
|
<x>0</x> |
||||
|
<y>0</y> |
||||
|
<width>800</width> |
||||
|
<height>600</height> |
||||
|
</rect> |
||||
|
</property> |
||||
|
<property name="windowTitle"> |
||||
|
<string>MainWindow</string> |
||||
|
</property> |
||||
|
<widget class="QWidget" name="centralwidget"/> |
||||
|
<widget class="QMenuBar" name="menubar"/> |
||||
|
<widget class="QStatusBar" name="statusbar"/> |
||||
|
</widget> |
||||
|
<resources/> |
||||
|
<connections/> |
||||
|
</ui> |
@ -0,0 +1,31 @@ |
|||||
|
QT += core gui |
||||
|
|
||||
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets |
||||
|
|
||||
|
CONFIG += c++11 |
||||
|
|
||||
|
# The following define makes your compiler emit warnings if you use |
||||
|
# any Qt feature that has been marked deprecated (the exact warnings |
||||
|
# depend on your compiler). Please consult the documentation of the |
||||
|
# deprecated API in order to know how to port your code away from it. |
||||
|
DEFINES += QT_DEPRECATED_WARNINGS |
||||
|
|
||||
|
# You can also make your code fail to compile if it uses deprecated APIs. |
||||
|
# In order to do so, uncomment the following line. |
||||
|
# You can also select to disable deprecated APIs only up to a certain version of Qt. |
||||
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 |
||||
|
|
||||
|
SOURCES += \ |
||||
|
main.cpp \ |
||||
|
MainWindow.cpp |
||||
|
|
||||
|
HEADERS += \ |
||||
|
MainWindow.h |
||||
|
|
||||
|
FORMS += \ |
||||
|
MainWindow.ui |
||||
|
|
||||
|
# Default rules for deployment. |
||||
|
qnx: target.path = /tmp/$${TARGET}/bin |
||||
|
else: unix:!android: target.path = /opt/$${TARGET}/bin |
||||
|
!isEmpty(target.path): INSTALLS += target |
@ -0,0 +1,11 @@ |
|||||
|
#include "MainWindow.h" |
||||
|
|
||||
|
#include <QApplication> |
||||
|
|
||||
|
int main(int argc, char *argv[]) |
||||
|
{ |
||||
|
QApplication a(argc, argv); |
||||
|
MainWindow w; |
||||
|
w.show(); |
||||
|
return a.exec(); |
||||
|
} |
Loading…
Reference in new issue