/*---------------------------------------------------------------------------* Project: TwlSDK - RTC - libraries File: external_ex.c Copyright 2007-2008 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. $Date:: 2008-09-18#$ $Rev: 8573 $ $Author: okubata_ryoma $ *---------------------------------------------------------------------------*/ #include #include #include #include #include "private.h" /*---------------------------------------------------------------------------* Internal Function Definitions *---------------------------------------------------------------------------*/ static void RtcexGetResultCallback(RTCResult result, void* arg); static void RtcexWaitBusy(u32* lock); /*---------------------------------------------------------------------------* Name: RTCEXi_GetCounterAsync Description: Asynchronously reads the Up Counter value from the RTC. Arguments: count: Specifies the buffer to store the Up Counter value. callback: Specifies the function to be called when the asynchronous process is completed. arg: Specifies the argument used when calling the callback function. Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_GetCounterAsync(u32* count, RTCCallback callback, void* arg) { OSIntrMode enabled; RTCWork* w = RTCi_GetSysWork(); SDK_NULL_ASSERT(count); SDK_NULL_ASSERT(callback); /* Check lock */ enabled = OS_DisableInterrupts(); if (w->lock != RTC_LOCK_OFF) { (void)OS_RestoreInterrupts(enabled); return RTC_RESULT_BUSY; } w->lock = RTC_LOCK_ON; (void)OS_RestoreInterrupts(enabled); /* Send the Up Counter read command */ w->sequence = RTC_SEQ_GET_COUNTER; w->index = 0; w->buffer[0] = (void*)count; w->callback = callback; w->callbackArg = arg; if (RTCEXi_ReadRawCounterAsync() == TRUE) { return RTC_RESULT_SUCCESS; } else { w->lock = RTC_LOCK_OFF; return RTC_RESULT_SEND_ERROR; } } /*---------------------------------------------------------------------------* Name: RTCEXi_GetCounter Description: Reads the Up Counter value from the RTC. Arguments: count: Specifies the buffer to store the Up Counter value. Returns: RTCResult: Returns the device operation processing result. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_GetCounter(u32* count) { RTCWork* w = RTCi_GetSysWork(); w->commonResult = RTCEXi_GetCounterAsync(count, RtcexGetResultCallback, NULL); if (w->commonResult == RTC_RESULT_SUCCESS) { RtcexWaitBusy(&(w->lock)); } return w->commonResult; } /*---------------------------------------------------------------------------* Name: RTCEXi_GetFoutAsync Description: Asynchronously reads FOUT setting values from the RTC. Arguments: fout: Specifies a buffer for storing FOUT setting values. callback: Specifies the function to be called when the asynchronous process is completed. arg: Specifies the argument used when calling the callback function. Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_GetFoutAsync(u16* fout, RTCCallback callback, void* arg) { OSIntrMode enabled; RTCWork* w = RTCi_GetSysWork(); SDK_NULL_ASSERT(fout); SDK_NULL_ASSERT(callback); /* Check lock */ enabled = OS_DisableInterrupts(); if (w->lock != RTC_LOCK_OFF) { (void)OS_RestoreInterrupts(enabled); return RTC_RESULT_BUSY; } w->lock = RTC_LOCK_ON; (void)OS_RestoreInterrupts(enabled); /* Send the FOUT setting value read command */ w->sequence = RTC_SEQ_GET_FOUT; w->index = 0; w->buffer[0] = (void*)fout; w->callback = callback; w->callbackArg = arg; if (RTCEXi_ReadRawFoutAsync() == TRUE) { return RTC_RESULT_SUCCESS; } else { w->lock = RTC_LOCK_OFF; return RTC_RESULT_SEND_ERROR; } } /*---------------------------------------------------------------------------* Name: RTCEXi_GetFout Description: Asynchronously reads FOUT setting values from the RTC. Arguments: fout: Specifies a buffer for storing FOUT setting values. Returns: RTCResult: Returns the device operation processing result. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_GetFout(u16* fout) { RTCWork* w = RTCi_GetSysWork(); w->commonResult = RTCEXi_GetFoutAsync(fout, RtcexGetResultCallback, NULL); if (w->commonResult == RTC_RESULT_SUCCESS) { RtcexWaitBusy(&(w->lock)); } return w->commonResult; } /*---------------------------------------------------------------------------* Name: RTCEXi_SetFoutAsync Description: Asynchronously writes FOUT settings to the RTC. Arguments: fout: Specifies the buffer storing FOUT setting values. callback: Specifies the function to be called when the asynchronous process is completed. arg: Specifies the argument used when calling the callback function. Returns: RTCResult: Returns the result of the process that starts the asynchronous device operation. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_SetFoutAsync(const u16* fout, RTCCallback callback, void* arg) { OSIntrMode enabled; RTCWork* w = RTCi_GetSysWork(); SDK_NULL_ASSERT(fout); SDK_NULL_ASSERT(callback); /* Check lock */ enabled = OS_DisableInterrupts(); if (w->lock != RTC_LOCK_OFF) { (void)OS_RestoreInterrupts(enabled); return RTC_RESULT_BUSY; } w->lock = RTC_LOCK_ON; (void)OS_RestoreInterrupts(enabled); /* Edit the data to set. */ ((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.fout.fout = *fout; /* Send the FOUT setting value write command */ w->sequence = RTC_SEQ_SET_FOUT; w->index = 0; w->callback = callback; w->callbackArg = arg; if (RTCEXi_WriteRawFoutAsync() == TRUE) { return RTC_RESULT_SUCCESS; } else { w->lock = RTC_LOCK_OFF; return RTC_RESULT_SEND_ERROR; } } /*---------------------------------------------------------------------------* Name: RTCEXi_SetFout Description: Writes FOUT settings values to the RTC. Arguments: fout: Specifies the buffer storing FOUT setting values. Returns: RTCResult: Returns the device operation processing result. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_SetFout(const u16* fout) { RTCWork* w = RTCi_GetSysWork(); w->commonResult = RTCEXi_SetFoutAsync(fout, RtcexGetResultCallback, NULL); if (w->commonResult == RTC_RESULT_SUCCESS) { RtcexWaitBusy(&(w->lock)); } return w->commonResult; } /*---------------------------------------------------------------------------* Name: RTCEXi_CommonCallback Description: Shared callback function corresponding to additional commands used by asynchronous RTC functions. Arguments: tag: PXI tag that shows the message type. data: Message from ARM7. err: PXI transfer error flag. Returns: RTCResult: Returns the asynchronous device operation processing result. *---------------------------------------------------------------------------*/ RTCResult RTCEXi_CommonCallback(void) { RTCWork* w = RTCi_GetSysWork(); RTCResult result = RTC_RESULT_SUCCESS; /* Various types of postprocessing according to the internal status */ switch(w->sequence) { /* Sequence to get the Up Counter value */ case RTC_SEQ_GET_COUNTER: { u32* pDst = (u32*)(w->buffer[0]); RTCRawCounter* pSrc = &(((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.counter); /* Change the endianness */ *pDst = (u32)(pSrc->bytes[0] | (pSrc->bytes[1] << 8) | (pSrc->bytes[2] << 16)); } break; /* Sequence to get the FOUT setting value */ case RTC_SEQ_GET_FOUT: { u16* pDst = (u16*)(w->buffer[0]); RTCRawFout* pSrc = &(((RTCRawDataEx*)(OS_GetSystemWork()->real_time_clock))->a.fout); *pDst = (u16)(pSrc->fout); } break; /* Sequence to change the FOUT setting value */ case RTC_SEQ_SET_FOUT: /* No processing in particular. */ break; default: /* Other unknown sequences */ w->index = 0; result = RTC_RESULT_INVALID_COMMAND; } return result; } /*---------------------------------------------------------------------------* Name: RtcexGetResultCallback Description: Called when asynchronous processing completes. Updates the processing results of internal variables. Arguments: result: The processing results from the asynchronous function. arg: Not used. Returns: None. *---------------------------------------------------------------------------*/ static void RtcexGetResultCallback(RTCResult result, void* arg) { #pragma unused(arg) RTCi_GetSysWork()->commonResult = result; } #include /*---------------------------------------------------------------------------* Name: RtcWaitBusy Description: Wait while the RTC's asynchronous processing is locked. Arguments: r0: Pointer to the lock control member in the library's shared work buffer. Returns: None. *---------------------------------------------------------------------------*/ static asm void RtcexWaitBusy(u32* lock) { loop: ldr r1, [r0] cmp r1, #RTC_LOCK_ON beq loop bx lr } #include