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.

HAL_UART with DMA troubleshooting

Other Parts Discussed in Thread: CC2540, CC2541

I spent days combing through old posts regarding HAL_UART with DMA support and I've finally reached a dead end. I'd really appreciate it if someone could take a look at my brief code and see if there is anything unusual about what I'm doing?  Thanks!

I've taken the keyfob code and commented out everything just to get uart communications working.  I've got a scope hooked to P0.4 (pin 15) and P1.5 (pin 5)

My preprocessor definitions are as follows:

HAL_UART
HAL_UART_DMA=1
HAL_UART_ISR=0
HAL_DMA=TRUE

and my main function looks like this:

int main(void){

  P0SEL = 0x30;
  P1SEL = 0x30; 
  P2SEL = 0; // Configure Port 2 as GPIO
  P0DIR = 0xEF; // Port 0 pins P0.0 and P0.1 as input (buttons),
                // all others (P0.2-P0.7) as output
  P1DIR = 0xEF; 
  P2DIR = 0x1F; 
  
  P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
  P1 = 0;   // All pins on port 1 to low
  P2 = 0;   // All pins on port 2 to low  
  
  
  
  halUARTCfg_t uartConfig;
  // configure UART
  uartConfig.configured           = TRUE;
  uartConfig.baudRate             = HAL_UART_BR_9600;
  uartConfig.flowControl          = FALSE;
  uartConfig.flowControlThreshold = 48;
  uartConfig.rx.maxBufSize        = 128;
  uartConfig.tx.maxBufSize        = 1287;
  uartConfig.idleTimeout          = 6;
  uartConfig.intEnable            = TRUE;
  uartConfig.callBackFunc         = NULL; //sbpSerialPacketParser;
  PERCFG |= 0x01;
  HalUARTInit(); 
  HalUARTOpen( HAL_UART_PORT_0, &uartConfig );
  while(1){
     //constantly write
      HalUARTWrite (HAL_UART_PORT_0, 0x55, 1);
  }
} //end main
  • Jonathan Cohn said:
      uartConfig.tx.maxBufSize        = 1287;

    what about the 1287 in the end, instead of 128?

  • Hey Igor,

    I see that was probably a typo on my end, but it didn't help. So far, i've only been trying to get TX working and wont work on RX until I can at least get some messages to appear on the UART.

    Any other suggestions?

  • Before I dive in, could you please tell me what is the HW you are using (EBs, DKs, etc..)?

    Any information is helpful at this point.

    Besides, have you followed the DN112?

    Meanwhile I'll try to think of something... :)

  • Hey Igor,

    So I'm using the keyfob hardware, probing on the Test header pin 2 for Port 1 TX and the Debug header Pin 5 for Port 0 TX.

    I have followed DN112, but I am currently looking through it again in case i missed something.

    Thanks again for all your help, I do appreciate it.

  • Some other information...

    I put some watches on certain registers to help debug.

    P0SEL = 0x30

    P0DIR = 0xEF

    P1SEL = 0x30

    P1DIR = 0xEF

    PERCFG = 0x03

    U0CSR = 0xC4

    U1CSR = 0x80

    IEN2 = 0x00

    IEN0 = 0x00

    IEN1 = 0x00

  • Ok,

    Let's try this step by step.

    By studying the Keyfob schematics and CC253x/4x I/O mapping the best choice for you is to use UART1,

    since in alternative mapping 2 the TX and RX pins are P1.6 and P1.7 respectively. P1.6 connected to "+"

    of the buzzer and P1.7 is pin #4 on test header.

    The following is the configuration of I/Os for UART1 in alternative 2 location:

    instead of all this

    Jonathan Cohn said:
      P0SEL = 0x30;
      P1SEL = 0x30; 
      P2SEL = 0; // Configure Port 2 as GPIO
      P0DIR = 0xEF; // Port 0 pins P0.0 and P0.1 as input (buttons),
                    // all others (P0.2-P0.7) as output
      P1DIR = 0xEF; 
      P2DIR = 0x1F; 
      
      P0 = 0x03; // All pins on port 0 to low except for P0.0 and P0.1 (buttons)
      P1 = 0;   // All pins on port 1 to low
      P2 = 0;   // All pins on port 2 to low  

    try to put only this:

    PERCFG |= 0x02; // Set UART1 Alternative 2 location

    P1SEL |= 0xC0; // Set P1.6 an P1.7 to peripheral function (at this point let's put aside the flow control)


    Try to test it with these settings. If it still doesn't work, the next thing would be to write

    a straight forward code w/o functions.

    Tomorrow I'll have a look on the configuration of UART and DMA of yours.

  • Good morning Igor,

    I agree, that configuration would work best.  I replaced the entire main function with the following:

    int main(void){
    PERCFG |= 0x02;
    P1SEL |= 0xC0;

    halUARTCfg_t uartConfig;
    // configure UART
    uartConfig.configured = TRUE;
    uartConfig.baudRate = HAL_UART_BR_9600;
    uartConfig.flowControl = FALSE;
    uartConfig.flowControlThreshold = 48;
    uartConfig.rx.maxBufSize = 1287;
    uartConfig.tx.maxBufSize = 1287;
    uartConfig.idleTimeout = 6;
    uartConfig.intEnable = TRUE;
    uartConfig.callBackFunc = NULL; //sbpSerialPacketParser;

    HalUARTInit();
    HalUARTOpen( HAL_UART_PORT_1, &uartConfig );
    unsigned char myByte = 0x55;
    while(1){
    //constantly write
    HalUARTWrite (HAL_UART_PORT_1, &myByte, 1);
    }


    return 0;
    }

    And still, no data being transmitted. hence no buzzer noises.  

    My preprocessor defined symbols are:

    HAL_UART
    HAL_UART_DMA=2
    HAL_UART_ISR=0
    HAL_DMA=TRUE
    OSAL_CBTIMER_NUM_TASKS=1
    HAL_AES_DMA=FALSE
    POWER_SAVING
    xPLUS_BROADCASTER
    HAL_LCD=FALSE
    HAL_LED=TRUE
    CC2540_MINIDK

    It's as if there are things in the keyfob project that are conflicting with uart hal driver. I can't see how there is anything else but the main function running, since i've commented it all out, including the osal

  • Hi,

    Good morning (actually afternoon here in Israel). :)

    So, two things:


    1. Jonathan Cohn said:
      uartConfig.rx.maxBufSize = 1287;
      uartConfig.tx.maxBufSize = 1287;

      Is there any particular reason you want to allocate such enormous buffers?
      Keep it around 128, it's enough for debugging purposes.
       
    2. Have you tried to operate with uaRT w/o the DMA?
      DMA is a complicated mechanism, so let's try to put it aside and deeal with UART first.
      At this point you have to be sure that the UART configs are correct and you are able to
      transmit (and receive) data.
      Once UART is fully operational w/o the usage of DMA, then you can move forward and
      add DMA functionality.
  • Where in Israel? I visited Israel last summer for two weeks.  Turns out, the desert is kind of hot in the summer.

    So there was no reason for such a large buffer. I knocked it down to 128.

    I have not tried UART with ISR yet, so i made the following changes to my precompiled defines: 

    HAL_UART
    HAL_UART_ISR=2
    HAL_DMA=FALSE

    And of course, still no luck (no buzzer and no signal with the probe attached).

    My watches are also showing:

    PERCFG = 0x02
    P1SEL = 0xC0
    P1 = 7F
    P1DIR = 0x00  //i also set P1DIR=0xFF and tried it like that, but still no luck. 

  • I'm not sure if you have the TI CC2540MINIDK_EM keyfob, but if you do, maybe this will help

    Basic IAR project I've created: https://www.dropbox.com/s/yrss3pbe7fhalpy/KeyFob3.zip

    (it's a subset of the original keyfob project found in the C:\Texas Instruments\BLE-CC254x-1.2.1\Projects\ble folder)

  • Hi,

    I'm from the North of Israel, it's nice here. :)

    I must take you a few steps back, try to run this code if it works then you can proceed to the next step:

    int main(void)
    {
    PERCFG |= 0x02; // Set UART1 to Alternative 2 location
    P1SEL |= 0xC0; // Set P1.6 and P1.7 to Peripheral function
     
    U1CSR |= 0x80;  // USART mode = UART (U1CSR.MODE = 1) 
    U1UCR |= 0x01; // Start bit level = high => Idle level = low (U1UCR.START = 1) 
    U1UCR &= ~0x02; // Stop bit level = low (U1UCR.STOP = 0) 
    U1UCR &= ~0x04; // Number of stop bits = 1 (U1UCR.SPB = 0) 
    U1UCR |= 0x08; // Parity = enabled (U1UCR.PARITY = 1)  
    U1UCR &= ~0x10; // 9-bit data disable = 8 bits transfer (U1UCR.BIT9 = 0) 
    U1UCR |= 0x20; // Parity = Even (U1UCR.D9 = 0)
    U1UCR &= ~0x40; // Flow control = disabled (U1UCR.FLOW = 0)
    U1GCR &= ~0x20; // Bit order = LSB first (U1GCR.ORDER = 0) => For PC/Hyperterminal
    U1BAUD = 59; // BAUD_M = 59 and BAUD_E = 8 => Baud rate of 9600
    U1GCR &= ~0x1F; // Clear BAUD_E bits
    U1GCR |= 0x08; // BAUD_E = 8
     
    uint8 cntr = 0; 
    UTX1IF = 0; 
    while(1) {
    if( cntr % 2 )
    U1DBUF = 0x55;
    else
    U1DBUF = 0xAA;
    while( !UTX1IF ); 
    UTX1IF = 0;
    for( uint8 i=0; i<10; i++ )
    asm("NOP");
    }
     
    return 0;
    }
  • Hey Igor, I will try that tonight, thank you for the idea.

    Meanwhile, I was digging around in _hal_uart_dma.c and found something interesting.  There is a define section that is based on what the hal_uart_dma definition is set to:

    #if (HAL_UART_DMA == 1)
    #define HAL_UART_PERCFG_BIT 0x01 // USART0 on P0, Alt-1; so clear this bit.
    #define HAL_UART_Px_RX_TX 0x0C // Peripheral I/O Select for Rx/Tx.
    #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
    #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
    #else
    #define HAL_UART_PERCFG_BIT 0x02 // USART1 on P1, Alt-2; so set this bit.
    #define HAL_UART_Px_RTS 0x20 // Peripheral I/O Select for RTS.
    #define HAL_UART_Px_CTS 0x10 // Peripheral I/O Select for CTS.
    #define HAL_UART_Px_RX_TX 0xC0 // Peripheral I/O Select for Rx/Tx.
    #endif

    This seems like a problem to me, because I cannot see when you would ever be able to use USART 1 (Alt-1) or USART 0 (Alt-2).  It seems like there should be 4 combinations of UART configuration, and the driver only has two.

  • Hi Jonathan,

    Yes, this is the case, unfortunately. For now I can only suggest that you change the code adding your own #ifdefs, keeping in mind that the HAL files are shared between projects, and that there are several places you will need to change the setup code for the UART. Do a CTRL+SHIFT+F search for HAL_UART_DMA perhaps.

    Details on register settings can be found in the CC2540/41 User Guide chapter 17, esp 17.8.

    Best regards,
    Aslak

  • Hey Aslak, thank you for confirming.

    What's troubling for me to understand is what the HAL_UART driver is supposed to cover.  I see that it sets the PxSEL and some other UART registers, but it doesn't handle the PxDIR and PERCFG.  Wouldn't it be useful if pin configuration was all contained within the UART driver?

    I say this, because I'm playing with the keyfob which has the buzzer connected to P1.6.  When i want to change the UART to another port or another Alternative location, I need to change the pin configuration and other registers elsewhere.

  • Igor, that buzzing sound is like music to my ears. And then it got annoying real fast. ;-)

    But awesome. At least my hardware is working. Moving on to the DMA UART: I've gone through every single register bit and ensured it's how you've set it up.  See my results below.  This goes to show me that the problem has to be in the Interrupt Register bits that have to do with the DMA...unless theres a peripheral register that I don't know about that i'm forgetting to set.  

    UART 0, ALT 2

    P1SEL = 0x34 = 0b00110100
    P1DIR = 0x28 = 0b00101000
    PERCFG = 0x02 = 0b00000010
    U1CSR = 0xC2 = 0b11000010
    U1GCR = 0x10 = 0b00001000
    U1UCR = 0x29 = 0b001010001
    U1BAUD = 0x3B = 0b00111011
    IEN2 = 0x0B = 0b00001011
    IEN1 = 0x25 = 0b00100101
    IEN0 = 0x80 = 0b10001000

    *These registers are all 0x00 when running your code.

    I haven't touched the HALUARTWriteDMA function, so it's exactly how it was sent from TI.

    I really appreciate your assistance. You've been extremely helpful.

  • ...well that was silly. While debugging for hours, I had commented out the actual HALUARTWriteDMA code inside the function, and forgot to uncomment it.

    Removing it causes the buzzer to beep when the message is transmitted.  Now I'll try to change the registers to move the UART to another port.  


    Wish me luck...

  • Good luck :)

  • Port Changed Failed.  After switching from UART 1, Alt 2  --->  UART 0, Alt 2, the buzzer no longer works (which is expected), but probing pin 1.5(TX) results in nothing.  Are there other registers I should be looking at besides the ones listed below?

    P1SEL = 0x48 = 0b00110000  //tx and rx pins as peripherals
    P1DIR = 0x00
    PERCFG = 0x03 = 0b00000011 //alt location for uart0
    U0CSR =  0xD2 = 0b11010010
    U0BAUD =  0x3B = 0b00111011 //9600 baud
    IEN2 =  0x0F = 0b00001111
    IEN1 = 0x25 = 0b00100101
    IEN0 =  0x8C = 0b10001100
    U0UCR = 0x29 = 0b00101001
    U0GCR =  0x08 = 0b00001000

    Thank you!

  • The CMA3000 accelerometer is on the same bus, I don't know how it can

    affect the communication, may be it forcing the pin to constantly LOW, or something like that,

    First thing, try to test the Tx Rx before the initialization of accelerometer taking place.

    Then probe the Tx line. If you experiencing the same faulty behavior, you can try to use UART0,

    or UART1 on alternative location 1, but keep in mind that in this case you'll need to test it on

    battery, I mean w/o the CC Debugger connected.

  • You my friend, are right. Accelerometer was pulling the uart pin low.  The UART configuration works fine on my board which does not have anything connected to those pins.

    Your help with this problem has been great. Thank you.

    Take care,

    Jonathan

  • Hello Igor,

    I use your code to have a try. But I have strange situation that I can't see any value changes in U1DBUF.

    I use IAR and my BLE version is 1.3.2.

    Why!? I can change any other registers' value but U0DBUF and U1DBUF...

    Or the two have been changed but just didn't show on IAR?

    Cheers,

    mh

  • Hello Jonathan,

    could you share me the register configuration list?I have the same problem as yours?

    Did you succeed in DMA mode or ISR?

    Cheers,

    mh

  • Hi,

    Where and how you are changing these registers?

  • Hello Igor,

    Great to get your reply.

    I am using BLE-cc254x-1.3.2 and using ISR mode.

    Here is preprocessor:

    INT_HEAP_LEN=3000
    HALNODEBUG
    OSAL_CBTIMER_NUM_TASKS=1
    HAL_AES_DMA=FALSE
    xPLUS_BROADCASTER
    HAL_LCD=FALSE
    HAL_LED=FALSE
    HAL_UART=TRUE
    HAL_UART_ISR=1
    HAL_UART_DMA=0

    CC2540MINI-DK, I config UART0, use P1 and Alt.2:

    PERCFG &= 0xFE;

    // P1SEL.SELP0_2/3/4/5 = 1 => CT = P1_2, RX = P1_3, RX = P1_4, TX = P1_5
    P1SEL |= 0x3C;

    U0BAUD = 0xD8;
    U0GCR = (U0GCR&~0x1F) | 0xD8;

    // USART mode = UART (U0CSR.MODE = 1)
    U0CSR |= 0x80|0x40;
    IEN0 |= 0x04;

    IEN2 |= 0x04;

    //TCON
    URX0IF = 1;
    //IRCON2
    UTX0IF = 1; // Prime the ISR pump.

    UART config:

    uartConfig.configured = TRUE;
    uartConfig.baudRate = HAL_UART_BR_115200;//SBP_UART_BR;
    uartConfig.flowControl = FALSE;//SBP_UART_FC;
    uartConfig.flowControlThreshold = 0;//SBP_UART_FC_THRESHOLD;
    uartConfig.rx.maxBufSize = 0;//SBP_UART_RX_BUF_SIZE;
    uartConfig.tx.maxBufSize = 0;//SBP_UART_TX_BUF_SIZE;
    uartConfig.idleTimeout = 0;//SBP_UART_IDLE_TIMEOUT;
    uartConfig.intEnable = TRUE;//SBP_UART_INT_ENABLE;
    uartConfig.callBackFunc = sbpSerialPacketParser;

    anything wrong?

    Cheers,

    mh


  • Hi Jonathan,

    I am working on BLE with CC2540 which will be connected to MSP430 over UART.

    I see you worked a lot on similar configuration.

    I thought you will be the right person to clarify my doubt which goes as follows.

    can we establish UART communication with CC2540 with out Flow control(RTS/CTS).

    Thanks

    Naveen. 


     

  • Hi Jonathan, 

    I really glad that i found your code.

    I have some questions for you, and i hope you can answer me.

    1. Is this code work for you?

    2. Do you work with Mini Development Kit of cc2540?

    3. PERCFG |= 0x02; refer to UART1 Alt 2, which means TX is P1_6. The Mini DK is connected to the Buzzer through this pin. Do you hear some noise when you run the code?

    Thanks

    Noam

  • hi i have a trouble when creat the project use hal_uart_isr

    Error[e27]: Entry "halUart0RxIsr" in module _hal_uart_isr ( C:\Users\Admin\Desktop\uart_MPU\main\Debug\Obj\_hal_uart_isr.r51 ) redefined in module hal_uart ( C:\
    My preprocessor :

    HAL_UART
    CC2541
    HAL_UART_ISR=1
    HAL_UART_DMA=0
    HAL_UART_SPI=0
    plz,help me thanks