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.

Stumped! CC1110 UART / DMA Short Packet occasionally transmitted

We're currently transmitting 252 byte packets on UART 1, alt 2 at 460.800 kBaud. We occasionally see a short 251 byte packet being sent 1 every 100 pkts (16 pkts/sec)

The missing byte is in the middle of the packet.

We have captured the output of the CC1110 directly on a logic analyzer and are able to decode the short packet (we're 99.999% sure it's not the receiver).

The RF is running at 400.828125 kBaud (26.112 MHz osc.)

 

Anyone else seen something similar?

What would cause the DMA / USART1 to drop a byte in the middle of a DMA transfer?

What can we try fix the problem (we've tried all permutations on DMA priorities)?

 

Apart from the niggly little issue we're very impressed with the CC1110.

 

  • have you found any solution to this problem?...i am having the exact same issue..please provide assistance

    ali

  •  

    Hi Ali

    Can you please send me your code so that I can try to reproduce the problem? I do not need you complete application, just the UART code that generates the issue.

    The best thing is if you can send me a complete IAR project/workspace and a zip file with all the necessary files so that I can test something that is identical to what you are doing.

    BR

    Siri

  • Hi Ali

    Can you please clarify which workspace I am going to look at? In the uart_dma_mrfi_receive_backup folder there are two different work spaces. rf_modem.eww is the only one that compiles but I cannot find any UART_RX functionality there. The easiest would be if you send me a simple project that does the following:

    void main (void)

    {

    Init IO's

    Init UART

    Init DMA for RX

    receive packet

    }

    BR

    Siri

  • hey sir!

    oh come on why would the mrfi receive contain the UART RX code section...the other folder that says uart_dma_mrfi_backup contains the project that containt UART RX section and it contains the working project directory...the code was compiled with IAR 8.10...should work with any newer version of IAR workbench...either way it contains the source files for the whole project...kindly take a thorough look....the project path is as follows

    uart_bridge_backup/uart_dma_mrfi_backup/backup_9600/swrc088/srf_cc1110/ide/iar/

    please hurryyyyyy...i am stuck...:(

  • If the problem is UART communication from the PC to the CC1110 there is no need to debug a projct where you include encryption and RF communication.

    I used the UART example available from our website (http://www.ti.com/lit/zip/swrc117) and pasted in your code in the file called UART_CC111x_CC251x_DMA.c.

    I removed everything that has nothing to do with the UART communication and added some lines to make debugging easier.

    The code is shown below.

     

    /***********************************************************************************
    * INCLUDES
    */
    
    #include <hal_types.h>
    #include <hal_defs.h>
    #include <hal_cc8051.h>
    #include <ioCCxx10_bitdef.h>
    #include <dma.h>
    
    #if (chip == 2510)
    #include <ioCC2510.h>
    #endif
    #if (chip == 1110)
    #include <ioCC1110.h>
    #endif
    #if (chip == 2511)
    #include <ioCC2511.h>
    #endif
    #if (chip == 1111)
    #include <ioCC1111.h>
    #endif
    
    
    /***********************************************************************************
    * CONSTANTS
    */
    
    // Size of allocated UART RX/TX buffer (just an example)
    #define SIZE_OF_UART_RX_BUFFER 48
    
    // Baudrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11)
    #define UART_BAUD_M 131 //9600 
    #define UART_BAUD_E 8
    
    
    /***********************************************************************************
    * LOCAL VARIABLES
    */
    
    // Buffer+index for UART RX/TX
    static uint8 __xdata uartRxBuffer[SIZE_OF_UART_RX_BUFFER];
    
    // Variable for UART packet monitoring
    static uint8 __xdata uartPktReceived = 1;
    
    // DMA descriptor for UART RX/TX
    static DMA_DESC __xdata uartDmaRxTxCh[2];
    
    // Prototype for local functions
    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr,
    uint8 uartDmaRxChan,
    uint8* uartRxBuf,
    uint16 uartRxBufSize);
    
    void main (void)
    {
      // Initialise the allocated UART buffers:
      for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)
      {
        uartRxBuffer[i] = 0xff;
      }
    
      // configuration for mapping UART on SOC
      PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG;
      P0SEL |= BIT5 | BIT4 | BIT3 | BIT2;
    
      // Configure UART
        
      // Set system clock source to 26 Mhz XSOSC to support maximum transfer speed,
      // ref. [clk]=>[clk_xosc.c]
      SLEEP &= ~SLEEP_OSC_PD;
      while( !(SLEEP & SLEEP_XOSC_S) );
      CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1;
      while (CLKCON & CLKCON_OSC);
      SLEEP |= SLEEP_OSC_PD;
    
      // Initialise bitrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11)
      U0BAUD = UART_BAUD_M;
      U0GCR = (U0GCR&~U0GCR_BAUD_E) | UART_BAUD_E;
    
      // Initialise UART protocol (start/stop bit, data bits, parity, etc.):
    
      // USART mode = UART (U0CSR.MODE = 1)
      U0CSR |= U0CSR_MODE;
    
      // Start bit level = low => Idle level = high (U0UCR.START = 0)
      U0UCR &= ~U0UCR_START;
    
      // Stop bit level = high (U0UCR.STOP = 1)
      U0UCR |= U0UCR_STOP;
    
      // Number of stop bits = 1 (U0UCR.SPB = 0)
      U0UCR &= ~U0UCR_SPB;
    
      // Parity = disabled (U0UCR.PARITY = 0)
      U0UCR &= ~U0UCR_PARITY;
    
      // 9-bit data enable = 8 bits transfer (U0UCR.BIT9 = 0)
      U0UCR &= ~U0UCR_BIT9;
    
      // Level of bit 9 = 0 (U0UCR.D9 = 0), used when U0UCR.BIT9 = 1
      // Level of bit 9 = 1 (U0UCR.D9 = 1), used when U0UCR.BIT9 = 1
      // Parity = Even (U0UCR.D9 = 0), used when U0UCR.PARITY = 1
      // Parity = Odd (U0UCR.D9 = 1), used when U0UCR.PARITY = 1
      U0UCR &= ~U0UCR_D9;
    
      // Flow control = disabled (U0UCR.FLOW = 0)
      U0UCR &= ~U0UCR_FLOW;
    
      // Bit order = LSB first (U0GCR.ORDER = 0)
      U0GCR &= ~U0GCR_ORDER;
    
      while(1)
      {
        if(uartPktReceived)
        {
          uartPktReceived = 0;
          for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)
          {
            if (uartRxBuffer[i] == 0)
              while (1);
          }
          
          for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)
            uartRxBuffer[i] = 0;
          uart0StartRxDmaChan(&uartDmaRxTxCh[0], 1, uartRxBuffer,SIZE_OF_UART_RX_BUFFER);
        }
      }
    }
    
    /***********************************************************************************
    * @fn uart0StartRxForIsr
    *
    * @brief Function which sets up a DMA channel for UART0 RX.
    *
    * @param DMA_DESC *uartDmaRxDescr - pointer to DMA descriptor for UART RX
    * uint8 uartDmaRxChan - DMA channel number for UART RX
    * uint8* uartRxBuf - pointer to allocated UART RX buffer
    * uint16 uartRxBufSize - size of allocated UART RX buffer
    *
    * @return 0
    */
    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr, uint8 uartDmaRxChan, uint8* uartRxBuf, uint16 uartRxBufSize)
    {
      // Set source/destination pointer (UART RX buffer address) for UART RX DMA channel,
      // and total number of DMA word transfer (according to UART RX buffer size).
      uartDmaRxDescr->DESTADDRH = (uint16)uartRxBuf>>8;
      uartDmaRxDescr->DESTADDRL = (uint16)uartRxBuf;
      uartDmaRxDescr->SRCADDRH = ((uint16)(&X_U0DBUF) >> 8) & 0x00FF;
      uartDmaRxDescr->SRCADDRL = (uint16)(&X_U0DBUF) & 0x00FF;
      uartDmaRxDescr->LENH = (uartRxBufSize>>8)&0xFF;
      uartDmaRxDescr->LENL = uartRxBufSize&0xFF;
    
      uartDmaRxDescr->VLEN = DMA_VLEN_FIXED; // Use fixed length DMA transfer count
    
      // Perform 1-byte transfers
      uartDmaRxDescr->WORDSIZE = DMA_WORDSIZE_BYTE;
    
      // Transfer a single word after each DMA trigger
      uartDmaRxDescr->TMODE = DMA_TMODE_SINGLE;
    
      // DMA word trigger = USART0 RX complete
      uartDmaRxDescr->TRIG = DMA_TRIG_URX0; 
    
      //DMAREQ=0x02;
      
      uartDmaRxDescr->SRCINC = DMA_SRCINC_0; // Do not increment source pointer;
    
      // points to USART UxDBUF register.
      uartDmaRxDescr->DESTINC = DMA_DESTINC_1; // Increment destination pointer by
    
      // 1 word address after each transfer.
      uartDmaRxDescr->IRQMASK = DMA_IRQMASK_ENABLE; // Enable DMA interrupt to the CPU
      uartDmaRxDescr->M8 = DMA_M8_USE_8_BITS; // Use all 8 bits for transfer count
      uartDmaRxDescr->PRIORITY = DMA_PRI_LOW; // DMA memory access has low priority
    
      // Link DMA descriptor with its corresponding DMA configuration register.
      if (uartDmaRxChan < 1)
      {
        DMA0CFGH = (uint8)((uint16)uartDmaRxDescr>>8);
        DMA0CFGL = (uint8)((uint16)uartDmaRxDescr&0x00FF);
      } else {
        DMA1CFGH = (uint8)((uint16)uartDmaRxDescr>>8);
        DMA1CFGL = (uint8)((uint16)uartDmaRxDescr&0x00FF);
      }
      // Arm the relevant DMA channel for I2S RX, and apply 45 NOP's
      // to allow the DMA configuration to load
      //DMAARM = ((1 << uartDmaRxChan) & (BIT4 | BIT3 | BIT2 | BIT1 | BIT0));
      DMAARM |= DMAARM1;
    
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
      asm("NOP");asm("NOP");asm("NOP");
    
      // Enable the DMA interrupt (IEN1.DMAIE = IEN0.EA = 1),
      // and clear potential pending DMA interrupt requests (IRCON.DMAIF = 0)
      EA = 1; DMAIE = 1; DMAIF = 0;
    
      // Enable UARTx RX, clear any pending RX interrupt request and permit data flow:
      // Enable UART0 RX (U0CSR.RE = 1)
      U0CSR |= U0CSR_RE;
    
      // At this point the UART peripheral generates a DMA trigger each time it
      // has received a byte, leading to a DMA transfer from the UxDBUF register
      // to the allocated target buffer. Once the DMA controller has completed the
      // defined range of transfers, the CPU vectors its execution to the DMA ISR.
    }
    
    /***********************************************************************************
    * @fn DMA_ISR
    *
    * @brief DMA Interrupt Service Routine, called when DMA has finished
    * transferring one packet/buffer between memory and UxDBUF.
    *
    * @param none
    *
    * @return 0
    */
    #pragma vector = DMA_VECTOR
    
    __interrupt void DMA_ISR(void)
    {
    
      // Clear the main DMA interrupt Request Flag (IRCON.DMAIF = 0)
      DMAIF = 0;
    
      // Start a new UART RX session on DMA channel 1:
      if (DMAIRQ & DMAIRQ_DMAIF1)
      {
        // Indicate UART packet received (monitored by main-loop for data integrity/error check
        uartPktReceived = 1;
    
        // Clear DMA Channel 0 Interrupt Request Flag (DMAIRQ.DMAIF = 0)
        DMAIRQ &= ~DMAIRQ_DMAIF1;
    
        // Re-arm DMA Channel 1 (DMAARM.DMAARM0 = 1)
        //DMAARM |= DMAARM1;
      }
    }
    

    When running this code the uartRxBuffer will be filled with 0’s before the DMA is armed. Once I get the interrupt I check that all 48 bytes are received.

    From the PC I sent 48 bytes every time I pressed a button. I sent several hundred packets and where not able to get it to fail.

    I assume you do the same exercise to make sure that the problem I related to the UART, as you suspect, and not to something else.

    When you experience problems like this it is always a good idea to break down the project into smaller pieces (UART, AES, RF) and then test them thoroughly before putting them together in a bigger application.

  • Hi

    Unfortunately I have problems running your code as well, something that makes it hard for me to help you as I cannot run the same thing here as you are doing. I am still not sure how you detect that your system fails. First you said that when you were sending 48 bytes from the PC over UART, only 47 was received on the EB. Now you have confirmed that your UART is working OK, but you still have bytes “missing”. Where are they missing from?

    What I would recommend that you do is to take one step back. Use the CC1110 code example from the web as I referred to in my last post and use that as a starting point.

    I would start by implementing the RF link- Send 48 bytes between the two EBs with the register settings you have chosen and confirm that the link is good. When this works fine, implement/add the UART. Transmit 48 bytes from the PC to the EB. Confirm that the data is OK. Transmit the data over RF link and confirm that they are received OK. Transmit the data from the EB to the PC over UART, and confirm again. I you are using DMA for the RF communication I would recommend that you not use it for the UART communication at first (or vice versa). When you have something up and running you can implement DMA for both UART and RF. There is a possibility that your problems might be DMA related if every module works separately but not when put together. When this step is completed and everything works satisfying, you can add AES.

    Siri

  • hello!

    i dont understand why the code is not working for you?..perhaps its something related to which version of IAR you are using....you need to have atleast IAR 8.10 of later to run the project properly....and to check the working of the system....you can use the hex file generated from uart_mrfi_dma as transmitter and hex file generated from uart_mrfi_dma_receiver folder as receiver and burn both hex files on different smartrf04 evaluation boards mounted with CC1110 EMs and connect a uart cable with both boards and then send continous 48 bytes from transmitter and receive it on the receiver in hyper terminal at 9600 bps...encryption and decryption has been taken care of...while the system runs perfectly 99% of the times....its just an occasional single byte that gets missed out....you can read the original post made a few years ago....read it again...that is the exact issue that i am facing...that guy's code and mine might be completely different but the problem is exactly similar....

    please provide assistance and advice

    best regards

    Ali

  • Hi Ali

    The code compiles but I get error messages when trying download and run it. I do not know why this is happening, but it is, and I have not the time to make the project from scratch to make it run. Downloading some hex files will not enable me to help you in any way as I need code that I can run through the debugger to be able to see where the problem is.

    Unfortunately we do not have the resources/bandwidth to debug all problems as they are presented to us from the customers. We need the help from you in this process to be able to help as many as possible.

    I have asked you to take a step back and given you advice on how to debug this. For me to help you I need you to take a project that runs and can be debugged without problem. For this I have recommended that you use the UART example on the web.

    You should then try the different steps I explained in my previous post.

    When you have some code you can share with me (that can be debugged) I can take a look at it.

    I then will need some more details on what is failing. Still not clear to me how/where you detect that a byte is missing (from PC to EB via UART, from EB to EB via RF, or from EB to PC via UART).

    If you are transmitting 48 bytes from the PC and only receive 47 on the other PC you need to divide your link down to smaller elements to see where it fails.

    I am sorry that I could not be of any more help at the moment.

    BR

    Siri

  • hellow there!

    i know its been a long while since i last posted because i found the exact cause to the problem and moved on with a temporary solution onto next things in the project...the problem was with the uart TX routine once the data has been received at the rf receiver end....the data is sent perfectly from transmitter and is received error free at the receiver.....my UART at rf transmitter side was running at 9600 bps....and 9600 as well at the rf receiver side....once i switched my uart at rf receiver side which receives data over the air and sends it to PC from 9600 to 14400 or 19200...the missing byte issue is resolved....and the data is received perfectly fine....this is beyond me and i have no idea why this is happening.....:/...i need 9600 bps at the rf receiver end as well....switching to higher baud rate for UART TX DMA routine temporarily solves the problem but doesnt satisfy project needs that i am supposed to follow....

    more over i am facing a problem using DMA Channel 2 to use USART 1 ALT 2 location in UART mode....i ve followed what was written in the following post:

    http://e2e.ti.com/support/wireless_connectivity/f/155/t/351373.aspx

    but it hasnt solved my problem....let me share my code with you,its a pseudo code but i will be more specific and careful in stating the variables that matter in the dma channel 2 operation...find the code in the next post

    best regards

    ali

  • // Size of allocated UART RX/TX buffer (just an example)
    #define SIZE_OF_UART_RX_BUFFER1 16
    #define SIZE_OF_UART_RX_BUFFER2 16

    // Variables for UART packet monitoring
    static uint8 __xdata uartPktReceived1 = 1;
    static uint8 __xdata uartPktReceived2 = 1;
    // DMA descriptor for UART RX/TX
    static DMA_DESC __xdata uartDmaRxTxCh[2];

    // Prototype for local functions


    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr1,
    uint8 uartDmaRxChan1,
    uint8* uartRxBuf1,
    uint16 uartRxBufSize1);


    void uart1StartRxDmaChan( DMA_DESC *uartDmaRxDescr2,
    uint8 uartDmaRxChan2,
    uint8* uartRxBuf2,
    uint16 uartRxBufSize2);

    void main (void)
    {


    //mapping uart0 on soc

    //assigning values to percfg for setting usart0 using uart0 at ALT 1 location

    //assigning values to set usart 0 baud rate at 9600 bps

    //configuring uart 0


    //mapping uart1 on soc

    //assigning values to percfg for setting usart1 using uart1 at ALT 2 location

    //assigning values to set usart 1 baud rate at 9600 bps

    //configuring uart 1


    while(1)

    {

    if(uartPktReceived1)

    {

    uartPktReceived1 = 0;

    uart0StartRxDmaChan(&uartDmaRxTxCh[0], 1, uartRxBuffer1,SIZE_OF_UART_RX_BUFFER1);

    toggle_led(); //just to check if data on any uart has been received

    }

    if(uarpktReceived2)

    {

    uartPktReceived2 = 0;

    uart1StartRxDmaChan(&uartDmaRxTxCh[1], 2, uartRxBuffer2,SIZE_OF_UART_RX_BUFFER2);

    toggle_led(); //just to check if data on any uart has been received


    }

    }

    }

    static void toggle_led(void)

    {

    halLedToggle(3);

    }


    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr1,
    uint8 uartDmaRxChan1,
    uint8* uartRxBuf1,
    uint16 uartRxBufSize1)
    {

    // Set source/destination pointer (UART RX buffer address) for UART RX DMA channel,
    // and total number of DMA word transfer (according to UART RX buffer size).
    uartDmaRxDescr1->DESTADDRH = (uint16)uartRxBuf>>8;
    uartDmaRxDescr1->DESTADDRL = (uint16)uartRxBuf;
    uartDmaRxDescr1->SRCADDRH = ((uint16)(&X_U0DBUF) >> 8) & 0x00FF;
    uartDmaRxDescr1->SRCADDRL = (uint16)(&X_U0DBUF) & 0x00FF;
    uartDmaRxDescr1->LENH = (uartRxBufSize>>8)&0xFF;
    uartDmaRxDescr1->LENL = uartRxBufSize&0xFF;

    uartDmaRxDescr1->VLEN = DMA_VLEN_FIXED; // Use fixed length DMA transfer count

    // Perform 1-byte transfers
    uartDmaRxDescr1->WORDSIZE = DMA_WORDSIZE_BYTE;

    // Transfer a single word after each DMA trigger
    uartDmaRxDescr1->TMODE = DMA_TMODE_SINGLE;

    // DMA word trigger = USART0 RX complete
    uartDmaRxDescr1->TRIG = DMA_TRIG_URX0;

    uartDmaRxDescr1->SRCINC = DMA_SRCINC_0; // Do not increment source pointer;
    // points to USART UxDBUF register.
    uartDmaRxDescr1->DESTINC = DMA_DESTINC_1; // Increment destination pointer by
    // 1 word address after each transfer.
    uartDmaRxDescr1->IRQMASK = DMA_IRQMASK_ENABLE; // Enable DMA interrupt to the CPU
    uartDmaRxDescr1>M8 = DMA_M8_USE_8_BITS; // Use all 8 bits for transfer count
    uartDmaRxDescr1->PRIORITY = DMA_PRI_LOW; // DMA memory access has low priority


    DMA1CFGH = (uint8)((uint16)uartDmaRxDescr>>8);
    DMA1CFGL = (uint8)((uint16)uartDmaRxDescr&0x00FF);


    DMAARM |= DMAARM1;

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");


    EA = 1; DMAIE = 1; DMAIF = 0;


    U0CSR |= U0CSR_RE;

    }


    void uart1StartRxDmaChan( DMA_DESC *uartDmaRxDescr2,
    uint8 uartDmaRxChan2,
    uint8* uartRxBuf2,
    uint16 uartRxBufSize2)
    {

    // Set source/destination pointer (UART RX buffer address) for UART RX DMA channel,
    // and total number of DMA word transfer (according to UART RX buffer size).
    uartDmaRxDescr2->DESTADDRH = (uint16)uartRxBuf>>8;
    uartDmaRxDescr2->DESTADDRL = (uint16)uartRxBuf;
    uartDmaRxDescr2->SRCADDRH = ((uint16)(&X_U1DBUF) >> 8) & 0x00FF;
    uartDmaRxDescr2->SRCADDRL = (uint16)(&X_U1DBUF) & 0x00FF;
    uartDmaRxDescr2->LENH = (uartRxBufSize>>8)&0xFF;
    uartDmaRxDescr2->LENL = uartRxBufSize&0xFF;

    uartDmaRxDescr2->VLEN = DMA_VLEN_FIXED; // Use fixed length DMA transfer count

    // Perform 1-byte transfers
    uartDmaRxDescr2->WORDSIZE = DMA_WORDSIZE_BYTE;

    // Transfer a single word after each DMA trigger
    uartDmaRxDescr2->TMODE = DMA_TMODE_SINGLE;

    // DMA word trigger = USART0 RX complete
    uartDmaRxDescr2->TRIG = DMA_TRIG_URX1;


    uartDmaRxDescr2->SRCINC = DMA_SRCINC_0; // Do not increment source pointer;
    // points to USART UxDBUF register.
    uartDmaRxDescr2->DESTINC = DMA_DESTINC_1; // Increment destination pointer by
    // 1 word address after each transfer.
    uartDmaRxDescr2->IRQMASK = DMA_IRQMASK_ENABLE; // Enable DMA interrupt to the CPU
    uartDmaRxDescr2->M8 = DMA_M8_USE_8_BITS; // Use all 8 bits for transfer count
    uartDmaRxDescr2->PRIORITY = DMA_PRI_LOW; // DMA memory access has low priority


    DMA1CFGH = (uint8)((uint16)uartDmaRxDescr2>>8);
    DMA1CFGL = (uint8)((uint16)uartDmaRxDescr2&0x00FF);


    DMAARM |= DMAARM2;

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
    asm("NOP");asm("NOP");asm("NOP");


    EA = 1; DMAIE = 1; DMAIF = 0;

    U1CSR |= U1CSR_RE;

    }


    /***********************************************************************************
    * @fn DMA_ISR

    #pragma vector = DMA_VECTOR

    __interrupt void DMA_ISR(void)
    {

    DMAIF = 0;


    if (DMAIRQ & DMAIRQ_DMAIF1)
    {
    // Indicate UART packet received (monitored by main-loop for data integrity/error check
    uartPktReceived1 = 1;

    // Clear DMA Channel 1 Interrupt Request Flag (DMAIRQ.DMAIF = 0)
    DMAIRQ &= ~DMAIRQ_DMAIF1;

    }


    if (DMAIRQ & DMAIRQ_DMAIF2)
    {
    // Indicate UART packet received (monitored by main-loop for data integrity/error check
    uartPktReceived2 = 1;

    // Clear DMA Channel 2 Interrupt Request Flag (DMAIRQ.DMAIF = 0)
    DMAIRQ &= ~DMAIRQ_DMAIF2;

    }


    }

  • Hi Ali

     

    Below is the same example as I have shared with you before but modified to use Channel 2 for UART RX. THe USART is the same as USART1, Alt 2 is not available on the SmartRF04EB.

    /***********************************************************************************

    * INCLUDES

    */

     

    #include <hal_types.h>

    #include <hal_defs.h>

    #include <hal_cc8051.h>

    #include <ioCCxx10_bitdef.h>

    #include <dma.h>

     

    #if (chip == 2510)

    #include <ioCC2510.h>

    #endif

    #if (chip == 1110)

    #include <ioCC1110.h>

    #endif

    #if (chip == 2511)

    #include <ioCC2511.h>

    #endif

    #if (chip == 1111)

    #include <ioCC1111.h>

    #endif

     

     

    /***********************************************************************************

    * CONSTANTS

    */

     

    // Size of allocated UART RX/TX buffer (just an example)

    #define SIZE_OF_UART_RX_BUFFER 48

     

    // Baudrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11)

    #define UART_BAUD_M 131 //9600

    #define UART_BAUD_E 8

     

     

    /***********************************************************************************

    * LOCAL VARIABLES

    */

     

    // Buffer+index for UART RX/TX

    static uint8 __xdata uartRxBuffer[SIZE_OF_UART_RX_BUFFER];

     

    // Variable for UART packet monitoring

    static uint8 __xdata uartPktReceived = 1;

     

    // DMA descriptor for UART RX/TX

    __xdata __no_init DMA_DESC dummyCh @ 0xF018; // Struct for the DMA channel 1 config.

    __xdata __no_init DMA_DESC uartDmaRxTxCh[2] @ 0xF020; // Struct for the DMA channel 2 and 3 config.

     

    // Prototype for local functions

    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr,

    uint8 uartDmaRxChan,

    uint8* uartRxBuf,

    uint16 uartRxBufSize);

     

    void main (void)

    {

    // Initialise the allocated UART buffers:

    for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)

    {

       uartRxBuffer[i] = 0xff;

    }

     

    // configuration for mapping UART on SOC

    PERCFG = (PERCFG & ~PERCFG_U0CFG) | PERCFG_U1CFG;

    P0SEL |= BIT5 | BIT4 | BIT3 | BIT2;

     

    // Configure UART

      

    // Set system clock source to 26 Mhz XSOSC to support maximum transfer speed,

    // ref. [clk]=>[clk_xosc.c]

    SLEEP &= ~SLEEP_OSC_PD;

    while( !(SLEEP & SLEEP_XOSC_S) );

    CLKCON = (CLKCON & ~(CLKCON_CLKSPD | CLKCON_OSC)) | CLKSPD_DIV_1;

    while (CLKCON & CLKCON_OSC);

    SLEEP |= SLEEP_OSC_PD;

     

    // Initialise bitrate = 57.6 kbps (U0BAUD.BAUD_M = 34, U0GCR.BAUD_E = 11)

    U0BAUD = UART_BAUD_M;

    U0GCR = (U0GCR&~U0GCR_BAUD_E) | UART_BAUD_E;

     

    // Initialise UART protocol (start/stop bit, data bits, parity, etc.):

     

    // USART mode = UART (U0CSR.MODE = 1)

    U0CSR |= U0CSR_MODE;

     

    // Start bit level = low => Idle level = high (U0UCR.START = 0)

    U0UCR &= ~U0UCR_START;

     

    // Stop bit level = high (U0UCR.STOP = 1)

    U0UCR |= U0UCR_STOP;

     

    // Number of stop bits = 1 (U0UCR.SPB = 0)

    U0UCR &= ~U0UCR_SPB;

     

    // Parity = disabled (U0UCR.PARITY = 0)

    U0UCR &= ~U0UCR_PARITY;

     

    // 9-bit data enable = 8 bits transfer (U0UCR.BIT9 = 0)

    U0UCR &= ~U0UCR_BIT9;

     

    // Level of bit 9 = 0 (U0UCR.D9 = 0), used when U0UCR.BIT9 = 1

    // Level of bit 9 = 1 (U0UCR.D9 = 1), used when U0UCR.BIT9 = 1

    // Parity = Even (U0UCR.D9 = 0), used when U0UCR.PARITY = 1

    // Parity = Odd (U0UCR.D9 = 1), used when U0UCR.PARITY = 1

    U0UCR &= ~U0UCR_D9;

     

    // Flow control = disabled (U0UCR.FLOW = 0)

    U0UCR &= ~U0UCR_FLOW;

     

    // Bit order = LSB first (U0GCR.ORDER = 0)

    U0GCR &= ~U0GCR_ORDER;

     

    while(1)

    {

       if(uartPktReceived)

       {

         uartPktReceived = 0;

         for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)

         {

           if (uartRxBuffer[i] == 0)

             while (1);

         }

        

         for (uint8 i = 0; i < SIZE_OF_UART_RX_BUFFER; i++)

           uartRxBuffer[i] = 0;

         uart0StartRxDmaChan(&uartDmaRxTxCh[0], 1, uartRxBuffer,SIZE_OF_UART_RX_BUFFER);

       }

    }

    }

     

    /***********************************************************************************

    * @fn uart0StartRxForIsr

    *

    * @brief Function which sets up a DMA channel for UART0 RX.

    *

    * @param DMA_DESC *uartDmaRxDescr - pointer to DMA descriptor for UART RX

    * uint8 uartDmaRxChan - DMA channel number for UART RX

    * uint8* uartRxBuf - pointer to allocated UART RX buffer

    * uint16 uartRxBufSize - size of allocated UART RX buffer

    *

    * @return 0

    */

    void uart0StartRxDmaChan( DMA_DESC *uartDmaRxDescr, uint8 uartDmaRxChan, uint8* uartRxBuf, uint16 uartRxBufSize)

    {

    // Set source/destination pointer (UART RX buffer address) for UART RX DMA channel,

    // and total number of DMA word transfer (according to UART RX buffer size).

    uartDmaRxDescr->DESTADDRH = (uint16)uartRxBuf>>8;

    uartDmaRxDescr->DESTADDRL = (uint16)uartRxBuf;

    uartDmaRxDescr->SRCADDRH = ((uint16)(&X_U0DBUF) >> 8) & 0x00FF;

    uartDmaRxDescr->SRCADDRL = (uint16)(&X_U0DBUF) & 0x00FF;

    uartDmaRxDescr->LENH = (uartRxBufSize>>8)&0xFF;

    uartDmaRxDescr->LENL = uartRxBufSize&0xFF;

     

    uartDmaRxDescr->VLEN = DMA_VLEN_FIXED; // Use fixed length DMA transfer count

     

    // Perform 1-byte transfers

    uartDmaRxDescr->WORDSIZE = DMA_WORDSIZE_BYTE;

     

    // Transfer a single word after each DMA trigger

    uartDmaRxDescr->TMODE = DMA_TMODE_SINGLE;

     

    // DMA word trigger = USART0 RX complete

    uartDmaRxDescr->TRIG = DMA_TRIG_URX0;

    uartDmaRxDescr->SRCINC = DMA_SRCINC_0; // Do not increment source pointer;

     

    // points to USART UxDBUF register.

    uartDmaRxDescr->DESTINC = DMA_DESTINC_1; // Increment destination pointer by

     

    // 1 word address after each transfer.

    uartDmaRxDescr->IRQMASK = DMA_IRQMASK_ENABLE; // Enable DMA interrupt to the CPU

    uartDmaRxDescr->M8 = DMA_M8_USE_8_BITS; // Use all 8 bits for transfer count

    uartDmaRxDescr->PRIORITY = DMA_PRI_LOW; // DMA memory access has low priority

     

    // Link DMA descriptor with its corresponding DMA configuration register.

    DMA1CFGH = (uint8)((uint16)&dummyCh>>8);

    DMA1CFGL = (uint8)((uint16)&dummyCh&0x00FF);

    // Arm the relevant DMA channel for I2S RX, and apply 45 NOP's

    // to allow the DMA configuration to load

    //DMAARM = ((1 << uartDmaRxChan) & (BIT4 | BIT3 | BIT2 | BIT1 | BIT0));

    DMAARM |= DMAARM2;

     

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");

    asm("NOP");asm("NOP");asm("NOP");

     

    // Enable the DMA interrupt (IEN1.DMAIE = IEN0.EA = 1),

    // and clear potential pending DMA interrupt requests (IRCON.DMAIF = 0)

    EA = 1; DMAIE = 1; DMAIF = 0;

     

    // Enable UARTx RX, clear any pending RX interrupt request and permit data flow:

    // Enable UART0 RX (U0CSR.RE = 1)

    U0CSR |= U0CSR_RE;

     

    // At this point the UART peripheral generates a DMA trigger each time it

    // has received a byte, leading to a DMA transfer from the UxDBUF register

    // to the allocated target buffer. Once the DMA controller has completed the

    // defined range of transfers, the CPU vectors its execution to the DMA ISR.

    }

     

    /***********************************************************************************

    * @fn DMA_ISR

    *

    * @brief DMA Interrupt Service Routine, called when DMA has finished

    * transferring one packet/buffer between memory and UxDBUF.

    *

    * @param none

    *

    * @return 0

    */

    #pragma vector = DMA_VECTOR

     

    __interrupt void DMA_ISR(void)

    {

    // Clear the main DMA interrupt Request Flag (IRCON.DMAIF = 0)

    DMAIF = 0;

     

    // Start a new UART RX session on DMA channel 2:

    if (DMAIRQ & DMAIRQ_DMAIF2)

    {

       // Indicate UART packet received (monitored by main-loop for data integrity/error check

       uartPktReceived = 1;

     

       // Clear DMA Channel 2 Interrupt Request Flag (DMAIRQ.DMAIF = 0)

       DMAIRQ &= ~DMAIRQ_DMAIF2;

    }

    }

    BR

    Siri

  • i ve tried this code...it just wont run....dont know why....no idea at all...dma channel 0 and dma channel 1 work perfectly fine..but the dma channel 2 just wont work when using USART0 AND USART1...and btw there is ALT2 on SMARTRF04EB...i ve ran it myself using dma channel 0
  • Hi

    USART1, Alt 2. uses pin p1.6 and P1.7. On SmartRF04EB these pins are connected to SPI MOSI and MISO. If you want to talk to a PC over UART, you need to use USART0, Alt. 1 which uses P0.3 and P0.2, as these are the pins connected to the RS232 interface. Not sure how you have been able to communicate with a PC using UART1, Alt. 2 without modifying the HW.

    I cannot understand why the code example does not work for you. I take the code example from the web and replace the UART_CC111x_CC251x_DMA.c with the code posted yesterday and it communicate well with a PC (using DMA channel 2).

    When running the example have you made sure that DMA1CFGH = 0xF0 and DMA1CFGL = 0x18?

    Are uartDmaRxTxCh[0] placed at 0x0F20 and is the struct. set up correctly?

    Telling me that thing does not work without giving me more details does not enable me to help you as everything runs OK here.

    Siri

  • i was able to run USART1 ALT2 by first converting the CMOS(TTL Logic) level to RS232 level (-12v to 12v) before feeding it to the PC UART...well thats not under discussion right now....and trust me what you have told me is exactly what i ve done too....well why dont you try both uarts at the same time...and maybe then see how it fares....well i took a fresh UART_DMA_251x.c file and then did some changes in it....fed DMA1CGFH and DMA1CFGL with uartdmatxrx[0] and armed the DMA1 and then fed DMA1CGFH and DMA1CFGL with uartdmatxrx[1] and armed DMA2....well the good news is that the the UART on my PC has an LED and it flickers when i receives some data over UART....whenever i press S1 on SMARTRF04EB...the light flickers when using DMA Channel 2 but no data on the terminal window....this is beyond me though...i will check my hardware again....and will let you know if i find a solution....
    secondly what about the temporary solution i found to my problem of need of a higher data rate...read my previous posts....
    please advise!
    best regards and sorry for bothering you time and over again...but i really need help...

    Ali
  • As I told you in the previous post, it is not possible to test USART1, Alt 2. on the SmartRF04EB board without doing changes to the HW. I have not the possibility to make changes to the boards, so I cannot do a test with 2 USARTS.

    I also think that you need to focus at one problem at the time. The first problem you described was that you could not make DMA channel 2 to work.

    To debug this problem there is no need to complicate things by modifying HW and running two USARTS at the same time.

    Start by running 1 DMA channel (DMA channel 2) on USART0, Alt. 1. The code posted last time shows how this is done. I do not understand why this does not work for you so I have included my complete project for you. When this runs OK you can change the USART0 to USART1 if you have HW to support this, and when this is up and running you can start by using two USART and two DMA channels if this is what you want.

    Unfortunately I do not have an answer to your question regarding why you have to increase the baud rate to get rid of your problem at 9600 baud, as I am not able to reproduce the problem here.cc1110_UART_DMA.zip