diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-28 00:00:24 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-03-28 00:00:24 +0000 |
commit | 451dd48adc2ef29fd2f900693393cc9b9b4a849b (patch) | |
tree | e15d20e602261866617210bde007966ce9b19293 /firmware | |
parent | 853bc3dcf85aa1284a0e5b550277c40beb7697a9 (diff) | |
download | rockbox-451dd48adc2ef29fd2f900693393cc9b9b4a849b.tar.gz rockbox-451dd48adc2ef29fd2f900693393cc9b9b4a849b.zip |
Sound api improvements, rockboy sound, contributed by xshock.
Playback of sound currently only works in boost mode, needs fixing.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6226 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/drivers/uda1380.c | 4 | ||||
-rw-r--r-- | firmware/export/pcm_playback.h | 2 | ||||
-rw-r--r-- | firmware/pcm_playback.c | 78 |
3 files changed, 71 insertions, 13 deletions
diff --git a/firmware/drivers/uda1380.c b/firmware/drivers/uda1380.c index e8b8c14399..8c3cf61eae 100644 --- a/firmware/drivers/uda1380.c +++ b/firmware/drivers/uda1380.c | |||
@@ -49,7 +49,7 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] = | |||
49 | REG_I2S, I2S_IFMT_IIS, | 49 | REG_I2S, I2S_IFMT_IIS, |
50 | REG_PWR, PON_PLL | PON_HP | PON_DAC | EN_AVC | PON_AVC | PON_BIAS, | 50 | REG_PWR, PON_PLL | PON_HP | PON_DAC | EN_AVC | PON_AVC | PON_BIAS, |
51 | REG_AMIX, AMIX_RIGHT(0x10) | AMIX_LEFT(0x10), /* 00=max, 3f=mute */ | 51 | REG_AMIX, AMIX_RIGHT(0x10) | AMIX_LEFT(0x10), /* 00=max, 3f=mute */ |
52 | REG_MASTER_VOL, MASTER_VOL_LEFT(0x7f) | MASTER_VOL_RIGHT(0x7f), /* 00=max, ff=mute */ | 52 | REG_MASTER_VOL, MASTER_VOL_LEFT(0x20) | MASTER_VOL_RIGHT(0x20), /* 00=max, ff=mute */ |
53 | REG_MIX_VOL, MIX_VOL_CHANNEL_1(0) | MIX_VOL_CHANNEL_2(0xff), /* 00=max, ff=mute */ | 53 | REG_MIX_VOL, MIX_VOL_CHANNEL_1(0) | MIX_VOL_CHANNEL_2(0xff), /* 00=max, ff=mute */ |
54 | REG_EQ, 0, | 54 | REG_EQ, 0, |
55 | REG_MUTE, MUTE_CH2, /* Mute channel 2 (digital decimation filter) */ | 55 | REG_MUTE, MUTE_CH2, /* Mute channel 2 (digital decimation filter) */ |
@@ -131,6 +131,8 @@ int uda1380_set_regs(void) | |||
131 | /* Initialize UDA1380 codec with default register values (uda1380_defaults) */ | 131 | /* Initialize UDA1380 codec with default register values (uda1380_defaults) */ |
132 | int uda1380_init(void) | 132 | int uda1380_init(void) |
133 | { | 133 | { |
134 | PLLCR &= ~(1 << 22); /* Set AudioClk = FXTAL/2*/ | ||
135 | |||
134 | if (uda1380_set_regs() == -1) | 136 | if (uda1380_set_regs() == -1) |
135 | return -1; | 137 | return -1; |
136 | 138 | ||
diff --git a/firmware/export/pcm_playback.h b/firmware/export/pcm_playback.h index c44fb283ec..6010293bbd 100644 --- a/firmware/export/pcm_playback.h +++ b/firmware/export/pcm_playback.h | |||
@@ -19,9 +19,11 @@ | |||
19 | #ifndef PCM_PLAYBACK_H | 19 | #ifndef PCM_PLAYBACK_H |
20 | #define PCM_PLAYBACK_H | 20 | #define PCM_PLAYBACK_H |
21 | 21 | ||
22 | void pcm_set_frequency(unsigned int frequency); | ||
22 | void pcm_play_data(const unsigned char* start, int size, | 23 | void pcm_play_data(const unsigned char* start, int size, |
23 | void (*get_more)(unsigned char** start, long* size)); | 24 | void (*get_more)(unsigned char** start, long* size)); |
24 | void pcm_play_stop(void); | 25 | void pcm_play_stop(void); |
25 | bool pcm_is_playing(void); | 26 | bool pcm_is_playing(void); |
27 | void pcm_set_volume(int volume); | ||
26 | 28 | ||
27 | #endif | 29 | #endif |
diff --git a/firmware/pcm_playback.c b/firmware/pcm_playback.c index fba85f083b..bc2218be69 100644 --- a/firmware/pcm_playback.c +++ b/firmware/pcm_playback.c | |||
@@ -37,20 +37,32 @@ | |||
37 | #include "file.h" | 37 | #include "file.h" |
38 | #include "buffer.h" | 38 | #include "buffer.h" |
39 | 39 | ||
40 | bool pcm_playing; | 40 | #include "sprintf.h" |
41 | #include "button.h" | ||
42 | #include <string.h> | ||
43 | |||
44 | static bool pcm_playing; | ||
45 | static int pcm_freq = 0x6; // 44.1 in default | ||
41 | 46 | ||
42 | /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ | 47 | /* Set up the DMA transfer that kicks in when the audio FIFO gets empty */ |
43 | static void dma_start(const void *addr, long size) | 48 | static void dma_start(const void *addr_r, long size) |
44 | { | 49 | { |
45 | pcm_playing = 1; | 50 | pcm_playing = 1; |
51 | int i; | ||
52 | |||
53 | int align; | ||
54 | align = 4; | ||
55 | |||
56 | void* addr = (void*)((((unsigned int)addr_r) >> 2) << 2); // always align data, never pass unaligned data | ||
57 | size = (size >> 2) << 2; // size shoudl also be always multiple of 4 | ||
46 | 58 | ||
47 | BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ | 59 | BUSMASTER_CTRL = 0x81; /* PARK[1,0]=10 + BCR24BIT */ |
48 | 60 | ||
49 | /* Set up DMA transfer */ | 61 | /* Set up DMA transfer */ |
50 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ | 62 | DIVR0 = 54; /* DMA0 is mapped into vector 54 in system.c */ |
51 | SAR0 = (unsigned long)addr; /* Source address */ | 63 | SAR0 = ((unsigned long)addr) + align*4; /* Source address */ |
52 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ | 64 | DAR0 = (unsigned long)&PDOR3; /* Destination address */ |
53 | BCR0 = size; /* Bytes to transfer */ | 65 | BCR0 = size-(align*4); /* Bytes to transfer */ |
54 | DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; | 66 | DMAROUTE = (DMAROUTE & 0xffffff00) | DMA0_REQ_AUDIO_1; |
55 | DMACONFIG = 1; /* Enable DMA0Req => set DMAROUTE |= DMA0_REQ_AUDIO_1 */ | 67 | DMACONFIG = 1; /* Enable DMA0Req => set DMAROUTE |= DMA0_REQ_AUDIO_1 */ |
56 | 68 | ||
@@ -61,14 +73,10 @@ static void dma_start(const void *addr, long size) | |||
61 | ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; | 73 | ICR4 = (ICR4 & 0xffff00ff) | 0x00001c00; |
62 | IMR &= ~(1<<14); /* bit 14 is DMA0 */ | 74 | IMR &= ~(1<<14); /* bit 14 is DMA0 */ |
63 | 75 | ||
64 | IIS2CONFIG = 0x4300; /* CLOCKSEL = AudioClk/8 (44.1kHz), | 76 | IIS2CONFIG = (pcm_freq << 12) | 0x300; /* CLOCKSEL for right frequency + data source = PDOR3 */ |
65 | data source = PDOR3 */ | ||
66 | 77 | ||
67 | PDOR3 = 0; /* These are needed to generate FIFO empty request to DMA.. */ | 78 | for(i = 0; i < align; i++) |
68 | PDOR3 = 0; | 79 | PDOR3 = ((unsigned int*)(addr))[i]; /* These are needed to generate FIFO empty request to DMA.. */ |
69 | PDOR3 = 0; | ||
70 | PDOR3 = 0; | ||
71 | PDOR3 = 0; | ||
72 | } | 80 | } |
73 | 81 | ||
74 | /* Stops the DMA transfer and interrupt */ | 82 | /* Stops the DMA transfer and interrupt */ |
@@ -76,12 +84,51 @@ static void dma_stop(void) | |||
76 | { | 84 | { |
77 | pcm_playing = 0; | 85 | pcm_playing = 0; |
78 | DCR0 = 0; | 86 | DCR0 = 0; |
87 | |||
88 | /* DMAROUTE &= 0xffffff00; | ||
89 | DMACONFIG = 0;*/ | ||
90 | |||
91 | IIS2CONFIG = 0x800; | ||
79 | 92 | ||
80 | /* Disable DMA0 interrupt */ | 93 | /* Disable DMA0 interrupt */ |
81 | IMR |= (1<<14); | 94 | IMR |= (1<<14); |
82 | ICR4 &= 0xffff00ff; | 95 | ICR4 &= 0xffff00ff; |
83 | } | 96 | } |
84 | 97 | ||
98 | |||
99 | /* set volume of the main channel */ | ||
100 | void pcm_set_volume(int volume) | ||
101 | { | ||
102 | if(volume > 0) | ||
103 | { | ||
104 | uda1380_mute(0); | ||
105 | uda1380_setvol(0xff - volume); | ||
106 | } | ||
107 | else | ||
108 | { | ||
109 | uda1380_mute(1); | ||
110 | } | ||
111 | } | ||
112 | |||
113 | /* sets frequency of input to DAC */ | ||
114 | void pcm_set_frequency(unsigned int frequency) | ||
115 | { | ||
116 | switch(frequency) | ||
117 | { | ||
118 | case 11025: | ||
119 | pcm_freq = 0x2; | ||
120 | break; | ||
121 | case 22050: | ||
122 | pcm_freq = 0x4; | ||
123 | break; | ||
124 | case 44100: | ||
125 | pcm_freq = 0x6; | ||
126 | break; | ||
127 | default: | ||
128 | pcm_freq = 0x6; | ||
129 | } | ||
130 | } | ||
131 | |||
85 | /* the registered callback function to ask for more mp3 data */ | 132 | /* the registered callback function to ask for more mp3 data */ |
86 | static void (*callback_for_more)(unsigned char**, long*) = NULL; | 133 | static void (*callback_for_more)(unsigned char**, long*) = NULL; |
87 | 134 | ||
@@ -110,8 +157,15 @@ void DMA0(void) | |||
110 | unsigned char* start; | 157 | unsigned char* start; |
111 | long size = 0; | 158 | long size = 0; |
112 | 159 | ||
160 | int res = DSR0; | ||
161 | |||
113 | DSR0 = 1; /* Clear interrupt */ | 162 | DSR0 = 1; /* Clear interrupt */ |
114 | 163 | ||
164 | if(res == 0x41) | ||
165 | { | ||
166 | dma_stop(); | ||
167 | } | ||
168 | |||
115 | if (callback_for_more) | 169 | if (callback_for_more) |
116 | { | 170 | { |
117 | callback_for_more(&start, &size); | 171 | callback_for_more(&start, &size); |