mirror of
https://github.com/F5OEO/rpitx.git
synced 2026-03-23 16:56:54 +01:00
First steps for gpio and dma
This commit is contained in:
16
src/Makefile
16
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
|
||||
|
||||
83
src/dma.cpp
Normal file
83
src/dma.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "dma.h"
|
||||
#include "stdio.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "mailbox.h"
|
||||
}
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
47
src/dma.h
Normal file
47
src/dma.h
Normal file
@@ -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
|
||||
51
src/gpio.cpp
Normal file
51
src/gpio.cpp
Normal file
@@ -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<<shift)) | (mode<<shift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t gpio::GetPeripheralBase()
|
||||
{
|
||||
RASPBERRY_PI_INFO_T info;
|
||||
uint32_t BCM2708_PERI_BASE=0;
|
||||
if (getRaspberryPiInformation(&info) > 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)
|
||||
{
|
||||
}
|
||||
54
src/gpio.h
Normal file
54
src/gpio.h
Normal file
@@ -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
|
||||
@@ -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 <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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 <linux/ioctl.h>
|
||||
// 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
|
||||
|
||||
7
src/v2rpitx.cpp
Normal file
7
src/v2rpitx.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
#include "dma.h"
|
||||
#include "gpio.h"
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user