V71+: change the way DMA is reset to cater for edge case

This commit is contained in:
joan2937 2019-09-29 10:13:04 +01:00
parent ad89f458c8
commit 5966a50e45
3 changed files with 25 additions and 15 deletions

View File

@ -375,12 +375,13 @@ bit 0 READ_LAST_NOT_SET_ERROR
/* DMA CS Control and Status bits */ /* DMA CS Control and Status bits */
#define DMA_CHANNEL_RESET (1<<31) #define DMA_CHANNEL_RESET (1<<31)
#define DMA_CHANNEL_ABORT (1<<30)
#define DMA_WAIT_ON_WRITES (1<<28) #define DMA_WAIT_ON_WRITES (1<<28)
#define DMA_PANIC_PRIORITY(x) ((x)<<20) #define DMA_PANIC_PRIORITY(x) ((x)<<20)
#define DMA_PRIORITY(x) ((x)<<16) #define DMA_PRIORITY(x) ((x)<<16)
#define DMA_INTERRUPT_STATUS (1<< 2) #define DMA_INTERRUPT_STATUS (1<< 2)
#define DMA_END_FLAG (1<< 1) #define DMA_END_FLAG (1<< 1)
#define DMA_ACTIVATE (1<< 0) #define DMA_ACTIVE (1<< 0)
/* DMA control block "info" field bits */ /* DMA control block "info" field bits */
#define DMA_NO_WIDE_BURSTS (1<<26) #define DMA_NO_WIDE_BURSTS (1<<26)
@ -7848,13 +7849,22 @@ static void initClock(int mainClock)
myGpioDelay(2000); myGpioDelay(2000);
} }
static void initKillDMA(volatile uint32_t *dmaAddr)
{
dmaAddr[DMA_CS] = DMA_CHANNEL_ABORT;
dmaAddr[DMA_CS] = 0;
dmaAddr[DMA_CS] = DMA_CHANNEL_RESET;
dmaAddr[DMA_CONBLK_AD] = 0;
}
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr) static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr)
{ {
DBG(DBG_STARTUP, ""); DBG(DBG_STARTUP, "");
dmaAddr[DMA_CS] = DMA_CHANNEL_RESET; initKillDMA(dmaAddr);
dmaAddr[DMA_CS] = DMA_INTERRUPT_STATUS | DMA_END_FLAG; dmaAddr[DMA_CS] = DMA_INTERRUPT_STATUS | DMA_END_FLAG;
@ -7870,7 +7880,7 @@ static void initDMAgo(volatile uint32_t *dmaAddr, uint32_t cbAddr)
dmaAddr[DMA_CS] = DMA_WAIT_ON_WRITES | dmaAddr[DMA_CS] = DMA_WAIT_ON_WRITES |
DMA_PANIC_PRIORITY(8) | DMA_PANIC_PRIORITY(8) |
DMA_PRIORITY(8) | DMA_PRIORITY(8) |
DMA_ACTIVATE; DMA_ACTIVE;
} }
/* ----------------------------------------------------------------------- */ /* ----------------------------------------------------------------------- */
@ -8632,8 +8642,11 @@ void gpioTerminate(void)
/* reset DMA */ /* reset DMA */
if (dmaReg != MAP_FAILED) dmaIn[DMA_CS] = DMA_CHANNEL_RESET; if (dmaReg != MAP_FAILED)
if (dmaReg != MAP_FAILED) dmaOut[DMA_CS] = DMA_CHANNEL_RESET; {
initKillDMA(dmaIn);
initKillDMA(dmaOut);
}
#ifndef EMBEDDED_IN_VM #ifndef EMBEDDED_IN_VM
if ((gpioCfg.internals & PI_CFG_STATS) && if ((gpioCfg.internals & PI_CFG_STATS) &&
@ -9688,11 +9701,7 @@ int gpioWaveTxSend(unsigned wave_id, unsigned wave_mode)
PWMClockInited = 0; PWMClockInited = 0;
} }
if (wave_mode < PI_WAVE_MODE_ONE_SHOT_SYNC) if (wave_mode < PI_WAVE_MODE_ONE_SHOT_SYNC) initKillDMA(dmaOut);
{
dmaOut[DMA_CS] = DMA_CHANNEL_RESET;
dmaOut[DMA_CONBLK_AD] = 0;
}
p = rawWaveCBAdr(waveInfo[wave_id].topCB); p = rawWaveCBAdr(waveInfo[wave_id].topCB);
@ -9935,8 +9944,8 @@ int gpioWaveChain(char *buf, unsigned bufSize)
PWMClockInited = 0; PWMClockInited = 0;
} }
dmaOut[DMA_CS] = DMA_CHANNEL_RESET; initKillDMA(dmaOut);
dmaOut[DMA_CONBLK_AD] = 0;
waveEndPtr = NULL; waveEndPtr = NULL;
endPtr = NULL; endPtr = NULL;
@ -10257,8 +10266,7 @@ int gpioWaveTxStop(void)
CHECK_INITED; CHECK_INITED;
dmaOut[DMA_CS] = DMA_CHANNEL_RESET; initKillDMA(dmaOut);
dmaOut[DMA_CONBLK_AD] = 0;
waveEndPtr = NULL; waveEndPtr = NULL;

View File

@ -30,7 +30,7 @@ For more information, please refer to <http://unlicense.org/>
#include <stdint.h> #include <stdint.h>
#include <pthread.h> #include <pthread.h>
#define PIGPIO_VERSION 7101 #define PIGPIO_VERSION 7102
/*TEXT /*TEXT

View File

@ -63,10 +63,12 @@ void t1()
CHECK(1, 1, v, 0, 0, "set mode, get mode"); CHECK(1, 1, v, 0, 0, "set mode, get mode");
gpioSetPullUpDown(GPIO, PI_PUD_UP); gpioSetPullUpDown(GPIO, PI_PUD_UP);
gpioDelay(1); /* 1 micro delay to let GPIO reach level reliably */
v = gpioRead(GPIO); v = gpioRead(GPIO);
CHECK(1, 2, v, 1, 0, "set pull up down, read"); CHECK(1, 2, v, 1, 0, "set pull up down, read");
gpioSetPullUpDown(GPIO, PI_PUD_DOWN); gpioSetPullUpDown(GPIO, PI_PUD_DOWN);
gpioDelay(1); /* 1 micro delay to let GPIO reach level reliably */
v = gpioRead(GPIO); v = gpioRead(GPIO);
CHECK(1, 3, v, 0, 0, "set pull up down, read"); CHECK(1, 3, v, 0, 0, "set pull up down, read");