summaryrefslogtreecommitdiff
path: root/firmware/test/i2c/main.c
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-05-13 22:44:07 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-05-13 22:44:07 +0000
commitbbdeba6d8cb2f2066e22d39c2d5937d3608fd8ed (patch)
tree35f16ac678a381ba913726913d3ce0105fbbff21 /firmware/test/i2c/main.c
parent1dd21edacfdc728d82953f43a2e535b0dc48334e (diff)
Beginning of an mpeg thread
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@570 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/test/i2c/main.c')
-rw-r--r--firmware/test/i2c/main.c357
1 files changed, 227 insertions, 130 deletions
diff --git a/firmware/test/i2c/main.c b/firmware/test/i2c/main.c
index 58f15dd911..43d3ef31d3 100644
--- a/firmware/test/i2c/main.c
+++ b/firmware/test/i2c/main.c
@@ -16,13 +16,14 @@
* KIND, either express or implied.
*
****************************************************************************/
-#include "types.h"
+#include <stdbool.h>
#include "i2c.h"
#include "mas.h"
#include "sh7034.h"
#include "system.h"
#include "debug.h"
#include "kernel.h"
+#include "thread.h"
#include "ata.h"
#include "disk.h"
#include "fat.h"
@@ -34,6 +35,15 @@
#define MIN(a, b) (((a)<(b))?(a):(b))
#endif
+#define MPEG_PLAY 1
+#define MPEG_STOP 2
+#define MPEG_PAUSE 3
+#define MPEG_RESUME 4
+#define MPEG_NEED_DATA 100
+
+#define MP3_LOW_WATER 0x30000
+#define MP3_CHUNK_SIZE 0x20000
+
unsigned char fliptable[] =
{
0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
@@ -81,8 +91,20 @@ int mp3buf_write;
int mp3buf_read;
int last_dma_chunk_size;
-bool dma_on;
+bool dma_on; /* The DMA is active */
+bool playing; /* We are playing an MP3 stream */
+bool filling; /* We are filling the buffer with data from disk */
+
+struct event_queue mpeg_queue;
+
static void mas_poll_start(unsigned int interval_in_ms);
+void mpeg_thread(void);
+
+void reset_mp3_buffer(void)
+{
+ mp3buf_read = 0;
+ mp3buf_write = 0;
+}
void setup_sci0(void)
{
@@ -124,13 +146,9 @@ void setup_sci0(void)
IPRC = (IPRC & 0xf0ff) | 0x0800;
/* Enable Tx (only!) */
-// SCR0 |= 0xa0;
+ SCR0 |= 0x20;
}
-int mas_tx_ready(void)
-{
- return (SSR0 & SCI_TDRE);
-}
void init_dma(void)
{
@@ -141,23 +159,25 @@ void init_dma(void)
last_dma_chunk_size = MIN(65536, mp3buf_write - mp3buf_read);
DTCR3 = last_dma_chunk_size & 0xffff;
DMAOR = 0x0001; /* Enable DMA */
+ CHCR3 |= 0x0001; /* Enable DMA IRQ */
}
void start_dma(void)
{
SCR0 |= 0x80;
- dma_on = TRUE;
+ dma_on = true;
}
void stop_dma(void)
{
SCR0 &= 0x7f;
- dma_on = FALSE;
+ dma_on = false;
}
void dma_tick(void)
{
- if(!dma_on)
+ /* Start DMA if it isn't running */
+ if(playing && !dma_on)
{
if(PBDR & 0x4000)
{
@@ -176,9 +196,6 @@ void bitswap(unsigned char *data, int length)
}
}
-struct event_queue disk_queue;
-int filling;
-
int main(void)
{
char buf[40];
@@ -186,12 +203,6 @@ int main(void)
int i=0;
DIR *d;
struct dirent *dent;
- int f;
- int free_space_left;
- int mp3_space_left;
- int amount_to_read;
- int play_song;
- struct event *ev;
/* Clear it all! */
SSR1 &= ~(SCI_RDRF | SCI_ORER | SCI_PER | SCI_FER);
@@ -205,7 +216,7 @@ int main(void)
i2c_init();
- dma_on = TRUE;
+ dma_on = true;
kernel_init();
@@ -270,100 +281,20 @@ int main(void)
closedir(d);
}
- f = open("/machinae_supremacy_-_arcade.mp3", O_RDONLY);
- if(f < 0)
- {
- debugf("Couldn't open file\n");
- }
+ queue_init(&mpeg_queue);
- mp3buf_read = mp3buf_write = 0;
-
- /* First read in a few seconds worth of MP3 data */
- i = read(f, mp3buf, 0x20000);
- debugf("Read %d bytes\n", i);
+ create_thread(mpeg_thread, stack - 0x2000, 0x4000);
- ata_spindown(-1);
-
- debugf("bit swapping...\n");
- bitswap(mp3buf + mp3buf_write, i);
-
- mp3buf_write = i;
-
- queue_init(&disk_queue);
-
- mas_poll_start(1);
+ mas_poll_start(2);
debugf("let's play...\n");
- init_dma();
-
- dma_on = TRUE;
-
- /* Enable Tx & TXIE */
- SCR0 |= 0xa0;
-
- CHCR3 |= 1;
-
-#define MP3_LOW_WATER 0x30000
-#define MP3_CHUNK_SIZE 0x20000
- play_song = 1;
- filling = 1;
+ queue_post(&mpeg_queue, MPEG_PLAY, 0);
- while(play_song)
+ while(1)
{
- if(filling)
- {
- free_space_left = mp3buf_read - mp3buf_write;
- if(free_space_left < 0)
- free_space_left = MP3BUF_LEN + free_space_left;
-
- if(free_space_left <= MP3_CHUNK_SIZE)
- {
- debugf("0\n");
- ata_spindown(-1);
- filling = 0;
- continue;
- }
-
- amount_to_read = MIN(MP3_CHUNK_SIZE, free_space_left);
- amount_to_read = MIN(MP3BUF_LEN - mp3buf_write, amount_to_read);
-
- /* Read in a few seconds worth of MP3 data. We don't want to
- read too large chunks because the bitswapping will take
- too much time. We must keep the DMA happy and also give
- the other threads a chance to run. */
- debugf("R\n", i);
- i = read(f, mp3buf+mp3buf_write, amount_to_read);
- if(i)
- {
- debugf("B\n");
- bitswap(mp3buf + mp3buf_write, i);
-
- mp3buf_write += i;
- if(mp3buf_write >= MP3BUF_LEN)
- {
- mp3buf_write = 0;
- debugf("W\n");
- }
- }
- else
- {
- play_song = 0;
- ata_spindown(-1);
- filling = 0;
- }
- }
- else
- {
- debugf("S\n");
- ev = queue_wait(&disk_queue);
- debugf("Q\n");
- debugf("1\n");
- filling = 1;
- }
+ sleep(HZ*1000);
}
- debugf("Song is finished\n");
- while(1);
}
#pragma interrupt
@@ -377,34 +308,39 @@ void DEI3(void)
{
int unplayed_space_left;
int space_until_end_of_buffer;
- mp3buf_read += last_dma_chunk_size;
- if(mp3buf_read >= MP3BUF_LEN)
- mp3buf_read = 0;
-
- unplayed_space_left = mp3buf_write - mp3buf_read;
- if(unplayed_space_left < 0)
- unplayed_space_left = MP3BUF_LEN + unplayed_space_left;
-
- space_until_end_of_buffer = MP3BUF_LEN - mp3buf_read;
- if(!filling && unplayed_space_left < MP3_LOW_WATER)
+ if(playing)
{
- queue_post(&disk_queue, 1, 0);
- }
+ mp3buf_read += last_dma_chunk_size;
+ if(mp3buf_read >= MP3BUF_LEN)
+ mp3buf_read = 0;
- if(unplayed_space_left)
- {
- last_dma_chunk_size = MIN(65536, unplayed_space_left);
- last_dma_chunk_size = MIN(last_dma_chunk_size, space_until_end_of_buffer);
- DTCR3 = last_dma_chunk_size & 0xffff;
- SAR3 = (unsigned int)mp3buf + mp3buf_read;
- CHCR3 &= ~0x0002;
- }
- else
- {
- debugf("No more MP3 data. Stopping.\n");
- CHCR3 = 0;
+ unplayed_space_left = mp3buf_write - mp3buf_read;
+ if(unplayed_space_left < 0)
+ unplayed_space_left = MP3BUF_LEN + unplayed_space_left;
+
+ space_until_end_of_buffer = MP3BUF_LEN - mp3buf_read;
+
+ if(!filling && unplayed_space_left < MP3_LOW_WATER)
+ {
+ queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
+ }
+
+ if(unplayed_space_left)
+ {
+ last_dma_chunk_size = MIN(65536, unplayed_space_left);
+ last_dma_chunk_size = MIN(last_dma_chunk_size, space_until_end_of_buffer);
+ DTCR3 = last_dma_chunk_size & 0xffff;
+ SAR3 = (unsigned int)mp3buf + mp3buf_read;
+ }
+ else
+ {
+ debugf("No more MP3 data. Stopping.\n");
+ CHCR3 = 0; /* Stop DMA interrupt */
+ }
}
+
+ CHCR3 &= ~0x0002; /* Clear DMA interrupt */
}
static void mas_poll_start(unsigned int interval_in_ms)
@@ -446,3 +382,164 @@ void IMIA1(void)
TSR1 &= ~0x01;
}
+char *tracks[] =
+{
+ "/machinae_supremacy_-_arcade.mp3"
+};
+
+char *peek_next_track(int index)
+{
+ return tracks[index];
+}
+
+int mpeg_file = -1;
+
+int new_file(void)
+{
+ int len;
+ char *trackname;
+
+ trackname = peek_next_track(0);
+
+ debugf("playing %s\n", trackname);
+ mpeg_file = open(trackname, O_RDONLY);
+ if(mpeg_file < 0)
+ {
+ debugf("Couldn't open file\n");
+ return -1;
+ }
+
+ /* First read in a few seconds worth of MP3 data */
+ len = read(mpeg_file, mp3buf + mp3buf_write, MP3_CHUNK_SIZE);
+
+ ata_spindown(-1);
+
+ bitswap(mp3buf + mp3buf_write, len);
+
+ mp3buf_write = len;
+
+ return 0;
+}
+
+void mpeg_thread(void)
+{
+ struct event ev;
+ int len;
+ int free_space_left;
+ int amount_to_read;
+
+ playing = false;
+
+ while(1)
+ {
+ debugf("S\n");
+ queue_wait(&mpeg_queue, &ev);
+ switch(ev.id)
+ {
+ case MPEG_PLAY:
+ /* Stop the current stream */
+ playing = false;
+ stop_dma();
+
+ reset_mp3_buffer();
+
+ new_file();
+
+ /* Make it read more data */
+ filling = true;
+ queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
+
+ playing = true;
+
+ init_dma();
+ start_dma();
+ break;
+
+ case MPEG_STOP:
+ /* Stop the current stream */
+ playing = false;
+ stop_dma();
+ break;
+
+ case MPEG_PAUSE:
+ /* Stop the current stream */
+ playing = false;
+ stop_dma();
+ break;
+
+ case MPEG_RESUME:
+ /* Stop the current stream */
+ playing = true;
+ start_dma();
+ break;
+
+ case MPEG_NEED_DATA:
+ free_space_left = mp3buf_read - mp3buf_write;
+ if(free_space_left < 0)
+ free_space_left = MP3BUF_LEN + free_space_left;
+
+ if(free_space_left <= MP3_CHUNK_SIZE)
+ {
+ debugf("0\n");
+ ata_spindown(-1);
+ filling = false;
+ break;;
+ }
+
+ amount_to_read = MIN(MP3_CHUNK_SIZE, free_space_left);
+ amount_to_read = MIN(MP3BUF_LEN - mp3buf_write, amount_to_read);
+
+ /* Read in a few seconds worth of MP3 data. We don't want to
+ read too large chunks because the bitswapping will take
+ too much time. We must keep the DMA happy and also give
+ the other threads a chance to run. */
+ debugf("R\n");
+ len = read(mpeg_file, mp3buf+mp3buf_write, amount_to_read);
+ if(len)
+ {
+ debugf("B\n");
+ bitswap(mp3buf + mp3buf_write, len);
+
+ mp3buf_write += len;
+ if(mp3buf_write >= MP3BUF_LEN)
+ {
+ mp3buf_write = 0;
+ debugf("W\n");
+ }
+
+ /* Tell ourselves that we want more data */
+ queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
+ }
+ else
+ {
+ close(mpeg_file);
+
+ /* Make sure that the write pointer is at a word
+ boundary */
+ mp3buf_write &= 0xfffffffe;
+
+ if(new_file() < 0)
+ {
+ /* No more data to play */
+ debugf("Finished playing\n");
+ playing = false;
+ ata_spindown(-1);
+ filling = false;
+ }
+ else
+ {
+ /* Tell ourselves that we want more data */
+ queue_post(&mpeg_queue, MPEG_NEED_DATA, 0);
+ }
+ }
+ break;
+ }
+ }
+}
+
+/* Newlib trap honeypot */
+void __trap34(void)
+{
+ debugf("newlib trap34\n");
+ while(1);
+}