Allow creation of two waves with 50% padding using gpioWaveCreatePad.
authorGuy McSwain <guy.mcswain@gmail.com>
Thu, 12 Mar 2020 14:27:51 +0000 (09:27 -0500)
committerGuy McSwain <guy.mcswain@gmail.com>
Thu, 12 Mar 2020 14:44:41 +0000 (09:44 -0500)
- gpioWaveCreatePad takes three arguments: %CB, %BOOL, %TOOL
- gpioWaveCreatePad checks range of arguments
- gpioWaveCreatePad checks dimension of wave fits inside padding
- wave2Cbs takes three arguments: numCB, numBOOL, numTOOL
- socket command PI_CMD_WVCAP is variadic

command.c
pigpio.c
pigpio.h
pigpio.py

index 0170005364ea50f789567509a4c25c898d0dc5da..ffc34630edbe8d174a56d98cdeec324b0694bd7d 100644 (file)
--- a/command.c
+++ b/command.c
@@ -694,7 +694,7 @@ int cmdParse(
       case 112: /* BI2CC FC  GDC  GPW  I2CC  I2CRB
                    MG  MICS  MILS  MODEG  NC  NP  PADG PFG  PRG
                    PROCD  PROCP  PROCS  PRRG  R  READ  SLRC  SPIC
-                   WVDEL  WVSC  WVSM  WVSP  WVTX  WVTXR  BSPIC
+                   WVCAP WVDEL  WVSC  WVSM  WVSP  WVTX  WVTXR  BSPIC
 
                    One positive parameter.
                 */
index 920b9fb19a6cc341373f4e8e22c172355dc76c25..bbac95d74567c3e23e20d920bcf3a502c4fa2fd6 100644 (file)
--- a/pigpio.c
+++ b/pigpio.c
@@ -2434,7 +2434,26 @@ static int myDoCommand(uintptr_t *p, unsigned bufSize, char *buf)
 
       case PI_CMD_WVCRE: res = gpioWaveCreate(); break;
 
-      case PI_CMD_WVCAP: res = gpioWaveCreatePad(p[1]); break;
+      case PI_CMD_WVCAP:
+         /* Make WVCAP variadic */
+         if (p[3] == 4)
+         {
+            memcpy(&tmp3, buf, 4); /* percent TOOL */
+            res = gpioWaveCreatePad(p[1], p[2], tmp3); /* rawWaveAdd* usage */
+            break;
+         }
+         if (p[2] && p[3]==0)
+         {
+            res = gpioWaveCreatePad(p[1], p[2], 0);
+            break;
+         }
+         if (p[2]==0 && p[3]==0)
+         {
+            res = gpioWaveCreatePad(p[1], p[1], 0); /* typical usage */
+            break;
+         }
+         res = PI_BAD_WAVE_ID; // FIX?
+         break;
 
       case PI_CMD_WVDEL: res = gpioWaveDelete(p[1]); break;
 
@@ -2994,7 +3013,8 @@ static void waveCBsOOLs(int *numCBs, int *numBOOLs, int *numTOOLs)
 
 /* ----------------------------------------------------------------------- */
 
-static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size)
+static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL,
+                    int numCB, int numBOOL, int numTOOL)
 {
    int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL;
 
@@ -3132,19 +3152,19 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size)
       }
    }
 
-   if (size)
+   if (numCB)
    {
-      /* pad the wave */
+      /* Pad the wave */
 
-      botCB = *CB + size - 1;
-      botOOL = *BOOL + size - 1;
-      //topOOL =   //Fix:  Ignore topOOL, flags not supported.
+      botCB = *CB + numCB - 1;
+      botOOL = *BOOL + numBOOL - 1;
+      topOOL = *TOOL - numTOOL;
 
-      /* link the last CB to end of wave */
+      /* Link the last CB to end of wave */
 
       p->next = waveCbPOadr(botCB);
 
-      /* add dummy cb at end of DMA */
+      /* Insert sentinel CB at end of DMA */
 
       p = rawWaveCBAdr(botCB++);
       p->info   = NORMAL_DMA | DMA_DEST_IGNORE;
@@ -9643,7 +9663,7 @@ int gpioWaveCreate(void)
    BOOL = waveInfo[wid].botOOL;
    TOOL = waveInfo[wid].topOOL;
 
-   wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, 0);
+   wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, 0, 0, 0);
 
    /* Sanity check. */
 
@@ -9673,23 +9693,43 @@ int gpioWaveCreate(void)
    return wid;
 }
 
-int gpioWaveCreatePad(int percent)  // Fix: Make variadic.
+int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL)
 {
    int i, wid;
    int numCB, numBOOL, numTOOL;
    int CB, BOOL, TOOL;
 
-   DBG(DBG_USER, "");
+   DBG(DBG_USER, "%d, %d, %d", pctCB, pctBOOL, pctTOOL);
 
    CHECK_INITED;
 
+   if (pctCB < 0 || pctCB > 100)
+      SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctCB=(%d)", pctCB);
+   if (pctBOOL < 0 || pctBOOL > 100)
+      SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctBOOL=(%d)", pctCB);
+   if (pctTOOL < 0 || pctTOOL > 100)
+      SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctTOOL=(%d)", pctCB);
+
    if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM;
 
    /* What resources are needed? */
+   waveCBsOOLs(&numCB, &numBOOL, &numTOOL);
+
+   /* Amount of pad required */
+   CB = (NUM_WAVE_CBS - PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE -1) * pctCB / 100;
+   BOOL = (NUM_WAVE_OOL - PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE -1) * pctBOOL /100;
+   TOOL = (NUM_WAVE_OOL * pctTOOL) / 100;
+
+   /* Reject if wave is too big */
+   if (numCB >= CB) return PI_TOO_MANY_CBS;
+   if (numBOOL >= BOOL) return PI_I2C_WRITE_FAILED; // Fix
+   if (numTOOL > TOOL) return PI_I2C_READ_FAILED; // Fix
+
+   /* Set the padding */
+   numCB = CB;
+   numBOOL = BOOL;
+   numTOOL = TOOL;
 
-   numCB = (NUM_WAVE_CBS * percent) / 100;
-   numBOOL = (NUM_WAVE_OOL * percent) /100;
-   numTOOL = 0;  // ignore TOOL, ie, no flags support
 
    wid = -1;
 
@@ -9742,7 +9782,7 @@ int gpioWaveCreatePad(int percent)  // Fix: Make variadic.
    BOOL = waveInfo[wid].botOOL;
    TOOL = waveInfo[wid].topOOL;
 
-   wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, numCB);
+   wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, numCB, numBOOL, numTOOL);
 
    /* Sanity check. */
 
index da29f1ba17fd1f0da45d390af9ba4849942122bd..bffcd8d31593694328f8bf86841fb21f49087664 100644 (file)
--- a/pigpio.h
+++ b/pigpio.h
@@ -1986,42 +1986,38 @@ Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
 PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
 D*/
 
-int gpioWaveCreatePad(int percent);
+int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL);
 /*D
-This function creates a waveform like wave_create but pads the consumed
-resources. Where percent gives the percentage of the resources to use (in terms
-of the theoretical maximum, not the current amount free). This allows the reuse 
-of deleted waves while a transmission is active. Upon success a wave id
-greater than or equal to 0 is returned, otherwise PI_EMPTY_WAVEFORM,
-PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
+Similar to gpioWaveCreate(), this function creates a waveform but pads the consumed
+resources. Padded waves of equal dimension can be re-cycled efficiently allowing
+newly created waves to re-use the resources of deleted waves of the same dimension.
 
 . .
-pi: >=0 (as returned by [*pigpio_start*]).
+pctCB: 0-100, the percent of all DMA control blocks to consume.
+pctBOOL: 0-100, the percent of On-Off-Level (OOL) buffer to consume for wave output.
+pctTOOL: 0-100, the percent of OOL buffer to consume for wave input (flags).
 . .
 
-The data provided by the [*wave_add_**] functions is consumed by this
-function.
+Upon success a wave id greater than or equal to 0 is returned, otherwise
+PI_EMPTY_WAVEFORM, PI_TOO_MANY_CBS, PI_TOO_MANY_OOL, or PI_NO_WAVEFORM_ID.
 
-As many waveforms may be created as there is space available. The
-wave id is passed to [*wave_send_**] to specify the waveform to transmit.
+Waveform data provided by [*gpioWaveAdd**] and [*rawWaveAdd**] functions are
+consumed by this function.
 
 A usage would be the creation of two waves where one is filled while the other
-is beeing transmitted. Each wave is assigned 50% of the available resources.
+is being transmitted. Each wave is assigned 50% of the resources.
 This buffer structure allows the transmission of infinite wave sequences.
 
-Step 1. [*wave_clear*] to clear all waveforms and added data.
+Step 1. [*gpioWaveClear*] to clear all waveforms and added data.
 
-Step 2. [*wave_add_**] calls to supply the waveform data.
+Step 2. [*gpioWaveAdd*] calls to supply the waveform data.
 
-Step 3. [*wave_create_and_pad*] to create a 50% padded waveform and get a unique id
+Step 3. gpioWaveCreatePad(50,50,0) to create a 50% padded waveform and get a unique id
 
-Step 4. [*wave_send_**] with the id of the waveform to transmit.
+Step 4. [*gpioWaveTxSend*] with the wave id and PI_WAVE_MODE_ONE_SHOT_SYNC.
 
 Repeat steps 2-4 as needed always waiting for the active waveform to be transmitted
 before marking it as deleted.
-
-Returns the new waveform id if OK, otherwise PI_EMPTY_WAVEFORM,
-PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
 D*/
 
 /*F*/
index fcc54a7bd788de5bb68223e5ce59fc2ccf838d33..a9f10e31520e05a16244d944a1094172b94930a1 100644 (file)
--- a/pigpio.py
+++ b/pigpio.py
@@ -2325,7 +2325,7 @@ class pi():
       wave id is passed to [*wave_send_**] to specify the waveform to transmit.
 
       A usage would be the creation of two waves where one is filled while the other
-      is beeing transmitted. Each wave is assigned 50% of the available resources.
+      is being transmitted. Each wave is assigned 50% of the available resources.
       This buffer structure allows the transmission of infinite wave sequences.
 
       Step 1. [*wave_clear*] to clear all waveforms and added data.