V28
authorjoan <joan@abyz.me.uk>
Wed, 11 Feb 2015 23:01:56 +0000 (23:01 +0000)
committerjoan <joan@abyz.me.uk>
Wed, 11 Feb 2015 23:01:56 +0000 (23:01 +0000)
pigpio.3
pigpio.c
pigpio.h
pigpiod_if.3
pigs.1
x_pigs
x_pipe

index 25af5c97b6c5995f08c8c6d49c3a5e08dbef9953..1d0231cde2cad19fe5e51083564ffa2435b14a8c 100644 (file)
--- a/pigpio.3
+++ b/pigpio.3
@@ -2659,8 +2659,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint spiWrite(unsigned handle, char *buf, unsigned count)\fP"
 .IP "" 4
@@ -2684,8 +2684,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint spiXfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)\fP"
 .IP "" 4
@@ -2712,8 +2712,8 @@ handle: >=0, as returned by a call to \fBspiOpen\fP
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint serOpen(char *sertty, unsigned serBaud, unsigned serFlags)\fP"
 .IP "" 4
@@ -4309,6 +4309,75 @@ The default setting (0) is that both interfaces are enabled.
 Or in PI_DISABLE_FIFO_IF to disable the pipe interface.
 Or in PI_DISABLE_SOCK_IF to disable the socket interface.
 
+.IP "\fBint gpioCustom1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP"
+.IP "" 4
+This function is available for user customisation.
+
+.br
+
+.br
+It returns a single integer value.
+
+.br
+
+.br
+
+.EX
+ arg1: >=0
+.br
+ arg2: >=0
+.br
+ argx: extra (byte) arguments
+.br
+count: number of extra arguments
+.br
+
+.EE
+
+.br
+
+.br
+Returns >= 0 if OK, less than 0 indicates a user defined error.
+
+.IP "\fBint gpioCustom2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP"
+.IP "" 4
+This function is available for user customisation.
+
+.br
+
+.br
+It differs from gpioCustom1 in that it returns an array of bytes
+rather than just an integer.
+
+.br
+
+.br
+The returned value is an integer indicating the number of returned bytes.
+
+.EX
+  arg1: >=0
+.br
+  argx: extra (byte) arguments
+.br
+ count: number of extra arguments
+.br
+retBuf: buffer for returned bytes
+.br
+retMax: maximum number of bytes to return
+.br
+
+.EE
+
+.br
+
+.br
+Returns >= 0 if OK, less than 0 indicates a user defined error.
+
+.br
+
+.br
+The number of returned bytes must be retMax or less.
+
 .IP "\fBint gpioCfgInternals(unsigned cfgWhat, int cfgVal)\fP"
 .IP "" 4
 Used to tune internal settings.
@@ -5643,7 +5712,7 @@ The hardware PWM dutycycle.
 .br
 
 .EX
-#define PI_HW_PWM_RANGE 1000
+#define PI_HW_PWM_RANGE 5000
 .br
 
 .EE
@@ -5662,7 +5731,7 @@ The hardware PWM frequency.
 .EX
 #define PI_HW_PWM_MIN_FREQ 5
 .br
-#define PI_HW_PWM_MAX_FREQ 250000
+#define PI_HW_PWM_MAX_FREQ 50000
 .br
 
 .EE
@@ -6411,6 +6480,12 @@ A 16-bit word value.
 #define PI_CMD_HP    86
 .br
 
+.br
+#define PI_CMD_CF1   87
+.br
+#define PI_CMD_CF2   88
+.br
+
 .br
 #define PI_CMD_NOIB  99
 .br
@@ -6617,9 +6692,9 @@ A 16-bit word value.
 .br
 #define PI_NOT_HPWM_GPIO    -95 // gpio has no hardware PWM
 .br
-#define PI_BAD_HPWM_FREQ    -96 // hardware PWM frequency not 5-250K
+#define PI_BAD_HPWM_FREQ    -96 // hardware PWM frequency not 5-50K
 .br
-#define PI_BAD_HPWM_DUTY    -97 // hardware PWM dutycycle not 0-1000
+#define PI_BAD_HPWM_DUTY    -97 // hardware PWM dutycycle not 0-5000
 .br
 #define PI_BAD_HCLK_FREQ    -98 // hardware clock frequency not 4689-25M
 .br
@@ -6631,6 +6706,20 @@ A 16-bit word value.
 .br
 #define PI_BAD_STOPBITS    -102 // serial (half) stop bits not 2-8
 .br
+#define PI_MSG_TOOBIG      -103 // socket/pipe message too big
+.br
+
+.br
+#define PI_PIGIF_ERR_0    -2000
+.br
+#define PI_PIGIF_ERR_99   -2099
+.br
+
+.br
+#define PI_CUSTOM_ERR_0   -3000
+.br
+#define PI_CUSTOM_ERR_999 -3999
+.br
 
 .br
 
index 803f2ea2143fdb11490ae7abf6a9b82c285b3fc8..8ccae64e99cbf5fce99b1be96a292bcdc896a0d6 100644 (file)
--- a/pigpio.c
+++ b/pigpio.c
@@ -25,7 +25,7 @@ OTHER DEALINGS IN THE SOFTWARE.
 For more information, please refer to <http://unlicense.org/>
 */
 
-/* pigpio version 27 */
+/* pigpio version 28 */
 
 #include <stdio.h>
 #include <string.h>
@@ -283,9 +283,15 @@ bit 0 READ_LAST_NOT_SET_ERROR
    }                                                               \
    while (0)
 
-static volatile unsigned int piModel = 1;
-static volatile unsigned int PI_PERI_BASE = 0x20000000;
-static volatile unsigned int DMA_BUS_ADR  = 0x40000000;
+#define PI_PERI_PHYS 0x7E000000
+
+static void *dummy = MAP_FAILED;
+
+static volatile uint32_t piModel = 1;
+
+static volatile uint32_t PI_PERI_BASE   = 0x20000000;
+static volatile uint32_t DMA_BUS_ADR    = 0x40000000;
+static volatile uint32_t DMA_BUS_CACHE  = 0x00000000;
 
 #define AUX_BASE   (PI_PERI_BASE + 0x00215000)
 #define CLK_BASE   (PI_PERI_BASE + 0x00101000)
@@ -894,6 +900,9 @@ typedef struct
    uint32_t emitFrags;
    uint32_t maxSamples;
    uint32_t numSamples;
+   uint32_t DMARestarts;
+   uint32_t DMAInits;
+   uint32_t dmaInitCbsCount;
 } gpioStats_t;
 
 typedef struct
@@ -1199,6 +1208,9 @@ static void intScriptBits(void);
 static int  gpioNotifyOpenInBand(int fd);
 static void initHWClk
    (int clkCtl, int clkDiv, int clkSrc, int divI, int divF, int MASH);
+static void initDMAgo(volatile uint32_t  *dmaAddr, uint32_t cbAddr);
+static void flushDMA(void);
+
 
 /* ======================================================================= */
 
@@ -1327,6 +1339,8 @@ static void myOffPageSlot(int pos, int * page, int * slot)
 
 static void myLvsPageSlot(int pos, int * page, int * slot)
 {
+//   *page = pos%DMAI_PAGES;
+//   *slot = pos/DMAI_PAGES;
    *page = pos/LVS_PER_IPAGE;
    *slot = pos%LVS_PER_IPAGE;
 }
@@ -1335,6 +1349,8 @@ static void myLvsPageSlot(int pos, int * page, int * slot)
 
 static void myTckPageSlot(int pos, int * page, int * slot)
 {
+//   *page = pos%DMAI_PAGES;
+//   *slot = pos/DMAI_PAGES;
    *page = pos/TCK_PER_IPAGE;
    *slot = pos%TCK_PER_IPAGE;
 }
@@ -2175,14 +2191,14 @@ static int wave2Cbs(unsigned wave_mode)
       p->info   = NORMAL_DMA |
                   DMA_DEST_DREQ |
                   DMA_PERIPHERAL_MAPPING(2);
-      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
    }
    else
    {
       p->info   = NORMAL_DMA |
                   DMA_DEST_DREQ |
                   DMA_PERIPHERAL_MAPPING(5);
-      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
    }
 
    p->src    = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
@@ -2203,7 +2219,7 @@ static int wave2Cbs(unsigned wave_mode)
 
          p->info   = NORMAL_DMA;
          p->src    = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
-         p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | 0x7e000000;
+         p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS;
          p->length = 4;
          p->next   = waveCbPOadr(botCB) | DMA_BUS_ADR;
       }
@@ -2218,7 +2234,7 @@ static int wave2Cbs(unsigned wave_mode)
 
          p->info   = NORMAL_DMA;
          p->src    = waveOOLPOadr(botOOL++) | DMA_BUS_ADR;
-         p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | 0x7e000000;
+         p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS;
          p->length = 4;
          p->next   = waveCbPOadr(botCB) | DMA_BUS_ADR;
       }
@@ -2230,7 +2246,7 @@ static int wave2Cbs(unsigned wave_mode)
          p = rawWaveCBAdr(botCB++);
 
          p->info   = NORMAL_DMA;
-         p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | 0x7e000000;
+         p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS;
          p->dst    = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
          p->length = 4;
          p->next   = waveCbPOadr(botCB) | DMA_BUS_ADR;
@@ -2243,7 +2259,7 @@ static int wave2Cbs(unsigned wave_mode)
          p = rawWaveCBAdr(botCB++);
 
          p->info   = NORMAL_DMA;
-         p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | 0x7e000000;
+         p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS;
          p->dst    = waveOOLPOadr(--topOOL) | DMA_BUS_ADR;
          p->length = 4;
          p->next   = waveCbPOadr(botCB) | DMA_BUS_ADR;
@@ -2330,7 +2346,7 @@ static int wave2Cbs(unsigned wave_mode)
                         DMA_DEST_DREQ |
                         DMA_PERIPHERAL_MAPPING(2);
 
-            p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+            p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
          }
          else
          {
@@ -2338,7 +2354,7 @@ static int wave2Cbs(unsigned wave_mode)
                         DMA_DEST_DREQ |
                         DMA_PERIPHERAL_MAPPING(5);
 
-            p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+            p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
          }
 
          p->src    = (uint32_t) (&dmaOPhys[0]->periphData) | DMA_BUS_ADR;
@@ -2607,7 +2623,8 @@ int i2cWriteQuick(unsigned handle, unsigned bit)
    if (bit > 1)
       SOFT_ERROR(PI_BAD_PARAM, "bad bit (%d)", bit);
 
-   err = my_smbus_access(i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL);
+   err = my_smbus_access(
+      i2cInfo[handle].fd, bit, 0, PI_I2C_SMBUS_QUICK, NULL);
 
    if (err < 0) return PI_I2C_WRITE_FAILED;
 
@@ -3117,7 +3134,7 @@ int i2cOpen(unsigned i2cBus, unsigned i2cAddr, unsigned i2cFlags)
       system("/sbin/modprobe i2c_dev");
       system("/sbin/modprobe i2c_bcm2708");
 
-      usleep(100000);
+      myGpioDelay(100000);
 
       if ((fd = open(dev, O_RDWR)) < 0)
       {
@@ -3274,7 +3291,7 @@ static void spiGoA(
       auxReg[AUX_SPI0_CNTL0_REG] =
          AUXSPI_CNTL0_ENABLE | AUXSPI_CNTL0_CLR_FIFOS;
 
-      usleep(10);
+      myGpioDelay(10);
 
       auxReg[AUX_SPI0_CNTL0_REG] = AUXSPI_CNTL0_ENABLE  | spiDefaults;
 
@@ -3438,15 +3455,12 @@ static void spiGo(
    char     *rxBuf,
    unsigned count)
 {
-   DBG(0, "spiGo");
    if (PI_SPI_FLAGS_GET_AUX_SPI(flags))
    {
-      DBG(0, "spiGoA");
       spiGoA(speed, flags, txBuf, rxBuf, count);
    }
    else
    {
-      DBG(0, "spiGoS");
       spiGoS(speed, flags, txBuf, rxBuf, count);
    }
 }
@@ -4037,8 +4051,7 @@ static unsigned dmaNowAtICB(void)
          endTick = systReg[SYST_CLO];
 
          if (endTick != startTick)
-              gpioStats.cbTicks += (endTick - startTick);
-         else gpioStats.cbTicks ++;
+            gpioStats.cbTicks += (endTick - startTick);
 
          gpioStats.cbCalls++;
 
@@ -4179,7 +4192,7 @@ static void dmaGpioOnCb(int b, int pos)
 
    p->info   = NORMAL_DMA;
    p->src    = dmaGpioOnAdr(pos) | DMA_BUS_ADR;
-   p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | 0x7e000000;
+   p->dst    = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_PHYS;
    p->length = 4;
    p->next   = dmaCbAdr(b+1) | DMA_BUS_ADR;
 }
@@ -4193,7 +4206,7 @@ static void dmaTickCb(int b, int pos)
    p = dmaCB2adr(b);
 
    p->info   = NORMAL_DMA;
-   p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | 0x7e000000;
+   p->src    = ((SYST_BASE + (SYST_CLO*4)) & 0x00ffffff) | PI_PERI_PHYS;
    p->dst    = dmaTickAdr(pos) | DMA_BUS_ADR;
    p->length = 4;
    p->next   = dmaCbAdr(b+1) | DMA_BUS_ADR;
@@ -4209,7 +4222,7 @@ static void dmaGpioOffCb(int b, int pos)
 
    p->info   = NORMAL_DMA;
    p->src    = dmaGpioOffAdr(pos) | DMA_BUS_ADR;
-   p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | 0x7e000000;
+   p->dst    = ((GPIO_BASE + (GPCLR0*4)) & 0x00ffffff) | PI_PERI_PHYS;
    p->length = 4;
    p->next   = dmaCbAdr(b+1) | DMA_BUS_ADR;
 }
@@ -4223,7 +4236,7 @@ static void dmaReadLevelsCb(int b, int pos)
    p = dmaCB2adr(b);
 
    p->info   = NORMAL_DMA;
-   p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | 0x7e000000;
+   p->src    = ((GPIO_BASE + (GPLEV0*4)) & 0x00ffffff) | PI_PERI_PHYS;
    p->dst    = dmaReadLevelsAdr(pos) | DMA_BUS_ADR;
    p->length = 4;
    p->next   = dmaCbAdr(b+1) | DMA_BUS_ADR;
@@ -4240,12 +4253,12 @@ static void dmaDelayCb(int b)
    if (gpioCfg.clockPeriph == PI_CLOCK_PCM)
    {
       p->info   = NORMAL_DMA | TIMED_DMA(2);
-      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+      p->dst    = ((PCM_BASE + PCM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
    }
    else
    {
       p->info   = NORMAL_DMA | TIMED_DMA(5);
-      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | 0x7e000000;
+      p->dst    = ((PWM_BASE + PWM_FIFO*4) & 0x00ffffff) | PI_PERI_PHYS;
    }
 
    p->src    = dmaPwmDataAdr(b%DMAI_PAGES) | DMA_BUS_ADR;
@@ -4265,6 +4278,8 @@ static void dmaInitCbs(void)
 
    DBG(DBG_STARTUP, "");
 
+   gpioStats.dmaInitCbsCount++;
+
    b = -1;
    level = 0;
 
@@ -4386,6 +4401,7 @@ static void * pthAlertThread(void *x)
    int numSamples, d;
    int b, n, v;
    int err;
+   int stopped;
    char fifo[32];
 
    req.tv_sec = 0;
@@ -4407,8 +4423,35 @@ static void * pthAlertThread(void *x)
    cycle = (oldSlot/PULSE_PER_CYCLE);
    pulse = (oldSlot%PULSE_PER_CYCLE);
 
+   stopped = 0;
+
    while (1)
    {
+
+      if (dmaIn[DMA_CONBLK_AD])
+      {
+         if (stopped)
+         {
+            DBG(1, "****** GOING ******");
+            stopped = 0;
+         }
+      }
+      else
+      {
+         if (!stopped)
+         {
+            DBG(1, "****** STOPPED ******");
+            stopped = 1;
+         }
+         dmaInitCbs();
+         flushDMA();
+         myGpioDelay(5000); /* let DMA run for a while */
+         initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
+         myGpioDelay(5000); /* let DMA run for a while */
+         oldSlot = 0;
+         gpioStats.DMARestarts++;
+      }
+
       gpioStats.alertTicks++;
 
       req.tv_nsec = 850000;
@@ -5161,6 +5204,13 @@ static void * pthFifoThread(void *x)
    flags = fcntl(fileno(outFifo), F_GETFL, 0);
    fcntl(fileno(outFifo), F_SETFL, flags | O_NONBLOCK);
 
+   /* don't start until DMA started */
+
+   while (!DMAstarted) myGpioDelay(1000);
+
+   myGpioDelay(20000); /* let DMA run for a while */
+
+
    while (1)
    {
       if (fgets(buf, sizeof(buf), inpFifo) == NULL)
@@ -5382,6 +5432,12 @@ static void * pthSocketThread(void *x)
    
    c = sizeof(struct sockaddr_in);
 
+   /* don't start until DMA started */
+
+   while (!DMAstarted) myGpioDelay(1000);
+
+   myGpioDelay(20000); /* let DMA run for a while */
+
    while ((fdC =
       accept(fdSock, (struct sockaddr *)&client, (socklen_t*)&c)))
    {
@@ -5484,7 +5540,7 @@ static int initZaps
          PROT_READ|PROT_WRITE,
          MAP_SHARED|MAP_FIXED|MAP_LOCKED|MAP_NORESERVE,
          fdMem,
-         (uint32_t)dmaP[n] | 0x40000000
+         (uint32_t)dmaP[n] | DMA_BUS_CACHE
       );
 
       pageAdr2 += PAGE_SIZE;
@@ -5649,6 +5705,31 @@ static int initDMAblock(int pagemapFd, int block)
    return 0;
 }
 
+#define FLUSH_PAGES 1000
+
+static void flushDMA(void)
+{
+   static int val = 0;
+
+   if (dummy != MAP_FAILED) munmap(dummy, FLUSH_PAGES*PAGE_SIZE);
+
+   dummy = MAP_FAILED;
+
+   dummy = mmap(
+       0, (FLUSH_PAGES*PAGE_SIZE),
+       PROT_READ|PROT_WRITE|PROT_EXEC,
+       MAP_SHARED|MAP_ANONYMOUS|MAP_NORESERVE|MAP_LOCKED,
+       -1, 0);
+
+   if (dummy == MAP_FAILED)
+   {
+      DBG(0, "mmap dummy failed (%m)");
+   }
+   else
+   {
+      memset(dummy, val++, (FLUSH_PAGES*PAGE_SIZE));
+   }
+}
 
 /* ----------------------------------------------------------------------- */
 
@@ -5740,8 +5821,6 @@ static int initDMAcbs(void)
    for (i=0; i<DMAI_PAGES; i++)
       DBG(DBG_STARTUP, "dmaIPhys[%d]=%08X", i, (uint32_t)dmaIPhys[i]);
 
-   dmaInitCbs();
-
    if (gpioCfg.dbgLevel >= DBG_DMACBS)
    {
       fprintf(stderr, "*** INPUT DMA CONTROL BLOCKS ***\n");
@@ -5945,8 +6024,6 @@ static void initDMAgo(volatile uint32_t  *dmaAddr, uint32_t cbAddr)
                      DMA_PANIC_PRIORITY(8) |
                      DMA_PRIORITY(8)       |
                      DMA_ACTIVATE;
-
-   DMAstarted = 1;
 }
 
 /* ----------------------------------------------------------------------- */
@@ -6390,6 +6467,81 @@ void rawDumpScript(unsigned script_id)
 
 /* ======================================================================= */
 
+void startPi1DMA(void)
+{
+   dmaInitCbs();
+
+   flushDMA();
+
+   initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
+
+   gpioStats.DMAInits++;
+}
+
+void startPi2DMA(void)
+{
+   int i, running, looped, firstCB, passedFirst;
+
+   for (i=0; i<150; i++)
+   {
+      dmaInitCbs();
+
+      flushDMA();
+   }
+
+   running = 0;
+
+   while (!running)
+   {
+      dmaInitCbs();
+      flushDMA();
+
+      initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
+
+      gpioStats.DMAInits++;
+
+      myGpioDelay(20000);
+      i = dmaNowAtICB();
+
+      if (i)
+      {
+         firstCB = i;
+
+         passedFirst = 0;
+
+         looped = 0;
+
+         while (looped < 10)
+         {
+            dmaInitCbs();
+            flushDMA();
+
+            myGpioDelay(1000);
+            i = dmaNowAtICB();
+
+            if (i < firstCB)
+            {
+               if (i)
+               {
+                  if (passedFirst)
+                  {
+                     looped++;
+                     running = 1;
+                     passedFirst = 0;
+                  }
+               }
+               else
+               {
+                  running = 0;
+                  looped = 1000;
+               }
+            }
+            else passedFirst = 1;
+         }
+      }
+   }
+}
+
 int gpioInitialise(void)
 {
    int i;
@@ -6495,11 +6647,17 @@ int gpioInitialise(void)
       pthSocketRunning = 1;
    }
 
-   initDMAgo((uint32_t *)dmaIn, (uint32_t)dmaIPhys[0]);
+   if (piModel == 1)
+      startPi1DMA();
+   else
+      startPi2DMA();
+
+   DMAstarted = 1;
 
    return PIGPIO_VERSION;
  }
 
+
 /* ----------------------------------------------------------------------- */
 
 void gpioTerminate(void)
@@ -6527,7 +6685,10 @@ void gpioTerminate(void)
 
       if (gpioCfg.showStats)
       {
-         fprintf(stderr, "micros=%d\n", gpioCfg.clockMicros);
+         fprintf(stderr,
+            "micros=%d dmaInitCbs=%d DMA inits=%d DMA restarts=%d\n",
+             gpioCfg.clockMicros, gpioStats.dmaInitCbsCount,
+             gpioStats.DMAInits, gpioStats.DMARestarts);
 
          fprintf(stderr, "samples %u maxSamples %u maxEmit %u emitFrags %u\n",
             gpioStats.numSamples, gpioStats.maxSamples,
@@ -8914,41 +9075,53 @@ unsigned gpioHardwareRevision(void)
    FILE * filp;
    char buf[512];
    char term;
+   int chars=4; /* number of chars in revision string */
 
    DBG(DBG_USER, "");
 
    if (rev) return rev;
 
+   piModel = 0;
+
    filp = fopen ("/proc/cpuinfo", "r");
 
    if (filp != NULL)
    {
       while (fgets(buf, sizeof(buf), filp) != NULL)
       {
-         if (!strncmp("model name", buf, 10))
+         if (piModel == 0)
          {
-            if (strstr (buf, "ARMv6") != NULL)
+            if (!strncasecmp("model name", buf, 10))
             {
-               piModel = 1;
-               PI_PERI_BASE = 0x20000000;
-               DMA_BUS_ADR  = 0x40000000;
-            }
-            else if (strstr (buf, "ARMv7") != NULL)
-            {
-               piModel = 2;
-               PI_PERI_BASE = 0x3F000000;
-               DMA_BUS_ADR  = 0xC0000000;
+               if (strstr (buf, "ARMv6") != NULL)
+               {
+                  piModel = 1;
+                  chars = 4;
+                  PI_PERI_BASE  = 0x20000000;
+                  DMA_BUS_ADR   = 0x40000000;
+                  DMA_BUS_CACHE = 0x40000000;
+               }
+               else if (strstr (buf, "ARMv7") != NULL)
+               {
+                  piModel = 2;
+                  chars = 6;
+                  PI_PERI_BASE  = 0x3F000000;
+                  DMA_BUS_ADR   = 0xC0000000;
+                  DMA_BUS_CACHE = 0x00000000;
+               }
             }
          }
 
-         if (!strncmp("Revision", buf, 8))
+         if (!strncasecmp("revision", buf, 8))
          {
-            if (sscanf(buf+strlen(buf)-5, "%x%c", &rev, &term) == 2)
+            if (sscanf(buf+strlen(buf)-(chars+1),
+               "%x%c", &rev, &term) == 2)
             {
                if (term != '\n') rev = 0;
             }
          }
       }
+
       fclose(filp);
    }
    return rev;
index 5b807a5aca73615925536756aea13a3f7d0a7f94..d47e5c0bbfb371e786858a012e01bd126977e6cf 100644 (file)
--- a/pigpio.h
+++ b/pigpio.h
@@ -31,7 +31,7 @@ For more information, please refer to <http://unlicense.org/>
 #include <stdint.h>
 #include <pthread.h>
 
-#define PIGPIO_VERSION 27
+#define PIGPIO_VERSION 28
 
 /*TEXT
 
index 0af3b824506cbc103cd884e8c245ea8d0dc59996..c6397938df4e332df7c26ecdf8c881e0990297e5 100644 (file)
@@ -1207,9 +1207,9 @@ daemon is started (option -t).
 .EX
    gpio: see descripton
 .br
-PWMfreq: 0 (off) or 5-250K
+PWMfreq: 0 (off) or 5-50K
 .br
-PWMduty: 0 (off) to 1000 (fully on).
+PWMduty: 0 (off) to 5000 (fully on).
 .br
 
 .EE
@@ -2671,8 +2671,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint spi_write(unsigned handle, char *buf, unsigned count)\fP"
 .IP "" 4
@@ -2696,8 +2696,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint spi_xfer(unsigned handle, char *txBuf, char *rxBuf, unsigned count)\fP"
 .IP "" 4
@@ -2724,8 +2724,8 @@ handle: >=0, as returned by a call to \fBspi_open\fP.
 .br
 
 .br
-Returns 0 if OK, otherwise PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or
-PI_SPI_XFER_FAILED.
+Returns the number of bytes transferred if OK, otherwise
+PI_BAD_HANDLE, PI_BAD_SPI_COUNT, or PI_SPI_XFER_FAILED.
 
 .IP "\fBint serial_open(char *ser_tty, unsigned ser_baud, unsigned ser_flags)\fP"
 .IP "" 4
@@ -2887,6 +2887,75 @@ handle: >=0, as returned by a call to \fBserial_open\fP.
 Returns the number of bytes of data available (>=0) if OK,
 otherwise PI_BAD_HANDLE.
 
+.IP "\fBint custom_1(unsigned arg1, unsigned arg2, char *argx, unsigned count)\fP"
+.IP "" 4
+This function is available for user customisation.
+
+.br
+
+.br
+It returns a single integer value.
+
+.br
+
+.br
+
+.EX
+ arg1: >=0
+.br
+ arg2: >=0
+.br
+ argx: extra (byte) arguments
+.br
+count: number of extra arguments
+.br
+
+.EE
+
+.br
+
+.br
+Returns >= 0 if OK, less than 0 indicates a user defined error.
+
+.IP "\fBint custom_2(unsigned arg1, char *argx, unsigned count, char *retBuf, unsigned retMax)\fP"
+.IP "" 4
+This function is available for user customisation.
+
+.br
+
+.br
+It differs from custom_1 in that it returns an array of bytes
+rather than just an integer.
+
+.br
+
+.br
+The return value is an integer indicating the number of returned bytes.
+
+.EX
+  arg1: >=0
+.br
+  argx: extra (byte) arguments
+.br
+ count: number of extra arguments
+.br
+retBuf: buffer for returned data
+.br
+retMax: maximum number of bytes to return
+.br
+
+.EE
+
+.br
+
+.br
+Returns >= 0 if OK, less than 0 indicates a user defined error.
+
+.br
+
+.br
+Note, the number of returned bytes will be retMax or less.
+
 .IP "\fBint callback(unsigned user_gpio, unsigned edge, CBFunc_t f)\fP"
 .IP "" 4
 This function initialises a new callback.
diff --git a/pigs.1 b/pigs.1
index 6235830f71dbc5272da6b2fe87245635dac44aee..78ff421209f30847c60470917762be013a3e93c6 100644 (file)
--- a/pigs.1
+++ b/pigs.1
@@ -534,11 +534,11 @@ will be returned.
 .br
 
 .EX
-$ pigs hp 18 100 900
+$ pigs hp 18 100 4000 # 80% dutycycle
 .br
 
 .br
-$ pigs hp 19 100 100
+$ pigs hp 19 100 1000 # 20% dutycycle
 .br
 
 .br
@@ -546,7 +546,7 @@ $ pigs hp 19 1 100
 .br
 -96
 .br
-ERROR: hardware PWM frequency not 5-250K
+ERROR: hardware PWM frequency not 5-50K
 .br
 
 .EE
diff --git a/x_pigs b/x_pigs
index 5a25b15edb8618bc58f0c7ee5053f6653df1978c..cd312143d45be885d2a15de8012332b89adfb51b 100755 (executable)
--- a/x_pigs
+++ b/x_pigs
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-VERSION=27
+VERSION=28
 
 GPIO=4
 
diff --git a/x_pipe b/x_pipe
index f49dfc7b7b1d863c22f7c9f43ab334bf0f3ca8a3..cfb4e86f6e7f261b6da87c6894a654164f41b206 100755 (executable)
--- a/x_pipe
+++ b/x_pipe
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-VERSION=27
+VERSION=28
 
 GPIO=4
 
@@ -159,6 +159,7 @@ read -t 1 s </dev/pigout
 if [[ $s = 0 ]]; then echo "PROCS($p) ok"; else echo "PROCS($p) fail ($s)"; fi
 
 echo "procd $p" >/dev/pigpio
+sleep 0.1
 read -t 1 s </dev/pigout
 if [[ $s = 0 ]]; then echo "PROCD($p) ok"; else echo "PROCD($p) fail ($s)"; fi