Thursday, April 26th 2018, 10:39pm UTC+2

You are not logged in.

  • Login
  • Register

Dear visitor, welcome to SEGGER Forum. If this is your first visit here, please read the Help. It explains how this page works. You must be registered before you can use all the page's features. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

aaa1

Beginner

Date of registration: Mar 8th 2018

Posts: 13

1

Thursday, March 8th 2018, 11:38am

LISTVIEW - Blinking cells

How can I have the cells of a Listview blink with a given frequency? I tried changing the background color of a cell by recreating the listview in a timer interrupt: inside the interrupt I use the createListview function. it works for a few seconds then everything stops...
Any idea?
thanks

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 562

2

Thursday, March 8th 2018, 11:51am

Hi,

There is no need to recreate the LISTVIEW. Just create a timer and change the LISTVIEW color when the timer expires.

Here is an example on how you could do it:

C/C++ Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "DIALOG.h"

/*********************************************************************
*
*   	Config
*
**********************************************************************
*/

/*********************************************************************
*
*   	Defines
*
**********************************************************************
*/
#define ID_WINDOW_0     	(GUI_ID_USER + 0x00)
#define ID_LISTVIEW_0     	(GUI_ID_USER + 0x01)

/*********************************************************************
*
*   	Static data
*
**********************************************************************
*/
/*********************************************************************
*
*   	_aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
  { WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 0, 320, 240, 0, 0x0, 0 },
  { LISTVIEW_CreateIndirect, "Listview", ID_LISTVIEW_0, 39, 23, 151, 83, 0, 0x0, 0 },
};

/*********************************************************************
*
*   	Static code
*
**********************************************************************
*/
/*********************************************************************
*
*   	_cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
  WM_HWIN hItem;
  int 	NCode;
  int 	Id;
  GUI_COLOR aBlinkColor[] = {GUI_WHITE, GUI_BLUE};
  static int Index;

  switch (pMsg->MsgId) {
  case WM_INIT_DIALOG:
	//
	// Initialization of 'Listview'
	//
	hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
	LISTVIEW_AddColumn(hItem, 30, "Col 0", GUI_TA_HCENTER | GUI_TA_VCENTER);
	LISTVIEW_AddColumn(hItem, 30, "Col 1", GUI_TA_HCENTER | GUI_TA_VCENTER);
	LISTVIEW_AddColumn(hItem, 30, "Col 2", GUI_TA_HCENTER | GUI_TA_VCENTER);
	LISTVIEW_AddRow(hItem, NULL);
	LISTVIEW_SetGridVis(hItem, 1);
	LISTVIEW_SetItemText(hItem, 0, 0, "Item");
	LISTVIEW_SetItemText(hItem, 1, 0, "Item");
	//
	// uncomment for selecting single cells
	//
	//LISTVIEW_EnableCellSelect(hItem, 1);
	//
	// Create a timer
	//
	WM_CreateTimer(pMsg->hWin, 0, 500, 0);
	break;
  case WM_TIMER:
	//
	// If the timer expires we set another color for the background and the text
	//
	hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
	LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
	Index ^= 1;
	LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
	//
	// Restart the timer, 0 = period like on creation
	//
	WM_RestartTimer((WM_HTIMER)pMsg->Data.v, 0);
	break;
  case WM_NOTIFY_PARENT:
	Id	= WM_GetId(pMsg->hWinSrc);
	NCode = pMsg->Data.v;
	switch(Id) {
	case ID_LISTVIEW_0: // Notifications sent by 'Listview'
  	switch(NCode) {
  	case WM_NOTIFICATION_CLICKED:
    	break;
  	case WM_NOTIFICATION_RELEASED:
    	break;
  	case WM_NOTIFICATION_SEL_CHANGED:
    	break;
  	}
  	break;
	}
	break;
  default:
	WM_DefaultProc(pMsg);
	break;
  }
}

/*********************************************************************
*
*   	Public code
*
**********************************************************************
*/
/*********************************************************************
*
*   	MainTask
*/
void MainTask(void) {
  GUI_Init();
  GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
  while (1) {
	GUI_Delay(100);
  }
}

/*************************** End of file ****************************/


EDIT:

It stops working most likely because you run out of memory. Each time you create the LISTVIEW it uses a bit of the GUI_RAM. Since you never delete the LISTVIEW you will run out of RAM.

To use a hardware timer to enable the blinking you can send a message to the window. Define a user message and send it to the widget and react in its callback on kthe message:

C/C++ Source code

1
2
3
#define USER_MESSAGE  WM_USER + 0x00

WM_SendMessageNoPara(hListView, USER_MESSAGE);



Regards
Sven

aaa1

Beginner

Date of registration: Mar 8th 2018

Posts: 13

3

Thursday, March 8th 2018, 2:47pm

I tried to use both methods but no results. I debugged and I never see the part of the code regarding "case: WM_TIMER" being run.
Here is my code. What is wrong?

int main(void)
{

/* Enable I-Cache-------------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache-------------------------------------------------------------*/
SCB_EnableDCache();

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */
SystemClock_Config();

/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_RTC_Init();
MX_TIM10_Init();
MX_LTDC_Init();
MX_DMA2D_Init();
MX_FMC_Init();
MX_DSIHOST_DSI_Init();
MX_TIM6_Init();

BSP_TS_Init(800, 480); //initialize touch panel
BSP_SDRAM_Init(); /* Initializes the SDRAM device */
__HAL_RCC_CRC_CLK_ENABLE();
GUI_Init();
GUI_Clear();
GUI_SetLayerVisEx(1, 0);
GUI_SelectLayer(0);

WM_MULTIBUF_Enable(1);

CreateLISTAWindow();

HAL_TIM_Base_Init(&htim6);
HAL_TIM_Base_Start_IT(&htim6);

HAL_TIM_Base_Init(&htim10);
HAL_TIM_Base_Start_IT(&htim10);

while (1)
{

}


In another file there is the LISTVIEW code:



#include "DIALOG.h"

/*********************************************************************
*
* Defines
*
**********************************************************************
*/
#define ID_WINDOW_0 (GUI_ID_USER + 0x00)
#define ID_LISTVIEW_0 (GUI_ID_USER + 0x01)
#define USER_MESSAGE WM_USER + 0x00

WM_HWIN hItem;


// USER START (Optionally insert additional defines)
// USER END

/*********************************************************************
*
* Static data
*
**********************************************************************
*/

// USER START (Optionally insert additional static data)
// USER END

/*********************************************************************
*
* _aDialogCreate
*/
static const GUI_WIDGET_CREATE_INFO _aDialogCreate[] = {
{ WINDOW_CreateIndirect, "Window", ID_WINDOW_0, 0, 100, 800, 380, 0, 0x0, 0 },
{ LISTVIEW_CreateIndirect, "Listview", ID_LISTVIEW_0, 5, 42, 790, 104, 0, 0x0, 0 },
// USER START (Optionally insert additional widgets)
// USER END
};

/*********************************************************************
*
* Static code
*
**********************************************************************
*/

// USER START (Optionally insert additional static code)
// USER END

/*********************************************************************
*
* _cbDialog
*/
static void _cbDialog(WM_MESSAGE * pMsg) {
// WM_HWIN hItem;
int NCode;
int Id;

GUI_COLOR aBlinkColor[] = {GUI_WHITE, GUI_BLUE};
static int Index;
// USER START (Optionally insert additional variables)
// USER END

switch (pMsg->MsgId) {
case WM_INIT_DIALOG:
//
// Initialization of 'Listview'
//
hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
LISTVIEW_AddColumn(hItem, 30, "Col 0", GUI_TA_HCENTER | GUI_TA_VCENTER);
LISTVIEW_AddColumn(hItem, 30, "Col 1", GUI_TA_HCENTER | GUI_TA_VCENTER);
LISTVIEW_AddColumn(hItem, 30, "Col 2", GUI_TA_HCENTER | GUI_TA_VCENTER);
LISTVIEW_AddRow(hItem, NULL);
LISTVIEW_SetGridVis(hItem, 1);
LISTVIEW_SetItemText(hItem, 0, 0, "Item");
LISTVIEW_SetItemText(hItem, 1, 0, "Item");
// USER START (Optionally insert additional code for further widget initialization)
// WM_CreateTimer(pMsg->hWin, 0, 500, 0);
// USER END
break;

case WM_TIMER:
//
// If the timer expires we set another color for the background and the text
//
hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);
LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
Index ^= 1;
LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);
//
// Restart the timer, 0 = period like on creation
//
WM_RestartTimer((WM_HTIMER)pMsg->Data.v, 0);
break;

case WM_USER:
WM_CreateTimer(pMsg->hWin, 0, 500, 0);
break;

case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch(Id) {
case ID_LISTVIEW_0: // Notifications sent by 'Listview'
switch(NCode) {
case WM_NOTIFICATION_CLICKED:
// USER START (Optionally insert code for reacting on notification message)
// USER END
break;
case WM_NOTIFICATION_RELEASED:
// USER START (Optionally insert code for reacting on notification message)
// USER END
break;
case WM_NOTIFICATION_SEL_CHANGED:
// USER START (Optionally insert code for reacting on notification message)
// USER END
break;
// USER START (Optionally insert additional code for further notification handling)
// USER END
}
break;
// USER START (Optionally insert additional code for further Ids)
// USER END
}
break;
// USER START (Optionally insert additional message handling)
// USER END
default:
WM_DefaultProc(pMsg);
break;
}
}

/*********************************************************************
*
* Public code
*
**********************************************************************
*/
/*********************************************************************
*
* CreateWindow
*/
WM_HWIN CreateLISTAWindow(void);
WM_HWIN CreateLISTAWindow(void) {
WM_HWIN hWin;

hWin = GUI_CreateDialogBox(_aDialogCreate, GUI_COUNTOF(_aDialogCreate), _cbDialog, WM_HBKWIN, 0, 0);
return hWin;
}

// USER START (Optionally insert additional public code)
// USER END

/*************************** End of file ****************************/

SEGGER - Schoenen

Super Moderator

Date of registration: Aug 13th 2015

Posts: 562

4

Thursday, March 8th 2018, 3:10pm

Hi,

did you implemented the following functions properly?

GUI_X_GetTime()
GUI_X_Delay(int Period)

The first function should return a a timer value which gets incremented each millisecond and the second should perform a delay for the given period in milliseconds.

Without these functions, you can't use any timer related functions (like WM_CreateTimer()).

You can either set up a hardware timer which increments a variable each ms or use the timer related API of an RTOS (like embOS).

I have attached some example files which show how to implement the functions above (and some others as well).

Regards
Sven
SEGGER - Schoenen has attached the following file:
  • GUI_X.zip (10.51 kB - 28 times downloaded - Last download: Apr 21st 2018, 7:59pm)

aaa1

Beginner

Date of registration: Mar 8th 2018

Posts: 13

5

Thursday, March 8th 2018, 3:34pm

The functions are correct since I had already imported the GUI_X.c file. By the way if I use the GUI_Delay(100) I notive that the code gets stuck inside this function. For this reason I started using GUI_Exec() to update the widgets.

Could my problem be related to the non-functioning of the GUI_Delay() function?
And in this case, why does the code get stuck inside the function?
Thanks

aaa1

Beginner

Date of registration: Mar 8th 2018

Posts: 13

6

Thursday, March 8th 2018, 3:46pm

I tried with a timer interrupt that occurs every few seconds: in the interrupt the only thing I do is:

C/C++ Source code

1
WM_SendMessageNoPara(hItem, USER_MESSAGE);



Then inside static void _cbDialog(WM_MESSAGE * pMsg), I added a new case for USER_MESSAGE:

C/C++ Source code

1
  case WM_USER:    hItem = WM_GetDialogItem(pMsg->hWin, ID_LISTVIEW_0);    LISTVIEW_SetBkColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);    Index ^= 1;    LISTVIEW_SetTextColor(hItem, LISTVIEW_CI_SELFOCUS, aBlinkColor[Index]);    break;



The USER_MESSAGE is defined as:

C/C++ Source code

1
#define USER_MESSAGE  WM_USER + 0x00



What I believe is that, once WM_SendMessageNoPara() inside the interrupt is called, the code does not move to the callback _cbDialog() and does not execute the code inside case WM_USER.


My question is: why doesn't this happen? I think that once WM_SendMessageNoPara() is called the code automatically moves to the callback _cbDialog(), right?

aaa1

Beginner

Date of registration: Mar 8th 2018

Posts: 13

7

Thursday, March 8th 2018, 4:45pm

I think I solved!
Thank you very much for you herp! :)

Similar threads