diff options
Diffstat (limited to 'firmware/target/arm/tms320dm320/dsp/dma.c')
-rw-r--r-- | firmware/target/arm/tms320dm320/dsp/dma.c | 54 |
1 files changed, 37 insertions, 17 deletions
diff --git a/firmware/target/arm/tms320dm320/dsp/dma.c b/firmware/target/arm/tms320dm320/dsp/dma.c index cf1e324a1f..430cc909f7 100644 --- a/firmware/target/arm/tms320dm320/dsp/dma.c +++ b/firmware/target/arm/tms320dm320/dsp/dma.c | |||
@@ -52,38 +52,58 @@ unsigned short sdem_level=0; | |||
52 | unsigned short last_size; | 52 | unsigned short last_size; |
53 | 53 | ||
54 | /* This tells us which half of the DSP buffer (data) is free */ | 54 | /* This tells us which half of the DSP buffer (data) is free */ |
55 | unsigned short dma0_unlocked; | 55 | unsigned short dma0_unlocked; |
56 | 56 | ||
57 | int waiting=0; | 57 | volatile unsigned short dma0_stopped=1; |
58 | |||
59 | short waiting=0; | ||
58 | /* rebuffer sets up the next SDRAM to SARAM transfer and tells the ARM when it | 60 | /* rebuffer sets up the next SDRAM to SARAM transfer and tells the ARM when it |
59 | * is done with a buffer. | 61 | * is done with a buffer. |
60 | */ | 62 | */ |
61 | 63 | ||
62 | /* Notes: Right now this can handle buffer sizes that are smaller even multiples | 64 | /* Notes: The upper limit on larger buffers is the size of a short. If larger |
63 | * of DSP_BUFFER_SIZE cleanly. It won't fail with buffers that are larger or | 65 | * buffer sizes are needed the code on the ARM side needs to be changed to |
64 | * non-multiples, but it won't sound right. The upper limit on larger buffers | 66 | * update a full long. |
65 | * is the size of a short. If larger buffer sizes are needed the code on the | ||
66 | * ARM side needs to be changed to update a full long. | ||
67 | */ | 67 | */ |
68 | void rebuffer(void) | 68 | void rebuffer(void) |
69 | { | 69 | { |
70 | unsigned long sdem_addr; | 70 | unsigned long sdem_addr; |
71 | 71 | ||
72 | if(dma0_stopped==1) /* Stop */ | ||
73 | { | ||
74 | DMPREC&=0xFFFE; /* Stop MCBSP DMA0 */ | ||
75 | audiohw_stop(); | ||
76 | DMSFC0 = 2 << 12 | 1 << 11; | ||
77 | sdem_level=0; | ||
78 | return; | ||
79 | } | ||
80 | |||
81 | if(dsp_level==DSP_BUFFER_SIZE || sdem_level==sdem_dsp_size) | ||
82 | { | ||
83 | if(dma0_stopped==2) /* Pause */ | ||
84 | { | ||
85 | DMPREC&=0xFFFE; /* Stop MCBSP DMA0 */ | ||
86 | audiohw_stop(); | ||
87 | return; | ||
88 | } | ||
89 | } | ||
90 | |||
72 | /* If the sdem_level is equal to the buffer size the ARM code gave | 91 | /* If the sdem_level is equal to the buffer size the ARM code gave |
73 | * (sdem_dsp_size) then reset the size and ask the arm for another buffer | 92 | * (sdem_dsp_size) then reset the size and ask the arm for another buffer |
74 | */ | 93 | */ |
75 | if(sdem_level==sdem_dsp_size) | 94 | if(sdem_level==sdem_dsp_size) |
76 | { | 95 | { |
77 | sdem_level=0; | 96 | sdem_level=0; |
78 | 97 | ||
79 | /* Get a new buffer (location and size) from ARM */ | 98 | /* Get a new buffer (location and size) from ARM */ |
80 | status.msg = MSG_REFILL; | 99 | status.msg = MSG_REFILL; |
81 | waiting=1; | 100 | waiting=1; |
101 | |||
82 | startack(); | 102 | startack(); |
83 | } | 103 | } |
84 | 104 | ||
85 | if(!waiting) | 105 | if(!waiting) |
86 | { | 106 | { |
87 | /* Size is in bytes (but forced 32 bit transfers */ | 107 | /* Size is in bytes (but forced 32 bit transfers */ |
88 | if( (dsp_level + (sdem_dsp_size - sdem_level) ) > DSP_BUFFER_SIZE) | 108 | if( (dsp_level + (sdem_dsp_size - sdem_level) ) > DSP_BUFFER_SIZE) |
89 | { | 109 | { |
@@ -130,7 +150,7 @@ void rebuffer(void) | |||
130 | interrupt void handle_dma0(void) | 150 | interrupt void handle_dma0(void) |
131 | { | 151 | { |
132 | /* Byte offset to half-buffer locked by DMA0. | 152 | /* Byte offset to half-buffer locked by DMA0. |
133 | 0 for top, PCM_SIZE/2(0x4000) for bottom */ | 153 | 0 for top, PCM_SIZE/2 for bottom */ |
134 | unsigned short dma0_locked; | 154 | unsigned short dma0_locked; |
135 | 155 | ||
136 | IFR = 1 << 6; | 156 | IFR = 1 << 6; |
@@ -156,18 +176,18 @@ interrupt void handle_dmac(void) { | |||
156 | 176 | ||
157 | dsp_level+=last_size; | 177 | dsp_level+=last_size; |
158 | sdem_level+=last_size; | 178 | sdem_level+=last_size; |
159 | 179 | ||
160 | if(dsp_level<DSP_BUFFER_SIZE) | 180 | if(dsp_level<DSP_BUFFER_SIZE) |
161 | { | 181 | { |
162 | rebuffer(); | 182 | rebuffer(); |
163 | } | 183 | } |
164 | } | 184 | } |
165 | 185 | ||
166 | void dma_init(void) { | 186 | void dma_init(void) { |
167 | /* Configure SARAM to McBSP DMA */ | 187 | /* Configure SARAM to McBSP DMA */ |
168 | 188 | ||
169 | /* Event XEVT0, 32-bit transfers, 0 frame count */ | 189 | /* Event XEVT0, 32-bit transfers, 0 frame count */ |
170 | DMSFC0 = 2 << 12 | 1 << 11; | 190 | DMSFC0 = 2 << 12 | 1 << 11; |
171 | 191 | ||
172 | /* Interrupts generated, Half and full buffer. | 192 | /* Interrupts generated, Half and full buffer. |
173 | * ABU mode, From data space with postincrement, to data space with no | 193 | * ABU mode, From data space with postincrement, to data space with no |
@@ -183,8 +203,8 @@ void dma_init(void) { | |||
183 | DMDST0 = (unsigned short)&DXR20; | 203 | DMDST0 = (unsigned short)&DXR20; |
184 | 204 | ||
185 | /* Set the size of the buffer */ | 205 | /* Set the size of the buffer */ |
186 | DMCTR0 = sizeof(data); | 206 | DMCTR0 = sizeof(data); |
187 | 207 | ||
188 | /* Run, Rudolf, run! (with DMA0 interrupts) */ | 208 | /* Setup DMA0 interrupts and start the transfer */ |
189 | DMPREC = 2 << 6 | 1; | 209 | DMPREC = 2 << 6; |
190 | } | 210 | } |