diff --git a/src/Makefile b/src/Makefile index f223057..60d140c 100644 --- a/src/Makefile +++ b/src/Makefile @@ -15,10 +15,10 @@ LDFLAGS = -lm -lrt -lpthread CCP = g++ CC = gcc -v2rpitx: gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c v2rpitx.cpp +v2rpitx: gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c v2rpitx.cpp fmdmasync.h fmdmasync.cpp $(CC) $(CFLAGS) -c -o mailbox.o mailbox.c $(CC) $(CFLAGS) -c -o raspberry_pi_revision.o raspberry_pi_revision.c - $(CCP) $(CFLAGS) -o v2rpitx dma.cpp gpio.cpp mailbox.o raspberry_pi_revision.o v2rpitx.cpp $(LDFLAGS) + $(CCP) $(CFLAGS) -o v2rpitx fmdmasync.cpp dma.cpp gpio.cpp mailbox.o raspberry_pi_revision.o v2rpitx.cpp $(LDFLAGS) diff --git a/src/dma.cpp b/src/dma.cpp index a0cd30b..5195ab2 100644 --- a/src/dma.cpp +++ b/src/dma.cpp @@ -4,13 +4,14 @@ extern "C" { #include "mailbox.h" +#include "raspberry_pi_revision.h" } #include #define BUS_TO_PHYS(x) ((x)&~0xC0000000) -dma::dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag) +dma::dma(int Channel,uint32_t CBSize,uint32_t UserMemSize) { channel=Channel; mbox.handle = mbox_open(); @@ -19,7 +20,10 @@ dma::dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag) fprintf(stderr,"Failed to open mailbox\n"); } - + cbsize=CBSize; + usermemsize=UserMemSize; + + GetRpiInfo(); // Fill mem_flag and dram_phys_base unsigned int MemoryRequired=CBSize*sizeof(dma_cb_t)+UserMemSize*sizeof(unsigned int); int NumPages=(MemoryRequired/PAGE_SIZE)+1; fprintf(stderr,"%d Size NUM PAGES %d PAGE_SIZE %d\n",MemoryRequired,NumPages,PAGE_SIZE); @@ -35,6 +39,31 @@ dma::dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag) usermem= (unsigned int *)(virtbase+UserMemSize*sizeof(unsigned int)); // user memory is placed after } +void dma::GetRpiInfo() +{ + RASPBERRY_PI_INFO_T info; + if (getRaspberryPiInformation(&info) > 0) + { + if(info.peripheralBase==RPI_BROADCOM_2835_PERIPHERAL_BASE) + { + + dram_phys_base = 0x40000000; + mem_flag = MEM_FLAG_L1_NONALLOCATING|MEM_FLAG_HINT_PERMALOCK|MEM_FLAG_NO_INIT;//0x0c; + } + + if((info.peripheralBase==RPI_BROADCOM_2836_PERIPHERAL_BASE)||(info.peripheralBase==RPI_BROADCOM_2837_PERIPHERAL_BASE)) + { + + dram_phys_base = 0xc0000000; + mem_flag = MEM_FLAG_L1_NONALLOCATING/*MEM_FLAG_DIRECT*/|MEM_FLAG_HINT_PERMALOCK|MEM_FLAG_NO_INIT;//0x04; + } + } + else + { + fprintf(stderr,"Unknown Raspberry architecture\n"); + } +} + dma::~dma() { unmapmem(mbox.virt_addr, NumPages * PAGE_SIZE); diff --git a/src/dma.h b/src/dma.h index 128c910..0ed24c2 100644 --- a/src/dma.h +++ b/src/dma.h @@ -3,6 +3,34 @@ #include "stdint.h" #include "gpio.h" +// ---- Memory allocating defines +// https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface +#define MEM_FLAG_DISCARDABLE (1 << 0) /* can be resized to 0 at any time. Use for cached data */ +#define MEM_FLAG_NORMAL (0 << 2) /* normal allocating alias. Don't use from ARM */ +#define MEM_FLAG_DIRECT (1 << 2) /* 0xC alias uncached */ +#define MEM_FLAG_COHERENT (2 << 2) /* 0x8 alias. Non-allocating in L2 but coherent */ +#define MEM_FLAG_L1_NONALLOCATING (MEM_FLAG_DIRECT | MEM_FLAG_COHERENT) /* Allocating in L2 */ +#define MEM_FLAG_ZERO ( 1 << 4) /* initialise buffer to all zeros */ +#define MEM_FLAG_NO_INIT ( 1 << 5) /* don't initialise (default is initialise to all ones */ +#define MEM_FLAG_HINT_PERMALOCK (1 << 6) /* Likely to be locked for long periods of time. */ + +#define BCM2708_DMA_SRC_IGNOR (1<<11) +#define BCM2708_DMA_SRC_INC (1<<8) +#define BCM2708_DMA_DST_IGNOR (1<<7) +#define BCM2708_DMA_NO_WIDE_BURSTS (1<<26) +#define BCM2708_DMA_WAIT_RESP (1<<3) + + +#define BCM2708_DMA_D_DREQ (1<<6) +#define BCM2708_DMA_PER_MAP(x) ((x)<<16) +#define BCM2708_DMA_END (1<<1) +#define BCM2708_DMA_RESET (1<<31) +#define BCM2708_DMA_INT (1<<2) + +#define DMA_CS (0x00/4) +#define DMA_CONBLK_AD (0x04/4) +#define DMA_DEBUG (0x20/4) + class dma { protected: @@ -29,17 +57,21 @@ class dma int NumPages=0; int channel; //DMA Channel dmagpio dma_reg; + + uint32_t mem_flag; //Cache or not depending on Rpi1 or 2/3 + uint32_t dram_phys_base; public: dma_cb_t *cbarray; + uint32_t cbsize; unsigned int *usermem; + uint32_t usermemsize; - - dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag); + dma(int Channel,uint32_t CBSize,uint32_t UserMemSize); ~dma(); uint32_t mem_virt_to_phys(volatile void *virt); uint32_t mem_phys_to_virt(volatile uint32_t phys); - + void GetRpiInfo(); int start(); int stop(); diff --git a/src/fmdmasync.cpp b/src/fmdmasync.cpp new file mode 100644 index 0000000..fcb4891 --- /dev/null +++ b/src/fmdmasync.cpp @@ -0,0 +1,12 @@ +#include "stdio.h" +#include "fmdmasync.h" + +fmdmasync::fmdmasync(int Channel,uint32_t FifoSize):dma(Channel,FifoSize*2,FifoSize) +{ + +} + +fmdmasync::~fmdmasync() +{ +} + diff --git a/src/fmdmasync.h b/src/fmdmasync.h new file mode 100644 index 0000000..a56e082 --- /dev/null +++ b/src/fmdmasync.h @@ -0,0 +1,14 @@ +#ifndef DEF_FMDMASYNC +#define DEF_FMDMASYNC + +#include "stdint.h" +#include "dma.h" + +class fmdmasync:public dma +{ + public: + fmdmasync(int Channel,uint32_t FifoSize); + ~fmdmasync(); +}; + +#endif