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.

RM48 SCI DMA data loss problem

Other Parts Discussed in Thread: RM48L952, HALCOGEN

hello,

i'm using rm48L952 's sci/lin module to Receive 10 byte of data from a RS232<>USB transiver. my problem is that although MCU receive data,but dma transfers only 9 byte of data and first byte is lost. but in interrupt mode i receive all 10 bytes of data. so i think the problem is from DMA.

i use halcogen to config sci/lin module in {8Data /0Parity /1stop} data format and 460800 bps transfer speed.relevant interrupt enable flags has been set correctly. and configured dma using sys_dma.c library generated by halcogen. i use channel 0 for Transmit and it work correctly. channel 1 is used for receive

  • DMA setting (set channel 1 for receive):
DMAChannelConfig((CPU_INT32U)(&scilinREG->RD),        /*destination address*/
                  (uint32)&Receive[0],                  /*source address*/
                  (CPU_INT32U)SCI_BUFF,                 /*transfer length*/
                  recChannel,
                  28,                                   /*Request Line*/
                  ADDR_FIXED,                           /*read addressing mode*/
                  ADDR_INC1);
  
  startChannelTransfer(recChannel);
  
  SCI_RX_DMA_ENABLE;

  • DMAChannelConfig function:
DMAChannelConfig(CPU_INT32U sourceAddress,
                      CPU_INT32U destinationAddress,
                      CPU_INT32U blockLength,
                      CPU_INT32U channelNumber,
                      CPU_INT32U requestLineNumber,
                      CPU_INT32U readAddressMode,
                      CPU_INT32U writeAddressMode){
    
    dmaEnableInterrupt(channelNumber, BTC);    // enable interrupt after receipt of data
    
    dmaReqAssign(channelNumber, requestLineNumber);

    dmaCtrlPacket.SADD = sourceAddress;            // RAM address
    dmaCtrlPacket.DADD = destinationAddress;        // peripheral address
    dmaCtrlPacket.CHCTRL = 0;                        // channel control
    dmaCtrlPacket.FRCNT = blockLength;                    // source address length
    dmaCtrlPacket.ELCNT = 1;                        // 1 byte
    dmaCtrlPacket.ELDOFFSET = 0;                    // element destination offset
    dmaCtrlPacket.ELSOFFSET = 0;                    // element source offset
    dmaCtrlPacket.FRDOFFSET = 0;                    // frame destination offset
    dmaCtrlPacket.FRSOFFSET = 0;                    // frame source offset
    dmaCtrlPacket.PORTASGN = 4;                    // port b
    dmaCtrlPacket.RDSIZE = ACCESS_8_BIT;            // read element size
    dmaCtrlPacket.WRSIZE = ACCESS_8_BIT;            // write element size
    dmaCtrlPacket.TTYPE = FRAME_TRANSFER;            // transfer type: frame
    dmaCtrlPacket.ADDMODERD = readAddressMode;            // read address mode
    dmaCtrlPacket.ADDMODEWR = writeAddressMode;            // write address mode
    dmaCtrlPacket.COMBO = AUTOINIT_OFF;            // autoinit off

    dmaSetCtrlPacket(channelNumber, dmaCtrlPacket);
}

anyone has any idea about this problem?

  • Hello,

    is Receive a pointer to a 32-bit array?

    Can you change the below two lines to 32-bit and try again if your 'Receive' variable is a 32-bit array. Let me know if it makes a difference.

    dmaCtrlPacket.RDSIZE = ACCESS_32_BIT; // read element size
    dmaCtrlPacket.WRSIZE = ACCESS_32_BIT; // write element size
  • no, Receive is a pointer to 8-bit array.
    i changed transfer size to 32 bit, but the problem still exist and first byte is lost.
  • Can you change the below line

    DMAChannelConfig((CPU_INT32U)(&scilinREG->RD+3),

    I think it may have something to do with the endianism. Since you are doing a 8-bit transfer then you will need to give the proper byte address for the RD register which is at offset 0x3 from its word address. Give it a try and let me know if it makes a difference. 

  • i applyied this change. then i send 10 byte {'0', '1', ..., '9'} through terminal, but in the receive buffer, i get one byte with value of 0x04 and other 9 bytes remain unchanged.
    i had same problem with another microcontroller and i fixed it by enableing UART module's internal FIFO. but RM58 doesn't have such an option.
  • Hi,

     I didn't realize that you have a little endianism device. So what I told you about +3 is incorrect.

     Here I create a simple project for RM48 device using DMA to receive data from the terminal (9600, 8, 2, None, None). I'm able to receive what is typed on the terminal into the array receive_buffer. Attached is the project and the screenshot of the terminal and on data stored at the receive_buffer. Compare to what you have and hopefully you will find out what is wrong with your code.

    5141.RM48_UART_9600_Receive.zip

  • hi,
    i checked the project you have created, and found the problem.
    i think RM48 treats first byte of data as an address frame! because the only difference between your project and mine is that you have set RX DMA ALL bit of SCISETINT register. i just set this bit in my project and now it's working properly!!!
    do you have any idea why is it happening? COMM MODE bit in GCR1 register has been set to 0 in both projects.

    thanks for your help!