librpitx/src/dma.h
2019-01-06 10:51:52 +00:00

118 lines
3.1 KiB
C++

#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)
//Page 61
#define DREQ_PCM_TX 2
#define DREQ_PCM_RX 3
#define DREQ_SMI 4
#define DREQ_PWM 5
#define DREQ_SPI_TX 6
#define DREQ_SPI_RX 7
#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;
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;
uint32_t *usermem;
uint32_t usermemsize;
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);
void GetRpiInfo();
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);
};
class bufferdma : public dma
{
protected:
uint32_t current_sample;
uint32_t last_sample;
uint32_t sample_available;
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);
void SetDmaAlgo();
int GetBufferAvailable();
int GetUserMemIndex();
int PushSample(int Index);
};
#endif