#if 0
//------------------------------------------------------------------------------
// Copyright (c) 2012 by Silicon Laboratories. 
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Silicon Laboratories End User 
// License Agreement which accompanies this distribution, and is available at
// http://developer.silabs.com/legal/version/v10/License_Agreement_v10.htm
// Original content and implementation provided by Silicon Laboratories.
//------------------------------------------------------------------------------
// library
#include <si32McuComponent.h>
#include <si32PseudOsComponent.h>
// hal
// use the leds for a visual indication of data flow, when MCU card SW4 is ON.
#include <SI32_PBSTD_A_Type.h>
// application
#include "myApplication.h"
#include "myDataPlane.h"
#include "myI2S0.h"
#include "myUsbAudioDevice.h"

// for profiling with a scope:
uint32 _scope = 0;

//------------------------------------------------------------------------------
// The value of myDataPlaneOutEp is manipulated in myUsbAudiodevice.c, in a poller.
// A NULL value for myDataPlaneOutEp indicates that audio-out streaming interface's
// endpoint is not enabled, and therefore no data can flow.  Non NULL indicates
// an enabled endpoint, and data can flow.  This value can change at any time
// and must be periodically checked, as it is currently the data plane thread's   
// only information about the state of the USB.  The same is true for myDataPlaneInEp.
static si32PseudoThreadObject _myDataPlane = si32PseudoThreadObject();
si32UsbEndpointObject* myDataPlaneOutEp = NULL;
si32UsbEndpointObject* myDataPlaneInEp = NULL;
si32PseudoThreadObject* myDataPlane = &_myDataPlane;

static uint8 buffer0[192] = {0};
static uint8 buffer1[192] = {0};

static bool _receive0 = NO;
static bool _receive1 = NO;

static bool _received0 = NO;
static bool _received1 = NO;

static bool _transmit0 = NO;
static bool _transmit1 = NO;

static bool _transmitted0 = YES;
static bool _transmitted1 = YES;

//------------------------------------------------------------------------------
typedef struct myDataPlaneContextStruct
{
  si32TimerTagType tmrtag;
} myDataPlaneContextType;

// forward references
void rx0(void);
void tx0(void);
void rx1(void);
void tx1(void);

#define RECEIVE_FROM_TX_ISR 0
#define TRANSMIT_FROM_RX_ISR 0

//------------------------------------------------------------------------------
static void tx0_callback(si32PortalObjectResultType result,
                        uint32 actual,
                        void* context0,
                        void* context1)
{
  si32Assert(result == SI32_PORTAL_OBJECT_RESULT_SUCCESS);
  _scope &= ~SCOPE_t0;
  scope();
  _transmitted0 = YES;
  if (_received1)
  {
    tx1();
  }
  #if RECEIVE_FROM_TX_ISR
  rx0();
  #else
  _receive0 = YES;
  si32PseudoThreadObject_resume(myDataPlane,
                                SI32_PSEUDO_THREAD_PRIORITY_HIGH);
  #endif
}

//------------------------------------------------------------------------------
static void tx1_callback(si32PortalObjectResultType result,
                        uint32 actual,
                        void* context0,
                        void* context1)
{
  si32Assert(result == SI32_PORTAL_OBJECT_RESULT_SUCCESS);
  _scope &= ~SCOPE_t1;
  scope();
  _transmitted1 = YES;
  if (_received0)
  {
    tx0();
  }
  #if RECEIVE_FROM_TX_ISR
  rx1();
  #else
  _receive1 = YES;
  si32PseudoThreadObject_resume(myDataPlane,
                                SI32_PSEUDO_THREAD_PRIORITY_HIGH);
  #endif
}

//------------------------------------------------------------------------------
static void rx0_callback(obj* delegate,
                        void* context,
                        uint32 tag,
                        obj* buffer,
                        si32IoRequestResultType result,
                        uint32 residue)
{
  //si32Assert(result == SI32_IO_REQUEST_RESULT_SUCCESS);
  si32Assert((result == SI32_IO_REQUEST_RESULT_SUCCESS)
          || (result == SI32_IO_REQUEST_RESULT_IN_PROGRESS));
  _scope &= ~SCOPE_r0;
  scope();
  _received0 = YES;
  bool transmitting = si32PortalObject_get_status(my_iis0_portal) & SI32_PORTAL_OBJECT_STATUS_TRANSMITTING;
  if (!transmitting &&
      _transmitted0 && _transmitted1)
  {
    #if TRANSMIT_FROM_RX_ISR
    tx0();
    #else
    _transmit0 = YES;
    si32PseudoThreadObject_resume(myDataPlane,
                                  SI32_PSEUDO_THREAD_PRIORITY_HIGH);
    #endif
  }
}

//------------------------------------------------------------------------------
static void rx1_callback(obj* delegate,
                        void* context,
                        uint32 tag,
                        obj* buffer,
                        si32IoRequestResultType result,
                        uint32 residue)
{
  //si32Assert(result == SI32_IO_REQUEST_RESULT_SUCCESS);
  si32Assert((result == SI32_IO_REQUEST_RESULT_SUCCESS)
          || (result == SI32_IO_REQUEST_RESULT_IN_PROGRESS));
  _scope &= ~SCOPE_r1;
  scope();
  _received1 = YES;
  bool transmitting = si32PortalObject_get_status(my_iis0_portal) & SI32_PORTAL_OBJECT_STATUS_TRANSMITTING;
  if (!transmitting &&
      _transmitted0 && _transmitted1)
  {
    #if TRANSMIT_FROM_RX_ISR
    tx1();
    #else
    _transmit1 = YES;
    si32PseudoThreadObject_resume(myDataPlane,
                                  SI32_PSEUDO_THREAD_PRIORITY_HIGH);
    #endif
  }
}

//------------------------------------------------------------------------------
static void rx0()
{
  if (!myDataPlaneOutEp)
  {
    return;
  }
  si32IoRequestTagType rqtag = SI32_IO_REQUEST_TAG_ERROR;
  _scope |= SCOPE_r0;
  scope();
  _received0 = NO;
  rqtag = si32UsbEndpointObject_receive(myDataPlaneOutEp,
                                        buffer0,
                                        192,
                                        rx0_callback,
                                        NULL,
                                        NULL);
  si32Assert(rqtag != SI32_IO_REQUEST_TAG_ERROR);
}

//------------------------------------------------------------------------------
static void tx0()
{
  if (!myDataPlaneOutEp)
  {
    return;
  }
  si32PortalObjectResultType result = SI32_PORTAL_OBJECT_RESULT_ERROR_BUS;
  _scope |= SCOPE_t0;
  scope();
  _transmitted0 = NO;
  result = si32IisAPortalObject_write_async(my_iis0_portal,
                                            buffer0,
                                            192,
                                            tx0_callback,
                                            NULL,
                                            NULL);
  si32Assert(result == SI32_PORTAL_OBJECT_RESULT_IN_PROGRESS);
}

//------------------------------------------------------------------------------
static void rx1()
{
  if (!myDataPlaneOutEp)
  {
    return;
  }
  si32IoRequestTagType rqtag = SI32_IO_REQUEST_TAG_ERROR;
  _scope |= SCOPE_r1;
  scope();
  _received1 = NO;
  rqtag = si32UsbEndpointObject_receive(myDataPlaneOutEp,
                                        buffer1,
                                        192,
                                        rx1_callback,
                                        NULL,
                                        NULL);
  si32Assert(rqtag != SI32_IO_REQUEST_TAG_ERROR);
}

//------------------------------------------------------------------------------
static void tx1()
{
  if (!myDataPlaneOutEp)
  {
    return;
  }
  si32PortalObjectResultType result = SI32_PORTAL_OBJECT_RESULT_ERROR_BUS;
  _scope |= SCOPE_t1;
  scope();
  _transmitted1 = NO;
  result = si32IisAPortalObject_write_async(my_iis0_portal,
                                            buffer1,
                                            192,
                                            tx1_callback,
                                            NULL,
                                            NULL);
  si32Assert(result == SI32_PORTAL_OBJECT_RESULT_IN_PROGRESS);
}

//------------------------------------------------------------------------------
static
uint32 myDataPlaneFn()
{
  si32PseudoThread_begin();
  while (1)
  {
    // if the ep is lost, stop moving data.
    si32PseudoThread_wait_until(myDataPlaneOutEp);
    rx0();
    rx1();
    while (myDataPlaneOutEp)
    {
      #if RECEIVE_FROM_TX_ISR && TRANSMIT_FROM_RX_ISR
      si32PseudoThread_yield();
      #else
      si32PseudoThread_wait_until(_receive0 || _receive1 || _transmit0 || _transmit1);
      if (_receive0)
      {
        _receive0 = NO;
        rx0();
      }
      if (_receive1)
      {
        _receive1 = NO;
        rx1();  
      }
      if (_transmit0)
      {
        _transmit0 = NO;
        _transmit1 = NO;
        tx0();
      }
      if (_transmit1)
      {
        _transmit0 = NO;
        _transmit1 = NO;
        tx1();  
      }
      #endif
    }
  }
  si32PseudoThread_end();
}

//------------------------------------------------------------------------------
void myDataPlaneIn_initialize()
{
  // initialize a thread to run this test.
  si32PseudoThreadObject_initialize(myDataPlane);

  // allocate the data needed for thread local storage.
  myDataPlaneContextType* tls = si32Base_allocate(si32Base_get_default_allocation_zone(),
                                                  sizeof(myDataPlaneContextType),
                                                  1);
  si32Assert(tls);

  // attach the tls to the thread.
  si32PseudoThreadObject_set_thread_local_storage(myDataPlane,
                                                  tls);

  // start the thread.
  si32PseudoThreadObject_run(myDataPlane,
                             myDataPlaneFn);
}

//---eof------------------------------------------------------------------------
#endif