summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichiel Van Der Kolk <not.valid@email.address>2005-03-28 00:00:24 +0000
committerMichiel Van Der Kolk <not.valid@email.address>2005-03-28 00:00:24 +0000
commit451dd48adc2ef29fd2f900693393cc9b9b4a849b (patch)
treee15d20e602261866617210bde007966ce9b19293 /firmware
parent853bc3dcf85aa1284a0e5b550277c40beb7697a9 (diff)
downloadrockbox-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.c4
-rw-r--r--firmware/export/pcm_playback.h2
-rw-r--r--firmware/pcm_playback.c78
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) */
132int uda1380_init(void) 132int 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
22void pcm_set_frequency(unsigned int frequency);
22void pcm_play_data(const unsigned char* start, int size, 23void 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));
24void pcm_play_stop(void); 25void pcm_play_stop(void);
25bool pcm_is_playing(void); 26bool pcm_is_playing(void);
27void 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
40bool pcm_playing; 40#include "sprintf.h"
41#include "button.h"
42#include <string.h>
43
44static bool pcm_playing;
45static 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 */
43static void dma_start(const void *addr, long size) 48static 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 */
100void 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 */
114void 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 */
86static void (*callback_for_more)(unsigned char**, long*) = NULL; 133static 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);