diff --git a/command.c b/command.c index 4a1da4d..0170005 100644 --- a/command.c +++ b/command.c @@ -201,7 +201,8 @@ cmdInfo_t cmdInfo[]= {PI_CMD_WVBSY, "WVBSY", 101, 2, 1}, // gpioWaveTxBusy {PI_CMD_WVCHA, "WVCHA", 197, 0, 0}, // gpioWaveChain {PI_CMD_WVCLR, "WVCLR", 101, 0, 1}, // gpioWaveClear - {PI_CMD_WVCRE, "WVCRE", 101, 2, 1}, // gpioWaveCreate + {PI_CMD_WVCRE, "WVCRE", 101, 2, 1}, // gpioWaveCreate + {PI_CMD_WVCAP, "WVCAP", 112, 2, 1}, // gpioWaveCreatePad {PI_CMD_WVDEL, "WVDEL", 112, 0, 1}, // gpioWaveDelete {PI_CMD_WVGO, "WVGO" , 101, 2, 0}, // gpioWaveTxStart {PI_CMD_WVGOR, "WVGOR", 101, 2, 0}, // gpioWaveTxStart diff --git a/pigpio.c b/pigpio.c index a2aeb66..fe5fc04 100644 --- a/pigpio.c +++ b/pigpio.c @@ -2432,7 +2432,7 @@ static int myDoCommand(uintptr_t *p, unsigned bufSize, char *buf) case PI_CMD_WVCLR: res = gpioWaveClear(); break; - case PI_CMD_WVCRE: res = gpioWaveCreate(p[1]); break; + case PI_CMD_WVCRE: res = gpioWaveCreate(); break; case PI_CMD_WVDEL: res = gpioWaveDelete(p[1]); break; @@ -2992,7 +2992,7 @@ 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 botCB=*CB, botOOL=*BOOL, topOOL=*TOOL; @@ -3130,28 +3130,6 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size) } } - if (size) - { - /* pad the wave */ - - botCB = *CB + NUM_WAVE_CBS / size - 1; - botOOL = *BOOL + NUM_WAVE_OOL / size - 1; - //topOOL = //Fix: Ignore topOOL, flags not supported. - - /* link the last CB to end of wave */ - - p->next = waveCbPOadr(botCB); - - /* add dummy cb at end of DMA */ - - p = rawWaveCBAdr(botCB++); - p->info = NORMAL_DMA | DMA_DEST_IGNORE; - p->src = waveOOLPOadr(botOOL++); - p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS; - p->length = 4; - p->next = 0; - } - if (p != NULL) { if (wave_mode == PI_WAVE_MODE_ONE_SHOT) @@ -9574,7 +9552,7 @@ int rawWaveAddSPI( /* ----------------------------------------------------------------------- */ -int gpioWaveCreate(int size) // Fix: Make variadic. +int gpioWaveCreate(void) { int i, wid; int numCB, numBOOL, numTOOL; @@ -9588,14 +9566,7 @@ int gpioWaveCreate(int size) // Fix: Make variadic. /* What resources are needed? */ - if (size == 0) - waveCBsOOLs(&numCB, &numBOOL, &numTOOL); - - else { - numCB = NUM_WAVE_CBS / size; - numBOOL = NUM_WAVE_OOL / size; - numTOOL = 0; // ignore TOOL, ie, no flags support - } + waveCBsOOLs(&numCB, &numBOOL, &numTOOL); wid = -1; @@ -9648,7 +9619,7 @@ int gpioWaveCreate(int size) // Fix: Make variadic. BOOL = waveInfo[wid].botOOL; TOOL = waveInfo[wid].topOOL; - wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, size); + wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL); /* Sanity check. */ @@ -9662,9 +9633,6 @@ int gpioWaveCreate(int size) // Fix: Make variadic. numTOOL, waveInfo[wid].topOOL-TOOL); } - DBG(DBG_USER, "Wave Stats: wid=%d CBs %d BOOL %d TOOL %d", wid, - numCB, numBOOL, numTOOL); - waveInfo[wid].deleted = 0; /* Consume waves. */ diff --git a/pigpio.h b/pigpio.h index e3eb97d..da29f1b 100644 --- a/pigpio.h +++ b/pigpio.h @@ -1986,6 +1986,43 @@ 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); +/*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. + +. . +pi: >=0 (as returned by [*pigpio_start*]). +. . + +The data provided by the [*wave_add_**] functions is consumed by this +function. + +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. + +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. +This buffer structure allows the transmission of infinite wave sequences. + +Step 1. [*wave_clear*] to clear all waveforms and added data. + +Step 2. [*wave_add_**] calls to supply the waveform data. + +Step 3. [*wave_create_and_pad*] to create a 50% padded waveform and get a unique id + +Step 4. [*wave_send_**] with the id of the waveform to transmit. + +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*/ int gpioWaveDelete(unsigned wave_id); @@ -6271,6 +6308,7 @@ PARAMS*/ #define PI_CMD_EVT 116 #define PI_CMD_PROCU 117 +#define PI_CMD_WVCAP 118 /*DEF_E*/ diff --git a/pigpiod_if2.c b/pigpiod_if2.c index 90fb5fb..7af8313 100644 --- a/pigpiod_if2.c +++ b/pigpiod_if2.c @@ -953,6 +953,9 @@ int wave_add_serial( int wave_create(int pi) {return pigpio_command(pi, PI_CMD_WVCRE, 0, 0, 1);} +int wave_create_and_pad(int pi, int percent) + {return pigpio_command(pi, PI_CMD_WVCAP, percent, 0, 1);} + int wave_delete(int pi, unsigned wave_id) {return pigpio_command(pi, PI_CMD_WVDEL, wave_id, 0, 1);} diff --git a/pigpiod_if2.h b/pigpiod_if2.h index 8d6f132..5406186 100644 --- a/pigpiod_if2.h +++ b/pigpiod_if2.h @@ -1371,6 +1371,43 @@ 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 wave_create_and_pad(int pi, int percent); +/*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. + +. . +pi: >=0 (as returned by [*pigpio_start*]). +. . + +The data provided by the [*wave_add_**] functions is consumed by this +function. + +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. + +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. +This buffer structure allows the transmission of infinite wave sequences. + +Step 1. [*wave_clear*] to clear all waveforms and added data. + +Step 2. [*wave_add_**] calls to supply the waveform data. + +Step 3. [*wave_create_and_pad*] to create a 50% padded waveform and get a unique id + +Step 4. [*wave_send_**] with the id of the waveform to transmit. + +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*/ int wave_delete(int pi, unsigned wave_id);