M5: Software halb fertig
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <thread>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include "gip.h"
|
||||
|
||||
// UIO & pointers
|
||||
int fdMmvs = open("/dev/uio0", O_RDWR);
|
||||
int fdMem = open("/dev/uio16", O_RDWR);
|
||||
static PGIP_AXI_2D_MM2VS mmvs = (PGIP_AXI_2D_MM2VS)mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fdMmvs, 0);
|
||||
|
||||
// Funktion zum fuellen des Buffers mit einer
|
||||
void fillBuffer(int16_t* pBuffer, size_t bufferSize);
|
||||
|
||||
// Hinweis zu "__attribute__((unused))"
|
||||
// Hiermit wird dem Compiler mitgeteilt, dass eine Variable oder eine Funktion eventuell nicht verwendet wird
|
||||
// Damit wird keine "Unused-Warnung" für diese Variable oder Funktion ausgegeben
|
||||
// Die hier mit diesem Attribut gekennzeichneten Variablen werden in der aktuellen Version des Codes nicht verwendet
|
||||
// Wenn der Milestone abgeschlossen ist, werden sie dagegen sehr wohl Verwendung finden
|
||||
|
||||
__attribute__((unused)) static uint8_t* pMem = (uint8_t*)mmap(NULL, 0x20000000, PROT_READ | PROT_WRITE, MAP_SHARED, fdMem, 0);
|
||||
|
||||
void MM2VS_Handler()
|
||||
{
|
||||
__attribute__((unused)) uint32_t uio16PhysBase = 0x30000000; // UIO16 physical Baseaddress
|
||||
uint32_t bufferStart = 0x38000000; // Start of Audiobuffers
|
||||
uint32_t bufferStartOffset = bufferStart - uio16PhysBase;
|
||||
uint32_t bufferChunkSize = 1024;
|
||||
uint32_t bufferNumChunks = 188;
|
||||
__attribute__((unused)) int16_t* pBuffer;
|
||||
|
||||
// MM2VS Initialization
|
||||
mmvs->VS2MM_Control &= ~1; // VS2MM: Run-Bit loeschen
|
||||
mmvs->MM2VS_Control &= ~1; // MM2VS: Run-Bit loeschen
|
||||
usleep(500000); // 500 ms warten. Falls das MMVS-IP noch aktiv war, kann es so noch ausstehende Speicherzugriffe beenden
|
||||
mmvs->MM2VS_HorizontalBytes = bufferChunkSize;
|
||||
mmvs->MM2VS_Stride = bufferChunkSize;
|
||||
mmvs->MM2VS_StartAddress = bufferStart;
|
||||
mmvs->MM2VS_VerticalLines = bufferNumChunks;
|
||||
mmvs->MM2VS_InterruptLine = bufferNumChunks - 1;
|
||||
mmvs->InterruptEnable = 0; // IP-INT-Enable zuruecksetzen
|
||||
mmvs->InterruptStatus = 0; // IP-INT-Status zuruecksetzen
|
||||
|
||||
// gesamten Pufferspeicher mit Daten fuellen
|
||||
//fillBuffer((int16_t *) ((uint32_t) pMem + bufferStartOffset), (size_t) bufferChunkSize*bufferNumChunks);
|
||||
|
||||
// Enable Interrupts
|
||||
mmvs->InterruptEnable = 0x1;
|
||||
int reenable = 1;
|
||||
write(fdMmvs, (void*) &reenable, 4);
|
||||
|
||||
// Run MM2VS
|
||||
mmvs->MM2VS_Control |= 0x1;
|
||||
|
||||
|
||||
while (1) {
|
||||
// Reenable Interrupts
|
||||
// Bitte beachten:
|
||||
// Wir verwenden pegel-sensitive Interrupts.
|
||||
// Das bedeutet, dass VOR der erneuten Freigabe der Interrupts (= reenable)
|
||||
// der Interrupt-Status im IP zurueckgesetzt werden muss - und NICHT DANACH
|
||||
// Falls Ihnen nicht klar ist, warum das so ist, fragen Sie nach!
|
||||
|
||||
int pending;
|
||||
int reenable = 1;
|
||||
|
||||
read(fdMmvs, (void*) &pending, 4);
|
||||
mmvs->InterruptStatus = 0;
|
||||
write(fdMmvs, (void*) &reenable, 4);
|
||||
|
||||
// Fill currrently unused buffer
|
||||
volatile uint32_t lastFrameAddress = mmvs->MM2VS_LastFrameAddress;
|
||||
printf("LastFrameAddress: 0x%x\n", (unsigned int) lastFrameAddress);
|
||||
|
||||
if ((void *) lastFrameAddress == NULL) {
|
||||
pBuffer = (int16_t *) ((uint32_t) pMem + bufferStartOffset);
|
||||
} else if (lastFrameAddress == bufferStart) {
|
||||
pBuffer = (int16_t *) ((uint32_t) pMem + bufferStartOffset + bufferChunkSize * bufferNumChunks);
|
||||
} else {
|
||||
pBuffer = (int16_t *) ((uint32_t) pMem + bufferStartOffset);
|
||||
}
|
||||
printf("Fill DataAddress: 0x%x\n", (unsigned int) pBuffer);
|
||||
|
||||
// Fill not used buffer with values
|
||||
fillBuffer(pBuffer, (size_t) bufferChunkSize*bufferNumChunks/2);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
printf("Start Program\n");
|
||||
std::thread t1(MM2VS_Handler);
|
||||
t1.join();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fillBuffer(int16_t* pBuffer, size_t bufferSize)
|
||||
{
|
||||
// Sinuswerte einer Periode auf 8 mal 16bit aufgeteilt
|
||||
int16_t sine_values[] = {0,23169,32767,23169,0,-23170,-32768,-23170};
|
||||
|
||||
for (size_t i = 0; i < bufferSize; i++) {
|
||||
int16_t *pData = pBuffer + i;
|
||||
*pData = sine_values[i%8];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
from math import pi, sin
|
||||
|
||||
# Dieses Skript berechnet die Sinuswerte, welche vom C-Programm in den
|
||||
# Pufferspeicher gelegt werden
|
||||
|
||||
|
||||
def arduino_map(x, in_min, in_max, out_min, out_max):
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
|
||||
|
||||
|
||||
sine_values = []
|
||||
dx = 2 * pi / 8
|
||||
|
||||
for i in range(8):
|
||||
sine_values.append(int(arduino_map(sin(i*dx), -1, 1, -32768, 32767)))
|
||||
print(sine_values[i])
|
||||
|
||||
print()
|
||||
print("{}", end="")
|
||||
for v in sine_values:
|
||||
print(v, end="")
|
||||
print(",", end="")
|
||||
print("}")
|
||||
Reference in New Issue
Block a user