mirror of https://github.com/joan2937/pigpio
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:
parent
c660e3fc8e
commit
038be60398
|
@ -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.
|
||||
*/
|
||||
|
|
72
pigpio.c
72
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. */
|
||||
|
||||
|
|
36
pigpio.h
36
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*/
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue