/*---------------------------------------------------------------------------*
  Project:  NitroSDK - WM - libraries
  File:     wm_dcf.c

  Copyright 2003,2004 Nintendo.  All rights reserved.

  These coded instructions, statements, and computer programs contain
  proprietary information of Nintendo of America Inc. and/or Nintendo
  Company Ltd., and are protected by Federal copyright law.  They may
  not be disclosed to third parties or copied or duplicated in any form,
  in whole or in part, without the prior written consent of Nintendo.

  $Log: wm_dcf.c,v $
  Revision 1.4  2004/10/22 04:37:28  terui
  Changed functions that return int type as WMErrCode so that they return WMErrCode enumerator type.

  Revision 1.3  2004/10/08 08:37:37  ooe
  small fix

  Revision 1.2  2004/10/05 09:45:28  terui
  Standardized the MAC address as the u8 type array

  Revision 1.1  2004/09/10 11:03:30  terui
  New upload reflecting division of wm.c.

  $NoKeywords: $
 *---------------------------------------------------------------------------*/

#include    <nitro/wm.h>
#include    "wm_arm9_private.h"


/*---------------------------------------------------------------------------*
  Name:         WM_StartDCF

  Description:  Starts communication in infrastructure mode.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                recvBuf     -   Pointer to data receive buffer.
                                ARM7 writes data directly so be careful of cache.
                recvBufSize -   size of data receive buffer

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  					when an asynchronous process started normally. After that, asynchronous
                                	process results are again passed to callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_StartDCF( WMCallbackFunc callback , WMDcfRecvBuf* recvBuf , u16 recvBufSize )
{
    WMErrCode   result;
    WMArm9Buf*  p   = WMi_GetSystemWork();

    // State check
    result = WMi_CheckState( WM_STATE_CHILD );
    WM_CHECK_RESULT( result );

    // Confirm DCF status 
    DC_InvalidateRange( &( p->status->dcf_flag ) , 4 );
    if( p->status->dcf_flag == TRUE )
    {
        WM_WARNING( "Already DCF mode. So can't start DCF again.\n" );
        return WM_ERRCODE_ILLEGAL_STATE;
    }

    // Check parameters 
    if( recvBufSize < 16 )
    {
        WM_WARNING( "Parameter \"recvBufSize\" must not be less than %d.\n" , 16 );
        return WM_ERRCODE_INVALID_PARAM;
    }
    if( recvBuf == NULL )
    {
        WM_WARNING( "Parameter \"recvBuf\" must not be NULL.\n" );
        return WM_ERRCODE_INVALID_PARAM;
    }
    if( (u32)recvBuf & 0x01f )
    {
        // Alignment check sends warning only. Will not result in error. 
        WM_WARNING( "Parameter \"recvBuf\" is not 32-byte aligned.\n" );
    }

    // Write the specified buffer cache. 
    DC_StoreRange( recvBuf , recvBufSize );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_START_DCF , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(
        WM_APIID_START_DCF , 2 ,
        (u32)recvBuf ,
        (u32)recvBufSize
    );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_SetDCFData

  Description:  Reserves data sent in infrastructure mode communication.

  Arguments:    callback    -   The callback function called when asynchronous process ends.
                destAdr     -   pointer to buffer showing MAC address of communication partner.
                sendData    -   pointer to data that send-reserves.
                                Note that send-reserve data is forcibly cache stored.
                sendDataSize -  Size of send-reserve data.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  					when an asynchronous process started normally. After that, asynchronous
                                	process results are again passed to callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_SetDCFData( WMCallbackFunc callback , const u8* destAdr , const u16* sendData, u16 sendDataSize )
{
    WMErrCode   result;
    WMArm9Buf*  p   = WMi_GetSystemWork();
    u32         wMac[2];

    // State check
    result = WMi_CheckState( WM_STATE_DCF_CHILD );
    WM_CHECK_RESULT( result );

    // Confirm DCF state
    DC_InvalidateRange( &( p->status->dcf_flag ) , 4 );
    if( p->status->dcf_flag == FALSE )
    {
        WM_WARNING( "It is not DCF mode now.\n" );
        return WM_ERRCODE_ILLEGAL_STATE;
    }

    // Check parameters
    if( sendDataSize > 1500 )
    {
        WM_WARNING( "Parameter \"sendDataSize\" is over %d.\n" , 1500 );
        return WM_ERRCODE_INVALID_PARAM;
    }
    if( (u32)sendData & 0x01f )
    {
        // Alignment check sends warning only. Will not result in error. 
        WM_WARNING( "Parameter \"sendData\" is not 32-byte aligned.\n" );
    }

    //  Write the specified buffer cache. 
    DC_StoreRange( (void*)sendData , sendDataSize );

    // Save the callback function
    WMi_SetCallbackTable( WM_APIID_SET_DCF_DATA , callback );

    // Copy MAC address
    MI_CpuCopy8( destAdr , wMac , 6 );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand(
        WM_APIID_SET_DCF_DATA , 4 ,
        (u32)wMac[ 0 ] ,
        (u32)wMac[ 1 ] ,
        (u32)sendData ,
        (u32)sendDataSize
    );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

/*---------------------------------------------------------------------------*
  Name:         WM_EndDCF

  Description:  Stops communication in infrastructure mode.

  Arguments:    callback    -   The callback function called when asynchronous process ends.

  Returns:      WMErrCode   -   Returns process results. WM_ERRCODE_OPERATING is returned
  					when an asynchronous process started normally. After that, asynchronous
                                	process results are again passed to callback.
 *---------------------------------------------------------------------------*/
WMErrCode
WM_EndDCF( WMCallbackFunc callback )
{
    WMErrCode   result;
    WMArm9Buf*  p   = WMi_GetSystemWork();

    // Check state
    result = WMi_CheckState( WM_STATE_DCF_CHILD );
    WM_CHECK_RESULT( result );

    // Confirm DCF status
    DC_InvalidateRange( &( p->status->dcf_flag ) , 4 );
    if( p->status->dcf_flag == FALSE )
    {
        WM_WARNING( "It is not DCF mode now.\n" );
        return WM_ERRCODE_ILLEGAL_STATE;
    }

    // Save callback function
    WMi_SetCallbackTable( WM_APIID_END_DCF , callback );

    // Notify ARM7 with FIFO
    result = WMi_SendCommand( WM_APIID_END_DCF , 0 );
    WM_CHECK_RESULT( result );

    return WM_ERRCODE_OPERATING;
}

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