M5: Software halb fertig

This commit is contained in:
Matthias Biermann
2024-12-02 23:37:04 +01:00
parent df100bd8b2
commit 51ade332de
2 changed files with 134 additions and 0 deletions
+111
View File
@@ -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];
}
}
+23
View File
@@ -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("}")