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.

CC2642R: device hang during connection parameter negotiation

Part Number: CC2642R
Other Parts Discussed in Thread: SYSCONFIG, SYSBIOS

Tool/software:

I'm using CC2642 ble peripheral application, and observed the device gets hang or reset after link established. 

Here's how to reproduce:

1. using the simple peripheral example application and added manual disconnect after 10 seconds

2. use auto click mobile app to repeat connection and disconnection automatically every 3xx milliseconds (I used 314ms), and run the nRF Connect mobile app on Samsung Galaxy Note8 (Android 9)

3. After some time (3min or 20min), it's random, the device gets hang. 

SimpleLink SDK version: 5.20.0.52, sysconfig: 1.8.2, I think the latest SDK has no difference. 

I found it during the project (already released to the market) and reproduced it with your basic example. 

I suspect that connection parameter update process, before or after connection parameter reply from the peripheral, in the SDK or stack has some issue.

If the automatic connection and disconnection time is enough long such as 1 sec, it looks fine (no hang or reset). 

It is risky that the application cannot provide the safe service to the customer. Please let me know the root cause and how to fix it.   

  • Hi,

    Thank you for reaching out. Were any modifications made to the simple_peripheral project besides adding a manual disconnection after a 10 second timer? Could you attempt to reproduce this on the latest SDK? Many improvements were made between the 5.20 release and the latest release so it is possible that this behavior may have been addressed already. When the device hangs, can you report what the call stack is by pausing executing while in debug mode? Does this behavior occur if a different smart phone is used?

    Best Regards,

    Jan

  • Hi Jan,

    It's same with the latest SDK. The main reason I'm asking is that the device hangs at the field randomly after connection, that means no specific phone or central device, and could reproduce it with the way I mentioned. I was not able to get the exact point where it has a problem. You can check with the apps (auto click - I used Clickmate and BLE app - Nordic nRF Connect), I also couldn't find any issue with the Nordic BLE and have used other vendor's BLE chip but it's the first time to see this kind of weird behavior only with your BLE chip now. 

    manual disconnection is in case GAP_LINK_ESTABLISHED_EVENT with the timer. 

    I can share the source code if you need it. 

    The problem does not happen when the application does not send GAP_UpdateLinkParamReqReply(&rsp).

    Regards,

    Jungin

  • Hi Jungin,

    Understood. Where any changes made to the SDK example to cause this behavior to occur? If so, then could you share them? If you are able to somewhat reliably reproduce the behavior, then could you connect the debugger to the device as a running target (see document linked below) or run the device in debug mode when reproducing? Once the behavior occurs, then pause execution and share a screenshot of the call stack. This will be very helpful in understanding what is going on and how we can implement the expected behavior.

    https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_7_41_00_17/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html#connect-the-debugger-to-a-running-target

    Best Regards,

    Jan

  • Hi Jan,

    Attaching the screenshot of callstack, console debug log and the source file, there's no progress after printing param update reply when it happens.

    1207.simple_peripheral_oad_offchip.c

  • Hi,

    Thank you for sharing. I will try to reproduce this on my side, but in the meantime can you confirm that if you pause and resume execution repeatedly it shows the same call stack? Seems that the project is getting stuck handling or waiting for a timer timeout.

    Best Regards,

    Jan

  • Hi,

    No, the call stack looks good when it's running well. 

    Anyway it happens frequently and randomly. What I can see is just the device prints connected debug message and no more response. 

    I've never seen this kind of issue before with other BLE chips. And is it known issue or first time you get it? 

    Regards,

    Jungin

  • Hi Jungin,

    This is the first time I am seeing this behavior. I tried to reproduce it on my side but was not able to see the same behavior. On my side, the project kept working. I used the apps you had suggested and for the frequency i had the following settings:

    Repeat Interval: 314ms

    Click Duration: 100ms

    The image i used is attached. Can you try the provided image on your side and check if the behavior is seen?

    Best Regards,

    Jan

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/538/simple_5F00_peripheral_5F00_CC26X2R1_5F00_LAUNCHXL_5F00_tirtos7_5F00_ticlang.out

  • Hi Jan,

    Did you use the source file that I attached? 

    Your image looks not having disconnection function and no debug message, I cannot see the correct behavior. 

    Please use the file I shared,or add disconnect timer, and check it again.

    Regards,

    Jungin

  • Hi Jungin,

    I used an unmodified simple_peripheral. Could you share the code snippet you added to enable the disconnect timer? This will help with debug and reproducing the issue on my side.

    Best Regards,

    Jan

  • Hi Jan,

    I've already attached my source code 7 days ago. 1207.simple_peripheral_oad_offchip.c 

    Regards,

    Jungin

  • Hi Jungin,

    You are right. I apologize. I did not see it because of the image. I have added that file to my project and got an error regarding the Uartlog.h file not being present. I commented out that include and now I am seeing many errors related to defines and identifiers:

    Could you try exporting your project from CCS as an archive and sharing the entire project with me? You should be able to attach the zip to a reply to this message.

    Best Regards,

    Jan

  • Hi Jan,

    Attaching the whole project file. 

    CCS version: 10.3.0.00007

    simple_peripheral_oad_offchip_CC26X2R1_LAUNCHXL_tirtos_ccs.zip

    Regards,

    Jungin

  • Hi Jungin,

    I truly apologize for the delay. Your latest project is showing less errors, but still seeing this:

    It says the SIMPLEPROFILE_CHAR1_LEN is not defined. I am guessing what is happening is that the define was placed in simple_gatt_profile.c or .h. By default that file is provided as a link resource in the project. That means that the file is fetched virtually from the copy in the SDK and any modifications made affect the copy in the SDK, but does not create a local modified copy in the project. So my copy of that file does not have the modifications you have made. I will assume that the define should be equal to 2 for now. Adding a #define equal to 2 allows the project to compile and I do see TEST advertising. However, I see no UART output. I checked the default pins for UART (DIO2 and DIO3) as well as the pins used in the project (DIO26 and DIO27) and i see no output. Regardless, I continued with the test. Using 314ms as the repeat interval and letting it run for 20minutes. Since I was not seeing any output I just let the test run for 20 minutes. Afterwards, I was not able to see the project advertising so it seems i h ave reproduced the behavior. I have a few questions.

    Are you seeing the output using a launchpad or a custom board? Can you replicate the output on a launchpad? If so, then could you share the project that has been configured to run this on a launchpad with the output enabled?

    Best Regards,

    Jan

  • Hi Jan,

    Good to hear that you reproduced it. it happens randomly, sometimes within 5 minutes or around 1 hour. I'm using a custom board for the company product, and no launchpad now. 

    I just used your default sample project to test that behavior, you can use it and just add the disconnection function which is not in the sample project but required function in our product, also need debug print function. 

    Is there any possibility of hardware issue?

    I suspect that your stack or SDK cannot handle some timer internally during connection or connection parameter update process correctly. If the connection/disconnection time (3xx ms for this test) is enough long like a couple of seconds the application runs well, probably the hang possibility is pretty low or not happen.

    Regards,

    Jungin

  • Hi Jungin,

    Understood. Thank you for clarifying! As it is happening on a LaunchPad and in your custom hardware, then I dont think the issue is due to HW. Out of curiosity, if you disable the UART. Does the behavior still happen?

    Best Regards,

    Jan

  • Hi Jan,

    Yes, I think it happens regardless of the UART, I removed debug print before and after connection/disconnection process but still seeing this problem. 

    Regards,

    Jungin

  • Hi Jungin,

    Understood, thank you for testing this. I would like to check two more things. Could you re-run the test and share the following?

    1. What is the heap/stack/memory usage before and after the behavior occurs? The followings section of the debugging guide shares how to do this: https://dev.ti.com/tirex/content/simplelink_cc13xx_cc26xx_sdk_7_41_00_17/docs/ble5stack/ble_user_guide/html/ble-stack-5.x-guide/debugging-index.html#debugging-common-heap-issues

    I am thinking its possible the heap is filling up on link established faster than it is emptying out on disconnect which may be causing weird behavior.

    2. Can you try changing the address mode to RPA (assuming it is Public Address)?

    Best Regards,

    Jan

  • Hi Jan,

    Can you check the attached images? I'm not sure it's correct to see the heap. 

    And what's your solution if it's a heap issue? and it's your job to find the root cause and provide how to fix the problem. I gave you all source codes and information. And let me know what I have to change in the code or replace some files in your SDK. 

    We don't use the RPA and no plan. 

    It's very critical issue to your customers and our business. 

    Regards,

    Jungin

    after:

      

    before:

  • Hi,

    Thank you for looking into this. I truly apologize for any frustrating or inconvenience this issue may be causing. I believe the cause of the issue lies with the repeated cancelled connection requests coupled with the disconnection timer. Could you provide some more information as to why the disconnection timer is started in LINK_ESTABLISHED? I am thinking that maybe moving it to GAP_LINK_PARAM_UPDATE_EVENT or GAP_UPDATE_LINK_PARAM_REQ_EVENT may be better.

    Best Regards,

    Jan

  • Hi Jan,

    No difference when moving the disconnection timer to GAP_LINK_PARAM_UPDATE_EVENT. I don't expect maybe or mitigation but complete safe solution from you. 

    Actually some central device tries to connect to our device and it hangs or resets now, I don't know why and what central devices do it, but our device has a peripheral role and it should not happen. So I think it happens without repeated connection and disconnection. When I monitor how many times unknown central device or app tries to connect, it's ones or multiple times a day, and it's dead if unlucky. 

    This test case is to reproduce quickly that happens at the field. I've tried the same test with Nordic BLE but it works fine without any problem. 

    Are you discussing with your engineers? Can you send TI engineer to us in Korea? 

    Regards,

    Jungin

  • Hi Jungin,

    Thank you for the details. I think we have enough information to discuss this with our R&D engineers to get their thoughts. Again, I truly apologize for the inconvenience. I will file a ticket with them and follow up via email with them. I am hopeful they will respond soon, however there may be delays due to holidays. I will update you as soon as possible. If you do not hear back from me by friday, then please reply to this thread and I will share what the latest status is at that time.

    Best Regards,

    Jan

  • Hi Jan,

    Thank you for your great support, I'm looking forward to hearing a good result soon.

    Regards,

    Jungin

  • Hi Jungin,

    We have some leads we are following. R&D thinks it may be possible that the disconnect timer may be causing the stack to attempt to execute a disconnection on a connection handle that no longer exists and this is not being handled gracefully. They have some ideas on how to solve this, but would like to test this issue on a project running the latest SDK. You had mentioned earlier you were able to reproduce this on 7.41. Could you share that exported project with me so that R&D and I can test their proposed workarounds?

    Best Regards,

    Jan

  • Hi Jan,

    Our application uses 15 second timer to disconnect after connection established, and what I observed is that the time difference between the connection established time and reset time (application restart time) in the log is around 12 seconds. That means I think disconnection didn't occur and it's not due to the disconnection function. 

    For example in the following log in Tera Term application, the last log time before reset was 17:27:23 but the application start time was 17:27:35.

    [Tue Sep 10 17:27:23.555 2024] #003457  [ 44565.121 ] mac: 49 AB 0E 90 B3 5E     --> connected central MAC address
    [Tue Sep 10 17:27:35.429 2024#000001  [ 0.000 ]
    [Tue Sep 10 17:27:35.429 2024 #000002 [ 0.000 ] TUNE!T APP START                    --> reset and application started
    [Tue Sep 10 17:27:35.445 2024 #000003 [ 0.062 ] my mac: 74 D2 85 F5 13 5B

    And when I commented out //VOID GAP_UpdateLinkParamReqReply(&rsp); in the GAP_UPDATE_LINK_PARAM_REQ_EVENT event, it didn't reset but  disconnection timeout (0x08) happens between the app and application so it's not the solution.

    If I use rsp.accepted = FALSE; when the pReq->req.intervalMin is less than some value like 20ms, the reset frequency reduced but still happened. That's why I suspect the connection parameter negotiation process in your stack.  

    You can try changing all the configuration for connection parameters, time value, response and so on, and see what happens and the difference, and the better is to make the application reset and see the timestamp for all events.

    We don't have a plan to update the SDK version since many products are in the field and it's a huge work to change the source code and re-evaluate all again and nobody knows about the side effects. It's risky to our business. 

    Regards,

    Jungin

  • Hi Jungin,

    We are struggling to reproduce this on the latest 7.41 SDK. You had mentioned earlier you were able to see this on the latest SDK. Could you share the project? This will allow us to continue debug on our side. We understand that you are unable to migrate to the latest SDK. Our hope is that if we can figure out how to fix the behavior on the 7.41 SDK, then we can provide a way to patch it on your SDK as well. I used the simple_peripheral project from 7.41 and modified only the simple_peripheral.c file (file is attached)

    28130.simple_peripheral.c

    Are any other changes required? If you could provide your project that exhibits the behavior already on 7.41, then this would greatly speed up debug.

    Best Regards,

    Jan

  • Hi Jan,

    Let me ask that what's the root cause and difference between 5.x and 7.x version if it does not happen with the latest SDK, and does your attached application code work fine with old SDK? is it a problem with an application code or SDK? I need a simple peripheral oad offchip based solution. and need your feedback what the exact problem is and how to fix it.

    I've tried to use the latest SDK in our product application several months ago but still happened very soon, and then I removed all CCS, SDK, XDC and so on because it messed up installed your old ones and our product application. I had to reinstall all of them, it's really bad experience and waste too much time. 

    Regards,

    Jungin

  • Hi Jungin,

    Between the 5.x and the 7.x SDK releases many bug fixes, improvements and features have been included in the SDK. Its possible that the behavior you are seeing is something that was fixed in one of the releases by coincidence. I did not test the exact same code on the earlier SDK, but wanted to share it with you in case you saw a flaw in how i was attempting to reproduce the behavior or if you saw the behavior on your side using the provided code.

    You had mentioned earlier on Nov 24th, that you saw this behavior on the latest SDK with minimal changes. This indicates that the issue is still present, but I was not able to see the issue with the code i implemented on 7.41. This may be due to something I missed when creating my project which is why I think it would be valuable to see your 7.41 project. Could you please share this project? This will help R&D figure out what may be causing the behavior on the latest SDK. Once we have root caused it we can then work together to find how to fix it on your SDK.

    Best Regards,

    Jan

  • Hi Jan,

    Ok, one thing sure is that the 5.x SDK has an issue. I'm going to retry to use the latest SDK (7.x) in our application and sample application, I think it will take time. In the meantime please try with multi-role application, enable debug print function, and various configuration in connection parameter values such as 7.5ms to 100ms, also enable scanning.  

    Regards,

    Jungin

  • Hi Jungin,

    Understood. I will try to reproduce using multirole instead to see if the behavior is reproduced. When you get a chance to reproduce on the latest SDK, then please let me know and provide the sample project. I will be able to then provide the project to R&D and this will help accelerate the debug.

    Best Regards,

    Jan

  • Hi Jan,

    I'm trying to use the latest SDK and multi-role application with the custom board, but I don't know how to configure the uart2 for debug print function. 

    I added the following code in the main function but cannot see any text on the tera term. 

    And when I try to import existing project into the latest CCS and SDK, I got the compile error, I guess it's related to XDC tool, and when I add app.cfg file, the CCS or SDK automatically install XDC tool but got compile error and all messed up, sysconfig file lost and ask me to configure all from the beginning. 

    In the old SDK, there's multi-role_app.cfg file in the project root, but I cannot find it in the latest SDK. 

    Please let me know how I can use the debug print function in the sdk 7.41 version, and which compiler version should I use, ti clang or ti v20?  need XDC tool? 

    UART2_Handle uart;
    UART2_Params uartParams;
    // Open an instance of the UART2 driver
    UART2_Params_init(&uartParams);
    uartParams.baudRate = 115200;
    uartParams.parityType = UART2_Parity_NONE;
    uartParams.stopBits = UART2_StopBits_1;
    uartParams.readMode = UART2_Mode_NONBLOCKING;
    uartParams.writeMode = UART2_Mode_NONBLOCKING;
    uart = UART2_open(CONFIG_UART_LOG, &uartParams);

    int32_t status;
    size_t bytesWritten;
    char buffer[100] = "print test\r\n";
    status = UART2_write(uart, buffer, 12, &bytesWritten);

    Regards,

    Jungin

  • Hi Jungin,

    The .cfg file is no longer used in the newer SDKs. Instead the information that this file contained, is now contained in the auto generated ti_devices_config.c file. The code you have shared should write UART data to the UART tx pin you have selected. Do you see any activity at all? Have you removed the display driver and the display driver references from the multirole project? Its likely that if these arent removed, then the UART driver is being held by the display driver.

    The correct compiler for 7.41 is TI Clang 3.2.0.

    Best Regards,

    Jan

  • Hi Jan,

    I didn't enable the display in the sysconfig as attached screenshot. Do I have to remove all Display related functions in the source code? 

    Is it ti_devices_config.c or ti_drivers_config.c? I attached driver.c file, please check it's ok or not. 

    I need two UART, one is for communication with a client MCU and the other one is for debugging log. 

    It looks like re-routing the UART to XDS110 UART needed to use the COM port. I use the 27 and 28 for log, and pin 7 and 8 for communication. 

    /*
     *  ======== ti_drivers_config.c ========
     *  Configured TI-Drivers module definitions
     *
     *  DO NOT EDIT - This file is generated for the CC26X2R1_LAUNCHXL
     *  by the SysConfig tool.
     */
    
    #include <stddef.h>
    #include <stdint.h>
    
    #ifndef DeviceFamily_CC26X2
    #define DeviceFamily_CC26X2
    #endif
    
    #include <ti/devices/DeviceFamily.h>
    
    #include "ti_drivers_config.h"
    
    /*
     *  =============================== AESCCM ===============================
     */
    
    #include <ti/drivers/AESCCM.h>
    #include <ti/drivers/aesccm/AESCCMCC26XX.h>
    
    #define CONFIG_AESCCM_COUNT 1
    AESCCMCC26XX_Object aesccmCC26XXObjects[CONFIG_AESCCM_COUNT];
    
    /*
     *  ======== aesccmCC26XXHWAttrs ========
     */
    const AESCCMCC26XX_HWAttrs aesccmCC26XXHWAttrs[CONFIG_AESCCM_COUNT] = {
        {
            .intPriority = (~0),
        },
    };
    
    const AESCCM_Config AESCCM_config[CONFIG_AESCCM_COUNT] = {
        {   /* CONFIG_AESCCM0 */
            .object  = &aesccmCC26XXObjects[CONFIG_AESCCM0],
            .hwAttrs = &aesccmCC26XXHWAttrs[CONFIG_AESCCM0]
        },
    };
    
    const uint_least8_t CONFIG_AESCCM0_CONST = CONFIG_AESCCM0;
    const uint_least8_t AESCCM_count = CONFIG_AESCCM_COUNT;
    
    /*
     *  =============================== AESCTRDRBG ===============================
     */
    
    #include <ti/drivers/AESCTRDRBG.h>
    #include <ti/drivers/aesctrdrbg/AESCTRDRBGXX.h>
    
    #define CONFIG_AESCTRDRBG_COUNT 1
    
    /*
     *  ======== aesctrdrbgXXObjects ========
     */
    AESCTRDRBGXX_Object aesctrdrbgXXObjects[CONFIG_AESCTRDRBG_COUNT];
    
    /*
     *  ======== aesctrdrbgXXHWAttrs ========
     */
    const AESCTRDRBGXX_HWAttrs aesctrdrbgXXHWAttrs[CONFIG_AESCTRDRBG_COUNT] = {
        /* CONFIG_AESCTRDRBG_0 */
        {
            .aesctrHWAttrs.intPriority = (~0)
        },
    };
    
    /*
     *  ======== AESCTRDRBG_config ========
     */
    const AESCTRDRBG_Config AESCTRDRBG_config[CONFIG_AESCTRDRBG_COUNT] = {
        /* CONFIG_AESCTRDRBG_0 */
        {
            .object = &aesctrdrbgXXObjects[CONFIG_AESCTRDRBG_0],
            .hwAttrs = &aesctrdrbgXXHWAttrs[CONFIG_AESCTRDRBG_0]
        },
    };
    
    const uint_least8_t CONFIG_AESCTRDRBG_0_CONST = CONFIG_AESCTRDRBG_0;
    const uint_least8_t AESCTRDRBG_count = CONFIG_AESCTRDRBG_COUNT;
    
    /*
     *  =============================== AESECB ===============================
     */
    
    #include <ti/drivers/AESECB.h>
    #include <ti/drivers/aesecb/AESECBCC26XX.h>
    
    #define CONFIG_AESECB_COUNT 1
    
    
    AESECBCC26XX_Object aesecbCC26XXObjects[CONFIG_AESECB_COUNT];
    
    /*
     *  ======== aesecbCC26XXHWAttrs ========
     */
    const AESECBCC26XX_HWAttrs aesecbCC26XXHWAttrs[CONFIG_AESECB_COUNT] = {
        {
            .intPriority = (~0),
        },
    };
    
    const AESECB_Config AESECB_config[CONFIG_AESECB_COUNT] = {
        {   /* CONFIG_AESECB0 */
            .object  = &aesecbCC26XXObjects[CONFIG_AESECB0],
            .hwAttrs = &aesecbCC26XXHWAttrs[CONFIG_AESECB0]
        },
    };
    
    
    const uint_least8_t CONFIG_AESECB0_CONST = CONFIG_AESECB0;
    const uint_least8_t AESECB_count = CONFIG_AESECB_COUNT;
    
    /*
     *  =============================== DMA ===============================
     */
    
    #include <ti/drivers/dma/UDMACC26XX.h>
    #include <ti/devices/cc13x2_cc26x2/driverlib/udma.h>
    #include <ti/devices/cc13x2_cc26x2/inc/hw_memmap.h>
    
    UDMACC26XX_Object udmaCC26XXObject;
    
    const UDMACC26XX_HWAttrs udmaCC26XXHWAttrs = {
        .baseAddr        = UDMA0_BASE,
        .powerMngrId     = PowerCC26XX_PERIPH_UDMA,
        .intNum          = INT_DMA_ERR,
        .intPriority     = (~0)
    };
    
    const UDMACC26XX_Config UDMACC26XX_config[1] = {
        {
            .object         = &udmaCC26XXObject,
            .hwAttrs        = &udmaCC26XXHWAttrs,
        },
    };
    
    /*
     *  =============================== ECDH ===============================
     */
    
    #include <ti/drivers/ECDH.h>
    #include <ti/drivers/ecdh/ECDHCC26X2.h>
    
    #define CONFIG_ECDH_COUNT 1
    
    
    ECDHCC26X2_Object ecdhCC26X2Objects[CONFIG_ECDH_COUNT];
    
    /*
     *  ======== ecdhCC26X2HWAttrs ========
     */
    const ECDHCC26X2_HWAttrs ecdhCC26X2HWAttrs[CONFIG_ECDH_COUNT] = {
        {
            .intPriority = (~0),
        },
    };
    
    const ECDH_Config ECDH_config[CONFIG_ECDH_COUNT] = {
        {   /* CONFIG_ECDH0 */
            .object         = &ecdhCC26X2Objects[CONFIG_ECDH0],
            .hwAttrs        = &ecdhCC26X2HWAttrs[CONFIG_ECDH0]
        },
    };
    
    const uint_least8_t CONFIG_ECDH0_CONST = CONFIG_ECDH0;
    const uint_least8_t ECDH_count = CONFIG_ECDH_COUNT;
    
    /*
     *  =============================== GPIO ===============================
     */
    
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/gpio/GPIOCC26XX.h>
    
    /* The range of pins available on this device */
    const uint_least8_t GPIO_pinLowerBound = 0;
    const uint_least8_t GPIO_pinUpperBound = 30;
    
    /*
     *  ======== gpioPinConfigs ========
     *  Array of Pin configurations
     */
    GPIO_PinConfig gpioPinConfigs[31] = {
        GPIO_CFG_NO_DIR, /* DIO_0 */
        GPIO_CFG_NO_DIR, /* DIO_1 */
        /* Owned by UART_HDK as TX */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_HIGH, /* CONFIG_GPIO_UART_HDK_TX */
        /* Owned by UART_HDK as RX */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_DOWN_INTERNAL, /* CONFIG_GPIO_UART_HDK_RX */
        GPIO_CFG_NO_DIR, /* DIO_4 */
        GPIO_CFG_NO_DIR, /* DIO_5 */
        GPIO_CFG_NO_DIR, /* DIO_6 */
        GPIO_CFG_NO_DIR, /* DIO_7 */
        GPIO_CFG_NO_DIR, /* DIO_8 */
        GPIO_CFG_NO_DIR, /* DIO_9 */
        GPIO_CFG_NO_DIR, /* DIO_10 */
        GPIO_CFG_NO_DIR, /* DIO_11 */
        GPIO_CFG_NO_DIR, /* DIO_12 */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL, /* CONFIG_GPIO_BTN1 */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_NONE_INTERNAL, /* CONFIG_GPIO_BTN2 */
        GPIO_CFG_NO_DIR, /* DIO_15 */
        /* Owned by CONFIG_UART_LOG as RX */
        GPIO_CFG_INPUT_INTERNAL | GPIO_CFG_IN_INT_NONE | GPIO_CFG_PULL_DOWN_INTERNAL, /* CONFIG_GPIO_UART_LOG_RX */
        /* Owned by CONFIG_UART_LOG as TX */
        GPIO_CFG_OUTPUT_INTERNAL | GPIO_CFG_OUT_STR_MED | GPIO_CFG_OUT_LOW, /* CONFIG_GPIO_UART_LOG_TX */
        GPIO_CFG_NO_DIR, /* DIO_18 */
        GPIO_CFG_NO_DIR, /* DIO_19 */
        GPIO_CFG_NO_DIR, /* DIO_20 */
        GPIO_CFG_NO_DIR, /* DIO_21 */
        GPIO_CFG_NO_DIR, /* DIO_22 */
        GPIO_CFG_NO_DIR, /* DIO_23 */
        GPIO_CFG_NO_DIR, /* DIO_24 */
        GPIO_CFG_NO_DIR, /* DIO_25 */
        GPIO_CFG_NO_DIR, /* DIO_26 */
        GPIO_CFG_NO_DIR, /* DIO_27 */
        GPIO_CFG_NO_DIR, /* DIO_28 */
        GPIO_CFG_NO_DIR, /* DIO_29 */
        GPIO_CFG_NO_DIR, /* DIO_30 */
    };
    
    /*
     *  ======== gpioCallbackFunctions ========
     *  Array of callback function pointers
     *  Change at runtime with GPIO_setCallback()
     */
    GPIO_CallbackFxn gpioCallbackFunctions[31];
    
    /*
     *  ======== gpioUserArgs ========
     *  Array of user argument pointers
     *  Change at runtime with GPIO_setUserArg()
     *  Get values with GPIO_getUserArg()
     */
    void* gpioUserArgs[31];
    
    const uint_least8_t CONFIG_GPIO_BTN1_CONST = CONFIG_GPIO_BTN1;
    const uint_least8_t CONFIG_GPIO_BTN2_CONST = CONFIG_GPIO_BTN2;
    const uint_least8_t CONFIG_GPIO_UART_LOG_TX_CONST = CONFIG_GPIO_UART_LOG_TX;
    const uint_least8_t CONFIG_GPIO_UART_LOG_RX_CONST = CONFIG_GPIO_UART_LOG_RX;
    const uint_least8_t CONFIG_GPIO_UART_HDK_TX_CONST = CONFIG_GPIO_UART_HDK_TX;
    const uint_least8_t CONFIG_GPIO_UART_HDK_RX_CONST = CONFIG_GPIO_UART_HDK_RX;
    
    /*
     *  ======== GPIO_config ========
     */
    const GPIO_Config GPIO_config = {
        .configs = (GPIO_PinConfig *)gpioPinConfigs,
        .callbacks = (GPIO_CallbackFxn *)gpioCallbackFunctions,
        .userArgs = gpioUserArgs,
        .intPriority = (~0)
    };
    
    /*
     *  =============================== NVS ===============================
     */
    
    #include <ti/drivers/NVS.h>
    #include <ti/drivers/nvs/NVSCC26XX.h>
    
    /*
     *  NVSCC26XX Internal NVS flash region definitions
     *
     * Place uninitialized char arrays at addresses
     * corresponding to the 'regionBase' addresses defined in
     * the configured NVS regions. These arrays are used as
     * place holders so that the linker will not place other
     * content there.
     *
     * For GCC targets, the char arrays are each placed into
     * the shared ".nvs" section. The user must add content to
     * their GCC linker command file to place the .nvs section
     * at the lowest 'regionBase' address specified in their NVS
     * regions.
     */
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__clang__)
    
    static char flashBuf0[0x4000] __attribute__ ((retain, noinit, location(0x48000)));
    
    #elif defined(__IAR_SYSTEMS_ICC__)
    
    __no_init static char flashBuf0[0x4000] @ 0x48000;
    
    #elif defined(__GNUC__)
    
    __attribute__ ((section (".nvs")))
    static char flashBuf0[0x4000];
    
    #endif
    
    NVSCC26XX_Object nvsCC26XXObjects[1];
    
    static const NVSCC26XX_HWAttrs nvsCC26XXHWAttrs[1] = {
        /* CONFIG_NVSINTERNAL */
        {
            .regionBase = (void *) flashBuf0,
            .regionSize = 0x4000
        },
    };
    
    #define CONFIG_NVS_COUNT 1
    
    const NVS_Config NVS_config[CONFIG_NVS_COUNT] = {
        /* CONFIG_NVSINTERNAL */
        {
            .fxnTablePtr = &NVSCC26XX_fxnTable,
            .object = &nvsCC26XXObjects[0],
            .hwAttrs = &nvsCC26XXHWAttrs[0],
        },
    };
    
    const uint_least8_t CONFIG_NVSINTERNAL_CONST = CONFIG_NVSINTERNAL;
    const uint_least8_t NVS_count = CONFIG_NVS_COUNT;
    
    /*
     *  =============================== Power ===============================
     */
    #include <ti/drivers/Power.h>
    #include <ti/drivers/power/PowerCC26X2.h>
    #include "ti_drivers_config.h"
    
    extern void PowerCC26XX_standbyPolicy(void);
    extern bool PowerCC26XX_calibrate(unsigned int);
    
    const PowerCC26X2_Config PowerCC26X2_config = {
        .enablePolicy             = true,
        .policyInitFxn            = NULL,
        .policyFxn                = PowerCC26XX_standbyPolicy,
        .calibrateFxn             = PowerCC26XX_calibrate,
        .calibrateRCOSC_LF        = true,
        .calibrateRCOSC_HF        = true,
        .enableTCXOFxn            = NULL
    };
    
    
    
    /*
     *  =============================== RF Driver ===============================
     */
    #include <ti/drivers/GPIO.h>
    #include <ti/devices/DeviceFamily.h>
    #include DeviceFamily_constructPath(driverlib/ioc.h)
    #include <ti/drivers/rf/RF.h>
    
    /*
     * Platform-specific driver configuration
     */
    const RFCC26XX_HWAttrsV2 RFCC26XX_hwAttrs = {
        .hwiPriority        = (~0),
        .swiPriority        = (uint8_t)0,
        .xoscHfAlwaysNeeded = true,
        .globalCallback     = NULL,
        .globalEventMask    = 0
    };
    
    
    /*
     *  =============================== TRNG ===============================
     */
    
    #include <ti/drivers/TRNG.h>
    #include <ti/drivers/trng/TRNGCC26XX.h>
    
    #define CONFIG_TRNG_COUNT 1
    
    
    TRNGCC26XX_Object trngCC26XXObjects[CONFIG_TRNG_COUNT];
    
    /*
     *  ======== trngCC26XXHWAttrs ========
     */
    static const TRNGCC26XX_HWAttrs trngCC26XXHWAttrs[CONFIG_TRNG_COUNT] = {
        {
            .intPriority = (~0),
            .swiPriority = 0,
            .samplesPerCycle = 240000
        },
    };
    
    const TRNG_Config TRNG_config[CONFIG_TRNG_COUNT] = {
        {   /* CONFIG_TRNG_0 */
            .object         = &trngCC26XXObjects[CONFIG_TRNG_0],
            .hwAttrs        = &trngCC26XXHWAttrs[CONFIG_TRNG_0]
        },
    };
    
    const uint_least8_t CONFIG_TRNG_0_CONST = CONFIG_TRNG_0;
    const uint_least8_t TRNG_count = CONFIG_TRNG_COUNT;
    
    /*
     *  =============================== UART2 ===============================
     */
    
    #include <ti/drivers/UART2.h>
    #include <ti/drivers/uart2/UART2CC26X2.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/Power.h>
    #include <ti/drivers/dma/UDMACC26XX.h>
    #include <ti/drivers/power/PowerCC26X2.h>
    #include <ti/devices/cc13x2_cc26x2/driverlib/ioc.h>
    #include <ti/devices/cc13x2_cc26x2/inc/hw_memmap.h>
    #include <ti/devices/cc13x2_cc26x2/inc/hw_ints.h>
    
    #define CONFIG_UART2_COUNT 2
    
    UART2CC26X2_Object uart2CC26X2Objects[CONFIG_UART2_COUNT];
    
    static unsigned char uart2RxRingBuffer0[32];
    /* TX ring buffer allocated to be used for nonblocking mode */
    static unsigned char uart2TxRingBuffer0[32];
    static unsigned char uart2RxRingBuffer1[32];
    /* TX ring buffer allocated to be used for nonblocking mode */
    static unsigned char uart2TxRingBuffer1[32];
    
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaUart1RxControlTableEntry, UDMA_CHAN_UART1_RX);
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaUart1TxControlTableEntry, UDMA_CHAN_UART1_TX);
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaUart0RxControlTableEntry, UDMA_CHAN_UART0_RX);
    ALLOCATE_CONTROL_TABLE_ENTRY(dmaUart0TxControlTableEntry, UDMA_CHAN_UART0_TX);
    
    static const UART2CC26X2_HWAttrs uart2CC26X2HWAttrs[CONFIG_UART2_COUNT] = {
      {
        .baseAddr           = UART1_BASE,
        .intNum             = INT_UART1_COMB,
        .intPriority        = (~0),
        .rxPin              = CONFIG_GPIO_UART_LOG_RX,
        .txPin              = CONFIG_GPIO_UART_LOG_TX,
        .ctsPin             = GPIO_INVALID_INDEX,
        .rtsPin             = GPIO_INVALID_INDEX,
        .flowControl        = UART2_FLOWCTRL_NONE,
        .powerId            = PowerCC26XX_PERIPH_UART1,
        .rxBufPtr           = uart2RxRingBuffer0,
        .rxBufSize          = sizeof(uart2RxRingBuffer0),
        .txBufPtr           = uart2TxRingBuffer0,
        .txBufSize          = sizeof(uart2TxRingBuffer0),
        .txPinMux           = IOC_PORT_MCU_UART1_TX,
        .rxPinMux           = IOC_PORT_MCU_UART1_RX,
        .ctsPinMux          = IOC_PORT_MCU_UART1_CTS,
        .rtsPinMux          = IOC_PORT_MCU_UART1_RTS,
        .dmaTxTableEntryPri = &dmaUart1TxControlTableEntry,
        .dmaRxTableEntryPri = &dmaUart1RxControlTableEntry,
        .rxChannelMask      = 1 << UDMA_CHAN_UART1_RX,
        .txChannelMask      = 1 << UDMA_CHAN_UART1_TX,
        .txIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_1_8,
        .rxIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_4_8
      },
      {
        .baseAddr           = UART0_BASE,
        .intNum             = INT_UART0_COMB,
        .intPriority        = (~0),
        .rxPin              = CONFIG_GPIO_UART_HDK_RX,
        .txPin              = CONFIG_GPIO_UART_HDK_TX,
        .ctsPin             = GPIO_INVALID_INDEX,
        .rtsPin             = GPIO_INVALID_INDEX,
        .flowControl        = UART2_FLOWCTRL_NONE,
        .powerId            = PowerCC26XX_PERIPH_UART0,
        .rxBufPtr           = uart2RxRingBuffer1,
        .rxBufSize          = sizeof(uart2RxRingBuffer1),
        .txBufPtr           = uart2TxRingBuffer1,
        .txBufSize          = sizeof(uart2TxRingBuffer1),
        .txPinMux           = IOC_PORT_MCU_UART0_TX,
        .rxPinMux           = IOC_PORT_MCU_UART0_RX,
        .ctsPinMux          = IOC_PORT_MCU_UART0_CTS,
        .rtsPinMux          = IOC_PORT_MCU_UART0_RTS,
        .dmaTxTableEntryPri = &dmaUart0TxControlTableEntry,
        .dmaRxTableEntryPri = &dmaUart0RxControlTableEntry,
        .rxChannelMask      = 1 << UDMA_CHAN_UART0_RX,
        .txChannelMask      = 1 << UDMA_CHAN_UART0_TX,
        .txIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_1_8,
        .rxIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_4_8
      },
    };
    
    const UART2_Config UART2_config[CONFIG_UART2_COUNT] = {
        {   /* CONFIG_UART_LOG */
            .object      = &uart2CC26X2Objects[CONFIG_UART_LOG],
            .hwAttrs     = &uart2CC26X2HWAttrs[CONFIG_UART_LOG]
        },
        {   /* UART_HDK */
            .object      = &uart2CC26X2Objects[UART_HDK],
            .hwAttrs     = &uart2CC26X2HWAttrs[UART_HDK]
        },
    };
    
    const uint_least8_t CONFIG_UART_LOG_CONST = CONFIG_UART_LOG;
    const uint_least8_t UART_HDK_CONST = UART_HDK;
    const uint_least8_t UART2_count = CONFIG_UART2_COUNT;
    
    
    #include <stdbool.h>
    
    #include <ti/devices/cc13x2_cc26x2/driverlib/ioc.h>
    #include <ti/devices/cc13x2_cc26x2/driverlib/cpu.h>
    
    #include <ti/drivers/GPIO.h>
    
    /* Board GPIO defines */
    #define BOARD_EXT_FLASH_SPI_CS      20
    #define BOARD_EXT_FLASH_SPI_CLK     10
    #define BOARD_EXT_FLASH_SPI_PICO    9
    #define BOARD_EXT_FLASH_SPI_POCI    8
    
    
    /*
     *  ======== Board_sendExtFlashByte ========
     */
    void Board_sendExtFlashByte(uint8_t byte)
    {
        uint8_t i;
    
        /* SPI Flash CS */
        GPIO_write(BOARD_EXT_FLASH_SPI_CS, 0);
    
        for (i = 0; i < 8; i++) {
            GPIO_write(BOARD_EXT_FLASH_SPI_CLK, 0); /* SPI Flash CLK */
    
            /* SPI Flash PICO */
            GPIO_write(BOARD_EXT_FLASH_SPI_PICO, (byte >> (7 - i)) & 0x01);
            GPIO_write(BOARD_EXT_FLASH_SPI_CLK, 1);  /* SPI Flash CLK */
    
            /*
             * Waste a few cycles to keep the CLK high for at
             * least 45% of the period.
             * 3 cycles per loop: 8 loops @ 48 Mhz = 0.5 us.
             */
            CPUdelay(8);
        }
    
        GPIO_write(BOARD_EXT_FLASH_SPI_CLK, 0);  /* CLK */
        GPIO_write(BOARD_EXT_FLASH_SPI_CS, 1);  /* CS */
    
        /*
         * Keep CS high at least 40 us
         * 3 cycles per loop: 700 loops @ 48 Mhz ~= 44 us
         */
        CPUdelay(700);
    }
    
    /*
     *  ======== Board_wakeUpExtFlash ========
     */
    void Board_wakeUpExtFlash(void)
    {
        /* SPI Flash CS*/
        GPIO_setConfig(BOARD_EXT_FLASH_SPI_CS, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_HIGH | GPIO_CFG_OUT_STR_MED);
    
        /*
         *  To wake up we need to toggle the chip select at
         *  least 20 ns and ten wait at least 35 us.
         */
    
        /* Toggle chip select for ~20ns to wake ext. flash */
        GPIO_write(BOARD_EXT_FLASH_SPI_CS, 0);
        /* 3 cycles per loop: 1 loop @ 48 Mhz ~= 62 ns */
        CPUdelay(1);
        GPIO_write(BOARD_EXT_FLASH_SPI_CS, 1);
        /* 3 cycles per loop: 560 loops @ 48 Mhz ~= 35 us */
        CPUdelay(560);
    }
    
    /*
     *  ======== Board_shutDownExtFlash ========
     */
    void Board_shutDownExtFlash(void)
    {
        /*
         *  To be sure we are putting the flash into sleep and not waking it,
         *  we first have to make a wake up call
         */
        Board_wakeUpExtFlash();
    
        /* SPI Flash CS*/
        GPIO_setConfig(BOARD_EXT_FLASH_SPI_CS, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_HIGH | GPIO_CFG_OUT_STR_MED);
        /* SPI Flash CLK */
        GPIO_setConfig(BOARD_EXT_FLASH_SPI_CLK, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW | GPIO_CFG_OUT_STR_MED);
        /* SPI Flash PICO */
        GPIO_setConfig(BOARD_EXT_FLASH_SPI_PICO, GPIO_CFG_OUTPUT | GPIO_CFG_OUT_LOW | GPIO_CFG_OUT_STR_MED);
        /* SPI Flash POCI */
        GPIO_setConfig(BOARD_EXT_FLASH_SPI_POCI, GPIO_CFG_IN_PD);
    
        uint8_t extFlashShutdown = 0xB9;
    
        Board_sendExtFlashByte(extFlashShutdown);
    
        GPIO_resetConfig(BOARD_EXT_FLASH_SPI_CS);
        GPIO_resetConfig(BOARD_EXT_FLASH_SPI_CLK);
        GPIO_resetConfig(BOARD_EXT_FLASH_SPI_PICO);
        GPIO_resetConfig(BOARD_EXT_FLASH_SPI_POCI);
    }
    
    
    #include <ti/drivers/Board.h>
    
    /*
     *  ======== Board_initHook ========
     *  Perform any board-specific initialization needed at startup.  This
     *  function is declared weak to allow applications to override it if needed.
     */
    void __attribute__((weak)) Board_initHook(void)
    {
    }
    
    /*
     *  ======== Board_init ========
     *  Perform any initialization needed before using any board APIs
     */
    void Board_init(void)
    {
        /* ==== /ti/drivers/Power initialization ==== */
        Power_init();
    
        /* ==== /ti/devices/CCFG initialization ==== */
    
        /* ==== /ti/drivers/GPIO initialization ==== */
        /* Setup GPIO module and default-initialise pins */
        GPIO_init();
    
        /* ==== /ti/drivers/RF initialization ==== */
    
    
        Board_shutDownExtFlash();
    
        Board_initHook();
    }
    
    

    Regards,

    Jungin

  • Hi Jungin,

    The XDS110's COM port routes to DIO3 and DIO4. This means that to see UART on the COM port, then the UART output must go to DIO3 and DIO2. Any UART configured to other pins will not be visible through the COM port exposed by the XDS and will require a seperate UART reader or logic analyzer. (Configuration used by Display driver)

    You may have to remove the Display driver references from the code. Try using these pins first to see if that works and if it does not then we may need to remove the display driver references.

    Best Regards,

    Jan

  • Hi Jan,

    I'm able to enable the debug log function now, but wondering where the idle function is to add the uart log flush. 

    In the old SDK, Idle.addFunc('&uartLog_flush'); needed in the app.cfg file.

    /*********************************************************************
    * SYSTEM HOOK FUNCTIONS
    */

    /*********************************************************************
    * @fn uartLog_flush
    *
    * @brief Log-buffer flush function
    *
    * In this implementation it is intended to be called by the
    * Idle task when nothing else is running.
    *
    * This is achieved by setting up the Idle task in the TI-RTOS
    * configuration script like so:
    *
    * var Idle = xdc.useModule('ti.sysbios.knl.Idle');
    * Idle.addFunc('&uartLog_flush');
    *
    * NOTE: This must be added _before_ the Power driver is included, in order
    * to output the pending log messages before going to sleep.
    *
    * Uses a utility function to convert a log record to a user-friendlier
    * string which is then printed to UART.
    *
    * @param None. Relies on global state.
    *
    * @return None.
    *
    * @post ::uartLog_tail is incremented to where uartLog_head is, then returns
    */
    void uartLog_flush()

    Now with the latest SDK and tirtos7, where should I put the uartLog_flush() or is it not necessary? just use the uart2_write in any place?

    Regards,

    Jungin

  • Hi Jungin,

    I believe you should be able to just use uart2_write in any spot. Are you seeing issues doing that?

    Best Regards,

    Jan

  • Hi Jan,

    uart2_write function makes our application unstable, do you have any workaround to use the old sdk?

    Regards,

    Jungin

  • Hi Jungin,

    Can you clarify how it makes it unstable? Are you using the same UART options as you were in the previous project? Running this on the latest SDK will be necessary for R&D to be able to efficiently support.

    Best Regards,

    Jan

  • Hi Jan,

    unblokcing does not print all message and blocking looks like making hardware fault. 

    I saw you mentioned that using uartlog rather than system print and flushing when idle time in this forum, but wondering why you say use uart2_write any spot. Don't you have any utility functions and file like uart log and flush in the latest sdk?

    Our application use a lot of print function to check and debug, and need it. 

    Regards,

    Jungin

  • Hi Jungin,

    Understood. To clarify, using the new SDK with UART2, the issue does not occur, but some prints are missed? Could you try increasing the TX ring buffer sizes (can be done through sysconfig) to see if that fixed the missing statements? Its possible too much is being printed too quickly and the buffers are running out of space.

    I think the closest thing to uart log would be to use the display driver with ANSI disabled (can be done through sysconfig):

    Best Regards,

    Jan