/*---------------------------------------------------------------------------* Project: TwlSDK - WXC - demos - relayStation-2 File: main.c Copyright 2005-2009 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:: 2007-11-15#$ $Rev: 2414 $ $Author: hatamoto_minoru $ *---------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------* This sample runs Chance Encounter Communications over a wireless connection. Child mode becomes 100%, and it behaves as a relay station Unlike relayStation-1, only one GGID is supported and registration data handling can be dynamically configured. [Description of Each Mode] BROADCAST : Continue using current registered data (Same data will be multiplying without limit) RELAY : Continue to reregister the data received in exchange as the new send data. (The basic operation of "relay station" corresponds to this) END : Shut down exchange processing itself. (If an exchange is currently in progress, processing will continue until the exchange has completed) *---------------------------------------------------------------------------*/ #include #include #include "user.h" #include "dispfunc.h" /*****************************************************************************/ /* Functions */ /*---------------------------------------------------------------------------* Name: WaitNextFrame Description: Waits for next frame and detects new key press. Arguments: None. Returns: Bit set of newly pressed key. *---------------------------------------------------------------------------*/ static u16 WaitNextFrame(void) { static u16 cont = 0xffff; /* Measures to handle A Button presses inside IPL */ u16 keyset, trigger; /* Wait for the next frame */ OS_WaitVBlankIntr(); /* Detect new key press */ keyset = PAD_Read(); trigger = (u16)(keyset & (keyset ^ cont)); cont = keyset; return trigger; } /*---------------------------------------------------------------------------* Name: InitializeAllocateSystem Description: Initializes the memory allocation system in the main memory arena. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void InitializeAllocateSystem(void) { void *tempLo; OSHeapHandle hh; OS_Printf(" arena lo = %08x\n", OS_GetMainArenaLo()); OS_Printf(" arena hi = %08x\n", OS_GetMainArenaHi()); tempLo = OS_InitAlloc(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi(), 1); OS_SetArenaLo(OS_ARENA_MAIN, tempLo); hh = OS_CreateHeap(OS_ARENA_MAIN, OS_GetMainArenaLo(), OS_GetMainArenaHi()); if (hh < 0) { OS_Panic("ARM9: Fail to create heap...\n"); } hh = OS_SetCurrentHeap(OS_ARENA_MAIN, hh); } /*---------------------------------------------------------------------------* Name: VBlankIntr Description: V-Blank interrupt handler. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ static void VBlankIntr(void) { /* Update background screen */ BgScrSetVblank(); /* Interrupt check flag */ OS_SetIrqCheckFlag(OS_IE_V_BLANK); } /*---------------------------------------------------------------------------* Name: NitroMain Description: Initialization and main loop. Arguments: None. Returns: None. *---------------------------------------------------------------------------*/ void NitroMain(void) { int cursor; /* Various types of initialization */ OS_Init(); OS_InitTick(); OS_InitAlarm(); RTC_Init(); /* Rendering settings initialization */ { GX_SetBankForLCDC(GX_VRAM_LCDC_ALL); MI_CpuClearFast((void *)HW_LCDC_VRAM, HW_LCDC_VRAM_SIZE); (void)GX_DisableBankForLCDC(); MI_CpuFillFast((void *)HW_OAM, 192, HW_OAM_SIZE); MI_CpuClearFast((void *)HW_PLTT, HW_PLTT_SIZE); MI_CpuFillFast((void *)HW_DB_OAM, 192, HW_DB_OAM_SIZE); MI_CpuClearFast((void *)HW_DB_PLTT, HW_DB_PLTT_SIZE); BgInitForPrintStr(); GX_SetVisiblePlane(GX_PLANEMASK_BG0); GXS_SetVisiblePlane(GX_PLANEMASK_BG0); } /* V-blank interrupt configuration */ (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr); (void)OS_EnableIrqMask(OS_IE_V_BLANK); (void)OS_EnableIrqMask(OS_IE_FIFO_RECV); (void)OS_EnableIrq(); (void)OS_EnableInterrupts(); (void)GX_VBlankIntr(TRUE); /* Start display */ GX_DispOn(); GXS_DispOn(); G2_SetBG0Offset(0, 0); G2S_SetBG0Offset(0, 0); /* Memory allocation initialization */ InitializeAllocateSystem(); /* Start sample demo */ OS_TPrintf("relayStation-2 demo started.\n"); /* Infinite loop of demo start and reset */ for (;;) { /* Wait for A button to be pressed */ while ((WaitNextFrame() & PAD_BUTTON_A) == 0) { BgClear(); BgPutString(3, 1, WHITE, "Press A to start"); } /* Initialize WXC and run user configuration (default setting is broadcast) */ station_is_relay = FALSE; cursor = 0; User_Init(); /* Main chance encounter communications loop */ while (WXC_GetStateCode() != WXC_STATE_END) { u16 key = WaitNextFrame(); enum { MODE_BROADCAST, MODE_RELAY, MODE_STOP, MODE_MAX }; /* Displays screen */ { const char *(mode[MODE_MAX]) = { "BROADCAST", "RELAY", "STOP",}; const char *status = ""; char tmp[32]; u8 mac[6]; int i; BgClear(); /* Current WXC status */ switch (WXC_GetStateCode()) { case WXC_STATE_END: status = "WXC_STATE_END"; break; case WXC_STATE_ENDING: status = "WXC_STATE_ENDING"; break; case WXC_STATE_READY: status = "WXC_STATE_READY"; break; case WXC_STATE_ACTIVE: status = "WXC_STATE_ACTIVE"; break; default: (void)OS_SPrintf(tmp, "?(%d)", WXC_GetStateCode()); status = tmp; break; } BgPrintf(2, 2, WHITE, "status = %s", status); /* Menu selection */ BgPrintf(4, 5 + (station_is_relay ? 1 : 0), WHITE, "*"); for (i = 0; i < MODE_MAX; ++i) { BgPrintf(3, 5 + i, WHITE, "%c", (cursor == i) ? '>' : ' '); BgPrintf(6, 5 + i, (cursor == i) ? YELLOW : WHITE, "%s", mode[i]); } /* Currently registered data */ BgPrintf(0, 12, GREEN, "------- CURRENT DATA -------"); BgPrintf(2, 14, WHITE, "MAC = "); for (i = 0; i < 6; ++i) { BgPrintf(8 + i * 3, 14, WHITE, "%02X", send_data_owner[i]); } BgPrintf(2, 16, WHITE, "DATA = "); for (i = 0; i < 8; ++i) { BgPrintf(9 + i * 3, 16, WHITE, "%02X", send_data[i]); } /* Your own MAC address for reference */ BgPrintf(2, 10, WHITE, "OWN MAC = "); OS_GetMacAddress(mac); for (i = 0; i < 6; ++i) { BgPrintf(12 + i * 3, 10, WHITE, "%02X", mac[i]); } } /* Key operations */ if (((key & PAD_KEY_DOWN) != 0) && (++cursor >= MODE_MAX)) { cursor -= MODE_MAX; } if (((key & PAD_KEY_UP) != 0) && (--cursor < 0)) { cursor += MODE_MAX; } if ((key & PAD_BUTTON_A) != 0) { switch (cursor) { case MODE_BROADCAST: station_is_relay = FALSE; break; case MODE_RELAY: station_is_relay = TRUE; break; case MODE_STOP: (void)WXC_End(); break; } } } } } /*----------------------------------------------------------------------------* /*---------------------------------------------------------------------------* End of file *---------------------------------------------------------------------------*/