/*
 * AXCConditionVariableFreeRTOS.cpp
 */

#include <string.h>
#include "FreeRTOS.h"
#include "AXCConditionVariableFreeRTOS.hpp"
#include "AXCStdioFreeRTOS.hpp"

AXCConditionVariableFreeRTOS::AXCConditionVariableFreeRTOS()
    : m_isInited(false) {
	m_cond = NULL;
}

AXCConditionVariableFreeRTOS::~AXCConditionVariableFreeRTOS() {
  if (m_isInited) {
    m_isInited = false;
  }

  /* Delete event flag */
	vEventGroupDelete(m_cond);
}

AXCConditionVariableFreeRTOS::condStatus AXCConditionVariableFreeRTOS::init() {
  condStatus stat = COND_ERROR;

  /* Check initialized */
  if (true == m_isInited) {
    goto err;
  }

  /* Create event flag */
	m_cond = xEventGroupCreate();
#ifdef USE_FRTOSDEBUG
  {
    AXCStdioFreeRTOS stdio;
    std::cout << "### cond id = " << m_cond << axstdio::endl;
    stdio.flush();
  }
#endif /* USE_FRTOSDEBUG */
	if (m_cond == NULL) {
		goto err;
	}
	
  m_isInited = true;

  return COND_SUCCESS;

  err:
#ifdef USE_FRTOSDEBUG
  {
    AXCStdioFreeRTOS stdio;
    std::cout << "### cond cre err= " << m_cond << axstdio::endl;
    stdio.flush();
  }
#endif /* USE_FRTOSDEBUG */

  return stat;
}

AXCConditionVariableFreeRTOS::condStatus AXCConditionVariableFreeRTOS::signal() {
  condStatus stat = COND_ERROR;

  /* Check initialized */
  if (true != m_isInited) {
    goto err;
  }

  /* Set event flag */
	(void)xEventGroupSetBits(m_cond, EVENT_FLAG_ID_1);	/* 戻り値は別タスク再度クリアされるため確認しない */

  return COND_SUCCESS;

  err:
#ifdef  USE_FRTOSDEBUG
  {
    AXCStdioFreeRTOS stdio;
    std::cout << "### cond set err= " << ercd << axstdio::endl;
    stdio.flush();
  }
#endif /* USE_FRTOSDEBUG */
  return stat;
}

AXCConditionVariableFreeRTOS::condStatus AXCConditionVariableFreeRTOS::wait() {
  condStatus stat = COND_ERROR;
	EventBits_t flgptn;	

  /* Check initialized */
  if (true != m_isInited) {
    goto err;
  }

  /* Wait event flag */
	flgptn = xEventGroupWaitBits(m_cond, EVENT_FLAG_ID_1, pdTRUE, pdFALSE, portMAX_DELAY);
	if ((flgptn & EVENT_FLAG_ID_1) != EVENT_FLAG_ID_1) {
		goto err;
	}

  return COND_SUCCESS;

  err:
#ifdef USE_FRTOSDEBUG
  {
    AXCStdioFreeRTOS stdio;
    std::cout << "### cond wai err= " << ercd << axstdio::endl;
    stdio.flush();
  }
#endif /* USE_FRTOSDEBUG */
  return stat;
}
