summaryrefslogtreecommitdiff
path: root/firmware/target/arm/tms320dm320/dsp/dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/tms320dm320/dsp/dma.c')
-rw-r--r--firmware/target/arm/tms320dm320/dsp/dma.c54
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;
52unsigned short last_size; 52unsigned 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 */
55unsigned short dma0_unlocked; 55unsigned short dma0_unlocked;
56 56
57int waiting=0; 57volatile unsigned short dma0_stopped=1;
58
59short 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 */
68void rebuffer(void) 68void 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)
130interrupt void handle_dma0(void) 150interrupt 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
166void dma_init(void) { 186void 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}