コード例 #1
0
void Start_input_buttonTask(void const * argument)
{
  GPIO_InitTypeDef GPIO_InitStruct;
  fsm_event_f button_fsm_event;

  /* Take both semaphores for the first time */
  osSemaphoreWait(sem_input_button_short_pressHandle, osWaitForever);
  osSemaphoreWait(sem_input_button_long_pressHandle, osWaitForever);

  /* Infinite loop */
  for(;;)
  {
    /* If I/O button is pressed */
    if (osSemaphoreWait(sem_input_button_short_pressHandle, osWaitForever) == osOK)
    {
      /* Make falling edge sensitive */
      GPIO_InitStruct.Pin = WAKEUP_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      HAL_GPIO_Init(WAKEUP_GPIO_Port, &GPIO_InitStruct);

      // TEST
      osSemaphoreRelease(sem_ecg_keygenHandle);

      /* Wait for falling edge */
      if (osSemaphoreWait(sem_input_button_long_pressHandle, 2000) == osErrorOS)
      {
        /* If falling edge is NOT detected before timeout
         * we have a long press
         */
        button_fsm_event = fsm_button_long;
        while(osMailPut(queue_fsm_eventsHandle, (void *) &button_fsm_event) != osOK)
        {
          osDelay(1);
        }
      }
      else
      {
        /* Make rising edge sensitive again */
        GPIO_InitStruct.Pin = WAKEUP_Pin;
        GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        HAL_GPIO_Init(WAKEUP_GPIO_Port, &GPIO_InitStruct);

        /* If falling edge is detected before timeout
         * we have a short press
         */
        button_fsm_event = fsm_button_short;
        while(osMailPut(queue_fsm_eventsHandle, (void *) &button_fsm_event) != osOK)
        {
          osDelay(1);
        }
      }
    }
  }
}
コード例 #2
0
void Start_input_clickTask(void const * argument)
{
  osEvent event_click;
  item_t item;

  click_t *click;
  buzzer_note_t beep;

  /* Infinite loop */
  for(;;)
  {
    /* Get click */
    event_click = osMailGet(queue_input_clickHandle, osWaitForever);
    if (event_click.status == osEventMail)
    {
      /* Get click position */
      click = (click_t *) event_click.value.p;

      /* Do something based on click type */
      switch (click->click_type)
      {
        case CLICK_DOWN:
          break;
        case CLICK_HOLD:
          break;
        case CLICK_UP:
          /* Search item in menu on click position */
          osMutexWait(mutex_menuHandle, osWaitForever);
          if (menu_search_click(&current_menu, click, &item))
          {
            /* Send item event */
            while(osMailPut(queue_fsm_eventsHandle, (void *) &(item.area.event)) != osOK)
            {
              osDelay(1);
            }

            /* Beep */
            beep.note = A5;
            beep.ms = 50;
            while(osMailPut(queue_periph_buzzerHandle, (void *) &beep) != osOK)
            {
              osDelay(1);
            }
          }
          osMutexRelease(mutex_menuHandle);
          break;
        default:
          break;
      }
    }
  }
}
コード例 #3
0
// NOTE: callback from ISR -- cannot wait
static void key_event_handler(uint8_t ri, uint8_t ci, bool state) {
    KeyEvent* e = (KeyEvent*)osMailAlloc(key_events, 0);
    if (!e) return;
    e->keycode = mapping[ri][ci];
    e->state = state;
    osMailPut(key_events, e);
}
コード例 #4
0
static s32 cpufreq_icc_read_cb(u32 id , u32 len, void* context)
{
	s32 ret = 0;
	u8 data[32];
	T_CPUFREQ_MAIL *smail;

	if((len == 0) || (len > 32))
	{
		M3CPUFREQ_PRINT("readcb len is 0 \n");
        return -1;
	}

	ret = bsp_icc_read(id, data, len);
	if(len != ret)/*lint !e737*/
	{
		M3CPUFREQ_PRINT("readcb error \r\n");
		return -1;
	}
	/*lint --e{569} */
	smail = osMailCAlloc(cpufreq_mail, osWaitForever);
	memcpy(smail, data, len);
	osMailPut(cpufreq_mail, smail);

	return 0;
}
コード例 #5
0
static void ecg_2_lead_gui_tick(state_ptr state)
{
  uint32_t i = 0;
  osEvent event;

  uint32_t bpm = 0;
  char str_bpm[4] = "-?-";

  int32_t lead_I = 0, lead_II = 0;

  /* Do transition actions */
  /* Get bpm data */
  event = osMessageGet(queue_ecg_bpm_screenHandle, 0);
  if (event.status == osEventMessage)
  {
    /* Retrieve value */
    bpm = (((uint32_t) event.value.v) >> 10);
    sprintf(str_bpm, "%u", bpm);

    item_area_set_text(&menu_ecg.items[1].item.area, str_bpm);
    while (osMailPut(queue_lcdHandle, (void *) &menu_ecg.items[1]) != osOK)
    {
      osDelay(1);
    }
  }
コード例 #6
0
/* State behaviour */
void behaviour_welcome(state_ptr state)
{
  /* Set events to react to */

  /* Do state actions */

  /* Set menu */
  osMutexWait(mutex_menuHandle, osWaitForever);
  menu_copy(&menu_welcome, &current_menu);
  osMutexRelease(mutex_menuHandle);

  /* Display menu */
  uint32_t i;
  for (i = 0; i < menu_welcome.item_num; i++)
  {
    while (osMailPut(queue_lcdHandle, (void *) &menu_welcome.items[i]) != osOK)
    {
      osDelay(1);
    }
  }

  /* Do state actions */
  bluetooth_init();
  osDelay(2500);
  entry_to_running(state);
}
コード例 #7
0
ファイル: main.c プロジェクト: pengphei/STM32Cube_L0
/**
  * @brief  Mail Producer Thread.
  * @param  argument: Not used
  * @retval None
  */
static void MailQueueProducer(const void *argument)
{
  Amail_TypeDef *pTMail;
  
  for(;;)
  {		

    pTMail = osMailAlloc(mailId, osWaitForever); /* Allocate memory */
    pTMail->var1 = ProducerValue1; /* Set the mail content */
    pTMail->var2 = ProducerValue2;
    pTMail->var3 = ProducerValue3;
    
    if(osMailPut(mailId, pTMail) != osOK) /* Send Mail */  
    {      
      /* Toggle LED2 to indicate error */
      BSP_LED_Toggle(LED2);
    }
    else
    {
      /* Increment the variables we are going to post next time round.  The
      consumer will expect the numbers to follow in numerical order. */
      ++ProducerValue1;
      ProducerValue2 += 2;
      ProducerValue3 += 3;
      
      /* Toggle LED2 to indicate a correct number received  */
      BSP_LED_Toggle(LED2);

      osDelay(250);
    }
  }
}
コード例 #8
0
/* State behaviour */
void behaviour_goodbye(state_ptr state)
{
  uint32_t i;
  buzzer_note_t beep;

  /* Set events to react to */

  /* Do state actions */

  /* Blink green pin before shutting down */
  HAL_GPIO_WritePin(GPIOC,UI_LED_R_Pin|UI_LED_B_Pin|UI_LED_G_Pin,GPIO_PIN_RESET);
  for (i = 0; i < 6; i++)
  {
    HAL_GPIO_TogglePin(GPIOC,UI_LED_G_Pin);
    osDelay(200);
  }

  /* Beep */
  beep.note = A4;
  beep.ms = 100;
  while(osMailPut(queue_periph_buzzerHandle, (void *) &beep) != osOK)
  {
    osDelay(1);
  }
  osDelay(105);

  beep.note = D4;
  beep.ms = 80;
  while(osMailPut(queue_periph_buzzerHandle, (void *) &beep) != osOK)
  {
    osDelay(1);
  }
  osDelay(80);

  // Sleep well little prince
  /* Turn off LED */
  HAL_GPIO_WritePin(GPIOC,UI_LED_R_Pin|UI_LED_B_Pin|UI_LED_G_Pin,GPIO_PIN_RESET);

  /* Disable RTC alarms to avoid waking the system up */
  __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
  __HAL_RTC_ALARMA_DISABLE(&hrtc);

  /* Enable wakeup pin and go to sleep */
  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  HAL_PWR_EnterSTANDBYMode();
}
コード例 #9
0
/**
 * Quick method to send a package to input mailbox
 * @param type  type of package
 * @param value value in package
 */
void MAIL_send_input(MAIL_package_type type, float value) {
	MAIL_package_typedef *package;

	package = osMailAlloc(input_mailbox, osWaitForever);
	package->value = value;
	package->type = type;
	osMailPut(input_mailbox, package);
}
コード例 #10
0
ファイル: main.cpp プロジェクト: Archcady/mbed-os
void send_thread (void const *argument) {
    uint32_t i = 0;
    while (true) {
        i++; // fake data update
        mail_t *mail = (mail_t*)osMailAlloc(mail_box, osWaitForever);
        mail->voltage = (i * 0.1) * 33;
        mail->current = (i * 0.1) * 11;
        mail->counter = i;
        osMailPut(mail_box, mail);
        osDelay(1000);
    }
}
コード例 #11
0
/* State behaviour */
void behaviour_h2h_connect(state_ptr state)
{
  /* Set events to react to */
  state->back = h2h_connect_to_main;
  state->h2h_connect = h2h_connect_to_h2h_ongoing;

  /* Do state actions */

  /* Set menu */
  osMailPut(queue_input_menuHandle, (void *) &menu_h2h_connect);

  /* Display menu */
  uint32_t i;
  for (i = 0; i < menu_h2h_connect.item_num; i++)
  {
    osMailPut(queue_lcdHandle, (void *) &menu_h2h_connect.items[i]);
  }

  /* Do state actions */
//  bluetooth_init();
}
コード例 #12
0
/* State behaviour */
void behaviour_h2h_autentication(state_ptr state)
{
  osEvent event;
  validation_key_t bt_key;
  /* Set events to react to */
  state->h2h_ok                 = h2h_autentication_to_validation_ok;
  state->h2h_error              = h2h_autentication_to_validation_error;
  /* Do state actions */
  
  item_area_set_text(&menu_h2h_devices.items[6].item.area,"Validating Key...");
  while (osMailPut(queue_lcdHandle, (void *) &menu_h2h_devices.items[6]) != osOK)
  {
    osDelay(1);
  }  
  
  event = osMailGet(queue_ecg_keyfsmHandle, osWaitForever);
  if (event.status == osEventMail)
  {
    bt_key = *((validation_key_t*) event.value.v);
    osMailPut(queue_ecg_keyHandle, (void *) &bt_key);  
  }
}
コード例 #13
0
ファイル: MailQueue.c プロジェクト: mpthompson/stm32_f4_ptpd
void Thread_MailQueue1(void const *argument) {
  MAILQUEUE_OBJ_t *pMail = 0;

  while(1) {
    ; // Insert thread code here...
    pMail = osMailAlloc(qid_MailQueue, osWaitForever);          // Allocate memory
    if(pMail) {
      pMail->Buf[0] = 0xff;                                     // Set the mail content
      pMail->Idx = 0;
      osMailPut(qid_MailQueue, pMail);                          // Send Mail
    }

    osThreadYield();                                            // suspend thread
  }
}
/* State behaviour */
void behaviour_settings_configtabs_bluetooth(state_ptr state)
{
  /* Set events to react to */

  /* Do state actions */

  /* Set menu */
  osMutexWait(mutex_menuHandle, osWaitForever);
  menu_copy(&menu_settings_configtabs_bluetooth, &current_menu);
  osMutexRelease(mutex_menuHandle);

  /* Display menu */
  uint32_t i;
  for (i = 0; i < menu_settings_configtabs_about.item_num; i++)
  {
    while (osMailPut(queue_lcdHandle, (void *) &menu_settings_configtabs_bluetooth.items[i]) != osOK)
    {
      osDelay(1);
    }
  }
}
コード例 #15
0
ファイル: main.c プロジェクト: ppejic/temperatura
void GetTemperature(void const *argument)
{
	T_MEAS *mptr;
	
	Chip_ADS1248_Init();
	Chip_ADS1248_SelfOffsetCal(CHIP_U1);
	Chip_ADS1248_SelfOffsetCal(CHIP_U3);
	
	while(1)
	{
		osSignalWait(ADS_TEMP_GET, osWaitForever);
		
		mptr=osMailAlloc(mail, osWaitForever);
		mptr->rtd1 = Chip_ADS1248_GetTemperature(CHIP_U1, RTD_1);
		mptr->rtd2 = Chip_ADS1248_GetTemperature(CHIP_U1, RTD_2);
		mptr->rtd3 = Chip_ADS1248_GetTemperature(CHIP_U3, RTD_3);
		mptr->rtd4 = Chip_ADS1248_GetTemperature(CHIP_U3, RTD_4);
		
		osMailPut(mail, mptr);
		osThreadYield();
	}
}
コード例 #16
0
/* State behaviour */
void behaviour_goodbye(state_ptr state)
{
  /* Set events to react to */

  /* Do state actions */

  /* Set menu */
  osMutexWait(mutex_menuHandle, osWaitForever);
  menu_copy(&menu_goodbye, &current_menu);
  osMutexRelease(mutex_menuHandle);

  /* Display menu */
  uint32_t i;
  for (i = 0; i < menu_goodbye.item_num; i++)
  {
    while (osMailPut(queue_lcdHandle, (void *) &menu_goodbye.items[i]) != osOK)
    {
      osDelay(1);
    }
  }

  /* Do state actions */
  osDelay(2000);

  // Sleep well little prince
  /* Turn off LED */
  HAL_GPIO_WritePin(GPIOC,UI_LED_R_Pin|UI_LED_B_Pin|UI_LED_G_Pin,GPIO_PIN_RESET);

  /* Disable RTC alarms to avoid waking the system up */
  __HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
  __HAL_RTC_ALARMA_DISABLE(&hrtc);

  /* Enable wakeup pin and go to sleep */
  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  HAL_PWR_EnterSTANDBYMode();
}
コード例 #17
0
/* StartDataProcessTask function */
void StartDataProcessTask(void const * argument)
{
  /* USER CODE BEGIN StartDataProcessTask */
  SYS_DEBUG_TRACK();

  SensorData_t* pSensorData;
  ControlData_t* pControlData;
  /* Infinite loop */
  for(;;)
  {
    SYS_DEBUG("one loop!\n");

    /* -----| 1.从邮箱接收传感器数据   |---------------------*/
    osEvent event = osMailGet( gSenorDataMail, osWaitForever);
    pSensorData = (SensorData_t *)event.value.p;
    
    
    /* -----| 2.申请输出数据邮箱 |-------------------------- */
    pControlData = (ControlData_t *) osMailAlloc(gControlDataMail, osWaitForever);    
    
    
    /* -----| 3.处理数据,处理结果存放于输出缓冲区  |--------*/
    DataProcess_DoProcess( pSensorData, pControlData  );
    
    
    /* -----| 4.发送处理结果(缓冲区)到输出邮箱 | -----------*/
    osMailPut( gControlDataMail , pControlData ) ;
   
    
    /* -----| 5.释放超声波数据缓冲区  |------------------------*/
    osMailFree( gSenorDataMail, pSensorData );
    
    
//    osDelay(1);
  }
  /* USER CODE END StartDataProcessTask */
}
コード例 #18
0
/* State behaviour */
void behaviour_h2h_start_connect(state_ptr state)
{
  uint8_t i;
  /* Set events to react to */
  state->back = h2h_start_connect_to_main;
  state->h2h_start_connect = h2h_start_connect_to_h2h_ongoing;

  /* Do state actions */

  /*Clean devices names */
  for( i = 1; i < 5;i++)
  {
    item_area_set_text(&menu_h2h_devices.items[i].item.area," ");
    menu_h2h_devices.items[i].item.area.is_active = GUI_INACTIVE;
  }
  item_area_set_text(&menu_h2h_devices.items[6].item.area,"Searching for devices...");
  /* Set menu */
  osMutexWait(mutex_menuHandle, osWaitForever);
  menu_copy(&menu_h2h_devices, &current_menu);
  osMutexRelease(mutex_menuHandle);

  /* Display menu */
  for (i = 0; i < menu_h2h_devices.item_num; i++)
  {
    while (osMailPut(queue_lcdHandle, (void *) &menu_h2h_devices.items[i]) != osOK)
    {
      osDelay(1);
    }
  }

  /* Do state actions */
  /* We close and reopen the spp port in case of "zombie" connection*/
  CloseServer();
  OpenServer(); 
  Inquiry(TIMEOUT);
}
コード例 #19
0
/* StartDataParseTask function */
void StartDataParseTask(void const * argument)
{
  /* USER CODE BEGIN StartDataParseTask */
  uint8_t tmp;
  SYS_DEBUG_TRACK();
  
  /* Infinite loop */
  for(;;)
  {
    SYS_DEBUG("one loop!\n");

    /*------------------------接收并解析数据包---------------------------*/
    /* 1. 开始接收数据帧*/
     /*读取帧头1——head1 */
    xSerialGetChar( ReceiveDataQueueHandle, &tmp, osWaitForever ); 

    /*判断是否为帧头1——head1*/
    if( tmp == SENSOR_PROTOCOL_PACK_HEADER0 )                            
    {
      /*读取帧头2——head2*/
      xSerialGetChar( ReceiveDataQueueHandle, &tmp, osWaitForever );

      /*如果读到的还是帧头1,则重新读帧头2;防止重复的帧头1干扰*/
      if( tmp == SENSOR_PROTOCOL_PACK_HEADER0 )                           
      {
        /* 重新读取帧头2 */
        xSerialGetChar( ReceiveDataQueueHandle, &tmp, osWaitForever );        
      }
 
      /* 验证帧头2——head2*/
      if( tmp == SENSOR_PROTOCOL_PACK_HEADER1  )                        
      {
        /* 读取数据段长度 len */
        uint8_t len;
        xSerialGetChar( ReceiveDataQueueHandle, &len, osWaitForever );
        if( len == SENSOR_PROTOCOL_PACK_MAX_DATA_LEN )
        {
          /* 从邮箱申请空间,用来保存读取结果 */
          SensorData_t* pSensorData;
          pSensorData = (SensorData_t *) osMailAlloc( gSenorDataMail, osWaitForever);
          
          /* 读取数据段内容 */
          uint8_t* ptr = (uint8_t*)pSensorData ;
          uint8_t i;
          for( i = 0; i < len; i++ )
          {
            /* 循环接收整个数据段 */
            xSerialGetChar( ReceiveDataQueueHandle, ptr++, osWaitForever ); 
          }
          
          /* 读取校验字节 */
          xSerialGetChar( ReceiveDataQueueHandle, &tmp , osWaitForever ); 
          if( tmp == doSumCheck( (uint8_t*)pSensorData, len ) )
          {
            /* 如果校验通过,则发送缓冲区到队列 */
            if( osOK != osMailPut( gSenorDataMail, pSensorData) )  
            {
              ;   //TODO: Add something here
            }
          }else
          {
            /* 释放内存空间 */
            osMailFree( gSenorDataMail, pSensorData );
          }
          
        }
      }
    }
    
//    osDelay(1);
  }
  /* USER CODE END StartDataParseTask */
}
コード例 #20
0
//Mailbox thread behaviour
void Thread_MAIL_CONTROLLER(void const *argument) {
	osEvent event;
	MAIL_package_typedef *package_recieved;
	MAIL_package_typedef *package_to_send;

	while (1) {
		event = osMailGet(input_mailbox, osWaitForever);

		if (event.status == osEventMail) {
			package_recieved = (MAIL_package_typedef *) event.value.p;

			if (package_recieved->type == MAIL_TEMP) { //Update temp

				//Synthetic alarm simulator
				//if (test < 150) package_recieved->value += 20;
				//test = (test +1) % 300;

				temperature = package_recieved->value;

				if (temperature >= ALARM_THRESHOLD && !alarm_on) {
					package_to_send = osMailAlloc(led_mailbox, osWaitForever);
					package_to_send->type = MAIL_ALARM;
					package_to_send->value = 100.0f;
					osMailPut(led_mailbox, package_to_send);
					alarm_on = 1;
				} else if(temperature < ALARM_THRESHOLD && alarm_on) {
					package_to_send = osMailAlloc(led_mailbox, osWaitForever);
					package_to_send->type = MAIL_ALARM;
					package_to_send->value = 0.0f;
					osMailPut(led_mailbox, package_to_send);
					alarm_on = 0;
				}

			} else if (package_recieved->type == MAIL_ANGLE) { //Update angle
				angle = package_recieved->value;

			} else if (package_recieved->type == MAIL_KEY) { //Update key event

				key_event = (int)package_recieved->value;
				printf("%i\n", key_event);
				if (key_event == KP_STAR) { //Star pressed
					//Change which type of event we send to led
					if (curent_display_type == MAIL_TEMP) {
						curent_display_type = MAIL_ANGLE;

						//Prepare package to send current angle value to led right away at last if of function
						package_recieved->type = curent_display_type;
						package_recieved->value = angle;

					} else if (curent_display_type == MAIL_ANGLE) {
						curent_display_type = MAIL_TEMP;

						//Prepare package to send current temp value to led right away at last if of function
						package_recieved->type = curent_display_type;
						package_recieved->value = temperature;
					}

				} else if (key_event == KP_POUND && curent_display_type != MAIL_TEMP) { //Pound pressed
					if (!target_set) {
						target_set = 1;

						//Send pound event to led to confirm current target value
						package_to_send = osMailAlloc(led_mailbox, osWaitForever);
						package_to_send->value = key_event;
						package_to_send->type = MAIL_KEY;
						osMailPut(led_mailbox, package_to_send);
					}

				} else { //Digit pressed
					if (!target_set) {

						//Send key event to led to change current digit
						package_to_send = osMailAlloc(led_mailbox, osWaitForever);
						package_to_send->value = key_event;
						package_to_send->type = MAIL_KEY;
						osMailPut(led_mailbox, package_to_send);
					}
				}
			}

			//Send new data to LED if of current type
			if (package_recieved->type == curent_display_type){
				package_to_send = osMailAlloc(led_mailbox, osWaitForever);
				package_to_send->value = package_recieved->value;
				package_to_send->type = package_recieved->type;
				osMailPut(led_mailbox, package_to_send);
			}

			osMailFree(input_mailbox, package_recieved);
		}
	}
}
コード例 #21
0
void Start_input_touchTask(void const * argument)
{
  uint8_t is_first_click = 1;
  lcd_pos_t current_lcd_pos;
  click_t click;

  /* Infinite loop */
  for(;;)
  {
    if (osSemaphoreWait(sem_input_touch_penHandle, osWaitForever) == osOK)
    {
      /* Mask PEN interrupts */
      EXTI->IMR &= (~TP_PEN_Pin);

      /* A finger is touching the screen.
       * Keep reading values until finger is lifted
       */
      do
      {
        /* Read value */
        touch_read_position(&touch);
        current_lcd_pos = touch_get_lcd_pos(&touch);

        /* If we detect a touch with enough pressure */
        if (touch.is_clicked == T_CLICKED)
        {
          /* Prepare click position */
          click.pos.x_pos = current_lcd_pos.x_pos;
          click.pos.y_pos = current_lcd_pos.y_pos;

          /* If it is the first one (the first click) */
          if (is_first_click)
          {
            /* A finger just pressed the screen
             * with enough pressure!
             */
            click.click_type = CLICK_DOWN;
            while(osMailPut(queue_input_clickHandle, (void *) &click) != osOK)
            {
              osDelay(1);
            }

            /* No longer detecting the first click */
            is_first_click = 0;
          }
          /* If it is not the first one (it keeps pressing the screen) */
          else
          {
            /* Finger is still pressing the screen!
             */
            click.click_type = CLICK_HOLD;
            while(osMailPut(queue_input_clickHandle, (void *) &click) != osOK)
            {
              osDelay(1);
            }
          }
        }
        /* Finger detection sample interval */
        osDelay(50);
      }
      while (HAL_GPIO_ReadPin(TP_PEN_GPIO_Port, TP_PEN_Pin) == GPIO_PIN_RESET);
      /* Keep polling until PEN signal goes high */

      /* If we have detected at least one valid click */
      if (!is_first_click)
      {
        /* Finger is lifted from the screen!
         */
        click.click_type = CLICK_UP;
        while(osMailPut(queue_input_clickHandle, (void *) &click) != osOK)
        {
          osDelay(1);
        }
        /* Set last position as not clicked */
        touch.is_clicked = T_NOT_CLICKED;
        touch.current_pos.pressure = 0;
      }

      /* Reset first click status */
      is_first_click = 1;

      /* Unmask PEN interrupts */
      EXTI->IMR |= TP_PEN_Pin;
    }
  }
}