summaryrefslogtreecommitdiff
path: root/firmware/pcm_playback.c
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/pcm_playback.c
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/pcm_playback.c')
-rw-r--r--firmware/pcm_playback.c78
1 files changed, 66 insertions, 12 deletions
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);