7171/*============================ MACROFIED FUNCTIONS ===========================*/
7272/*============================ TYPES =========================================*/
7373enum {
74- WAVEFORM_START ,
74+ WAVEFORM_START = 0 ,
7575 WAVEFORM_UPDATE_BINS ,
7676 WAVEFORM_DONE ,
7777};
7878
79+ enum {
80+ WAVEFORM_BIN_LAST = 0 ,
81+ WAVEFORM_BIN_NEW ,
82+ };
83+
7984/*============================ GLOBAL VARIABLES ==============================*/
8085/*============================ PROTOTYPES ====================================*/
8186ARM_NONNULL (1 )
@@ -90,6 +95,10 @@ arm_2d_err_t __waveform_view_draw( arm_generic_loader_t *ptObj,
9095 uint32_t iTargetStrideInByte ,
9196 uint_fast8_t chBitsPerPixel );
9297
98+ __STATIC_INLINE
99+ bool __waveform_view_get_sample_y ( waveform_view_t * ptThis ,
100+ q16_t * pq16Y );
101+
93102/*============================ LOCAL VARIABLES ===============================*/
94103/*============================ IMPLEMENTATION ================================*/
95104
@@ -105,6 +114,8 @@ arm_2d_err_t waveform_view_init(waveform_view_t *ptThis,
105114 this .tCFG = * ptCFG ;
106115 //}
107116
117+ this .tCFG .__bValid = false;
118+
108119 arm_2d_err_t tResult = ARM_2D_ERR_NONE ;
109120
110121 do {
@@ -177,23 +188,28 @@ arm_2d_err_t waveform_view_init(waveform_view_t *ptThis,
177188 & this .DirtyRegion .tDirtyRegionItem ,
178189 this .tCFG .ptScene );
179190
180- if (this .tCFG .chDirtyRegionItemCount > 0 && NULL != this .tCFG .ptWaveformDirtyRegionItems ) {
191+ if (this .tCFG .chDirtyRegionItemCount > 0 && NULL != this .tCFG .ptDirtyBins ) {
181192
182193 /* update bin width */
183194 this .DirtyRegion .q16BinWidth
184195 = reinterpret_q16_f32 ( (float )this .tCFG .tSize .iWidth
185196 / (float )this .tCFG .chDirtyRegionItemCount );
186197
187198 /* reset bins */
188- memset ( this .tCFG .ptWaveformDirtyRegionItems ,
199+ memset ( this .tCFG .ptDirtyBins ,
189200 0 ,
190- ( sizeof (waveform_dirty_region_item_t )
201+ ( sizeof (waveform_view_dirty_bin_t )
191202 * this .tCFG .chDirtyRegionItemCount ));
192203
204+ if (255 == this .tCFG .chDirtyRegionItemCount ) {
205+ this .tCFG .chDirtyRegionItemCount = 254 ;
206+ }
193207 } else {
194208 this .tCFG .chDirtyRegionItemCount = 0 ;
195209 }
196210 }
211+
212+ this .tCFG .__bValid = true;
197213
198214
199215 return tResult ;
@@ -218,18 +234,110 @@ ARM_NONNULL(1)
218234void waveform_view_on_load ( waveform_view_t * ptThis )
219235{
220236 assert (NULL != ptThis );
237+ if (!this .tCFG .__bValid ) {
238+ return ;
239+ }
221240
222241 arm_generic_loader_on_load (& this .use_as__arm_generic_loader_t );
223242}
224243
244+ static void __waveform_view_update_dirty_bins (waveform_view_t * ptThis )
245+ {
246+ assert (NULL != ptThis );
247+ assert (NULL != this .tCFG .ptDirtyBins );
248+ assert (this .tCFG .chDirtyRegionItemCount > 0 );
249+
250+ uint_fast8_t chSampleDataSize = 1 << this .tCFG .u2SampleSize ;
251+ int16_t iLastUnUpdatedX = 0 ;
252+ uint_fast8_t nDotHeight = this .tCFG .u5DotHeight + 1 ;
253+
254+ for ( uint_fast8_t chBinIndex = 0 ;
255+ chBinIndex < this .tCFG .chDirtyRegionItemCount ;
256+ chBinIndex ++ ) {
257+
258+ waveform_view_dirty_bin_t * ptBin = & this .tCFG .ptDirtyBins [chBinIndex ];
259+
260+ /* save the last dirty bin */
261+ ptBin -> Coverage [WAVEFORM_BIN_LAST ] = ptBin -> Coverage [WAVEFORM_BIN_NEW ];
262+
263+ memset ( & ptBin -> Coverage [WAVEFORM_BIN_NEW ],
264+ 0 ,
265+ sizeof (ptBin -> Coverage [WAVEFORM_BIN_NEW ]));
266+
267+ /* calculate the new dirty bin */
268+ int16_t iX1 = reinterpret_s16_q16 ( mul_n_q16 (this .DirtyRegion .q16BinWidth ,
269+ chBinIndex + 1 ));
270+
271+ int16_t iSampleCount = iX1 - iLastUnUpdatedX ;
272+ if (iSampleCount <= 0 ) {
273+ continue ;
274+ }
275+
276+ if (iLastUnUpdatedX == 0 ) {
277+ arm_loader_io_seek ( this .tCFG .IO .ptIO ,
278+ this .tCFG .IO .pTarget ,
279+ & this .use_as__arm_generic_loader_t ,
280+ 0 ,
281+ SEEK_SET );
282+ } else {
283+ arm_loader_io_seek ( this .tCFG .IO .ptIO ,
284+ this .tCFG .IO .pTarget ,
285+ & this .use_as__arm_generic_loader_t ,
286+ (iLastUnUpdatedX - 1 ) * chSampleDataSize ,
287+ SEEK_SET );
288+ }
289+
290+ q16_t q16LastY = 0 ;
291+ if (!__waveform_view_get_sample_y ( ptThis , & q16LastY )) {
292+ continue ;
293+ }
294+
295+ arm_loader_io_seek ( this .tCFG .IO .ptIO ,
296+ this .tCFG .IO .pTarget ,
297+ & this .use_as__arm_generic_loader_t ,
298+ iLastUnUpdatedX * chSampleDataSize ,
299+ SEEK_SET );
300+
301+ iLastUnUpdatedX = iX1 ;
302+ ptBin -> iWidth = iSampleCount ;
303+
304+ q16_t q16Ymin = __Q16_MAX__ ;
305+ q16_t q16Ymax = 0 ;
306+
307+ q16LastY -= reinterpret_q16_s16 (nDotHeight );
308+ q16Ymin = MIN (q16LastY , q16Ymin );
309+ q16Ymax = MAX (q16LastY , q16Ymax );
310+
311+ do {
312+ q16_t q16Y ;
313+ if (!__waveform_view_get_sample_y ( ptThis , & q16Y )) {
314+ break ;
315+ }
316+
317+ q16Ymin = MIN (q16Y , q16Ymin );
318+ q16Ymax = MAX (q16Y , q16Ymax );
319+ } while (-- iSampleCount );
320+
321+ ptBin -> Coverage [WAVEFORM_BIN_NEW ].iY0 = reinterpret_s16_q16 (q16Ymin );
322+ ptBin -> Coverage [WAVEFORM_BIN_NEW ].iY1 = reinterpret_s16_q16 (q16Ymax ) + 1 + nDotHeight ;
323+ }
324+ }
325+
225326ARM_NONNULL (1 )
226- void waveform_view_on_frame_start ( waveform_view_t * ptThis )
327+ void waveform_view_on_frame_start ( waveform_view_t * ptThis , bool bUpdate )
227328{
228329 assert (NULL != ptThis );
229330
331+ if (!this .tCFG .__bValid ) {
332+ return ;
333+ }
334+
230335 arm_generic_loader_on_frame_start (& this .use_as__arm_generic_loader_t );
231336
232- if (this .tCFG .bUseDirtyRegion ) {
337+ if (this .tCFG .bUseDirtyRegion && bUpdate ) {
338+
339+ __waveform_view_update_dirty_bins (ptThis );
340+
233341 arm_2d_dynamic_dirty_region_on_frame_start (
234342 & this .DirtyRegion .tDirtyRegionItem ,
235343 WAVEFORM_START );
@@ -240,6 +348,9 @@ ARM_NONNULL(1)
240348void waveform_view_on_frame_complete ( waveform_view_t * ptThis )
241349{
242350 assert (NULL != ptThis );
351+ if (!this .tCFG .__bValid ) {
352+ return ;
353+ }
243354
244355 arm_generic_loader_on_frame_complete (& this .use_as__arm_generic_loader_t );
245356}
@@ -251,6 +362,11 @@ void waveform_view_show(waveform_view_t *ptThis,
251362 bool bIsNewFrame )
252363{
253364 assert (NULL != ptThis );
365+
366+ if (!this .tCFG .__bValid ) {
367+ return ;
368+ }
369+
254370 if (-1 == (intptr_t )ptTile ) {
255371 ptTile = arm_2d_get_default_frame_buffer ();
256372 }
@@ -268,16 +384,76 @@ void waveform_view_show(waveform_view_t *ptThis,
268384 switch (arm_2d_dynamic_dirty_region_wait_next (
269385 & this .DirtyRegion .tDirtyRegionItem )) {
270386 case WAVEFORM_START :
271- if (0 == this .tCFG .chDirtyRegionItemCount ) {
387+ if ( 0 == this .tCFG .chDirtyRegionItemCount ) {
272388 /* The user doesn't provide dirty region bins, let's update the whole diagram instead */
273389 arm_2d_dynamic_dirty_region_update (
274390 & this .DirtyRegion .tDirtyRegionItem ,
275391 & __waveform_panel ,
276392 & __centre_region ,
277393 WAVEFORM_DONE );
394+ break ;
395+ } else {
396+ this .DirtyRegion .chCurrentBin = 0 ;
397+ }
398+ //fall-through
399+ case WAVEFORM_UPDATE_BINS : {
400+
401+ do {
402+ uint8_t chBinIndex = this .DirtyRegion .chCurrentBin ;
403+ int16_t iX = reinterpret_s16_q16 (
404+ mul_n_q16 ( this .DirtyRegion .q16BinWidth ,
405+ chBinIndex ));
406+ waveform_view_dirty_bin_t * ptBin = & this .tCFG .ptDirtyBins [chBinIndex ];
407+
408+ int16_t iY0 = ptBin -> Coverage [1 ].iY0 ;
409+ int16_t iY1 = ptBin -> Coverage [1 ].iY1 ;
410+
411+ if (ptBin -> Coverage [0 ].iY0 != ptBin -> Coverage [0 ].iY1 ) {
412+ iY0 = MIN (iY0 , ptBin -> Coverage [0 ].iY0 );
413+ iY1 = MAX (iY1 , ptBin -> Coverage [0 ].iY1 );
414+ }
415+
416+ arm_2d_region_t tDrawRegion = {
417+ .tLocation = {
418+ .iX = __centre_region .tLocation .iX + iX ,
419+ .iY = __centre_region .tLocation .iY + iY0 ,
420+ },
421+ .tSize = {
422+ .iWidth = ptBin -> iWidth ,
423+ .iHeight = iY1 - iY0 ,
424+ },
425+ };
426+ if (!arm_2d_region_intersect (& tDrawRegion , & __centre_region , NULL )) {
427+ this .DirtyRegion .chCurrentBin ++ ;
428+ if (this .DirtyRegion .chCurrentBin >= this .tCFG .chDirtyRegionItemCount ) {
429+ /* end early*/
430+ arm_2d_dynamic_dirty_region_change_user_region_index_only (
431+ & this .DirtyRegion .tDirtyRegionItem ,
432+ WAVEFORM_DONE
433+ );
434+ } else {
435+ continue ;
436+ }
437+ break ;
438+ }
439+
440+ if (this .DirtyRegion .chCurrentBin ++ < this .tCFG .chDirtyRegionItemCount ) {
441+ arm_2d_dynamic_dirty_region_update (
442+ & this .DirtyRegion .tDirtyRegionItem ,
443+ & __waveform_panel ,
444+ & tDrawRegion ,
445+ WAVEFORM_UPDATE_BINS );
446+ break ;
447+ } else {
448+ arm_2d_dynamic_dirty_region_update (
449+ & this .DirtyRegion .tDirtyRegionItem ,
450+ & __waveform_panel ,
451+ & tDrawRegion ,
452+ WAVEFORM_DONE );
453+ break ;
454+ }
455+ } while (true);
278456 }
279- break ;
280- case WAVEFORM_UPDATE_BINS :
281457 break ;
282458 default :
283459 case WAVEFORM_DONE :
@@ -384,8 +560,12 @@ arm_2d_err_t __waveform_view_draw( arm_generic_loader_t *ptObj,
384560{
385561 assert (NULL != ptObj );
386562 assert (__GLCD_CFG_COLOUR_DEPTH__ == chBitsPerPixel );
387-
388563 waveform_view_t * ptThis = (waveform_view_t * )ptObj ;
564+
565+ if (!this .tCFG .__bValid ) {
566+ return ARM_2D_ERR_NOT_AVAILABLE ;
567+ }
568+
389569 uint_fast8_t chSampleDataSize = 1 << this .tCFG .u2SampleSize ;
390570
391571 int_fast16_t iXLimit = ptROI -> tSize .iWidth + ptROI -> tLocation .iX ;
0 commit comments