1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - OS - demos - waitIrq-2
3   File:     main.c
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date:: 2008-09-17#$
14   $Rev: 8556 $
15   $Author: okubata_ryoma $
16  *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18 
19 #define    STACK_SIZE     1024
20 #define    THREAD1_PRIO   17
21 #define    THREAD2_PRIO   18
22 
23 typedef enum
24 {
25 	WAIT_VBLANK,
26 	WAIT_ANY
27 } WaitType;
28 
29 OSThread thread1;
30 OSThread thread2;
31 u32      stack1[STACK_SIZE / sizeof(u32)];
32 u32      stack2[STACK_SIZE / sizeof(u32)];
33 
34 OSMessage      mesgBuffer[1];
35 OSMessageQueue mesgQueue;
36 
37 WaitType waitType;
38 
39 void startThreads(WaitType t);
40 void VBlankIntr(void);
41 void proc1(void *arg);
42 
43 //================================================================================
44 // Description:
45 //
46 // Creates two threads from the running thread. (We'll call these thread 1 and thread 2)
47 //
48 // In test 1, the two threads wait for a V-Blank interrupt.
49 // Internally, they wait using the IRQ thread queue.
50 // When the V-Blank interrupt occurs, both threads enter the executable state, but because OS_WaitIrq also checks the interrupt flag, only one of the threads will actually run.
51 //
52 //
53 //
54 // In test 2, two threads wait on a V-Blank interrupt in the same way, but because OS_WaitAnyIrq just starts the threads registered in the IRQ thread queue, both threads will run.
55 //
56 //
57 //
58 /*---------------------------------------------------------------------------*
59   Name:         NitroMain
60 
61   Description:  Main.
62 
63   Arguments:    None.
64 
65   Returns:      None.
66  *---------------------------------------------------------------------------*/
NitroMain()67 void NitroMain()
68 {
69     OS_Init();
70     OS_InitThread();
71 
72 	//---- message queue setting
73     OS_InitMessageQueue(&mesgQueue, &mesgBuffer[0], 1);
74 
75     //---- vblank interrupt setting
76     (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
77     (void)OS_EnableIrqMask(OS_IE_V_BLANK);
78     (void)OS_EnableIrq();
79     (void)GX_VBlankIntr(TRUE);
80 
81 	//======== TEST1
82 	OS_Printf("==== TEST1: WAIT_VBLANK\n");
83 	startThreads( WAIT_VBLANK );
84 
85 	//======== TEST2
86 	OS_Printf("==== TEST2: WAIT_ANY\n");
87 	startThreads( WAIT_ANY );
88 
89     OS_Printf("==== Finish sample.\n");
90     OS_Terminate();
91 }
92 
93 //--------------------------------------------------------------------------------
94 //    Start test threads
95 //
startThreads(WaitType t)96 void startThreads(WaitType t)
97 {
98 	waitType = t;
99 
100     OS_CreateThread(&thread1, proc1, (void*)1, stack1 + STACK_SIZE / sizeof(u32), STACK_SIZE, THREAD1_PRIO);
101     OS_CreateThread(&thread2, proc1, (void*)2, stack2 + STACK_SIZE / sizeof(u32), STACK_SIZE, THREAD2_PRIO);
102     OS_WakeupThreadDirect(&thread1);
103     OS_WakeupThreadDirect(&thread2);
104 	(void)OS_ReceiveMessage(&mesgQueue, NULL, OS_MESSAGE_BLOCK);
105 	OS_DestroyThread(&thread1);
106 	OS_DestroyThread(&thread2);
107 }
108 
109 //--------------------------------------------------------------------------------
110 //    V-Blank interrupt handler
111 //
VBlankIntr(void)112 void VBlankIntr(void)
113 {
114 	OS_Printf("VBLANK\n");
115     OS_SetIrqCheckFlag(OS_IE_V_BLANK);
116 }
117 
118 //--------------------------------------------------------------------------------
119 //    proc1
120 //
proc1(void * arg)121 void proc1(void *arg)
122 {
123 	int threadNo = (int)arg;
124 	int n;
125     for( n=0; n<5; n++ )
126     {
127 		switch( waitType )
128 		{
129 			case WAIT_VBLANK:
130 				OS_WaitIrq(TRUE, OS_IE_V_BLANK);
131 				break;
132 			case WAIT_ANY:
133 				OS_WaitAnyIrq();
134 				break;
135 		}
136 
137         OS_Printf("thread %d\n", threadNo);
138     }
139 
140 	(void)OS_SendMessage(&mesgQueue, NULL, OS_MESSAGE_NOBLOCK);
141 }
142 
143 /*====== End of main.c ======*/
144