From b977a07a34ee64379bf4ea4851a7ccfb8bc1077c Mon Sep 17 00:00:00 2001 From: F5OEO Date: Mon, 26 Feb 2018 13:45:28 +0000 Subject: [PATCH] First steps for gpio and dma --- src/Makefile | 16 +++++++++- src/dma.cpp | 83 +++++++++++++++++++++++++++++++++++++++++++++++++ src/dma.h | 47 ++++++++++++++++++++++++++++ src/gpio.cpp | 51 ++++++++++++++++++++++++++++++ src/gpio.h | 54 ++++++++++++++++++++++++++++++++ src/mailbox.c | 4 ++- src/mailbox.h | 6 ++++ src/v2rpitx.cpp | 7 +++++ 8 files changed, 266 insertions(+), 2 deletions(-) create mode 100644 src/dma.cpp create mode 100644 src/dma.h create mode 100644 src/gpio.cpp create mode 100644 src/gpio.h create mode 100644 src/v2rpitx.cpp diff --git a/src/Makefile b/src/Makefile index 225f4fc..f223057 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,4 +1,5 @@ -all: ../rpitx ../pissb ../pisstv ../pifsq ../pifm ../piam ../pidcf77 ../piopera +#all: ../rpitx ../pissb ../pisstv ../pifsq ../pifm ../piam ../pidcf77 ../piopera +all: ../rpitx v2rpitx #CFLAGS = -Wall -g -O2 -D DIGITHIN CFLAGS = -Wall -g -O2 -Wno-unused-variable @@ -7,6 +8,19 @@ LDFLAGS = -lm -lrt -lpthread ../rpitx: RpiGpio.c RpiTx.c mailbox.c RpiDma.c raspberry_pi_revision.c calibrationpi2.h calibrationpizero.h calibrationpi3.h $(CC) $(CFLAGS) -o ../rpitx RpiTx.c RpiGpio.c mailbox.c RpiDma.c raspberry_pi_revision.c $(LDFLAGS) + + +CFLAGS = -Wall -g -O2 -Wno-unused-variable +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 + $(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) + + CFLAGS_Pissb = -Wall -g -O2 -Wno-unused-variable LDFLAGS_Pissb = -lm -lrt -lpthread -lsndfile diff --git a/src/dma.cpp b/src/dma.cpp new file mode 100644 index 0000000..a0cd30b --- /dev/null +++ b/src/dma.cpp @@ -0,0 +1,83 @@ +#include "dma.h" +#include "stdio.h" + +extern "C" +{ +#include "mailbox.h" +} +#include + + +#define BUS_TO_PHYS(x) ((x)&~0xC0000000) + +dma::dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag) +{ + channel=Channel; + mbox.handle = mbox_open(); + if (mbox.handle < 0) + { + fprintf(stderr,"Failed to open mailbox\n"); + + } + + 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); + mbox.mem_ref = mem_alloc(mbox.handle, NumPages* PAGE_SIZE, PAGE_SIZE, mem_flag); + /* TODO: How do we know that succeeded? */ + //printf("mem_ref %x\n", mbox.mem_ref); + mbox.bus_addr = mem_lock(mbox.handle, mbox.mem_ref); + //printf("bus_addr = %x\n", mbox.bus_addr); + mbox.virt_addr = (uint8_t *)mapmem(BUS_TO_PHYS(mbox.bus_addr), NumPages* PAGE_SIZE); + //printf("virt_addr %p\n", mbox.virt_addr); + virtbase = (uint8_t *)((uint32_t *)mbox.virt_addr); + cbarray = (dma_cb_t *)virtbase; // We place DMA Control Blocks (CB) at beginning of virtual memory + usermem= (unsigned int *)(virtbase+UserMemSize*sizeof(unsigned int)); // user memory is placed after +} + +dma::~dma() +{ + unmapmem(mbox.virt_addr, NumPages * PAGE_SIZE); + //printf("Unmapmem Done\n"); + mem_unlock(mbox.handle, mbox.mem_ref); + //printf("Unmaplock Done\n"); + mem_free(mbox.handle, mbox.mem_ref); +} + +uint32_t dma::mem_virt_to_phys(volatile void *virt) +{ + //MBOX METHOD + uint32_t offset = (uint8_t *)virt - mbox.virt_addr; + return mbox.bus_addr + offset; +} + +uint32_t dma::mem_phys_to_virt(volatile uint32_t phys) +{ + //MBOX METHOD + uint32_t offset=phys-mbox.bus_addr; + uint32_t result=(uint32_t)((uint8_t *)mbox.virt_addr+offset); + //printf("MemtoVirt:Offset=%lx phys=%lx -> %lx\n",offset,phys,result); + return result; +} + +int dma::start() +{ + dma_reg.gpioreg[DMA_CONBLK_AD+channel*0x40]=mem_virt_to_phys((void*)cbarray ); // reset to beginning + usleep(100); + dma_reg.gpioreg[DMA_CS+channel*0x40] = DMA_CS_PRIORITY(7) | DMA_CS_PANIC_PRIORITY(7) | DMA_CS_DISDEBUG |DMA_CS_ACTIVE; + return 0; +} + +int dma::stop() +{ + dma_reg.gpioreg[DMA_CS+channel*0x40] = BCM2708_DMA_RESET; + usleep(1000); + dma_reg.gpioreg[DMA_CS+channel*0x40] = BCM2708_DMA_INT | BCM2708_DMA_END; + usleep(100); + dma_reg.gpioreg[DMA_CONBLK_AD+channel*0x40]=mem_virt_to_phys((void *)cbarray ); + usleep(100); + dma_reg.gpioreg[DMA_DEBUG+channel*0x40] = 7; // clear debug error flags + usleep(100); + return 0; +} + diff --git a/src/dma.h b/src/dma.h new file mode 100644 index 0000000..128c910 --- /dev/null +++ b/src/dma.h @@ -0,0 +1,47 @@ +#ifndef DEF_DMA +#define DEF_DMA +#include "stdint.h" +#include "gpio.h" + +class dma +{ + protected: + struct { + int handle; /* From mbox_open() */ + unsigned mem_ref; /* From mem_alloc() */ + unsigned bus_addr; /* From mem_lock() */ + uint8_t *virt_addr; /* From mapmem() */ + } mbox; + + typedef struct { + uint32_t info, src, dst, length, + stride, next, pad[2]; + } dma_cb_t; + + typedef struct { + uint8_t *virtaddr; + uint32_t physaddr; + } page_map_t; + + page_map_t *page_map; + + uint8_t *virtbase; + int NumPages=0; + int channel; //DMA Channel + dmagpio dma_reg; + public: + dma_cb_t *cbarray; + unsigned int *usermem; + + + + dma(int Channel,int CBSize,int UserMemSize,unsigned int mem_flag); + ~dma(); + uint32_t mem_virt_to_phys(volatile void *virt); + uint32_t mem_phys_to_virt(volatile uint32_t phys); + + int start(); + int stop(); + +}; +#endif diff --git a/src/gpio.cpp b/src/gpio.cpp new file mode 100644 index 0000000..41f9d80 --- /dev/null +++ b/src/gpio.cpp @@ -0,0 +1,51 @@ +extern "C" +{ +#include "mailbox.h" +} +#include "gpio.h" +#include "raspberry_pi_revision.h" + +gpio::gpio(uint32_t base, uint32_t len) +{ + + gpioreg=( uint32_t *)mapmem(base,len); + +} + +int gpio::setmode(uint32_t gpio, uint32_t mode) +{ + int reg, shift; + + reg = gpio/10; + shift = (gpio%10) * 3; + + gpioreg[reg] = (gpioreg[reg] & ~(7< 0) + { + if(info.peripheralBase==RPI_BROADCOM_2835_PERIPHERAL_BASE) + { + BCM2708_PERI_BASE = info.peripheralBase ; + } + + if((info.peripheralBase==RPI_BROADCOM_2836_PERIPHERAL_BASE)||(info.peripheralBase==RPI_BROADCOM_2837_PERIPHERAL_BASE)) + { + BCM2708_PERI_BASE = info.peripheralBase ; + } + } + return BCM2708_PERI_BASE; +} + + +//******************** DMA Registers *************************************** + +dmagpio::dmagpio():gpio(GetPeripheralBase()+DMA_BASE,DMA_LEN) +{ +} diff --git a/src/gpio.h b/src/gpio.h new file mode 100644 index 0000000..c4fb6b9 --- /dev/null +++ b/src/gpio.h @@ -0,0 +1,54 @@ +#ifndef DEF_GPIO +#define DEF_GPIO +#include "stdint.h" + +class gpio +{ + + public: + volatile uint32_t *gpioreg; + gpio(uint32_t base, uint32_t len); + int setmode(uint32_t gpio, uint32_t mode); + uint32_t GetPeripheralBase(); +}; + + +#define DMA_BASE (0x00007000 ) +#define DMA_LEN 0xF00 + +#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_ABORT (1<<30) +#define BCM2708_DMA_INT (1<<2) + +#define DMA_CS (0x00/4) +#define DMA_CONBLK_AD (0x04/4) +#define DMA_DEBUG (0x20/4) + +#define DMA_CS_RESET (1<<31) +#define DMA_CS_ABORT (1<<30) +#define DMA_CS_DISDEBUG (1<<28) +#define DMA_CS_END (1<<1) +#define DMA_CS_ACTIVE (1<<0) +#define DMA_CS_PRIORITY(x) ((x)&0xf << 16) +#define DMA_CS_PANIC_PRIORITY(x) ((x)&0xf << 20) + +class dmagpio:public gpio +{ + + public: + dmagpio(); + + +}; + + +#endif diff --git a/src/mailbox.c b/src/mailbox.c index a1d0ad7..4223d4b 100644 --- a/src/mailbox.c +++ b/src/mailbox.c @@ -25,6 +25,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + + #include #include #include @@ -38,7 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "mailbox.h" -#define PAGE_SIZE (4*1024) + void *mapmem(unsigned base, unsigned size) { diff --git a/src/mailbox.h b/src/mailbox.h index e76371a..566f0d3 100644 --- a/src/mailbox.h +++ b/src/mailbox.h @@ -25,6 +25,8 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef DEF_MAILBOX + #include // Newer kernels (>= 4.1) use major 249, older ones major 100. #define MAJOR_NUM_A 249 @@ -34,6 +36,9 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define LOCAL_DEVICE_FILE_NAME "/dev/rpidatv-mb" #define VCIO_DEVICE_FILE_NAME "/dev/vcio" +#define PAGE_SIZE (4*1024) + + int mbox_open(); void mbox_close(int file_desc); @@ -48,3 +53,4 @@ void *unmapmem(void *addr, unsigned size); unsigned execute_code(int file_desc, unsigned code, unsigned r0, unsigned r1, unsigned r2, unsigned r3, unsigned r4, unsigned r5); unsigned execute_qpu(int file_desc, unsigned num_qpus, unsigned control, unsigned noflush, unsigned timeout); unsigned qpu_enable(int file_desc, unsigned enable); +#endif diff --git a/src/v2rpitx.cpp b/src/v2rpitx.cpp new file mode 100644 index 0000000..e8149bf --- /dev/null +++ b/src/v2rpitx.cpp @@ -0,0 +1,7 @@ + +#include "dma.h" +#include "gpio.h" +int main(int argc, char* argv[]) +{ + +}