1 #include <Mega32.h>
2 #include <delay.h>
3 #include <math.h>
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include "os.h"
7 #include "os.c"
8 #include "thread.c"
9 #include "semaphore.c"
10 #include "message.c"
11 #include "spm.c"
12 #include "mmc.c"
13
14 void initialize(void);
15 void sdthread(void);
16
17 void main(void)
18 {
19 DDRC = 0xFF;
20 initialize();
21
22 // how did we get here???
23 while (1)
24 {
25 PORTC ^= 0xFF;
26 delay_ms(1000);
27 }
28 }
29 os_thread *tt1;
30 #asm
31 .cseg
32 .equ oldpc1=pc
33 .org 0x3000
34 #endasm
35
36 void sdthread()
37 {
38 os_thread *thread, *temp_thread, *next_thread;
39 char c;
40 UCHAR *buffer;
41 UINT *ibuffer;
42 register UINT progSize, i;
43 thread = g_currthread;
44
45 PORTC = 0xFF;
46
47 while (1)
48 {
49 c = MmcInit();
50 if (c == 0)
51 {
52 PORTC &= 0b11111110;
53 }
54 else
55 {
56 PORTC |= 0b00000001;
57 }
58 if (c == 0 && PINB.1 == 0)
59 {
60 // we want to load a new program
61 temp_thread = g_usedthreads;
62 while (temp_thread != NULL)
63 {
64 // kill any thread but the null/sd thread
65 if (temp_thread != thread)
66 {
67 next_thread = temp_thread->next;
68 TerminateThread(temp_thread);
69 temp_thread = next_thread;
70 }
71 else
72 {
73 temp_thread = temp_thread->next;
74 }
75 }
76 os_reset_stack();
77
78 // grab some stack space
79 buffer = (UCHAR*)os_alloc_stack(512);
80
81 // read in the first sector. The first 2 bytes are the size of the program
82 mmc_read_sector(0, buffer);
83 progSize = (((int)buffer[0]) << 8) | buffer[1];
84
85 // just write 0x00 and jmp to 0x01
86 buffer[0] = buffer[1] = 0;
87
88 // write the first sector
89 WriteSector(0, buffer);
90
91 for (i = 512; i < progSize; i += 512)
92 {
93 mmc_read_sector(i, buffer);
94 WriteSector(i, buffer);
95 }
96 os_reset_stack();
97 #asm("cli");
98 temp_thread = CreateThread(1, 255, 150, 150);
99 #asm("sei");
100 }
101 }
102 }
103
104 //**********************************************************
105 //Set it all up
106
107 void init_api(void)
108 {
109 SleepThreadPtr = SleepThread;
110 CreateThreadPtr = CreateThread;
111 SuspendThreadPtr = SuspendThread;
112 ResumeThreadPtr = ResumeThread;
113 TerminateThreadPtr = TerminateThread;
114 FindThreadPtr = FindThread;
115
116 CreateSemaphorePtr = CreateSemaphore;
117 WaitSemaphorePtr = WaitSemaphore;
118 SignalSemaphorePtr = SignalSemaphore;
119
120 SendMessagePtr = SendMessage;
121 ReceiveMessagePtr = ReceiveMessage;
122 }
123 void init_structures(void)
124 {
125 register char i;
126 os_thread *temp_thread, *prev_thread;
127 os_semaphore *temp_semaphore, *prev_semaphore;
128 os_threadsem *temp_threadsem;
129 os_message *temp_message;
130
131 g_threadcount = 0;
132
133 // initialize list of threads
134 g_freethreads = &g_allthreads[0];
135 prev_thread = NULL;
136 temp_thread = g_freethreads;
137 for (i = 1; i < THREAD_COUNT; ++i)
138 {
139 temp_thread->next = &g_allthreads[i];
140 temp_thread->prev = prev_thread;
141 temp_thread->threadID = i;
142
143 prev_thread = temp_thread;
144 temp_thread = temp_thread->next;
145 }
146 temp_thread->threadID = i;
147 temp_thread->prev = prev_thread;
148 temp_thread->next = NULL;
149
150 // initialize list of semaphores
151 g_freesemaphores = &g_allsemaphores[0];
152 prev_semaphore = NULL;
153 temp_semaphore = g_freesemaphores;
154 for (i = 1; i < SEMAPHORE_COUNT; ++i)
155 {
156 temp_semaphore->next = &g_allsemaphores[i];
157 temp_semaphore->prev = prev_semaphore;
158
159 prev_semaphore = temp_semaphore;
160 temp_semaphore = temp_semaphore->next;
161 }
162 temp_semaphore->prev = prev_semaphore;
163 temp_semaphore->next = NULL;
164
165 // initialize list of thread/semaphore holders
166 g_freethreadsems = &g_allthreadsems[0];
167 temp_threadsem = g_freethreadsems;
168 for (i = 1; i < THREADSEM_COUNT; ++i)
169 {
170 temp_threadsem->next = &g_allthreadsems[i];
171 temp_threadsem = temp_threadsem->next;
172 }
173 temp_threadsem->next = NULL;
174
175 // initialize list of message holders
176 g_freemessages = &g_allmessages[0];
177 temp_message = g_freemessages;
178 for (i = 1; i < MESSAGE_COUNT; ++i)
179 {
180 temp_message->next = &g_allmessages[i];
181 temp_message = temp_message->next;
182 }
183 temp_threadsem->next = NULL;
184
185 // allocate the stack
186 g_stkCurrent = g_stkStart = &g_stkBlock[0];
187 g_stkEnd = g_stkStart + TOTAL_STACK_SIZE;
188 }
189 void initialize(void)
190 {
191 UCHAR *sd_swstack, *sd_hwstack;
192
193 // set up UART
194 UCSRB = 0x18;
195 UBRRL = 51;
196
197 // set up Timer0 for scheduling every 10ms
198 TCNT0 = 0x00;
199 OCR0 = 15.6 * 10;
200 TIMSK = 0x02;
201 TCCR0 = 0b00001101;
202
203 init_api();
204 init_structures();
205
206 // create some uart semaphores
207 g_uart_t_semaphore = CreateSemaphore(1);
208 g_uart_r_semaphore = CreateSemaphore(1);
209
210 // create the SD card thread
211 g_currthread = CreateThread(sdthread, 255, 150, 150);
212
213 // We never want to free the sd threads stack
214 g_stkStart += 200;
215
216 sd_swstack = g_currthread->swstack;
217 sd_hwstack = g_currthread->hwstack;
218
219 #asm
220 ; Load new HW stack pointer, low first
221 LDD R30,Y+0
222 OUT SPL,R30
223 LDD R30,Y+1
224 OUT SPH,R30
225
226 ; Load new data stack pointer, low first
227 LDD R30,Y+2
228 LDD R31,Y+3
229 MOV R28,R30
230 MOV R29,R31
231 #endasm
232
233
234 // OUT SREG, R0 will enable interrupts, so CPU control will
235 // yield here to the other thread. It will return when control
236 // is switched back to the null thread.
237 #asm
238 POP R0
239 OUT SREG,R0
240 POP R31
241 POP R30
242 POP R27
243 POP R26
244 POP R25
245 POP R24
246 POP R23
247 POP R22
248 POP R21
249 POP R20
250 POP R19
251 POP R18
252 POP R17
253 POP R16
254 POP R15
255 POP R14
256 POP R13
257 POP R12
258 POP R11
259 POP R10
260 POP R9
261 POP R8
262 POP R7
263 POP R6
264 POP R5
265 POP R4
266 POP R3
267 POP R2
268 POP R1
269 POP R0
270
271 RETI
272 #endasm
273 }
274 #asm
275 .org oldpc1
276 #endasm