/*******************************************************************************
* DISCLAIMER
* This software is supplied by Renesas Electronics Corporation and is only
* intended for use with Renesas products. No other uses are authorized. This
* software is owned by Renesas Electronics Corporation and is protected under
* all applicable laws, including copyright laws.
* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT
* LIMITED TO WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
* AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED.
* TO THE MAXIMUM EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS
* ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES SHALL BE LIABLE
* FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR
* ANY REASON RELATED TO THIS SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* Renesas reserves the right, without notice, to make changes to this software
* and to discontinue the availability of this software. By using this software,
* you agree to the additional terms and conditions found by accessing the
* following link:
* http://www.renesas.com/disclaimer
* Copyright (C) 2014 Renesas Electronics Corporation. All rights reserved.
*******************************************************************************/
/*******************************************************************************
* File Name    : usb0_os_if.c
* $Rev: 682 $
* $Date:: 2014-01-23 09:15:07 +0900#$
* Device(s)    :
* Tool-Chain   :
* OS           : None
* H/W Platform :
* Description  : USB Sample Program
* Operation    :
* Limitations  :
*******************************************************************************/


/*******************************************************************************
Includes   <System Includes> , "Project Includes"
*******************************************************************************/
#include "usb_hdrv_rza1.h"
#include "usb_hub_rza1.h"
#include "Renesas_RZ_A1.h"


/*******************************************************************************
Typedef definitions
*******************************************************************************/


/*******************************************************************************
Macro definitions
*******************************************************************************/
#define __HMSCD_SAME_RESOURCE__


/*******************************************************************************
Imported global variables and functions (from other files)
*******************************************************************************/


/*******************************************************************************
Exported global variables and functions (to be accessed by other files)
*******************************************************************************/
/* ==== Task ==== */
osThreadId g_usb0_hmgr_taskid;
osThreadId g_usb0_hcd_taskid;
osThreadId g_usb0_hub_taskid;
osThreadId g_usb0_het_taskid;

osThreadDef(usb0_hmgr_task, osPriorityAboveNormal, 1, 0);
osThreadDef(usb0_hcd_task,  osPriorityAboveNormal, 1, 0);
osThreadDef(usb0_hub_task,  osPriorityNormal,      1, 0);
osThreadDef(usb0_ele_task,  osPriorityNormal,      1, 0);

/* ==== Memory Pool ==== */
osPoolId g_usb0_hmgr_mempoolid;
osPoolId g_usb0_hcd_mempoolid;
osPoolId g_usb0_hub_mempoolid;

osPoolDef(usb0_hmgr_mempool, 16, USB_HMGR_MESSAGE_t);
osPoolDef(usb0_hcd_mempool,  16, USB_HCD_MESSAGE_t);
osPoolDef(usb0_hub_mempool,  16, USB_HUB_MESSAGE_t);

/* ==== Messasge ==== */
osMessageQId g_usb0_hmgr_messageid;
osMessageQId g_usb0_hmgr_hcd_messageid;
osMessageQId g_usb0_hcd_messageid;
osMessageQId g_usb0_hclass_messageid;
osMessageQId g_usb0_hub_messageid;
osMessageQId g_usb0_hmscd1_messageid;
osMessageQId g_usb0_hmscd2_messageid;
osMessageQId g_usb0_hmscd3_messageid;
osMessageQId g_usb0_hmscd4_messageid;
osMessageQId g_usb0_hmscd5_messageid;
osMessageQId g_usb0_haudio_in_messageid;
osMessageQId g_usb0_haudio_out_messageid;

osMessageQDef(usb0_hmgr_message,     16, USB_HMGR_MESSAGE_t);
osMessageQDef(usb0_hmgr_hcd_message, 16, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hcd_message,      16, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hclass_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hub_message,      16, USB_HUB_MESSAGE_t);
osMessageQDef(usb0_hmscd1_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hmscd2_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hmscd3_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hmscd4_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_hmscd5_message,    1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_haudio_in_message, 1, USB_HCD_MESSAGE_t);
osMessageQDef(usb0_haudio_out_message,1, USB_HCD_MESSAGE_t);

/* ==== Mutex ==== */
osMutexId g_usb0_hmgr_mutexid;
osMutexId g_usb0_hcd_mutexid;
osMutexId g_usb0_hmscd1_mutexid;
osMutexId g_usb0_hmscd2_mutexid;
osMutexId g_usb0_hmscd3_mutexid;
osMutexId g_usb0_hmscd4_mutexid;
osMutexId g_usb0_hmscd5_mutexid;

osMutexDef(usb0_hmgr_mutex);
osMutexDef(usb0_hcd_mutex);
osMutexDef(usb0_hmscd1_mutex);
osMutexDef(usb0_hmscd2_mutex);
osMutexDef(usb0_hmscd3_mutex);
osMutexDef(usb0_hmscd4_mutex);
osMutexDef(usb0_hmscd5_mutex);


/*******************************************************************************
Private global variables and functions
*******************************************************************************/
static const int32_t g_usb0_signal_bitset[ 16 ] = {   0x00000001, 0x00000002, 0x00000004, 0x00000008,
                                                      0x00000010, 0x00000020, 0x00000040, 0x00000080,
                                                      0x00000100, 0x00000200, 0x00000400, 0x00000800,
                                                      0x00001000, 0x00002000, 0x00004000, 0x00008000 };

osThreadId g_usb0_fifo_signal[ 2 ][USB_MAX_WAIT_SIGNAL_TASK];

static osThreadId g_usb0_usbid_2_osThreadId_tbl[ USB_END_ID ] =
{
    (osThreadId)0,               /* USB_MGR      */
    (osThreadId)0,               /* USB_MGR_HCD  */
    (osThreadId)0,               /* USB_HCD      */
    (osThreadId)0,               /* USB_HCLASS   */
    (osThreadId)0,               /* USB_ELE_TEST */
    (osThreadId)0,               /* USB_HUB      */
    (osThreadId)0,               /* USB_HMSCD    */
    (osThreadId)0,               /* USB_HMSCD1   */
    (osThreadId)0,               /* USB_HMSCD2   */
    (osThreadId)0,               /* USB_HMSCD3   */
    (osThreadId)0,               /* USB_HMSCD4   */
    (osThreadId)0,               /* USB_HMSCD5   */
    (osThreadId)0,               /* USB_HAUDIO_IN  */
    (osThreadId)0,               /* USB_HAUDIO_OUT */
};

static osMessageQId g_usb0_usbid_2_osMessageId_tbl[ USB_END_ID ] =
{
    (osMessageQId)0,             /* USB_MGR      */
    (osMessageQId)0,             /* USB_MGR_HCD  */
    (osMessageQId)0,             /* USB_HCD      */
    (osMessageQId)0,             /* USB_HCLASS   */
    (osMessageQId)0,             /* USB_ELE_TEST */
    (osMessageQId)0,             /* USB_HUB      */
    (osMessageQId)0,             /* USB_HMSCD    */
    (osMessageQId)0,             /* USB_HMSCD1   */
    (osMessageQId)0,             /* USB_HMSCD2   */
    (osMessageQId)0,             /* USB_HMSCD3   */
    (osMessageQId)0,             /* USB_HMSCD4   */
    (osMessageQId)0,             /* USB_HMSCD5   */
    (osMessageQId)0,             /* USB_HAUDIO_IN  */
    (osMessageQId)0,             /* USB_HAUDIO_OUT */
};

static osPoolId g_usb0_usbid_2_osPoolId_tbl[ USB_END_ID ] =
{
    (osPoolId)0,                 /* USB_MGR      */
    (osPoolId)0,                 /* USB_MGR_HCD  */
    (osPoolId)0,                 /* USB_HCD      */
    (osPoolId)0,                 /* USB_HCLASS   */
    (osPoolId)0,                 /* USB_ELE_TEST */
    (osPoolId)0,                 /* USB_HUB      */
    (osPoolId)0,                 /* USB_HMSCD    */
    (osPoolId)0,                 /* USB_HMSCD1   */
    (osPoolId)0,                 /* USB_HMSCD2   */
    (osPoolId)0,                 /* USB_HMSCD3   */
    (osPoolId)0,                 /* USB_HMSCD4   */
    (osPoolId)0,                 /* USB_HMSCD5   */
    (osPoolId)0,                 /* USB_HAUDIO_IN  */
    (osPoolId)0,                 /* USB_HAUDIO_OUT */
};

static osMutexId g_usb0_usbid_2_osMutexId_tbl[ USB_END_ID ] =
{
    (osMutexId)0,                /* USB_MGR      */
    (osMutexId)0,                /* USB_MGR_HCD  */
    (osMutexId)0,                /* USB_HCD      */
    (osMutexId)0,                /* USB_HCLASS   */
    (osMutexId)0,                /* USB_ELE_TEST */
    (osMutexId)0,                /* USB_HUB      */
    (osMutexId)0,                /* USB_HMSCD    */
    (osMutexId)0,                /* USB_HMSCD1   */
    (osMutexId)0,                /* USB_HMSCD2   */
    (osMutexId)0,                /* USB_HMSCD3   */
    (osMutexId)0,                /* USB_HMSCD4   */
    (osMutexId)0,                /* USB_HMSCD5   */
    (osMutexId)0,                /* USB_HAUDIO_IN  */
    (osMutexId)0,                /* USB_HAUDIO_OUT */
};




/*******************************************************************************
* Function Name: usb0_userdef_os_init_id
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
void usb0_userdef_os_init_id(void)
{
    int32_t     task;
    uint16_t    fifo;

    /* ==== Task ==== */
    g_usb0_hmgr_taskid = (osThreadId)0;
    g_usb0_hcd_taskid  = (osThreadId)0;
    g_usb0_hub_taskid  = (osThreadId)0;
    g_usb0_het_taskid  = (osThreadId)0;

    /* ==== Memory Pool ==== */
    g_usb0_hmgr_mempoolid = (osPoolId)0;
    g_usb0_hcd_mempoolid  = (osPoolId)0;
    g_usb0_hub_mempoolid  = (osPoolId)0;

    /* ==== Messasge ==== */
    g_usb0_hmgr_messageid     = (osMessageQId)0;
    g_usb0_hmgr_hcd_messageid = (osMessageQId)0;
    g_usb0_hcd_messageid      = (osMessageQId)0;
    g_usb0_hclass_messageid   = (osMessageQId)0;
    g_usb0_hub_messageid      = (osMessageQId)0;
    g_usb0_hmscd1_messageid   = (osMessageQId)0;
    g_usb0_hmscd2_messageid   = (osMessageQId)0;
    g_usb0_hmscd3_messageid   = (osMessageQId)0;
    g_usb0_hmscd4_messageid   = (osMessageQId)0;
    g_usb0_hmscd5_messageid   = (osMessageQId)0;
    g_usb0_haudio_in_messageid  = (osMessageQId)0;
    g_usb0_haudio_out_messageid = (osMessageQId)0;

    /* ==== Mutex ==== */
    g_usb0_hmgr_mutexid = (osMutexId)0;
    g_usb0_hcd_mutexid  = (osMutexId)0;

    /* ==== signal ==== */
    for( fifo = 0; fifo < 2; fifo++ )
    {
        for( task = 0; task < USB_MAX_WAIT_SIGNAL_TASK; task++ )
        {
            g_usb0_fifo_signal[ fifo ][ task ] = (osThreadId)0;
        }
    }
}

/*******************************************************************************
* Function Name: usb0_userdef_os_interrupt_regist
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_interrupt_regist( void )
{
    InterruptHandlerRegister(USBI0_IRQn, usb0_host_interrupt);
    GIC_SetPriority(USBI0_IRQn, 5);
    GIC_EnableIRQ(USBI0_IRQn);

    InterruptHandlerRegister(DMAINT1_IRQn, usb0_dma_interrupt_d0fifo);
    GIC_SetPriority(DMAINT1_IRQn, 5);
    GIC_EnableIRQ(DMAINT1_IRQn);

    InterruptHandlerRegister(DMAINT2_IRQn, usb0_dma_interrupt_d1fifo);
    GIC_SetPriority(DMAINT2_IRQn, 5);
    GIC_EnableIRQ(DMAINT2_IRQn);

    return 0;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_set_signal_tskid
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_set_signal_tskid(uint16_t fifo, int32_t *task_ofst)
{
    osThreadId    task_id;

    for( *task_ofst = 0; *task_ofst < USB_MAX_WAIT_SIGNAL_TASK; *task_ofst += 1 )
    {
        if( g_usb0_fifo_signal[ fifo ][ *task_ofst ] == (osThreadId)0 )
        {
            break;
        }
    }

    if( *task_ofst == USB_MAX_WAIT_SIGNAL_TASK )
    {
        return USB_ERROR;
    }

    task_id = osThreadGetId();
    g_usb0_fifo_signal[ fifo ][ *task_ofst ] = task_id;

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_clear_signal_tskid
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_clear_signal_tskid(uint16_t fifo, int32_t task_ofst)
{
    g_usb0_fifo_signal[ fifo ][ task_ofst ] = (osThreadId)0;

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_wait_signal
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_wait_signal(uint16_t fifo, uint32_t timeout)
{
    osEvent    evt;
    int32_t    signal;

    signal = g_usb0_signal_bitset[ fifo ];
    if( timeout == 0 )
    {
        evt = osSignalWait(signal, osWaitForever);
        if (evt.status != osEventSignal)
        {
            return USB_ERROR;
        }
    }
    else
    {
        evt = osSignalWait(signal, timeout);
        if (evt.status != osEventSignal)
        {
            if(evt.status == osEventTimeout)
            {
                return USB_TIMEOUT;
            }
            return USB_ERROR;
        }
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_set_signal
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_set_signal(uint16_t fifo)
{
    int32_t    task_ofst;
    int32_t    signal;

    signal = g_usb0_signal_bitset[ fifo ];
    for( task_ofst = 0; task_ofst < USB_MAX_WAIT_SIGNAL_TASK; task_ofst += 1 )
    {
        if( g_usb0_fifo_signal[ fifo ][ task_ofst ] != (osThreadId)0 )
        {
            osSignalSet(g_usb0_fifo_signal[ fifo ][ task_ofst ], signal);
        }
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_sta_tsk
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_sta_tsk( uint32_t usbid, int32_t stacd )
{
    switch( usbid )
    {
    case USB_MGR:
        if( g_usb0_usbid_2_osThreadId_tbl[USB_MGR] == (osThreadId)0 )
        {
            g_usb0_hmgr_taskid = osThreadCreate(osThread(usb0_hmgr_task), (void *)0);
            if( g_usb0_hmgr_taskid == (osThreadId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osThreadId_tbl[USB_MGR] = g_usb0_hmgr_taskid;
        }
        break;
    case USB_HCD:
        if( g_usb0_usbid_2_osThreadId_tbl[USB_HCD] == (osThreadId)0 )
        {
            g_usb0_hcd_taskid = osThreadCreate(osThread(usb0_hcd_task), (void *)0);
            if( g_usb0_hcd_taskid == (osThreadId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osThreadId_tbl[USB_HCD] = g_usb0_hcd_taskid;
        }
        break;
    case USB_HUB:
        if( g_usb0_usbid_2_osThreadId_tbl[USB_HUB] == (osThreadId)0 )
        {
            g_usb0_hub_taskid = osThreadCreate(osThread(usb0_hub_task), (void *)0);
            if( g_usb0_hub_taskid == (osThreadId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osThreadId_tbl[USB_HUB] = g_usb0_hub_taskid;
        }
        break;
    case USB_ELE_TEST:
        if( g_usb0_usbid_2_osThreadId_tbl[USB_ELE_TEST] == (osThreadId)0 )
        {
            g_usb0_het_taskid = osThreadCreate(osThread(usb0_ele_task), (void *)0);
            if( g_usb0_het_taskid == (osThreadId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osThreadId_tbl[USB_ELE_TEST] = g_usb0_het_taskid;
        }
        break;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_ter_tsk
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_ter_tsk( uint32_t usbid )
{
    osThreadId    osThread_id;
    osStatus      os_status;

    osThread_id = g_usb0_usbid_2_osThreadId_tbl[usbid];
    if( osThread_id != (osThreadId)0 )
    {
        os_status = osThreadTerminate( osThread_id );
        if( os_status != osOK )
        {
            return USB_ERROR;
        }
        g_usb0_usbid_2_osThreadId_tbl[usbid] = (osThreadId)0;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_create_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_create_mbx( uint32_t usbid )
{
    switch( usbid )
    {
    case USB_MGR:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_MGR] == (osMessageQId)0 )
        {
            g_usb0_hmgr_messageid = osMessageCreate(osMessageQ(usb0_hmgr_message), NULL);
            if( g_usb0_hmgr_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_MGR] = g_usb0_hmgr_messageid;
        }
        break;
    case USB_MGR_HCD:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_MGR_HCD] == (osMessageQId)0 )
        {
            g_usb0_hmgr_hcd_messageid = osMessageCreate(osMessageQ(usb0_hmgr_hcd_message), NULL);
            if( g_usb0_hmgr_hcd_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_MGR_HCD] = g_usb0_hmgr_hcd_messageid;
        }
        break;
    case USB_HCD:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HCD] == (osMessageQId)0 )
        {
            g_usb0_hcd_messageid = osMessageCreate(osMessageQ(usb0_hcd_message), NULL);
            if( g_usb0_hcd_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HCD] = g_usb0_hcd_messageid;
        }
        break;
    case USB_HCLASS:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HCLASS] == (osMessageQId)0 )
        {
            g_usb0_hclass_messageid = osMessageCreate(osMessageQ(usb0_hclass_message), NULL);
            if( g_usb0_hclass_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HCLASS] = g_usb0_hclass_messageid;
        }
        break;
    case USB_HUB:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HUB] == (osMessageQId)0 )
        {
            g_usb0_hub_messageid = osMessageCreate(osMessageQ(usb0_hub_message), NULL);
            if( g_usb0_hub_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HUB] = g_usb0_hub_messageid;
        }
        break;
    case USB_HMSCD1:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD1] == (osMessageQId)0 )
        {
            g_usb0_hmscd1_messageid = osMessageCreate(osMessageQ(usb0_hmscd1_message), NULL);
            if( g_usb0_hmscd1_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD1] = g_usb0_hmscd1_messageid;
        }
        break;
    case USB_HMSCD2:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD2] == (osMessageQId)0 )
        {
            g_usb0_hmscd2_messageid = osMessageCreate(osMessageQ(usb0_hmscd2_message), NULL);
            if( g_usb0_hmscd2_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD2] = g_usb0_hmscd2_messageid;
        }
        break;
    case USB_HMSCD3:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD3] == (osMessageQId)0 )
        {
            g_usb0_hmscd3_messageid = osMessageCreate(osMessageQ(usb0_hmscd3_message), NULL);
            if( g_usb0_hmscd3_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD3] = g_usb0_hmscd3_messageid;
        }
        break;
    case USB_HMSCD4:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD4] == (osMessageQId)0 )
        {
            g_usb0_hmscd4_messageid = osMessageCreate(osMessageQ(usb0_hmscd4_message), NULL);
            if( g_usb0_hmscd4_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD4] = g_usb0_hmscd4_messageid;
        }
        break;
    case USB_HMSCD5:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD5] == (osMessageQId)0 )
        {
            g_usb0_hmscd5_messageid = osMessageCreate(osMessageQ(usb0_hmscd5_message), NULL);
            if( g_usb0_hmscd5_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HMSCD5] = g_usb0_hmscd5_messageid;
        }
        break;
    case USB_HAUDIO_IN:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HAUDIO_IN] == (osMessageQId)0 )
        {
            g_usb0_haudio_in_messageid = osMessageCreate(osMessageQ(usb0_haudio_in_message), NULL);
            if( g_usb0_haudio_in_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HAUDIO_IN] = g_usb0_haudio_in_messageid;
        }
        break;
    case USB_HAUDIO_OUT:
        if( g_usb0_usbid_2_osMessageId_tbl[USB_HAUDIO_OUT] == (osMessageQId)0 )
        {
            g_usb0_haudio_out_messageid = osMessageCreate(osMessageQ(usb0_haudio_out_message), NULL);
            if( g_usb0_haudio_out_messageid == (osMessageQId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMessageId_tbl[USB_HAUDIO_OUT] = g_usb0_haudio_out_messageid;
        }
        break;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_delete_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_delete_mbx( uint32_t usbid )
{
    osMessageQId    osMessgae_id;

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    /* nothig to do */
    /* because osMessageDelete not exist */

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_snd_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_snd_mbx( uint32_t usbid, void *msg )
{
    osStatus        os_status;
    osMessageQId    osMessgae_id;

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    os_status = osMessagePut(osMessgae_id, (uint32_t)msg, osWaitForever);
    if( (os_status != osOK) && (os_status != osEventMessage) )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_isnd_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_isnd_mbx( uint32_t usbid, void *msg )
{
    osStatus        os_status;
    osMessageQId    osMessgae_id;

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    os_status = osMessagePut(osMessgae_id, (uint32_t)msg, 0);    /* isnd wait must be 0 */
    if( (os_status != osOK) && (os_status != osEventMessage) )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_rcv_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_rcv_mbx( uint32_t usbid, void **msg )
{
    osEvent         evt;
    osMessageQId    osMessgae_id;

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    evt = osMessageGet(osMessgae_id, osWaitForever);
    if (evt.status != osEventMessage)
    {
        return USB_ERROR;
    }

    *msg = (void *)evt.value.p;

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_prcv_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_prcv_mbx( uint32_t usbid, void **msg )
{
    osEvent         evt;
    osMessageQId    osMessgae_id;

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    evt = osMessageGet(osMessgae_id, 0);
    if (evt.status != osEventMessage)
    {
        return USB_ERROR;
    }

    *msg = (void *)evt.value.p;

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_trcv_mbx
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_trcv_mbx( uint32_t usbid, void **msg, uint32_t timeout )
{
    int32_t         ret;
    osEvent         evt;
    osMessageQId    osMessgae_id;

    if( timeout == 0 )
    {
        ret = usb0_userdef_os_rcv_mbx(usbid, msg);
        return ret;
    }

    osMessgae_id = g_usb0_usbid_2_osMessageId_tbl[usbid];
    if( osMessgae_id == (osMessageQId)0 )
    {
        return USB_ERROR;
    }

    evt = osMessageGet(osMessgae_id, timeout);
    if (evt.status != osEventMessage)
    {
        if(evt.status == osEventTimeout)
        {
            return USB_TIMEOUT;
        }
        return USB_ERROR;
    }

    *msg = (void *)evt.value.p;

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_create_mpf
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_create_mpf( uint32_t usbid )
{
    switch( usbid )
    {
    case USB_MGR:
        if( g_usb0_usbid_2_osPoolId_tbl[USB_MGR] == (osPoolId)0 )
        {
            g_usb0_hmgr_mempoolid = osPoolCreate(osPool(usb0_hmgr_mempool));
            if( g_usb0_hmgr_mempoolid == (osPoolId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osPoolId_tbl[USB_MGR] = g_usb0_hmgr_mempoolid;
        }
        break;
    case USB_HCD:
        if( g_usb0_usbid_2_osPoolId_tbl[USB_HCD] == (osPoolId)0 )
        {
            g_usb0_hcd_mempoolid = osPoolCreate(osPool(usb0_hcd_mempool));
            if( g_usb0_hcd_mempoolid == (osPoolId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osPoolId_tbl[USB_HCD] = g_usb0_hcd_mempoolid;
        }
        break;
    case USB_HUB:
        if( g_usb0_usbid_2_osPoolId_tbl[USB_HUB] == (osPoolId)0 )
        {
            g_usb0_hub_mempoolid = osPoolCreate(osPool(usb0_hub_mempool));
            if( g_usb0_hub_mempoolid == (osPoolId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osPoolId_tbl[USB_HUB] = g_usb0_hub_mempoolid;
        }
        break;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_pget_mpf
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_pget_mpf( uint32_t usbid, void **mpf )
{
    osPoolId    osPool_id;

    osPool_id = g_usb0_usbid_2_osPoolId_tbl[usbid];
    if( osPool_id == (osPoolId)0 )
    {
        return USB_ERROR;
    }

    *mpf = osPoolAlloc(osPool_id);

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_ipget_mpf
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_ipget_mpf( uint32_t usbid, void **mpf )
{
    osPoolId    osPool_id;

    osPool_id = g_usb0_usbid_2_osPoolId_tbl[usbid];
    if( osPool_id == (osPoolId)0 )
    {
        return USB_ERROR;
    }

    *mpf = osPoolAlloc(osPool_id);

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_rel_mpf
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_rel_mpf( uint32_t usbid, void *mpf )
{
    osStatus    os_status;
    osPoolId    osPool_id;

    osPool_id = g_usb0_usbid_2_osPoolId_tbl[usbid];
    if( osPool_id == (osPoolId)0 )
    {
        return USB_ERROR;
    }

    os_status = osPoolFree(osPool_id, mpf);
    if( os_status != osOK )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_irel_mpf
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_irel_mpf( uint32_t usbid, void *mpf )
{
    osStatus    os_status;
    osPoolId    osPool_id;

    osPool_id = g_usb0_usbid_2_osPoolId_tbl[usbid];
    if( osPool_id == (osPoolId)0 )
    {
        return USB_ERROR;
    }

    os_status = osPoolFree(osPool_id, mpf);
    if( os_status != osOK )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_create_sem
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_create_sem( uint32_t usbid )
{
    switch( usbid )
    {
    case USB_MGR:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_MGR] == (osMutexId)0 )
        {
            g_usb0_hmgr_mutexid = osMutexCreate(osMutex(usb0_hmgr_mutex));
            if( g_usb0_hmgr_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_MGR] = g_usb0_hmgr_mutexid;
        }
        break;
    case USB_HCD:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HCD] == (osMutexId)0 )
        {
            g_usb0_hcd_mutexid = osMutexCreate(osMutex(usb0_hcd_mutex));
            if( g_usb0_hcd_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HCD]    = g_usb0_hcd_mutexid;
        }
        break;
#ifdef __HMSCD_SAME_RESOURCE__
    case USB_HMSCD1:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD1] == (osMutexId)0 )
        {
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
                if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
                {
                    return USB_ERROR;
                }
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD1] = g_usb0_hmscd1_mutexid;
        }
        break;
    case USB_HMSCD2:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD2] == (osMutexId)0 )
        {
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
                if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
                {
                    return USB_ERROR;
                }
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD2] = g_usb0_hmscd1_mutexid;
        }
        break;
    case USB_HMSCD3:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD3] == (osMutexId)0 )
        {
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
                if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
                {
                    return USB_ERROR;
                }
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD3] = g_usb0_hmscd1_mutexid;
        }
        break;
    case USB_HMSCD4:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD4] == (osMutexId)0 )
        {
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
                if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
                {
                    return USB_ERROR;
                }
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD4] = g_usb0_hmscd1_mutexid;
        }
        break;
    case USB_HMSCD5:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD5] == (osMutexId)0 )
        {
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
                if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
                {
                    return USB_ERROR;
                }
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD5] = g_usb0_hmscd1_mutexid;
        }
        break;
#else
    case USB_HMSCD1:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD1] == (osMutexId)0 )
        {
            g_usb0_hmscd1_mutexid = osMutexCreate(osMutex(usb0_hmscd1_mutex));
            if( g_usb0_hmscd1_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD1] = g_usb0_hmscd1_mutexid;
        }
        break;
    case USB_HMSCD2:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD2] == (osMutexId)0 )
        {
            g_usb0_hmscd2_mutexid = osMutexCreate(osMutex(usb0_hmscd2_mutex));
            if( g_usb0_hmscd2_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD2] = g_usb0_hmscd2_mutexid;
        }
        break;
    case USB_HMSCD3:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD3] == (osMutexId)0 )
        {
            g_usb0_hmscd3_mutexid = osMutexCreate(osMutex(usb0_hmscd3_mutex));
            if( g_usb0_hmscd3_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD3] = g_usb0_hmscd3_mutexid;
        }
    case USB_HMSCD4:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD4] == (osMutexId)0 )
        {
            g_usb0_hmscd4_mutexid = osMutexCreate(osMutex(usb0_hmscd4_mutex));
            if( g_usb0_hmscd4_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD4] = g_usb0_hmscd4_mutexid;
        }
        break;
    case USB_HMSCD5:
        if( g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD5] == (osMutexId)0 )
        {
            g_usb0_hmscd5_mutexid = osMutexCreate(osMutex(usb0_hmscd5_mutex));
            if( g_usb0_hmscd5_mutexid == (osMutexId)0 )
            {
                return USB_ERROR;
            }
            g_usb0_usbid_2_osMutexId_tbl[USB_HMSCD5] = g_usb0_hmscd5_mutexid;
        }
        break;
#endif
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_wai_sem
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_wai_sem( uint32_t usbid )
{
    osStatus    os_status;
    osMutexId   osMutex_id;

    osMutex_id = g_usb0_usbid_2_osMutexId_tbl[usbid];
    if( osMutex_id == (osMutexId)0 )
    {
        return USB_ERROR;
    }

    os_status = osMutexWait(osMutex_id, osWaitForever);
    if( os_status != osOK )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_twai_sem
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_twai_sem( uint32_t usbid, uint32_t timeout )
{
    int32_t     ret;
    osStatus    os_status;
    osMutexId   osMutex_id;

    if( timeout == 0 )
    {
        ret = usb0_userdef_os_wai_sem(usbid);
        return ret;
    }

    osMutex_id = g_usb0_usbid_2_osMutexId_tbl[usbid];
    if( osMutex_id == (osMutexId)0 )
    {
        return USB_ERROR;
    }

    os_status = osMutexWait(osMutex_id, timeout);
    if( os_status != osOK )
    {
        if( os_status == osEventTimeout )
        {
            return USB_TIMEOUT;
        }
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_sig_sem
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_sig_sem( uint32_t usbid )
{
    osStatus    os_status;
    osMutexId   osMutex_id;

    osMutex_id = g_usb0_usbid_2_osMutexId_tbl[usbid];
    if( osMutex_id == (osMutexId)0 )
    {
        return USB_ERROR;
    }

    os_status = osMutexRelease(osMutex_id);
    if( os_status != osOK )
    {
        return USB_ERROR;
    }

    return USB_SUCCESS;
}

/*******************************************************************************
* Function Name: usb0_userdef_os_dly_tsk
* Description  :
* Arguments    :
* Return Value :
*******************************************************************************/
int32_t usb0_userdef_os_dly_tsk( uint32_t tm )
{
    osDelay(tm);
    return USB_SUCCESS;
}

/* End of File */
