1 /*---------------------------------------------------------------------------*
2 Project: TwlSDK - OS - demos - mutex-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-04-01#$
14 $Rev: 5205 $
15 $Author: yada $
16 *---------------------------------------------------------------------------*/
17 #include <nitro.h>
18
19
20 void VBlankIntr(void);
21 void proc1(void *p1);
22 void proc2(void *p1);
23 void common(u32 val);
24
25 //---- thread
26 #define STACK_SIZE 1024
27 #define THREAD1_PRIO 10
28 #define THREAD2_PRIO 11
29 OSThread thread1;
30 OSThread thread2;
31 u64 stack1[STACK_SIZE / sizeof(u64)];
32 u64 stack2[STACK_SIZE / sizeof(u64)];
33
34 BOOL th1_sw = FALSE;
35
36 OSMutex mutex;
37
38 //---- pad
39 u16 preKeyData;
40 u16 keyData;
41 u16 keyTrigger;
42
43 //================================================================================
44 /*---------------------------------------------------------------------------*
45 Name: NitroMain
46
47 Description: main
48
49 Arguments: None
50
51 Returns: None
52 *---------------------------------------------------------------------------*/
NitroMain(void)53 void NitroMain(void)
54 {
55 //================ initialize
56 OS_Init();
57 GX_Init();
58 OS_InitThread();
59
60 //---- start thread-2
61 OS_InitMutex(&mutex);
62 OS_CreateThread(&thread2, proc2, NULL, stack2 + STACK_SIZE / sizeof(u64), STACK_SIZE,
63 THREAD2_PRIO);
64 OS_WakeupThreadDirect(&thread2);
65
66 //---- VBlank setting
67 (void)OS_SetIrqFunction(OS_IE_V_BLANK, VBlankIntr);
68 (void)OS_EnableIrqMask(OS_IE_V_BLANK);
69 (void)OS_EnableIrq();
70 (void)GX_VBlankIntr(TRUE);
71
72 //---- Dummy READ workaround for pushing 'A' at IPL
73 preKeyData = PAD_Read();
74
75 //================ main loop
76 while (1)
77 {
78 //---- wait VBlank
79 OS_WaitVBlankIntr();
80
81 //---- read pad
82 keyData = PAD_Read();
83 keyTrigger = (u16)((preKeyData ^ keyData) & keyData);
84 preKeyData = keyData;
85
86 //---- press A button to start thread-1
87 if (keyTrigger & PAD_BUTTON_A && !th1_sw)
88 {
89 th1_sw = TRUE;
90 OS_CreateThread(&thread1, proc1, NULL, stack1 + STACK_SIZE / sizeof(u64), STACK_SIZE,
91 THREAD1_PRIO);
92 OS_WakeupThreadDirect(&thread1);
93 }
94
95 OS_WakeupThreadDirect(&thread2);
96 }
97 }
98
99
100 //--------------------------------------------------------------------------------
101 // VBlank interrupt handler
102 //
VBlankIntr(void)103 void VBlankIntr(void)
104 {
105 OS_SetIrqCheckFlag(OS_IE_V_BLANK);
106 }
107
108 //--------------------------------------------------------------------------------
109 // thread 1
110 //
proc1(void * p1)111 void proc1(void *p1)
112 {
113 #pragma unused(p1)
114 int cnt = 0;
115
116 OS_LockMutex(&mutex);
117 while (1)
118 {
119 common(1);
120
121 //---- exit thread after count 10
122 if (++cnt > 10)
123 {
124 th1_sw = FALSE;
125 OS_ExitThread(); // exit thread with locking mutex
126
127 // even if exit thread-1 with locking mutex,
128 // release the mutex automatically in OS_ExitThread()
129 }
130 }
131 }
132
133 //--------------------------------------------------------------------------------
134 // thread 2
135 //
proc2(void * p1)136 void proc2(void *p1)
137 {
138 #pragma unused(p1)
139 while (1)
140 {
141 OS_LockMutex(&mutex);
142 common(2);
143 OS_UnlockMutex(&mutex);
144
145 OS_SleepThread(NULL);
146 }
147 }
148
149 //--------------------------------------------------------------------------------
150 // common routine ( as critical routine here )
151 //
common(u32 val)152 void common(u32 val)
153 {
154 #ifdef SDK_FINALROM
155 #pragma unused( val )
156 #endif
157
158 OS_Printf("critical routine called from thread=%d\n", val);
159 }
160
161 /*====== End of main.c ======*/
162