#define DMA_DEST_WIDTH (1<< 5)
#define DMA_DEST_INC (1<< 4)
#define DMA_WAIT_RESP (1<< 3)
+#define DMA_TDMODE (1<< 1)
#define DMA_DEBUG_READ_ERR (1<<2)
#define DMA_DEBUG_FIFO_ERR (1<<1)
/* --------------------------------------------------------------- */
#define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP)
+#define TWO_BEAT_DMA (DMA_TDMODE | DMA_BURST_LENGTH(1))
#define TIMED_DMA(x) (DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(x))
for (i=0; i<numWaves; i++)
{
- if (waves[i].gpioOn) {numCB++; numBOOL++;}
- if (waves[i].gpioOff) {numCB++; numBOOL++;}
+ if (waves[i].gpioOn || waves[i].gpioOff) {numCB++; numBOOL++;}
if (waves[i].flags & WAVE_FLAG_READ) {numCB++; numTOOL++;}
if (waves[i].flags & WAVE_FLAG_TICK) {numCB++; numTOOL++;}
{
int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL;
- int status;
+ int status, s_stride;
rawCbs_t *p=NULL;
for (i=0; i<numWaves; i++)
{
- if (waves[i].gpioOn)
+ if (waves[i].gpioOn && waves[i].gpioOff)
+ /* Use 2-beat burst */
+ {
+ p = rawWaveCBAdr(botCB++);
+
+ p->info = TWO_BEAT_DMA;
+ p->src = waveOOLPOadr(botOOL);
+ waveSetOOL(botOOL++, waves[i].gpioOn);
+ s_stride = waveOOLPOadr(botOOL) - p->src;
+ waveSetOOL(botOOL++, waves[i].gpioOff);
+ p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS;
+ p->length = (2<<16) + 4; // 2 transfers of 4 bytes each
+ p->stride = (12<<16) + s_stride; // d_stride = (GPCLR0-GPSET0)*4 = 12
+ p->next = waveCbPOadr(botCB);
+ }
+ if (waves[i].gpioOn && !waves[i].gpioOff)
{
waveSetOOL(botOOL, waves[i].gpioOn);
p->length = 4;
p->next = waveCbPOadr(botCB);
}
-
- if (waves[i].gpioOff)
+ if (waves[i].gpioOff && !waves[i].gpioOn)
{
waveSetOOL(botOOL, waves[i].gpioOff);
p->length = 4;
p->next = waveCbPOadr(botCB);
}
-
if (waves[i].flags & WAVE_FLAG_READ)
{
p = rawWaveCBAdr(botCB++);
cbs += waveDelayCBs(tDelay);
- if (out[outPos].gpioOn) cbs++; /* one cb if gpio on */
-
- if (out[outPos].gpioOff) cbs++; /* one cb if gpio off */
+ if (out[outPos].gpioOn || out[outPos].gpioOff) cbs++;
if (out[outPos].flags & WAVE_FLAG_READ)
{