summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/test/i2c/Makefile10
-rw-r--r--firmware/test/i2c/main.c210
2 files changed, 186 insertions, 34 deletions
diff --git a/firmware/test/i2c/Makefile b/firmware/test/i2c/Makefile
index 9089020fae..0d3ff884ed 100644
--- a/firmware/test/i2c/Makefile
+++ b/firmware/test/i2c/Makefile
@@ -8,13 +8,13 @@ INCLUDES=-I../../common -I../.. -I../../drivers
8 8
9TARGET = -DARCHOS_PLAYER_OLD=1 9TARGET = -DARCHOS_PLAYER_OLD=1
10 10
11CFLAGS = -g -Wall -m1 -nostdlib -Wstrict-prototypes -fschedule-insns -fno-builtin $(INCLUDES) $(TARGET) -DDEBUG 11CFLAGS = -g -Wall -m1 -save-temps -nostdlib -Wstrict-prototypes -fschedule-insns -fno-builtin $(INCLUDES) $(TARGET) -DDEBUG
12AFLAGS += -small -relax 12AFLAGS += -small -relax
13 13
14OBJS= ../../crt0.o main.o ../../drivers/i2c.o ../../drivers/mas.o \ 14OBJS= ../../crt0.o main.o ../../drivers/i2c.o ../../drivers/mas.o \
15 ../../debug.o ../../kernel.o thread.o ../../common/sprintf.o \ 15 ../../debug.o ../../kernel.o thread.o ../../common/sprintf.o \
16 ../../panic.o ../../system.o ../../drivers/led.o \ 16 ../../panic.o ../../system.o ../../drivers/led.o \
17 ../../drivers/lcd.o ../../drivers/ata.o ../../drivers/fat.o \ 17 ../../drivers/lcd.o ata.o ../../drivers/fat.o \
18 ../../common/disk.o ../../common/file.o ../../common/dir.o 18 ../../common/disk.o ../../common/file.o ../../common/dir.o
19 19
20%.o: %.S 20%.o: %.S
@@ -52,3 +52,9 @@ install:
52thread.o: ../../thread.c 52thread.o: ../../thread.c
53 $(CC) -O $(CFLAGS) -c $< 53 $(CC) -O $(CFLAGS) -c $<
54 54
55ata.o: ../../drivers/ata.c
56 $(CC) -O $(CFLAGS) -c $<
57
58main.o: main.c
59 $(CC) -O $(CFLAGS) -c $<
60
diff --git a/firmware/test/i2c/main.c b/firmware/test/i2c/main.c
index 68f5e9b030..58f15dd911 100644
--- a/firmware/test/i2c/main.c
+++ b/firmware/test/i2c/main.c
@@ -20,6 +20,7 @@
20#include "i2c.h" 20#include "i2c.h"
21#include "mas.h" 21#include "mas.h"
22#include "sh7034.h" 22#include "sh7034.h"
23#include "system.h"
23#include "debug.h" 24#include "debug.h"
24#include "kernel.h" 25#include "kernel.h"
25#include "ata.h" 26#include "ata.h"
@@ -27,6 +28,11 @@
27#include "fat.h" 28#include "fat.h"
28#include "file.h" 29#include "file.h"
29#include "dir.h" 30#include "dir.h"
31#include "panic.h"
32
33#ifndef MIN
34#define MIN(a, b) (((a)<(b))?(a):(b))
35#endif
30 36
31unsigned char fliptable[] = 37unsigned char fliptable[] =
32{ 38{
@@ -66,13 +72,17 @@ unsigned char fliptable[] =
66 72
67extern unsigned int stack[]; 73extern unsigned int stack[];
68/* Place the MP3 data right after the stack */ 74/* Place the MP3 data right after the stack */
75
76#define MP3BUF_LEN 0x100000 /* 1 Mbyte */
77
69unsigned char *mp3buf = (unsigned char *)stack; 78unsigned char *mp3buf = (unsigned char *)stack;
70int mp3datalen;
71 79
72unsigned char *mp3dataptr; 80int mp3buf_write;
73int mp3_transmitted; 81int mp3buf_read;
82int last_dma_chunk_size;
74 83
75bool dma_on; 84bool dma_on;
85static void mas_poll_start(unsigned int interval_in_ms);
76 86
77void setup_sci0(void) 87void setup_sci0(void)
78{ 88{
@@ -124,11 +134,12 @@ int mas_tx_ready(void)
124 134
125void init_dma(void) 135void init_dma(void)
126{ 136{
127 SAR3 = (unsigned int) mp3buf; 137 SAR3 = (unsigned int) mp3buf + mp3buf_read;
128 DAR3 = 0x5FFFEC3; 138 DAR3 = 0x5FFFEC3;
129 CHCR3 &= ~0x0002; /* Clear interrupt */ 139 CHCR3 &= ~0x0002; /* Clear interrupt */
130 CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */ 140 CHCR3 = 0x1504; /* Single address destination, TXI0, IE=1 */
131 DTCR3 = 64000; 141 last_dma_chunk_size = MIN(65536, mp3buf_write - mp3buf_read);
142 DTCR3 = last_dma_chunk_size & 0xffff;
132 DMAOR = 0x0001; /* Enable DMA */ 143 DMAOR = 0x0001; /* Enable DMA */
133} 144}
134 145
@@ -156,6 +167,18 @@ void dma_tick(void)
156 } 167 }
157} 168}
158 169
170void bitswap(unsigned char *data, int length)
171{
172 unsigned int i;
173 for(i = 0;i < length;i++)
174 {
175 data[i] = fliptable[data[i]];
176 }
177}
178
179struct event_queue disk_queue;
180int filling;
181
159int main(void) 182int main(void)
160{ 183{
161 char buf[40]; 184 char buf[40];
@@ -164,6 +187,11 @@ int main(void)
164 DIR *d; 187 DIR *d;
165 struct dirent *dent; 188 struct dirent *dent;
166 int f; 189 int f;
190 int free_space_left;
191 int mp3_space_left;
192 int amount_to_read;
193 int play_song;
194 struct event *ev;
167 195
168 /* Clear it all! */ 196 /* Clear it all! */
169 SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER); 197 SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER);
@@ -173,12 +201,13 @@ int main(void)
173 SCR1 |= 0x40; 201 SCR1 |= 0x40;
174 SCR1 &= ~0x80; 202 SCR1 &= ~0x80;
175 203
204 IPRE |= 0xf000; /* Highest priority */
205
176 i2c_init(); 206 i2c_init();
177 207
178 dma_on = TRUE; 208 dma_on = TRUE;
179 209
180 kernel_init(); 210 kernel_init();
181 tick_add_task(dma_tick);
182 211
183 set_irq_level(0); 212 set_irq_level(0);
184 213
@@ -247,37 +276,94 @@ int main(void)
247 debugf("Couldn't open file\n"); 276 debugf("Couldn't open file\n");
248 } 277 }
249 278
250 i = read(f, mp3buf, 1000000); 279 mp3buf_read = mp3buf_write = 0;
280
281 /* First read in a few seconds worth of MP3 data */
282 i = read(f, mp3buf, 0x20000);
251 debugf("Read %d bytes\n", i); 283 debugf("Read %d bytes\n", i);
252 284
253 mp3datalen = i;
254
255 ata_spindown(-1); 285 ata_spindown(-1);
256 286
257 debugf("bit swapping...\n"); 287 debugf("bit swapping...\n");
258 for(i = 0;i < mp3datalen;i++) 288 bitswap(mp3buf + mp3buf_write, i);
259 { 289
260 mp3buf[i] = fliptable[mp3buf[i]]; 290 mp3buf_write = i;
261 }
262 291
263 while(1) 292 queue_init(&disk_queue);
264 { 293
265 debugf("let's play...\n"); 294 mas_poll_start(1);
266 init_dma(); 295
296 debugf("let's play...\n");
297 init_dma();
298
299 dma_on = TRUE;
300
301 /* Enable Tx & TXIE */
302 SCR0 |= 0xa0;
267 303
268 mp3dataptr = mp3buf; 304 CHCR3 |= 1;
269 mp3_transmitted = 0; 305
270 306#define MP3_LOW_WATER 0x30000
271 dma_on = TRUE; 307#define MP3_CHUNK_SIZE 0x20000
272 308
273 /* Enable Tx & TXIE */ 309 play_song = 1;
274 SCR0 |= 0xa0; 310 filling = 1;
275 311
276 CHCR3 |= 1; 312 while(play_song)
277 313 {
278 debugf("sleeping...\n"); 314 if(filling)
279 sleep(1000000); 315 {
316 free_space_left = mp3buf_read - mp3buf_write;
317 if(free_space_left < 0)
318 free_space_left = MP3BUF_LEN + free_space_left;
319
320 if(free_space_left <= MP3_CHUNK_SIZE)
321 {
322 debugf("0\n");
323 ata_spindown(-1);
324 filling = 0;
325 continue;
326 }
327
328 amount_to_read = MIN(MP3_CHUNK_SIZE, free_space_left);
329 amount_to_read = MIN(MP3BUF_LEN - mp3buf_write, amount_to_read);
330
331 /* Read in a few seconds worth of MP3 data. We don't want to
332 read too large chunks because the bitswapping will take
333 too much time. We must keep the DMA happy and also give
334 the other threads a chance to run. */
335 debugf("R\n", i);
336 i = read(f, mp3buf+mp3buf_write, amount_to_read);
337 if(i)
338 {
339 debugf("B\n");
340 bitswap(mp3buf + mp3buf_write, i);
341
342 mp3buf_write += i;
343 if(mp3buf_write >= MP3BUF_LEN)
344 {
345 mp3buf_write = 0;
346 debugf("W\n");
347 }
348 }
349 else
350 {
351 play_song = 0;
352 ata_spindown(-1);
353 filling = 0;
354 }
355 }
356 else
357 {
358 debugf("S\n");
359 ev = queue_wait(&disk_queue);
360 debugf("Q\n");
361 debugf("1\n");
362 filling = 1;
363 }
280 } 364 }
365 debugf("Song is finished\n");
366 while(1);
281} 367}
282 368
283#pragma interrupt 369#pragma interrupt
@@ -289,14 +375,74 @@ void IRQ6(void)
289#pragma interrupt 375#pragma interrupt
290void DEI3(void) 376void DEI3(void)
291{ 377{
292 mp3_transmitted += 64000; 378 int unplayed_space_left;
293 if(mp3_transmitted < mp3datalen) 379 int space_until_end_of_buffer;
380 mp3buf_read += last_dma_chunk_size;
381 if(mp3buf_read >= MP3BUF_LEN)
382 mp3buf_read = 0;
383
384 unplayed_space_left = mp3buf_write - mp3buf_read;
385 if(unplayed_space_left < 0)
386 unplayed_space_left = MP3BUF_LEN + unplayed_space_left;
387
388 space_until_end_of_buffer = MP3BUF_LEN - mp3buf_read;
389
390 if(!filling && unplayed_space_left < MP3_LOW_WATER)
294 { 391 {
295 DTCR3 = 64000; 392 queue_post(&disk_queue, 1, 0);
393 }
394
395 if(unplayed_space_left)
396 {
397 last_dma_chunk_size = MIN(65536, unplayed_space_left);
398 last_dma_chunk_size = MIN(last_dma_chunk_size, space_until_end_of_buffer);
399 DTCR3 = last_dma_chunk_size & 0xffff;
400 SAR3 = (unsigned int)mp3buf + mp3buf_read;
296 CHCR3 &= ~0x0002; 401 CHCR3 &= ~0x0002;
297 } 402 }
298 else 403 else
299 { 404 {
405 debugf("No more MP3 data. Stopping.\n");
300 CHCR3 = 0; 406 CHCR3 = 0;
301 } 407 }
302} 408}
409
410static void mas_poll_start(unsigned int interval_in_ms)
411{
412 unsigned int count;
413
414 count = FREQ / 1000 / 8 * interval_in_ms;
415
416 if(count > 0xffff)
417 {
418 panicf("Error! The MAS poll interval is too long (%d ms)\n",
419 interval_in_ms);
420 return;
421 }
422
423 /* We are using timer 1 */
424
425 TSTR &= ~0x02; /* Stop the timer */
426 TSNC &= ~0x02; /* No synchronization */
427 TMDR &= ~0x02; /* Operate normally */
428
429 TCNT1 = 0; /* Start counting at 0 */
430 GRA1 = count;
431 TCR1 = 0x23; /* Clear at GRA match, sysclock/8 */
432
433 /* Enable interrupt on level 2 */
434 IPRC = (IPRC & ~0x000f) | 0x0002;
435
436 TSR1 &= ~0x02;
437 TIER1 = 0xf9; /* Enable GRA match interrupt */
438
439 TSTR |= 0x02; /* Start timer 2 */
440}
441
442#pragma interrupt
443void IMIA1(void)
444{
445 dma_tick();
446 TSR1 &= ~0x01;
447}
448