This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SPI Communiation using DMA

Other Parts Discussed in Thread: MSP430FR5739, MSP430F2274

#include "msp430f2618.h"
char RX_Buffer[10];
int main( void )
{
unsigned int i=0;
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD; // Wait for xtal to stabilize
while (IFG1 & OFIFG)
{
// Clear oscillator fault flag
IFG1 &= ~OFIFG;
for (i = 0x4800; i > 0; i--); //NOP();.
}
// Set clock source to DCO @ 16 MHz
DCOCTL = CALDCO_16MHZ;
BCSCTL1 = CALBC1_16MHZ;
BCSCTL1 |= XT2OFF;

// Wait for DCO to synchronize with ACLK (at least 28*32 ACLK cycles)
for (i = 0x1C00; i > 0; i--);// NOP();
/*****************************************************************************/

UCB0CTL1 |= UCSWRST; //Initialize all USCI registers

UCB0CTL0 |= UCCKPH +UCSYNC+UCMODE_2+UCMSB;//spi slave,4-pin, msbfirst, sync, 8-bit
UCB0CTL1 |= UCSSEL_2; //clock source select SMCLK (dont't care in slave mode)
P3SEL = 0X0F; //p3.0,1,2,3 for spi communication

UCB0CTL1 &= ~UCSWRST; //releases USCI for operation


DMACTL0 = DMA1TSEL_12 + DMA0TSEL_13; // DMA1=URXIFG1, DMA0=UTXIFG1

// Playback (using channel0 )
/*DMA channel 0 source address*/
DMA0SA = (unsigned short)RX_Buffer; // Src = RAM memory

/*DMA channel 0 destination address*/
DMA0DA = (unsigned short)&UCB0TXBUF; // Dest single address

/*DMA channel 0 transfer block size*/
DMA0SZ = 0x08; // Block size

/*DMA channel0 Destination address increment by 1 */
/*transfer is byte wise */
/*DMA channel0 INT disabled */
/*DMA channel0 is disabled */
DMA0CTL = DMASRCINCR_3 + DMASBDB + DMALEVEL;// inc src, enable, byte access



// Record (using channel1)
/*DMA channel 1 source address*/
DMA1SA = (int)&UCB0RXBUF; // Src single addr = UC_RX Buffer

/*DMA channel 1 destination address*/
DMA1DA = (int)RX_Buffer; // Dst address = RAM memory

/*DMA channel 1 transfer block size*/
DMA1SZ = 0x08; // Size in bytes

/*DMA channel 1 Destination address increment by 1 byte */
/*transfer is byte wise */
/*DMA channel 1 INT enabled */
/*DMA channel 1 is enabled */
DMA1CTL = DMADSTINCR_3 + DMASBDB + DMAIE + DMAEN; // Sng, config, byte access

_BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt
}

// DMA interrupt service routine
#pragma vector = DMA_VECTOR
__interrupt void DMA_ISR(void)
{
/**clearing DMA channel 1 interrupt flag*/
DMA1CTL &= ~DMAIFG; // Clear DMA1 interrupt flag

//enablig DMA channel 0 (for transfer)
DMA0CTL |= DMAEN; // Enable

//re-enabling channel 1 (for transfer)
DMA1CTL |= DMAEN; // (re)Enable
}
The above code is for SPI Slave for MSP430f2168 64 pin microcontroller, i want to play back all the
 data to windows hyperterminal . 
the code is written for  spi using DMA. I have used Two channels for receive and transmit seperately.
 SPI is configured on 10 MHz.
Slave is receiving  4 bytes (12 34 56 78).
 DMA channels have been configured in fixed to block and block to fixed address transfer modes.
the DMA1 and DMA0 triggers are 0x00c0 and 0x000d respectively. 
Now in place of  4 bytes DMA block i require 8 byte block for proper play back.
I cannot not understand why?
Also that whether I am missing any byte  of data ?
  • What happens if you change:

      _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt

    To:

      _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt 

    For reasons I didn't understand, on a MSP430FR5739 SPI DMA didn't complete as expected if LPM3 was entered, but did complete in LPM0. 

  • Chester Gillon said:
    For reasons I didn't understand, on a MSP430FR5739 SPI DMA didn't complete as expected if LPM3 was entered, but did complete in LPM0. 

    Maybe because LPM3 disables the clock that is needed for the DMA transfer (MCLK source = DCO or XTAL) and it needs to be switched on with the defined waiting time before the transfer can take place.

    About the block size, well, two things.

    First, DMALEVEL should only be set for the external DMA signal. The internal ones should not set this bit (I read it somewhere in the users guide).

    Also, when starting the TX DMA, TXIFG is already set and the transfer starts. Even if nothing has ever been received into the buffer yet. The concept is wrong.

    YOu can do the following:

    set up one DMA channel to copy from RXBUF to ram and one channel to copy from RXBUF (or ram) to TXBUF. Both triggered by the RXIFG bit on edge trigger. So once RXIFG is set, the data is copied to ram and to TXBUF by the two DMA, since they are both triggered by the edge event, not the current level of TXIFG (which is clear again after the first of the two transfers).

    Since RX and TX have the same clock, TXBUF is always empty if a byte has been received with RXBUF. You have, however, a 1-byte delay. The master will receive nothing (dummy value) when sending the first byte and the return of the 4th byte appears at the master only after a 5th (dummy) byte has been sent.

  • Hi guys

    Does anybody know how to free download DMA Library for msp430f2274?

    The program does not understand any register of DMA, although I included the header file of mspx22x4.

  • yarub alazzawi said:

    Does anybody know how to free download DMA Library for msp430f2274?

    The program does not understand any register of DMA, although I included the header file of mspx22x4.

    The MSP430F22x4 devices don't have the on-chip DMA module. 

**Attention** This is a public forum