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
|
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.
|
||||||
*/
|
*/
|
||||||
|
|
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_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. */
|
||||||
|
|
||||||
|
|
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.
|
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*/
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue