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.

cc2541 Keyfob U1DBUF register issue (BLE_Bridge, UART)

Other Parts Discussed in Thread: CC2541, CC2540

Hi TI engineers and Forum members,

Please help.  I'm trying to send data out of P1_6 [TxD] (USART1, Alt.2) but do not see any activity at the port.  I've set breakpoints at UxDBUF and the line after [in BOLD] in the UART Transmit Interrupt [halUartTxIsr] below, stepping through the code in the Disassembly window, while monitoring the U1DBUF and Basic Registers.  I'm using the cc2541 Keyfob and cc2540 USB Dongle.

[--Begin code--

/***************************************************************************************************
 * @fn      halUartTxIsr
 *
 * @brief   UART Transmit Interrupt
 *
 * @param   None
 *
 * @return  None
 ***************************************************************************************************/
#if (HAL_UART_DMA == 1)
HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
#else
HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
#endif
{
  HAL_ENTER_ISR();

  if (dmaCfg.txHead == dmaCfg.txTail)
  {
    IEN2 &= ~UTXxIE;
    dmaCfg.txMT = 1;
  }
  else
  {
//    UTXxIF = 1;
    UTXxIF = 0;
    UxDBUF = dmaCfg.txBuf[dmaCfg.txHead++];

    if ((HAL_UART_DMA_TX_MAX != 256) && (dmaCfg.txHead >= HAL_UART_DMA_TX_MAX))
    {
      dmaCfg.txHead = 0;
    }
  }

  HAL_EXIT_ISR();
}
#endif
/***************************************************************************************************
 * @fn      halUartTxIsr
 *
 * @brief   UART Transmit Interrupt
 *
 * @param   None
 *
 * @return  None
 ***************************************************************************************************/
#if (HAL_UART_DMA == 1)
HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
#else
HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
#endif
{
  HAL_ENTER_ISR();

  if (dmaCfg.txHead == dmaCfg.txTail)
  {
    IEN2 &= ~UTXxIE;
    dmaCfg.txMT = 1;
  }
  else
  {
    UTXxIF = 0;
    UxDBUF = dmaCfg.txBuf[dmaCfg.txHead++];

    if ((HAL_UART_DMA_TX_MAX != 256) && (dmaCfg.txHead >= HAL_UART_DMA_TX_MAX))
    {
      dmaCfg.txHead = 0;
    }
  }

  HAL_EXIT_ISR();
}
#endif

--End code--]

U1DBUF stays at 0x00 even though each byte of the data message can be seen, being built in the Basic Registers and written to U1DBUF one at a time.  Is there a specific condition that needs to be met before a byte of data written to U1DBUF is seen in the register?

Any help is appreciated.  Thanks.

Regards,


Dag

  • Hi Dag,

    Have you read the UART chapter in the CC253x/40/41 User Guide?

    Cheers,
    Fredrik
  • Hello Fredrik,

    Yes, I have read the UART chapter in the CC253x/40/41 User Guide, which is the reason for my post.
  • Ok. The reason for asking is because the register description says: "USART receive and transmit data. When writing this register, the data written is written to the internal transmit-data register. When reading this register, the data from the internal read-data register is read."

    U1DBUF will in other words never reflect what you actually write to it. That is expected behavior.

    Are you sure you have configured the IO ports correctly (with right priority etc.)?
  • I'm using the following settings:

    1) Preprocessor defined symbol used is HAL_UART_DMA=2.

    2) I added a line of code to set P1_6 today (see below)

    3) A scope probe is set at the Keyfob's Buzzer [B2:1] to monitor the P1_6 output.

    [--Begin code--

    static void HalUARTInitDMA(void)

    {

     halDMADesc_t *ch;

    #if (HAL_UART_DMA == 1)

     PERCFG &= ~HAL_UART_PERCFG_BIT;    // Set UART0 I/O to Alt. 1 location on P0.

    #else

     PERCFG |= HAL_UART_PERCFG_BIT;     // Set UART1 I/O to Alt. 2 location on P1.

    #endif

     PxSEL  |= HAL_UART_Px_SEL;         // Enable Peripheral control of Rx/Tx on Px.

     UxCSR = CSR_MODE;                  // Mode is UART Mode.

     UxUCR = UCR_FLUSH;                 // Flush it.

     P2DIR &= ~P2DIR_PRIPO;

     P2DIR |= HAL_UART_PRIPO;

     PxDIR |= 0x40;                      // #: [30Nov2015] Setup P1_6 as output

    ...

    }

    --End Code--]


    After HalUARTInitDMA() executes this is the status of the registers.



    Is the setup correct?

  • Hello Fredrik,

    Is it possible to use port P1_6 on the cc2541 Keyfob, which connects from the cc2541 (pin-38) to the buzzer (B2:1), as the TxD port for my application?

    Thanks for your help.


    Regards,

    Dag

  • Hello Dag,

    Yes, I think it should be possible.

    • Which project did you base this code on and how did you modify the code?
    • Have you tested the UART example in CC2541/43/44/45 Peripherals Software Examples?
    • You set up HAL_UART_DMA=2, but implement ISR version. Should you not set HAL_UART_ISR=2 instead?

    I cannot see where you write to start the transmissions (write to U1DBUF or trigger dma transfer). Look more in details at the implementations in the following files:

    C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c

    C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_dma.c

  • Hello Eirik,

    It's good to learn that P1_6 on the cc2541 Keyfob can serve as a UART TxD output, despite being physically connected to the buzzer [B2:1].

    1. The code I'm using is based on the BLE_Bridge.  To create the new application, I modified the BLE_Bridge code using the "Tutorial: How to Create a Custom Bluetooth Smart Embedded Application with the CC2650DK."

      processors.wiki.ti.com/.../Tutorial:_How_to_Create_a_Custom_Bluetooth_Smart_Embedded_Application_with_the_CC2650DK

    2. Are the "...UART example in CC2541/43/44/45 Peripherals Software Examples..." files part of the [BLE-CC254x-1.4.1.43908] BLE stack?

    3. Thanks for the tip about HAL_UART_ISR=2 defined symbol; I'll add it to the list of Preprocessor Defined Symbols and test the application again.  The list of Preprocessor Defined Symbols I'm currently using is:

    INT_HEAP_LEN=3072
    HALNODEBUG
    OSAL_CBTIMER_NUM_TASKS=1
    HAL_AES_DMA=TRUE
    HAL_DMA=TRUE
    xPOWER_SAVING
    HAL_LCD=FALSE
    HAL_LED=FALSE
    HAL_UART=TRUE
    xHAL_UART_DMA=1
    HAL_UART_DMA=2
    xHAL_UART_ISR=0
    HAL_KEY=FALSE
    xNPI_UART_PORT=HAL_UART_PORT_0
    NPI_UART_PORT=HAL_UART_PORT_1
    NPI_UART_FC=FALSE

    In reference to U1DBUF, I saw it was dereferenced to UxDBUF in _hal_uart_dma.c; so, I placed a breakpoint at

       UxDBUF = dmaCfg.txBuf[dmaCfg.txHead++];

    in the ISR code below--code execution does stop there.  I was able to step through and observe the Basic Registers, to verify and validate the UART message I need to transmit out of TxD output port P1_6; however, P1_6 doesn't produce an output when it is probed with an oscilloscope at the buzzer [B2:1].

    [ --Begin code--

    #if HAL_UART_TX_BY_ISR

    /***************************************************************************************************
     * @fn      halUartTxIsr
     *
     * @brief   UART Transmit Interrupt
     *
     * @param   None
     *
     * @return  None
     ***************************************************************************************************/
    #if (HAL_UART_DMA == 1)
    HAL_ISR_FUNCTION( halUart0TxIsr, UTX0_VECTOR )
    #else
    HAL_ISR_FUNCTION( halUart1TxIsr, UTX1_VECTOR )
    #endif
    {
      HAL_ENTER_ISR();

      if (dmaCfg.txHead == dmaCfg.txTail)
      {
        IEN2 &= ~UTXxIE;
        dmaCfg.txMT = 1;
      }
      else
      {
    //    UTXxIF = 1;
        UTXxIF = 0;
        UxDBUF = dmaCfg.txBuf[dmaCfg.txHead++];

        if ((HAL_UART_DMA_TX_MAX != 256) && (dmaCfg.txHead >= HAL_UART_DMA_TX_MAX))
        {
          dmaCfg.txHead = 0;
        }
      }

      HAL_EXIT_ISR();
    }
    #endif

    --End code-- ]

    This prompts some more questions:

    1. Is HAL_UART_TX_BY_ISR a Preprocessor Defined Symbol?
    2. Do I need to add the symbol to the list?
    3. How is the HAL_UART_TX_BY_ISR Defined Symbol set?
      1. HAL_UART_TX_BY_ISR, or
      2. HAL_UART_TX_BY_ISR=<[0|1|2|TRUE]>

    I'll await your responses.  Thanks for you help.

    Regards,

    Dag

  • After adding HAL_UART_ISR=2 defined symbol to the list of Preprocessor Defined Symbols, the compiler returns the following warnings and errors.

    Warning[Pe301]: typedef name has already been declared (with same type) C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 204

    Warning[Pe301]: typedef name has already been declared (with same type) C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 210

    Error[Pa052]: #pragma "call_graph_root" can only be used on a definition C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 607

    Error[Pe247]: function "halUart1TxIsr" has already been defined (at line 1016 of "C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_dma.c") C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 607

    Error while running C/C++ Compiler


    Does this mean that HAL_UART_DMA=2 conflicts with HAL_UART_ISR=2 and needs to be removed from the Preprocessor list?  Please advise.

    Thanks for you help.

    Regards,

     

    Dag

     

  • Hello,
    You cannot define both at the same time.
  • Hello Eirik,

    I've disabled the HAL_UART_DMA=2 Defined Symbol (please see Preprocessor list below) and now the compiler returns these warnings:

    Warning[Pe301]: typedef name has already been declared (with same type) C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 204

    Warning[Pe301]: typedef name has already been declared (with same type) C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c 210

    which points to TYPEDEFS in the _hal_uart_isr.c code file.

    [--Begin code--

    ...

    /*********************************************************************
     * TYPEDEFS
     */

    #if HAL_UART_ISR_RX_MAX <= 256
    typedef uint8 rxIdx_t;
    #else
    typedef uint16 rxIdx_t;
    #endif

    #if HAL_UART_ISR_TX_MAX <= 256
    typedef uint8 txIdx_t;
    #else
    typedef uint16 txIdx_t;
    #endif

    ...

    --End code--]

    The Preprocessor Defined Symbols list is now:

    INT_HEAP_LEN=3072
    HALNODEBUG
    OSAL_CBTIMER_NUM_TASKS=1
    HAL_AES_DMA=TRUE
    HAL_DMA=TRUE
    xPOWER_SAVING
    HAL_LCD=FALSE
    HAL_LED=FALSE
    HAL_UART=TRUE
    xHAL_UART_DMA=1
    xHAL_UART_DMA=2
    xHAL_UART_ISR=0
    HAL_UART_ISR=2
    HAL_KEY=FALSE
    xNPI_UART_PORT=HAL_UART_PORT_0
    NPI_UART_PORT=HAL_UART_PORT_1
    NPI_UART_FC=FALSE

    How can I fix the warnings?  Please advise.  Thanks.

  • Hello Dag,

    1. P1.6:
    I meant that using P1.6 should work. But you might have to disconnect the buzzer as it might add some load to the line.

    2. Warnings:
    There are a lot of defines in the hal_board_cfg.h files that mess things up. However, before I continue, I would advice you to consider using the dma implementation instead of ISR as it is a more reliable solution. If you want to get rid of the warnings you have to remove all the HAL_UART_DMA and HAL_UART_ISR defines and just have the HAL_UART_ISR =2 in your projcet options->defines symbols. The warning comes due to the fact that HAL_UART_DMA gets defined with a non-zero value which in turn will add both the "_hal_uart_dma.c" and the "_hal_uart_isr.c" in the hal_uart.c file:
    #if HAL_UART_DMA
    #include "_hal_uart_dma.c"

    #endif
    #if HAL_UART_ISR
    #include "_hal_uart_isr.c"

    #endif
    .....

    3. CC2541/43/44/45 Peripherals Software Examples is standalone example code and is not a part of the BLE stack. The following are a part of the ble stack:
    C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_isr.c
    C:\Texas Instruments\BLE-CC254x-1.4.1.43908\Components\hal\target\CC2540EB\_hal_uart_dma.c

  • Hello Eirik,

    Thank you.  Following your recommendation about using HAL_UART_DMA=2, the cc2541 Keyfob now transmits a message from P1.6.  For now, I'll keep the buzzer connected because the audible feedback is quite useful for my application.

    On the other hand, the message transmitted from P1.6 is actually a command being sent to an external MCU, which needs to be transmitted continuously at 10Hz, as soon as the Keyfob pairs with the USB Dongle.  Which example code can I modify to accomplish this task?  Please advise.  Thanks.

  • Hello Dag,
    You can trigger a ready buffered message when you hit case GAPROLE_CONNECTED: in peripheralStateNotificationCB?
  • Hello Eirik,

    That worked, thanks.

    I have another issue.  The message being transmitted is composed of two 8-bit tokens.  The complete, concatenated message is being transmitted, however, the USART appears to be inserting a additional STOP bit between the first 8-bit and second 8-bit token.  What could be causing this behavior?

    For example, I need to transmit this message:

    <START BIT><0x91><STOP BIT><START BIT><0x0D><STOP BIT>

    The USART transmits the message this way:

    <START BIT><0x91><STOP BIT><STOP BIT><START BIT><0x0D><STOP BIT>

     

    The port is set for 9600 BAUD,n,8,1:

    [--Begin code from npi.h--

    #if !defined( NPI_UART_BR )
    // #: [2Oct2015] Changed the baud rate to 9600 for transmission between the Host MCU and the cc2541
    // #define NPI_UART_BR                    HAL_UART_BR_115200
    #define NPI_UART_BR                    HAL_UART_BR_9600
    #endif // !NPI_UART_BR

    --End code from npi.h--]

    [--Begin code from _hal_uart_dma.c--

    UxUCR = UCR_STOP;                 // 8 bits/char; no parity; 1 stop bit; stop bit hi.

    --End code from _hal_uart_dma.c--]

     

    Thanks for your help.

  • Hello Dag,
    This appears to be due a HW bug:
    e2e.ti.com/.../220542
    e2e.ti.com/.../745009