Hot!UART transmitter + dma

Author
Shishi
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2016/06/15 05:34:10
  • Location: 0
  • Status: offline
2018/01/12 04:41:41 (permalink)
0

UART transmitter + dma

Hello every one
i have 2 electronic bords, that i called them Master(the one that send data) and slave(secound board that recives data), my first test was:
Master board programed with  uart transmitter without dma and Slave borad with Uart reciver with dam, and it works.
then i made a change to Master board to work with uart transmitter with dma, but it does not send anything and my slave board does not recive anything, i read dma data sheet but i could not find my problem. my ucontroller is Dspic33ep and my compiler is xc16 (mplabx)
this is my code:

 
unsigned int U1TXREG[110] __attribute__((space(xmemory)));
 
 
 
 
 
//************master******//
 
void InitUART1( void ){

U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
 
//U1MODEbits.notimplemented; // Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0; // Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
 
//U1MODEbits.notimplemented; // Bit10
U1MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U1MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U1MODEbits.LPBACK = 0; // Bit6 No Loop Back
U1MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U1MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U1MODEbits.RXINV = 0; // Bit3 16 clocks per bit period

U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
 
// U1BRG = (Fcy/(16*BaudRate))-1
U1BRG = 64; //baudrate 19200 40Mhz osc, / 259 or 129 ??? 519
 
// Load all values in for U1STA SFR
U1STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U1STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U1STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
 
//U1STAbits.notimplemented = 0; //Bit12
U1STAbits.UTXBRK = 0; //Bit11 Disabled
U1STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U1STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U1STAbits.TRMT = 0; //Bit8 *Read Only bit*
U1STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U1STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U1STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U1STAbits.PERR = 0; //Bit3 *Read Only Bit*
U1STAbits.FERR = 0; //Bit2 *Read Only Bit*
U1STAbits.OERR = 0; //Bit1 *Read Only Bit*
U1STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC2bits.U1RXIP = 2; // Mid Range Interrupt Priority level, no urgent reason
IPC3bits.U1TXIP= 0; // Mid Range Interrupt Priority level, no urgent reason
IFS0bits.U1TXIF = 0; // Clear the Transmit Interrupt Flag
IEC0bits.U1TXIE = 0; // Enable Transmit Interrupts
IFS0bits.U1RXIF = 0; // Clear the Recieve Interrupt Flag
IEC0bits.U1RXIE = 1; // Enable Recieve Interrupts

U1MODEbits.UARTEN = 1;
U1STAbits.UTXEN = 1;
}
 
void ConfigDMA3tx(void) {//tra
 
DMA3CONbits.SIZE = 0; //word
DMA3CONbits.DIR = 1; //DMA_TO_PERIPHERAL
DMA3CONbits.HALF = 0; //DMA_INTERRUPT_BLOCK
DMA3CONbits.NULLW = 0; //DMA_NORMAL
DMA3CONbits.AMODE = 0; //
DMA3CONbits.MODE = 0; // DMA_CONTINUOUS without ping_pong
DMA3REQ = 0x000C; // DMA Peripheral IRQ Number Select bits
DMA3STAL = (unsigned int) &TxBufferB;
DMA3STAH = 0;
DMA3PAD = (volatile unsigned int) &U1TXREG;
DMA3CNT = 15;
IFS2bits.DMA3IF = 0; // Clear DMA interrupt
IEC2bits.DMA3IE = 1; // Enable DMA interrupt
DMA3REQbits.FORCE = 1; //DMA1_MANUAL
DMA3CONbits.CHEN = 1; //DMA1_MODULE_ON
 
}
 
 
 
void __attribute__((__interrupt__, no_auto_psv)) _DMA3Interrupt(void) {

IFS2bits.DMA3IF = 0; // Clear DMA interrupt

}
 
 

//******************************  Slave *******************

 
unsigned int RxBufferBTmp[110] __attribute__((space(xmemory)));
 
 
 
unsigned int RxBufferB[110];
 
 
 
 
 
void InitUART2( void ){

U2MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
 
//U2MODEbits.notimplemented; // Bit14
U2MODEbits.USIDL = 0; // Bit13 Continue in Idle
U2MODEbits.IREN = 0; // Bit12 No IR translation
U2MODEbits.RTSMD = 0; // Bit11 Simplex Mode
 
//U2MODEbits.notimplemented; // Bit10
U2MODEbits.UEN = 0; // Bits8,9 TX,RX enabled, CTS,RTS not
U2MODEbits.WAKE = 0; // Bit7 No Wake up (since we don't sleep here)
U2MODEbits.LPBACK = 0; // Bit6 No Loop Back
U2MODEbits.ABAUD = 0; // Bit5 No Autobaud (would require sending '55')
U2MODEbits.BRGH = 0; // Bit3 16 clocks per bit period
U2MODEbits.RXINV = 0; // Bit3 16 clocks per bit period

U2MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U2MODEbits.STSEL = 0; // Bit0 One Stop Bit
 
// U2BRG = (Fcy/(16*BaudRate))-1
U2BRG = 64; //baudrate 19200 40Mhz osc, / 259 or 129 ??? 519
 
// Load all values in for U2STA SFR
U2STAbits.UTXISEL1 = 0; //Bit15 Int when Char is transferred (1/2 config!)
U2STAbits.UTXINV = 0; //Bit14 N/A, IRDA config
U2STAbits.UTXISEL0 = 0; //Bit13 Other half of Bit15
 
//U2STAbits.notimplemented = 0; //Bit12
U2STAbits.UTXBRK = 0; //Bit11 Disabled
U2STAbits.UTXEN = 0; //Bit10 TX pins controlled by periph
U2STAbits.UTXBF = 0; //Bit9 *Read Only Bit*
U2STAbits.TRMT = 0; //Bit8 *Read Only bit*
U2STAbits.URXISEL = 0; //Bits6,7 Int. on character recieved
U2STAbits.ADDEN = 0; //Bit5 Address Detect Disabled
U2STAbits.RIDLE = 0; //Bit4 *Read Only Bit*
U2STAbits.PERR = 0; //Bit3 *Read Only Bit*
U2STAbits.FERR = 0; //Bit2 *Read Only Bit*
U2STAbits.OERR = 0; //Bit1 *Read Only Bit*
U2STAbits.URXDA = 0; //Bit0 *Read Only Bit*
IPC7bits.U2RXIP = 0; // Mid Range Interrupt Priority level, no urgent reason
IPC7bits.U2TXIP = 0; // Mid Range Interrupt Priority level, no urgent reason
IFS1bits.U2TXIF = 0; // Clear the Transmit Interrupt Flag
IEC1bits.U2TXIE = 0; // Enable Transmit Interrupts
IFS1bits.U2RXIF = 0; // Clear the Recieve Interrupt Flag
IEC1bits.U2RXIE = 0; // Enable Recieve Interrupts

U2MODEbits.UARTEN = 1;
U2STAbits.UTXEN = 1;
}
 
 

void ConfigDMA2rx(void) { //reception
 
DMA2CONbits.SIZE = 0; //word
DMA2CONbits.DIR = 0; //PERIPHERAL_TO_DMA2
DMA2CONbits.HALF = 0; //DMA2_INTERRUPT_BLOCK
DMA2CONbits.NULLW = 0; //DMA2_NORMAL
DMA2CONbits.AMODE = 0; //DMA2_REGISTER
DMA2CONbits.MODE = 0; //DMA2_CONTINUOUS without ping_pong
DMA2REQ = 0x001E; // UART2 receiver
DMA2STAL = (unsigned int) &RxBufferBTmp;
DMA2STAH = 0;
DMA2PAD = (volatile unsigned int) &U2RXREG;
 
DMA2CNT = 15;//110; //120 dma request
IFS1bits.DMA2IF = 0; // Clear DMA interrupt
IEC1bits.DMA2IE = 1; // Enable DMA interrupt
DMA2CONbits.CHEN = 1; //DMA0_MODULE_ON
 
}
 
 
 
void __attribute__((__interrupt__, auto_psv)) _DMA2Interrupt(void) {
 
memcpy(RxBufferB,RxBufferBTmp,220);
 
IFS1bits.DMA2IF = 0; // Clear the DMA0 Interrupt flag
 
}
 
 
 
 
 
 
 

 
is there somthing wrong in my configuration?
post edited by Shishi - 2018/01/12 04:43:59
#1

10 Replies Related Threads

    bblessing
    Super Member
    • Total Posts : 692
    • Reward points : 0
    • Joined: 2008/12/04 06:44:21
    • Location: Cincinnati, OH
    • Status: offline
    Re: UART transmitter + dma 2018/01/12 05:03:38 (permalink)
    0
    First of all, I wouldn't call memcpy in an ISR. Second of all, read up on making variables cache coherent and using physical addresses (KVA_TO_PA).
    #2
    Shishi
    Super Member
    • Total Posts : 342
    • Reward points : 0
    • Joined: 2016/06/15 05:34:10
    • Location: 0
    • Status: offline
    Re: UART transmitter + dma 2018/01/12 05:33:41 (permalink)
    0
    bblessing
    First of all, I wouldn't call memcpy in an ISR. Second of all, read up on making variables cache coherent and using physical addresses (KVA_TO_PA).

    sorry i did not undrestand.what is the secound?
    #3
    bblessing
    Super Member
    • Total Posts : 692
    • Reward points : 0
    • Joined: 2008/12/04 06:44:21
    • Location: Cincinnati, OH
    • Status: offline
    Re: UART transmitter + dma 2018/01/12 07:16:08 (permalink)
    0
    You'll need to declare your buffers like this:
     
     
    static uint8_t __attribute__((coherent)) arr

     
    Additionally, when you're setting the source and destination addresses, it should look like this:
     
    PLIB_DMA_ChannelXSourceStartAddressSet(DMA_ID_0, usart_dma_ch[id], KVA_TO_PA(ptr));

     
    The second code snippet contains the all important KVA_TO_PA macro. The reason I said to read up on these things is because there are quite a few references to them in these fora.
     
    Edit: This may not apply, my apologies, as you're using a DSPIC instead of a PIC32. I need to pay more attention to which fora the questions are coming from.
    post edited by bblessing - 2018/01/12 07:20:32
    #4
    NKurzman
    A Guy on the Net
    • Total Posts : 16647
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: UART transmitter + dma 2018/01/12 07:36:43 (permalink)
    0
    Since they did not say what chip they are using it is hard to say. Some require that the DMA ram be in certain areas of memory.
    #5
    Shishi
    Super Member
    • Total Posts : 342
    • Reward points : 0
    • Joined: 2016/06/15 05:34:10
    • Location: 0
    • Status: offline
    Re: UART transmitter + dma 2018/01/12 07:55:12 (permalink)
    0
    NKurzman
    Since they did not say what chip they are using it is hard to say. Some require that the DMA ram be in certain areas of memory.

    dsPIC33EP512GM710
    #6
    NKurzman
    A Guy on the Net
    • Total Posts : 16647
    • Reward points : 0
    • Joined: 2008/01/16 19:33:48
    • Location: 0
    • Status: online
    Re: UART transmitter + dma 2018/01/12 09:31:12 (permalink)
    0
    Nope, Full RAM for that PIC.
     
    I assume you looked at this:
    http://ww1.microchip.com/...n/DeviceDoc/70348C.pdf
    #7
    Nikolay_Po
    Super Member
    • Total Posts : 1736
    • Reward points : 0
    • Joined: 2012/04/01 13:49:27
    • Location: Russia, Novorossiysk
    • Status: offline
    Re: UART transmitter + dma 2018/01/13 14:29:23 (permalink)
    0
    Also there a different approach may be applicable to avoid memcpy: instead of main and temporary buffers make them both the same range. One will be "Ping", another "Pong". Use the flag for downstream software which buffer is ready for the data exchange. AFAIK the DMA supports ping-pong mode.
    #8
    Shishi
    Super Member
    • Total Posts : 342
    • Reward points : 0
    • Joined: 2016/06/15 05:34:10
    • Location: 0
    • Status: offline
    Re: UART transmitter + dma 2018/01/15 02:49:44 (permalink)
    0
    why i should not put memcpy in ISR?
    #9
    Batgoy
    New Member
    • Total Posts : 29
    • Reward points : 0
    • Joined: 2004/06/15 04:33:51
    • Status: offline
    Re: UART transmitter + dma 2018/02/06 00:37:38 (permalink)
    0
    Also You have to enable DMA first, then initiate transmittion:
     
    DMA3CONbits.CHEN = 1; //DMA1_MODULE_ON
    DMA3REQbits.FORCE = 1; //DMA1_MANUAL
     
    #10
    RISC
    Super Member
    • Total Posts : 5355
    • Reward points : 0
    • Status: offline
    Re: UART transmitter + dma 2018/02/06 07:03:32 (permalink)
    0
    Hi,
    Herewith an example from an old Microchip Masters class for dsPIC33EP512MU810 which should be fairly easy to adapt to the dsPIC33EP512GM7810.
    Remove the .txt exension as it is a zip archive
    Regards
    #11
    Jump to:
    © 2018 APG vNext Commercial Version 4.5