Allow creation of two waves with 50% padding using gpioWaveCreatePad.

- 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
This commit is contained in:
Guy McSwain 2020-03-12 09:27:51 -05:00
parent c660e3fc8e
commit 038be60398
4 changed files with 74 additions and 38 deletions

View File

@ -694,7 +694,7 @@ int cmdParse(
case 112: /* BI2CC FC GDC GPW I2CC I2CRB case 112: /* BI2CC FC GDC GPW I2CC I2CRB
MG MICS MILS MODEG NC NP PADG PFG PRG MG MICS MILS MODEG NC NP PADG PFG PRG
PROCD PROCP PROCS PRRG R READ SLRC SPIC 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. One positive parameter.
*/ */

View File

@ -2434,7 +2434,26 @@ static int myDoCommand(uintptr_t *p, unsigned bufSize, char *buf)
case PI_CMD_WVCRE: res = gpioWaveCreate(); break; 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; 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; 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; botCB = *CB + numCB - 1;
botOOL = *BOOL + size - 1; botOOL = *BOOL + numBOOL - 1;
//topOOL = //Fix: Ignore topOOL, flags not supported. topOOL = *TOOL - numTOOL;
/* link the last CB to end of wave */ /* Link the last CB to end of wave */
p->next = waveCbPOadr(botCB); p->next = waveCbPOadr(botCB);
/* add dummy cb at end of DMA */ /* Insert sentinel CB at end of DMA */
p = rawWaveCBAdr(botCB++); p = rawWaveCBAdr(botCB++);
p->info = NORMAL_DMA | DMA_DEST_IGNORE; p->info = NORMAL_DMA | DMA_DEST_IGNORE;
@ -9643,7 +9663,7 @@ int gpioWaveCreate(void)
BOOL = waveInfo[wid].botOOL; BOOL = waveInfo[wid].botOOL;
TOOL = waveInfo[wid].topOOL; 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. */ /* Sanity check. */
@ -9673,23 +9693,43 @@ int gpioWaveCreate(void)
return wid; return wid;
} }
int gpioWaveCreatePad(int percent) // Fix: Make variadic. int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL)
{ {
int i, wid; int i, wid;
int numCB, numBOOL, numTOOL; int numCB, numBOOL, numTOOL;
int CB, BOOL, TOOL; int CB, BOOL, TOOL;
DBG(DBG_USER, ""); DBG(DBG_USER, "%d, %d, %d", pctCB, pctBOOL, pctTOOL);
CHECK_INITED; 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; if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM;
/* What resources are needed? */ /* 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; wid = -1;
@ -9742,7 +9782,7 @@ int gpioWaveCreatePad(int percent) // Fix: Make variadic.
BOOL = waveInfo[wid].botOOL; BOOL = waveInfo[wid].botOOL;
TOOL = waveInfo[wid].topOOL; 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. */ /* Sanity check. */

View File

@ -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. PI_NO_WAVEFORM_ID, PI_TOO_MANY_CBS, or PI_TOO_MANY_OOL.
D*/ D*/
int gpioWaveCreatePad(int percent); int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL);
/*D /*D
This function creates a waveform like wave_create but pads the consumed Similar to gpioWaveCreate(), this function creates a waveform but pads the consumed
resources. Where percent gives the percentage of the resources to use (in terms resources. Padded waves of equal dimension can be re-cycled efficiently allowing
of the theoretical maximum, not the current amount free). This allows the reuse newly created waves to re-use the resources of deleted waves of the same dimension.
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.
. . . .
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 Upon success a wave id greater than or equal to 0 is returned, otherwise
function. 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 Waveform data provided by [*gpioWaveAdd**] and [*rawWaveAdd**] functions are
wave id is passed to [*wave_send_**] to specify the waveform to transmit. consumed by this function.
A usage would be the creation of two waves where one is filled while the other 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. 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 Repeat steps 2-4 as needed always waiting for the active waveform to be transmitted
before marking it as deleted. 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*/ D*/
/*F*/ /*F*/

View File

@ -2325,7 +2325,7 @@ class pi():
wave id is passed to [*wave_send_**] to specify the waveform to transmit. 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 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. This buffer structure allows the transmission of infinite wave sequences.
Step 1. [*wave_clear*] to clear all waveforms and added data. Step 1. [*wave_clear*] to clear all waveforms and added data.