/*---------------------------------------------------------------------------*
  Project:  NitroSDK - CARD - libraries
  File:     card_request.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: card_request.c,v $
  Revision 1.7  2004/11/15 00:54:38  yosizaki
  move ARM7 implementations to ../arm7/src/card_command.c

  Revision 1.6  2004/09/02 11:54:42  yosizaki
  fix CARD include directives.

  Revision 1.5  2004/08/23 10:38:10  yosizaki
  add write-command.
  add retry count on writing timeout.

  Revision 1.4  2004/08/18 08:19:02  yosizaki
  change CARDBackupType format.

  Revision 1.3  2004/08/18 03:24:14  yosizaki
  fix around PXI-INIT command.

  Revision 1.2  2004/07/28 13:18:06  yosizaki
  asynchronous mode support.

  Revision 1.1  2004/07/23 08:29:16  yosizaki
  (none)

 *---------------------------------------------------------------------------*/
#if	defined(SDK_ARM9)


#include <nitro.h>

#include "../include/card_common.h"
#include "../include/card_spi.h"



/******************************************************************************/
/* function */

/* Send a request, and block the completion at that location */
BOOL	CARDi_Request(CARDiCommon *p, int command, int retry_count)
{
	/* Execute here if PXI is not initialized */
	if((p->flag & CARD_STAT_INIT_CMD) == 0) {
		p->flag |= CARD_STAT_INIT_CMD;
		while(!PXI_IsCallbackReady(PXI_FIFO_TAG_FS, PXI_PROC_ARM7))
			OS_SpinWait(100);
		/* Send the first command "INIT" (recursion) */
		(void)CARDi_Request(p, CARD_REQ_INIT, 1);
	}
	/* Flash the configured shared memory */
	DC_FlushRange(p->cmd, sizeof(*p->cmd));
	DC_WaitWriteBufferEmpty();

	do {
		/* command request send  */
		p->command = command;
		p->flag |= CARD_STAT_REQ;
		CARDi_SendPxi(command);
		/* Additional send if there are subsequent arguments */
		switch(command) {
		case CARD_REQ_INIT:
			CARDi_SendPxi((u32)p->cmd);
			break;
		}
		{	/* Wait for command completion */
			OSIntrMode	bak_psr = OS_DisableInterrupts();
			while((p->flag & CARD_STAT_REQ) != 0)
				OS_SleepThread(NULL);
			(void)OS_RestoreInterrupts(bak_psr);
		}
		/* Retry until the designated number of timeouts */
	} while(
		(p->cmd->result == CARD_RESULT_TIMEOUT) &&
		(--retry_count > 0));

	/* Return the success or failure */
	return	(p->cmd->result == CARD_RESULT_SUCCESS);
}


/******************************************************************************/
#endif	/* defined(SDK_ARM9) */
