From f4a4b9772f6d039d5026fa7348f09e557abe898c Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Tue, 3 Mar 2020 23:13:57 -0600 Subject: [PATCH 01/13] Wave create using fixed size CB, OOL --- command.c | 2 +- pigpio.c | 39 ++++++++++++++++++++++++++++++++++----- pigpio.h | 2 +- pigpio.py | 4 ++-- x_pigpio.c | 4 ++-- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/command.c b/command.c index 4a1da4d..0687057 100644 --- a/command.c +++ b/command.c @@ -201,7 +201,7 @@ 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", 112, 2, 1}, // gpioWaveCreate {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 fe5fc04..45d274f 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(); break; + case PI_CMD_WVCRE: res = gpioWaveCreate(p[1]); 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) +static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size) { int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL; @@ -3130,6 +3130,25 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL) } } + /* pad the wave */ + botCB = *CB + NUM_WAVE_CBS / size - 1; + botOOL = *BOOL + NUM_WAVE_OOL / size - 1; + //topOOL = *TOOL - (NUM_WAVE_OOL / size / 8); + + /* 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) @@ -9552,7 +9571,7 @@ int rawWaveAddSPI( /* ----------------------------------------------------------------------- */ -int gpioWaveCreate(void) +int gpioWaveCreate(int size) // Fix: Make variadic. { int i, wid; int numCB, numBOOL, numTOOL; @@ -9566,7 +9585,14 @@ int gpioWaveCreate(void) /* What resources are needed? */ - waveCBsOOLs(&numCB, &numBOOL, &numTOOL); + 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 + } wid = -1; @@ -9619,7 +9645,7 @@ int gpioWaveCreate(void) BOOL = waveInfo[wid].botOOL; TOOL = waveInfo[wid].topOOL; - wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL); + wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, size); /* Sanity check. */ @@ -9633,6 +9659,9 @@ int gpioWaveCreate(void) 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..8930d12 100644 --- a/pigpio.h +++ b/pigpio.h @@ -1933,7 +1933,7 @@ D*/ /*F*/ -int gpioWaveCreate(void); +int gpioWaveCreate(int); /*D This function creates a waveform from the data provided by the prior calls to the [*gpioWaveAdd**] functions. Upon success a wave id diff --git a/pigpio.py b/pigpio.py index cfaf845..af63a19 100644 --- a/pigpio.py +++ b/pigpio.py @@ -2257,7 +2257,7 @@ class pi(): else: return 0 - def wave_create(self): + def wave_create(self, size): """ Creates a waveform from the data provided by the prior calls to the [*wave_add_**] functions. @@ -2302,7 +2302,7 @@ class pi(): wid = pi.wave_create() ... """ - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, 0, 0)) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, size, 0)) def wave_delete(self, wave_id): """ diff --git a/x_pigpio.c b/x_pigpio.c index cd15389..61b37c2 100644 --- a/x_pigpio.c +++ b/x_pigpio.c @@ -391,7 +391,7 @@ To the lascivious pleasing of a lute.\n\ e = gpioWaveAddGeneric(4, wf); CHECK(5, 2, e, 4, 0, "pulse, wave add generic"); - wid = gpioWaveCreate(); + wid = gpioWaveCreate(0); e = gpioWaveTxSend(wid, PI_WAVE_MODE_REPEAT); if (e < 14) CHECK(5, 3, e, 9, 0, "wave tx repeat"); else CHECK(5, 3, e, 19, 0, "wave tx repeat"); @@ -413,7 +413,7 @@ To the lascivious pleasing of a lute.\n\ e = gpioWaveAddSerial(GPIO, BAUD, 8, 2, 5000000, strlen(TEXT), TEXT); CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial"); - wid = gpioWaveCreate(); + wid = gpioWaveCreate(0); e = gpioWaveTxSend(wid, PI_WAVE_MODE_ONE_SHOT); if (e < 6964) CHECK(5, 8, e, 6811, 0, "wave tx start"); else CHECK(5, 8, e, 7116, 0, "wave tx start"); From 58c5ad756bb751fab80619ac89d19fbe8bbd8829 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 4 Mar 2020 01:25:01 -0600 Subject: [PATCH 02/13] Skip wave padding when size = 0 --- pigpio.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/pigpio.c b/pigpio.c index 45d274f..a2aeb66 100644 --- a/pigpio.c +++ b/pigpio.c @@ -3130,24 +3130,27 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size) } } - /* pad the wave */ - botCB = *CB + NUM_WAVE_CBS / size - 1; - botOOL = *BOOL + NUM_WAVE_OOL / size - 1; - //topOOL = *TOOL - (NUM_WAVE_OOL / size / 8); + if (size) + { + /* pad the wave */ - /* link the last CB to end of wave */ + botCB = *CB + NUM_WAVE_CBS / size - 1; + botOOL = *BOOL + NUM_WAVE_OOL / size - 1; + //topOOL = //Fix: Ignore topOOL, flags not supported. - 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; + /* 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) { From 71fe78aac9389eb0d17349e0d3e90e406e0035da Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 13:53:44 +0100 Subject: [PATCH 03/13] Added .so.* to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index f67291c..4108796 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.o *.so +*.so.* *.pyc pig2vcd pigpiod From 773378fd24e1a8584613c0b3385f411caae9c7c2 Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 14:02:26 +0100 Subject: [PATCH 04/13] Reverte added site paramezer in wave_create --- command.c | 2 +- pigpio.h | 2 +- pigpio.py | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/command.c b/command.c index 0687057..4a1da4d 100644 --- a/command.c +++ b/command.c @@ -201,7 +201,7 @@ 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", 112, 2, 1}, // gpioWaveCreate + {PI_CMD_WVCRE, "WVCRE", 101, 2, 1}, // gpioWaveCreate {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.h b/pigpio.h index 8930d12..e3eb97d 100644 --- a/pigpio.h +++ b/pigpio.h @@ -1933,7 +1933,7 @@ D*/ /*F*/ -int gpioWaveCreate(int); +int gpioWaveCreate(void); /*D This function creates a waveform from the data provided by the prior calls to the [*gpioWaveAdd**] functions. Upon success a wave id diff --git a/pigpio.py b/pigpio.py index af63a19..cfaf845 100644 --- a/pigpio.py +++ b/pigpio.py @@ -2257,7 +2257,7 @@ class pi(): else: return 0 - def wave_create(self, size): + def wave_create(self): """ Creates a waveform from the data provided by the prior calls to the [*wave_add_**] functions. @@ -2302,7 +2302,7 @@ class pi(): wid = pi.wave_create() ... """ - return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, size, 0)) + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, 0, 0)) def wave_delete(self, wave_id): """ From b9b8eff3903f322f0ed3d70d7cbda7f153103ee4 Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 16:37:23 +0100 Subject: [PATCH 05/13] Reverted size paramter fore wavecreate in x_pigpio.c --- x_pigpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x_pigpio.c b/x_pigpio.c index 61b37c2..cd15389 100644 --- a/x_pigpio.c +++ b/x_pigpio.c @@ -391,7 +391,7 @@ To the lascivious pleasing of a lute.\n\ e = gpioWaveAddGeneric(4, wf); CHECK(5, 2, e, 4, 0, "pulse, wave add generic"); - wid = gpioWaveCreate(0); + wid = gpioWaveCreate(); e = gpioWaveTxSend(wid, PI_WAVE_MODE_REPEAT); if (e < 14) CHECK(5, 3, e, 9, 0, "wave tx repeat"); else CHECK(5, 3, e, 19, 0, "wave tx repeat"); @@ -413,7 +413,7 @@ To the lascivious pleasing of a lute.\n\ e = gpioWaveAddSerial(GPIO, BAUD, 8, 2, 5000000, strlen(TEXT), TEXT); CHECK(5, 7, e, 3405, 0, "wave clear, wave add serial"); - wid = gpioWaveCreate(0); + wid = gpioWaveCreate(); e = gpioWaveTxSend(wid, PI_WAVE_MODE_ONE_SHOT); if (e < 6964) CHECK(5, 8, e, 6811, 0, "wave tx start"); else CHECK(5, 8, e, 7116, 0, "wave tx start"); From 4ab125cfff720e48fe2d055fe27eb4b8fc415876 Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 17:42:55 +0100 Subject: [PATCH 06/13] Added WaveCreatePad to API --- command.c | 3 ++- pigpio.c | 42 +++++------------------------------------- pigpio.h | 38 ++++++++++++++++++++++++++++++++++++++ pigpiod_if2.c | 3 +++ pigpiod_if2.h | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 85 insertions(+), 38 deletions(-) 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); From a9f5dc17d9ae3a17337e6df10a1eebb653c3a742 Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 18:26:08 +0100 Subject: [PATCH 07/13] Added wave_create_and_pad to pigpio.py --- pigpio.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/pigpio.py b/pigpio.py index cfaf845..fcc54a7 100644 --- a/pigpio.py +++ b/pigpio.py @@ -571,6 +571,7 @@ _PI_CMD_EVM =115 _PI_CMD_EVT =116 _PI_CMD_PROCU=117 +_PI_CMD_WVCAP=118 # pigpio error numbers @@ -2304,6 +2305,42 @@ class pi(): """ return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCRE, 0, 0)) + def wave_create_and_pad(self, percent): + """ + 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. + """ + return _u2i(_pigpio_command(self.sl, _PI_CMD_WVCAP, percent, 0)) + def wave_delete(self, wave_id): """ This function deletes the waveform with id wave_id. From c660e3fc8e23c80bbc2f025ac659e07d9f3045e1 Mon Sep 17 00:00:00 2001 From: Jul3k Date: Thu, 5 Mar 2020 18:28:31 +0100 Subject: [PATCH 08/13] Added WaveCreatePad to pigpio.c --- pigpio.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/pigpio.c b/pigpio.c index fe5fc04..920b9fb 100644 --- a/pigpio.c +++ b/pigpio.c @@ -2434,6 +2434,8 @@ 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_WVDEL: res = gpioWaveDelete(p[1]); break; case PI_CMD_WVGO: res = gpioWaveTxStart(PI_WAVE_MODE_ONE_SHOT); break; @@ -2992,7 +2994,7 @@ static void waveCBsOOLs(int *numCBs, int *numBOOLs, int *numTOOLs) /* ----------------------------------------------------------------------- */ -static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL) +static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, int size) { int botCB=*CB, botOOL=*BOOL, topOOL=*TOOL; @@ -3130,6 +3132,28 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL) } } + if (size) + { + /* pad the wave */ + + botCB = *CB + size - 1; + botOOL = *BOOL + 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) @@ -9566,7 +9590,7 @@ int gpioWaveCreate(void) /* What resources are needed? */ - waveCBsOOLs(&numCB, &numBOOL, &numTOOL); + waveCBsOOLs(&numCB, &numBOOL, &numTOOL); wid = -1; @@ -9619,7 +9643,7 @@ int gpioWaveCreate(void) BOOL = waveInfo[wid].botOOL; TOOL = waveInfo[wid].topOOL; - wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL); + wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, 0); /* Sanity check. */ @@ -9633,6 +9657,9 @@ int gpioWaveCreate(void) 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. */ @@ -9646,6 +9673,104 @@ int gpioWaveCreate(void) return wid; } +int gpioWaveCreatePad(int percent) // Fix: Make variadic. +{ + int i, wid; + int numCB, numBOOL, numTOOL; + int CB, BOOL, TOOL; + + DBG(DBG_USER, ""); + + CHECK_INITED; + + if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM; + + /* What resources are needed? */ + + numCB = (NUM_WAVE_CBS * percent) / 100; + numBOOL = (NUM_WAVE_OOL * percent) /100; + numTOOL = 0; // ignore TOOL, ie, no flags support + + wid = -1; + + /* Is there an exact fit with a deleted wave. */ + + for (i=0; i= NUM_WAVE_CBS) + return PI_TOO_MANY_CBS; + + if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL)) + return PI_TOO_MANY_OOL; + + if (wid >= PI_MAX_WAVES) + return PI_NO_WAVEFORM_ID; + + wid = waveOutCount++; + + waveInfo[wid].botCB = waveOutBotCB; + waveInfo[wid].topCB = waveOutBotCB + numCB -1; + waveInfo[wid].botOOL = waveOutBotOOL; + waveInfo[wid].topOOL = waveOutTopOOL; + waveInfo[wid].numCB = numCB; + waveInfo[wid].numBOOL = numBOOL; + waveInfo[wid].numTOOL = numTOOL; + + waveOutBotCB += numCB; + waveOutBotOOL += numBOOL; + waveOutTopOOL -= numTOOL; + } + + /* Must be room if got this far. */ + + CB = waveInfo[wid].botCB; + BOOL = waveInfo[wid].botOOL; + TOOL = waveInfo[wid].topOOL; + + wave2Cbs(PI_WAVE_MODE_ONE_SHOT, &CB, &BOOL, &TOOL, numCB); + + /* Sanity check. */ + + if ( (numCB != (CB-waveInfo[wid].botCB)) || + (numBOOL != (BOOL-waveInfo[wid].botOOL)) || + (numTOOL != (waveInfo[wid].topOOL-TOOL)) ) + { + DBG(DBG_ALWAYS, "ERROR wid=%d CBs %d=%d BOOL %d=%d TOOL %d=%d", wid, + numCB, CB-waveInfo[wid].botCB, + numBOOL, BOOL-waveInfo[wid].botOOL, + 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. */ + + wfc[0] = 0; + wfc[1] = 0; + wfc[2] = 0; + + wfcur = 0; + + return wid; +} /* ----------------------------------------------------------------------- */ int gpioWaveDelete(unsigned wave_id) From 038be6039851577a06624867749d4d817bcaf9f7 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Thu, 12 Mar 2020 09:27:51 -0500 Subject: [PATCH 09/13] 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 --- command.c | 2 +- pigpio.c | 72 ++++++++++++++++++++++++++++++++++++++++++------------- pigpio.h | 36 +++++++++++++--------------- pigpio.py | 2 +- 4 files changed, 74 insertions(+), 38 deletions(-) diff --git a/command.c b/command.c index 0170005..ffc3463 100644 --- a/command.c +++ b/command.c @@ -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. */ diff --git a/pigpio.c b/pigpio.c index 920b9fb..bbac95d 100644 --- a/pigpio.c +++ b/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. */ diff --git a/pigpio.h b/pigpio.h index da29f1b..bffcd8d 100644 --- a/pigpio.h +++ b/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*/ diff --git a/pigpio.py b/pigpio.py index fcc54a7..a9f10e3 100644 --- a/pigpio.py +++ b/pigpio.py @@ -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. From 7f05ff4c48b00503b77a08d854364f431758525c Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Thu, 12 Mar 2020 09:46:58 -0500 Subject: [PATCH 10/13] Fix error messages on gpioWaveCreatePad --- pigpio.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pigpio.c b/pigpio.c index bbac95d..4be1b67 100644 --- a/pigpio.c +++ b/pigpio.c @@ -9722,8 +9722,8 @@ int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL) /* 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 + if (numBOOL >= BOOL) return PI_TOO_MANY_OOL; + if (numTOOL > TOOL) return PI_TOO_MANY_OOL; /* Set the padding */ numCB = CB; From c38087352fcc7e4d99af1d8be6eabd18a5b543fc Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 18 Mar 2020 16:31:42 -0500 Subject: [PATCH 11/13] Use two-beat DMA control block on pulse with set and clear OOLs. --- pigpio.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/pigpio.c b/pigpio.c index 4be1b67..1f3dd68 100644 --- a/pigpio.c +++ b/pigpio.c @@ -396,6 +396,7 @@ bit 0 READ_LAST_NOT_SET_ERROR #define DMA_DEST_WIDTH (1<< 5) #define DMA_DEST_INC (1<< 4) #define DMA_WAIT_RESP (1<< 3) +#define DMA_TDMODE (1<< 1) #define DMA_DEBUG_READ_ERR (1<<2) #define DMA_DEBUG_FIFO_ERR (1<<1) @@ -664,6 +665,7 @@ bit 0 READ_LAST_NOT_SET_ERROR /* --------------------------------------------------------------- */ #define NORMAL_DMA (DMA_NO_WIDE_BURSTS | DMA_WAIT_RESP) +#define TWO_BEAT_DMA (DMA_TDMODE | DMA_BURST_LENGTH(1)) #define TIMED_DMA(x) (DMA_DEST_DREQ | DMA_PERIPHERAL_MAPPING(x)) @@ -2998,8 +3000,7 @@ static void waveCBsOOLs(int *numCBs, int *numBOOLs, int *numTOOLs) for (i=0; iinfo = TWO_BEAT_DMA; + p->src = waveOOLPOadr(botOOL); + waveSetOOL(botOOL++, waves[i].gpioOn); + s_stride = waveOOLPOadr(botOOL) - p->src; + waveSetOOL(botOOL++, waves[i].gpioOff); + p->dst = ((GPIO_BASE + (GPSET0*4)) & 0x00ffffff) | PI_PERI_BUS; + p->length = (2<<16) + 4; // 2 transfers of 4 bytes each + p->stride = (12<<16) + s_stride; // d_stride = (GPCLR0-GPSET0)*4 = 12 + p->next = waveCbPOadr(botCB); + } + if (waves[i].gpioOn && !waves[i].gpioOff) { waveSetOOL(botOOL, waves[i].gpioOn); @@ -3074,8 +3090,7 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, p->length = 4; p->next = waveCbPOadr(botCB); } - - if (waves[i].gpioOff) + if (waves[i].gpioOff && !waves[i].gpioOn) { waveSetOOL(botOOL, waves[i].gpioOff); @@ -3087,7 +3102,6 @@ static int wave2Cbs(unsigned wave_mode, int *CB, int *BOOL, int *TOOL, p->length = 4; p->next = waveCbPOadr(botCB); } - if (waves[i].flags & WAVE_FLAG_READ) { p = rawWaveCBAdr(botCB++); @@ -3368,9 +3382,7 @@ int rawWaveAddGeneric(unsigned numIn1, rawWave_t *in1) cbs += waveDelayCBs(tDelay); - if (out[outPos].gpioOn) cbs++; /* one cb if gpio on */ - - if (out[outPos].gpioOff) cbs++; /* one cb if gpio off */ + if (out[outPos].gpioOn || out[outPos].gpioOff) cbs++; if (out[outPos].flags & WAVE_FLAG_READ) { From b229b67ce02dbd1ea2daa7bf107e570e0cc73144 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Sun, 22 Mar 2020 12:26:26 -0500 Subject: [PATCH 12/13] Correct max wave resource comparison tests. --- .gitignore | 2 ++ pigpio.c | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 4108796..140d796 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ __pycache__ build dist *.egg-info +wavepad_jitter.py + diff --git a/pigpio.c b/pigpio.c index 1f3dd68..474da1c 100644 --- a/pigpio.c +++ b/pigpio.c @@ -9645,10 +9645,10 @@ int gpioWaveCreate(void) { /* Are there enough spare resources? */ - if ((numCB+waveOutBotCB) >= NUM_WAVE_CBS) + if ((numCB+waveOutBotCB) > NUM_WAVE_CBS) return PI_TOO_MANY_CBS; - if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL)) + if ((numBOOL+waveOutBotOOL) > (waveOutTopOOL-numTOOL)) return PI_TOO_MANY_OOL; if (wid >= PI_MAX_WAVES) @@ -9718,9 +9718,9 @@ int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL) 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); + SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctBOOL=(%d)", pctBOOL); if (pctTOOL < 0 || pctTOOL > 100) - SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctTOOL=(%d)", pctCB); + SOFT_ERROR(PI_BAD_PARAM, "bad wave param, pctTOOL=(%d)", pctTOOL); if (wfc[wfcur] == 0) return PI_EMPTY_WAVEFORM; @@ -9728,13 +9728,13 @@ int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL) 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; + CB = (NUM_WAVE_CBS - PI_WAVE_COUNT_PAGES*CBS_PER_OPAGE) * pctCB / 100; + BOOL = (NUM_WAVE_OOL - PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE) * pctBOOL /100; + TOOL = (NUM_WAVE_OOL - PI_WAVE_COUNT_PAGES*OOL_PER_OPAGE) * pctTOOL /100; /* Reject if wave is too big */ - if (numCB >= CB) return PI_TOO_MANY_CBS; - if (numBOOL >= BOOL) return PI_TOO_MANY_OOL; + if (numCB > CB) return PI_TOO_MANY_CBS; + if (numBOOL > BOOL) return PI_TOO_MANY_OOL; if (numTOOL > TOOL) return PI_TOO_MANY_OOL; /* Set the padding */ @@ -9764,10 +9764,10 @@ int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL) { /* Are there enough spare resources? */ - if ((numCB+waveOutBotCB) >= NUM_WAVE_CBS) + if ((numCB+waveOutBotCB) > NUM_WAVE_CBS) return PI_TOO_MANY_CBS; - if ((numBOOL+waveOutBotOOL) >= (waveOutTopOOL-numTOOL)) + if ((numBOOL+waveOutBotOOL) > (waveOutTopOOL-numTOOL)) return PI_TOO_MANY_OOL; if (wid >= PI_MAX_WAVES) @@ -9808,7 +9808,7 @@ int gpioWaveCreatePad(int pctCB, int pctBOOL, int pctTOOL) numTOOL, waveInfo[wid].topOOL-TOOL); } - DBG(DBG_USER, "Wave Stats: wid=%d CBs %d BOOL %d TOOL %d", wid, + DBG(DBG_USER, "Wave padding: wid=%d CBs %d BOOL %d TOOL %d", wid, numCB, numBOOL, numTOOL); waveInfo[wid].deleted = 0; From c27a968bcc0f7f5f50c7a416eb76de6a394701a1 Mon Sep 17 00:00:00 2001 From: Guy McSwain Date: Wed, 29 Apr 2020 11:25:02 -0500 Subject: [PATCH 13/13] Add test cases to x_* for padded waves. --- x_pigpio.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ x_pigpio.py | 41 +++++++++++++++++++++++++++++++++++++++++ x_pigpiod_if2.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ x_pigs | 20 ++++++++++++++++++++ 4 files changed, 150 insertions(+) diff --git a/x_pigpio.c b/x_pigpio.c index cd15389..8119d73 100644 --- a/x_pigpio.c +++ b/x_pigpio.c @@ -459,6 +459,51 @@ To the lascivious pleasing of a lute.\n\ c = gpioWaveGetMaxCbs(); CHECK(5, 21, c, 25016, 0, "wave get max cbs"); + + /* waveCreatePad tests */ + gpioWaveTxStop(); + gpioWaveClear(); + gpioSetAlertFunc(GPIO, t5cbf); + + e = gpioWaveAddGeneric(2, (gpioPulse_t[]) + { {1<