Skip to content

Commit

Permalink
simplify dma writting
Browse files Browse the repository at this point in the history
  • Loading branch information
F5OEO committed Jan 6, 2019
1 parent d23e1fd commit 326d51c
Show file tree
Hide file tree
Showing 12 changed files with 498 additions and 769 deletions.
2 changes: 1 addition & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ LDFLAGS = -lm -lrt -lpthread
CCP = c++
CC = cc

librpitx: librpitx.h gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c fmdmasync.h fmdmasync.cpp ngfmdmasync.h ngfmdmasync.cpp dsp.h dsp.cpp iqdmasync.h iqdmasync.cpp serialdmasync.h serialdmasync.cpp phasedmasync.h phasedmasync.cpp fskburst.h fskburst.cpp ookburst.cpp ookburst.h atv.h atv.cpp
librpitx: librpitx.h gpio.h gpio.cpp dma.h dma.cpp mailbox.c raspberry_pi_revision.c fmdmasync.h fmdmasync.cpp ngfmdmasync.h ngfmdmasync.cpp dsp.h dsp.cpp iqdmasync.h iqdmasync.cpp serialdmasync.h serialdmasync.cpp phasedmasync.h phasedmasync.cpp fskburst.h fskburst.cpp ookburst.cpp ookburst.h atv.h atv.cpp util.h
$(CC) $(CFLAGS) -c -o mailbox.o mailbox.c
$(CC) $(CFLAGS) -c -o raspberry_pi_revision.o raspberry_pi_revision.c
$(CCP) $(CXXFLAGS) -c dsp.cpp iqdmasync.cpp ngfmdmasync.cpp fmdmasync.cpp dma.cpp gpio.cpp serialdmasync.cpp phasedmasync.cpp amdmasync.h amdmasync.cpp fskburst.cpp ookburst.cpp atv.cpp
Expand Down
28 changes: 3 additions & 25 deletions src/amdmasync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,39 +72,17 @@ void amdmasync::SetDmaAlgo()

//@0
//Set Amplitude by writing to PADS
cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample]);
cbp->dst = 0x7E000000+(PADS_GPIO_0<<2)+PADS_GPIO;
cbp->length = 4;
cbp->stride = 0;
cbp->next = mem_virt_to_phys(cbp + 1);
SetEasyCB(cbp,samplecnt*registerbysample,dma_pad,1);
cbp++;

//@1
//Set Amplitude to FSEL for amplitude=0
cbp->info = 0;//BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP ;
cbp->src = mem_virt_to_phys(&usermem[samplecnt*registerbysample+1]);
cbp->dst = 0x7E000000 + (GPFSEL0<<2)+GENERAL_BASE;
cbp->length = 4;
cbp->stride = 0;
cbp->next = mem_virt_to_phys(cbp + 1);
SetEasyCB(cbp,samplecnt*registerbysample+1,dma_fsel,1);
cbp++;


// Delay
if(syncwithpwm)
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);
else
cbp->info = BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP |BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PCM_TX);
cbp->src = mem_virt_to_phys(cbarray); // Data is not important as we use it only to feed the PWM
if(syncwithpwm)
cbp->dst = 0x7E000000 + (PWM_FIFO<<2) + PWM_BASE ;
else
cbp->dst = 0x7E000000 + (PCM_FIFO_A<<2) + PCM_BASE ;
cbp->length = 4;
cbp->stride = 0;
cbp->next = mem_virt_to_phys(cbp + 1);
//fprintf(stderr,"cbp : sample %x src %x dest %x next %x\n",samplecnt,cbp->src,cbp->dst,cbp->next);
SetEasyCB(cbp,samplecnt*registerbysample,syncwithpwm?dma_pwm:dma_pcm,1);
cbp++;

}
Expand Down
280 changes: 33 additions & 247 deletions src/atv.cpp

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions src/dma.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ This program is free software: you can redistribute it and/or modify

#include "dma.h"
#include "stdio.h"
#include "util.h"

extern "C"
{
Expand Down Expand Up @@ -166,6 +167,33 @@ bool dma::isunderflow()
return ((dma_reg.gpioreg[DMA_CS+channel*0x40]&DMA_CS_INT)>0);
}

bool dma::SetCB(dma_cb_t *cbp,uint32_t dma_flag,uint32_t src,uint32_t dst,uint32_t repeat)
{
cbp->info = dma_flag;
cbp->src = src;
cbp->dst = dst;
cbp->length = 4*repeat;
cbp->stride = 0;
cbp->next = mem_virt_to_phys(cbp + 1);
return true;
}

bool dma::SetEasyCB(dma_cb_t *cbp,uint32_t index,dma_common_reg dst,uint32_t repeat)
{
uint32_t flag=BCM2708_DMA_NO_WIDE_BURSTS | BCM2708_DMA_WAIT_RESP;
uint32_t src=mem_virt_to_phys(&usermem[index]);
switch(dst)
{
case dma_pllc_frac :break;
case dma_fsel:break;
case dma_pad:break;
case dma_pwm : flag|=BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PWM);break;
case dma_pcm : flag|=BCM2708_DMA_D_DREQ | BCM2708_DMA_PER_MAP(DREQ_PCM_TX);break;
}
SetCB(cbp,flag,src,dst,repeat);
return true;
}

//**************************************** BUFFER DMA ********************************************************
bufferdma::bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample):dma(Channel,tbuffersize*tcbbysample,tbuffersize*tregisterbysample)
{
Expand Down
143 changes: 70 additions & 73 deletions src/dma.h
Original file line number Diff line number Diff line change
@@ -1,35 +1,35 @@
#ifndef DEF_DMA
#define DEF_DMA

#include "stdint.h"
#include "gpio.h"

#include "util.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)
#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)

//Page 61
#define DREQ_PCM_TX 2
Expand All @@ -41,81 +41,78 @@
#define DREQ_SPI_SLAVE_TX 8
#define DREQ_SPI_SLAVE_RX 9


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; //8*4=32 bytes

typedef struct {
uint8_t *virtaddr;
uint32_t physaddr;
} page_map_t;

page_map_t *page_map;

uint8_t *virtbase;
int NumPages=0;
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; //8*4=32 bytes

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;

uint32_t mem_flag; //Cache or not depending on Rpi1 or 2/3
uint32_t dram_phys_base;


public:
dma_cb_t *cbarray;
public:
dma_cb_t *cbarray;
uint32_t cbsize;
uint32_t *usermem;
uint32_t *usermem;
uint32_t usermemsize;
bool Started=false;
bool Started = false;

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);
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();
int start();
int stop();
int getcbposition();
bool isrunning();
bool isunderflow();

bool SetCB(dma_cb_t *cbp, uint32_t dma_flag, uint32_t src, uint32_t dst, uint32_t repeat);
bool SetEasyCB(dma_cb_t *cbp, uint32_t index, dma_common_reg dst, uint32_t repeat);
};

#define PHYSICAL_BUS 0x7E000000

class bufferdma:public dma
class bufferdma : public dma
{
protected:


protected:
uint32_t current_sample;
uint32_t last_sample;
uint32_t sample_available;
public:

public:
uint32_t buffersize;
uint32_t cbbysample;
uint32_t registerbysample;
uint32_t *sampletab;
public:
bufferdma(int Channel,uint32_t tbuffersize,uint32_t tcbbysample,uint32_t tregisterbysample);

public:
bufferdma(int Channel, uint32_t tbuffersize, uint32_t tcbbysample, uint32_t tregisterbysample);
void SetDmaAlgo();
int GetBufferAvailable();
int GetUserMemIndex();
int PushSample(int Index);

};
#endif
Loading

0 comments on commit 326d51c

Please sign in to comment.