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;
/* ----------------------------------------------------------------------- */
-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;
}
}
- 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;
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. */
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;
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. */
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*/