I'm having some trouble modifying a working app to use DMA. I have
timer 2 on the DSP56309 set up in "Toggle" mode so that I can produce waveforms whose pulse width varies. The current version of the program works fine as I am using the timer compare interrupt to update the TCPR value which varies the pulse width. The ISR repeatedly cycles through a buffer (OutBuf) of 12 TCPR values to produce a periodic waveform. Now I want to use a DMA channel to feed the TCPR of timer 2, and so the timer compare interrupt is not used. I have instead installed a DMA transfer complete interrupt to restart the DMA transfer. Here's the code: TCPR2 = 498; // initial delay value coreInstallIntVec(0x18/2, (_P UInt24*) cic3DMA0ISR ); // install interrupt vector for DMA IPRC.B.D0L = 3; // High priority for DMA channel 0 DSR0 = (int * )OutBuf; DDR0 = (int *) 0xFFFF85; // dest is TCPR2 DCO0 = 12-1; // (num values in OutBuf)-1 DCR0.B.DSS = 0; // source is in X DCR0.B.DDS = 0; // dest is in X DCR0.B.DAM = 0x25; // source addr is ++, no update of dest addr DCR0.B.D3D = 0; // non-3D mode DCR0.B.DRS = 0x12; // DMA Req Source is Tmr 2 Cmp Flag DCR0.B.DCON = 0; // DCR0.B.DPR = 3; // DCR0.B.DTM = 1; // word-by-word block transfer; DE cleared after transfer complete DCR0.B.DIE = 1; // DCR0.B.DE = 1; // And here's the DMA complete interrupt service routine: void _long_interrupt (-1) cic3DMA0ISR (void) { DCO0 = 12-1; // DSR0 = (int * )&OutBuf[0]; DCR0.B.DE = 1; // do it again } With this code running, everything seems to be working fine, except that the TCPR2 vaue never changes from the initial value of 498. The source of the DMA transfer (OutBuf) contains values other than 498. As I step through the code, I note that the DMA controller is functioning as I expect because: DSR0 increments as it should while DDR0 is fixed at the address of TCPR2, DCO0 counts in step with DSR0, and the DACT and DTD0 bits in the status reg change as I expect them to. What I observe in this case is that the TIO2 pin produces a square wave proportional to the initial TCSR2 value, indicating that it never gets updated. I have a feeling I'm missing something obvious, but for the life of me I can't see it. Any help is much appreciated. |
|
Using DMA on DSP56309
Started by ●March 31, 2004
Reply by ●April 1, 20042004-04-01
John, DMA cannot be used to update configuration registers in I/O space. The only registers it can communicate within I/O space are transmit and receive registers. See item number 2 in Section 10.6 DMA Restrictions in the 56300 Family Manual... -- dB --- "Wygonski, John" <> wrote: > I'm having some trouble modifying a working app to use DMA. I have > timer 2 on the DSP56309 set up in "Toggle" mode so that I can produce > waveforms whose pulse width varies. The current version of the > program works fine as I am using the timer compare interrupt to > update the TCPR value which varies the pulse width. The ISR > repeatedly cycles through a buffer (OutBuf) of 12 TCPR values to > produce a periodic waveform. > > Now I want to use a DMA channel to feed the TCPR of timer 2, and so > the timer compare interrupt is not used. I have instead installed a > DMA transfer complete interrupt to restart the DMA transfer. Here's > the code: > > TCPR2 = 498; // initial delay value > coreInstallIntVec(0x18/2, (_P UInt24*) cic3DMA0ISR ); // > install interrupt vector for DMA > IPRC.B.D0L = 3; // High priority for DMA channel 0 > DSR0 = (int * )OutBuf; > DDR0 = (int *) 0xFFFF85; // dest is TCPR2 > DCO0 = 12-1; // (num values in OutBuf)-1 > DCR0.B.DSS = 0; // source is in X > DCR0.B.DDS = 0; // dest is in X > DCR0.B.DAM = 0x25; // source addr is ++, no update of dest > addr > DCR0.B.D3D = 0; // non-3D mode > DCR0.B.DRS = 0x12; // DMA Req Source is Tmr 2 Cmp Flag > DCR0.B.DCON = 0; // > DCR0.B.DPR = 3; // > DCR0.B.DTM = 1; // word-by-word block transfer; DE > cleared after transfer complete > DCR0.B.DIE = 1; // > DCR0.B.DE = 1; // > > And here's the DMA complete interrupt service routine: > > void _long_interrupt (-1) > cic3DMA0ISR (void) { > DCO0 = 12-1; // > DSR0 = (int * )&OutBuf[0]; > DCR0.B.DE = 1; // do it again > } > > With this code running, everything seems to be working fine, except > that the TCPR2 vaue never changes from the initial value of 498. The > source of the DMA transfer (OutBuf) contains values other than 498. > As I step through the code, I note that the DMA controller is > functioning as I expect because: DSR0 increments as it should while > DDR0 is fixed at the address of TCPR2, DCO0 counts in step with DSR0, > and the DACT and DTD0 bits in the status reg change as I expect them > to. What I observe in this case is that the TIO2 pin produces a > square wave proportional to the initial TCSR2 value, indicating that > it never gets updated. > > I have a feeling I'm missing something obvious, but for the life of > me I can't see it. Any help is much appreciated. > __________________________________ |
|
Reply by ●April 1, 20042004-04-01
Sorry, it's item number 3 in that section not number 2... -- dB --- "Wygonski, John" <> wrote: > I'm having some trouble modifying a working app to use DMA. I have > timer 2 on the DSP56309 set up in "Toggle" mode so that I can produce > waveforms whose pulse width varies. The current version of the > program works fine as I am using the timer compare interrupt to > update the TCPR value which varies the pulse width. The ISR > repeatedly cycles through a buffer (OutBuf) of 12 TCPR values to > produce a periodic waveform. > > Now I want to use a DMA channel to feed the TCPR of timer 2, and so > the timer compare interrupt is not used. I have instead installed a > DMA transfer complete interrupt to restart the DMA transfer. Here's > the code: > > TCPR2 = 498; // initial delay value > coreInstallIntVec(0x18/2, (_P UInt24*) cic3DMA0ISR ); // > install interrupt vector for DMA > IPRC.B.D0L = 3; // High priority for DMA channel 0 > DSR0 = (int * )OutBuf; > DDR0 = (int *) 0xFFFF85; // dest is TCPR2 > DCO0 = 12-1; // (num values in OutBuf)-1 > DCR0.B.DSS = 0; // source is in X > DCR0.B.DDS = 0; // dest is in X > DCR0.B.DAM = 0x25; // source addr is ++, no update of dest > addr > DCR0.B.D3D = 0; // non-3D mode > DCR0.B.DRS = 0x12; // DMA Req Source is Tmr 2 Cmp Flag > DCR0.B.DCON = 0; // > DCR0.B.DPR = 3; // > DCR0.B.DTM = 1; // word-by-word block transfer; DE > cleared after transfer complete > DCR0.B.DIE = 1; // > DCR0.B.DE = 1; // > > And here's the DMA complete interrupt service routine: > > void _long_interrupt (-1) > cic3DMA0ISR (void) { > DCO0 = 12-1; // > DSR0 = (int * )&OutBuf[0]; > DCR0.B.DE = 1; // do it again > } > > With this code running, everything seems to be working fine, except > that the TCPR2 vaue never changes from the initial value of 498. The > source of the DMA transfer (OutBuf) contains values other than 498. > As I step through the code, I note that the DMA controller is > functioning as I expect because: DSR0 increments as it should while > DDR0 is fixed at the address of TCPR2, DCO0 counts in step with DSR0, > and the DACT and DTD0 bits in the status reg change as I expect them > to. What I observe in this case is that the TIO2 pin produces a > square wave proportional to the initial TCSR2 value, indicating that > it never gets updated. > > I have a feeling I'm missing something obvious, but for the life of > me I can't see it. Any help is much appreciated. > __________________________________ |
Reply by ●April 1, 20042004-04-01
Well, thanks so much for clearing that up. I did see that item, but I just mis-interpreted it. So even though the timer compare event can trigger a DMA transfer, I basically can't reprogram the timer using DMA at all because it has no Tx/Rx regs. Well, back to the drawing board, as they say. --- In , dbaudiopro <dbaudiopro@y...> wrote: > John, > > DMA cannot be used to update configuration registers in I/O space. The > only registers it can communicate within I/O space are transmit and > receive registers. See item number 2 in Section 10.6 DMA Restrictions > in the 56300 Family Manual... > > -- > dB > > --- "Wygonski, John" <jwygonski@h...> wrote: > > I'm having some trouble modifying a working app to use DMA. I have > > timer 2 on the DSP56309 set up in "Toggle" mode so that I can produce > > waveforms whose pulse width varies. The current version of the > > program works fine as I am using the timer compare interrupt to > > update the TCPR value which varies the pulse width. The ISR > > repeatedly cycles through a buffer (OutBuf) of 12 TCPR values to > > produce a periodic waveform. > > > > Now I want to use a DMA channel to feed the TCPR of timer 2, and so > > the timer compare interrupt is not used. I have instead installed a > > DMA transfer complete interrupt to restart the DMA transfer. Here's > > the code: > > > > TCPR2 = 498; // initial delay value > > coreInstallIntVec(0x18/2, (_P UInt24*) cic3DMA0ISR ); // > > install interrupt vector for DMA > > IPRC.B.D0L = 3; // High priority for DMA channel 0 > > DSR0 = (int * )OutBuf; > > DDR0 = (int *) 0xFFFF85; // dest is TCPR2 > > DCO0 = 12-1; // (num values in OutBuf)-1 > > DCR0.B.DSS = 0; // source is in X > > DCR0.B.DDS = 0; // dest is in X > > DCR0.B.DAM = 0x25; // source addr is ++, no update of dest > > addr > > DCR0.B.D3D = 0; // non-3D mode > > DCR0.B.DRS = 0x12; // DMA Req Source is Tmr 2 Cmp Flag > > DCR0.B.DCON = 0; // > > DCR0.B.DPR = 3; // > > DCR0.B.DTM = 1; // word-by-word block transfer; DE > > cleared after transfer complete > > DCR0.B.DIE = 1; // > > DCR0.B.DE = 1; // > > > > And here's the DMA complete interrupt service routine: > > > > void _long_interrupt (-1) > > cic3DMA0ISR (void) { > > DCO0 = 12-1; // > > DSR0 = (int * )&OutBuf[0]; > > DCR0.B.DE = 1; // do it again > > } > > > > With this code running, everything seems to be working fine, except > > that the TCPR2 vaue never changes from the initial value of 498. The > > source of the DMA transfer (OutBuf) contains values other than 498. > > As I step through the code, I note that the DMA controller is > > functioning as I expect because: DSR0 increments as it should while > > DDR0 is fixed at the address of TCPR2, DCO0 counts in step with DSR0, > > and the DACT and DTD0 bits in the status reg change as I expect them > > to. What I observe in this case is that the TIO2 pin produces a > > square wave proportional to the initial TCSR2 value, indicating that > > it never gets updated. > > > > I have a feeling I'm missing something obvious, but for the life of > > me I can't see it. Any help is much appreciated. > > __________________________________ > |
|
Reply by ●April 2, 20042004-04-02
It doesn't matter if the peripheral has TX or RX registers. The
point is that DMA can only read or write peripheral TX or TX registers. For instance, you can't use DMA to write an ESSI control register. However, you can service an ESSI TX or RX register with DMA. No control register for any peripheral located in I/O space can be written or read with DMA... -- dB --- wygonski <> wrote: > Well, thanks so much for clearing that up. I did see that item, but > I just mis-interpreted it. > > So even though the timer compare event can trigger a DMA transfer, I > basically can't reprogram the timer using DMA at all because it has > no Tx/Rx regs. > > Well, back to the drawing board, as they say. > > --- In , dbaudiopro <dbaudiopro@y...> > wrote: > > John, > > > > DMA cannot be used to update configuration registers in I/O space. > The > > only registers it can communicate within I/O space are transmit and > > receive registers. See item number 2 in Section 10.6 DMA > Restrictions > > in the 56300 Family Manual... > > > > -- > > dB > > > > --- "Wygonski, John" <jwygonski@h...> wrote: > > > I'm having some trouble modifying a working app to use DMA. I > have > > > timer 2 on the DSP56309 set up in "Toggle" mode so that I can > produce > > > waveforms whose pulse width varies. The current version of the > > > program works fine as I am using the timer compare interrupt to > > > update the TCPR value which varies the pulse width. The ISR > > > repeatedly cycles through a buffer (OutBuf) of 12 TCPR values to > > > produce a periodic waveform. > > > > > > Now I want to use a DMA channel to feed the TCPR of timer 2, and > so > > > the timer compare interrupt is not used. I have instead > installed a > > > DMA transfer complete interrupt to restart the DMA transfer. > Here's > > > the code: > > > > > > TCPR2 = 498; // initial delay value > > > coreInstallIntVec(0x18/2, (_P UInt24*) cic3DMA0ISR ); // > > > install interrupt vector for DMA > > > IPRC.B.D0L = 3; // High priority for DMA channel 0 > > > DSR0 = (int * )OutBuf; > > > DDR0 = (int *) 0xFFFF85; // dest is TCPR2 > > > DCO0 = 12-1; // (num values in OutBuf)-1 > > > DCR0.B.DSS = 0; // source is in X > > > DCR0.B.DDS = 0; // dest is in X > > > DCR0.B.DAM = 0x25; // source addr is ++, no update of > dest > > > addr > > > DCR0.B.D3D = 0; // non-3D mode > > > DCR0.B.DRS = 0x12; // DMA Req Source is Tmr 2 Cmp Flag > > > DCR0.B.DCON = 0; // > > > DCR0.B.DPR = 3; // > > > DCR0.B.DTM = 1; // word-by-word block transfer; DE > > > cleared after transfer complete > > > DCR0.B.DIE = 1; // > > > DCR0.B.DE = 1; // > > > > > > And here's the DMA complete interrupt service routine: > > > > > > void _long_interrupt (-1) > > > cic3DMA0ISR (void) { > > > DCO0 = 12-1; // > > > DSR0 = (int * )&OutBuf[0]; > > > DCR0.B.DE = 1; // do it again > > > } > > > > > > With this code running, everything seems to be working fine, > except > > > that the TCPR2 vaue never changes from the initial value of 498. > > The > > > source of the DMA transfer (OutBuf) contains values other than > 498. > > > As I step through the code, I note that the DMA controller is > > > functioning as I expect because: DSR0 increments as it should > while > > > DDR0 is fixed at the address of TCPR2, DCO0 counts in step with > DSR0, > > > and the DACT and DTD0 bits in the status reg change as I expect > them > > > to. What I observe in this case is that the TIO2 pin produces a > > > square wave proportional to the initial TCSR2 value, indicating > that > > > it never gets updated. > > > > > > I have a feeling I'm missing something obvious, but for the life > of > > > me I can't see it. Any help is much appreciated. > > > > > > > > > __________________________________ > > > __________________________________ |