CC2340R5: 蓝牙固件通过uart串口烧录时失败

Part Number: CC2340R5
Other Parts Discussed in Thread: UNIFLASH, SYSCONFIG

Tool/software:

When upgrading the CC2340R5 Bluetooth firmware via the serial port, the process fails during the CRC verification step, even though the flash erase and write operations were successful earlier. How should this issue be addressed?

  • Hi mike,

    When using the TI_CC2340_Linux_SBL tool you have to make sure that you create a custom bin file and ensure that the firmware binary file is aligned with the sector size (0x800).  The "Byte Count" of your image (0x64db4) implies that these instructions were not adhered to.

    Regards,
    Ryan

  • Could you please let me know the standard bin binary file format for the CC2340R5RGE Bluetooth firmware, or how to generate it through the memory option in the Uniflash tool? Alternatively, could you send me a copy directly? Thank you!

  • Hi, TI Engineer,

    I have sent you my host computer and CC2340R5RGE Bluetooth firmware code. Could you please help take a look? Our upgrades have been unsuccessful. The specific code is included in the attachment. Thank you!

    /*蓝牙固件地址cmd地址配置文件*/
    /******************************************************************************
    
     @file  cc23x0_app_freertos.cmd
    
     @brief cc23x0R5 linker configuration file for FreeRTOS
            with Code Composer Studio.
    
            Imported Symbols
            Note: Linker defines are located in the CCS IDE project by placing them
            in
            Properties->Build->Linker->Advanced Options->Command File Preprocessing.
    
            ICALL_RAM0_START:   RAM start of BLE stack.
            ICALL_STACK0_START: Flash start of BLE stack.
            PAGE_AlIGN:         Align BLE stack boundary to a page boundary.
                                Aligns to Flash word boundary by default.
    
     Group: WCS, BTS
     $Target Device: DEVICES $
    
     ******************************************************************************
     $License: BSD3 2017 $
     ******************************************************************************
     $Release Name: PACKAGE NAME $
     $Release Date: PACKAGE RELEASE DATE $
     *****************************************************************************/
    
    /*******************************************************************************
     * CCS Linker configuration
     */
    
    /* Override default entry point.                                             */
    --entry_point=resetISR
    
    /* Retain interrupt vector table variable                                    */
    --retain "*(.resetVecs)"
    
    /* Suppress warnings and errors:                                             */
    /* - 10063: Warning about entry point not being _c_int00                     */
    /* - 16011, 16012: 8-byte alignment errors. Observed when linking in object  */
    /*   files compiled using Keil (ARM compiler)                                */
    --diag_suppress=10063,16011,16012
    --heap_size=0
    --stack_size=800
    /* The following command line options are set as part of the CCS project.    */
    /* If you are building using the command line, or for some reason want to    */
    /* define them here, you can uncomment and modify these lines as needed.     */
    /* If you are using CCS for building, it is probably better to make any such */
    /* modifications in your CCS project and leave this file alone.              */
    /*                                                                           */
    /* --heap_size=0                                                             */
    /* --stack_size=256                                                          */
    /* --library=rtsv7M3_T_le_eabi.lib                                           */
    
    /* The starting address of the application.  Normally the interrupt vectors  */
    /* must be located at the beginning of the application. Flash is 128KB, with */
    /* sector length of 4KB                                                      */
    /*******************************************************************************
     * Memory Sizes
     */
    #define FLASH_BASE   0x00000000
    #define RAM_BASE     0x20000000
    #define FLASH_SIZE   0x00080000
    #define RAM_SIZE     0x00009000
    #define CCFG_BASE    0x4E020000
    #define CCFG_SIZE    0x800
    #define NVS_SIZE     0x4000
    #define NVS_BASE     (FLASH_SIZE - NVS_SIZE)
    
    #if defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT) || defined(OAD_DUAL_IMAGE)
    #define MCU_HDR_SIZE    0x100
    #define MCUBOOT_BASE    FLASH_BASE
    #define MCUBOOT_SIZE    0x6000
    #define APP_HDR_BASE    APP_HDR_ADDR
    #define APP_BASE        (APP_HDR_BASE + MCU_HDR_SIZE)
    #endif //defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT) || defined(OAD_DUAL_IMAGE)
    
    #if defined(OAD_APP_ONCHIP)|| defined(OAD_PERSISTENT)
    #define PERSISTENT_HDR_BASE 0x6000
    #define PERSISTENT_BASE     (PERSISTENT_HDR_BASE + MCU_HDR_SIZE)
    #define PERSISTENT_SIZE     (APP_HDR_BASE - PERSISTENT_BASE)
    #define APP_SIZE            (FLASH_SIZE - APP_BASE - NVS_SIZE)
    #endif //defined(OAD_APP_ONCHIP)|| defined(OAD_PERSISTENT)
    
    #ifdef OAD_APP_OFFCHIP
    #define APP_SIZE        (FLASH_SIZE - APP_BASE - NVS_SIZE)
    #endif //OAD_APP_OFFCHIP
    
    #ifdef OAD_DUAL_IMAGE
    #define APP_SIZE        ((FLASH_SIZE - NVS_SIZE - MCUBOOT_SIZE)/2 - MCU_HDR_SIZE)
    #endif //OAD_DUAL_IMAGE
    
    /*******************************************************************************
     * Memory Definitions
     ******************************************************************************/
    
    /*******************************************************************************
     * RAM
     */
    #define RAM_START      (RAM_BASE)
    #ifdef ICALL_RAM0_START
      #define RAM_END      (ICALL_RAM0_START - 1)
    #else
      #define RAM_END      (RAM_BASE + RAM_SIZE - 1)
    #endif /* ICALL_RAM0_START */
    
    /*******************************************************************************
     * Flash
     */
    
    #define FLASH_START                FLASH_BASE
    #define WORD_SIZE                  4
    
    #define PAGE_SIZE                  0x800
    
    #ifdef PAGE_ALIGN
      #define FLASH_MEM_ALIGN          PAGE_SIZE
    #else
      #define FLASH_MEM_ALIGN          WORD_SIZE
    #endif /* PAGE_ALIGN */
    
    #define PAGE_MASK                  0xFFFFE000
    
    /* The last Flash page is reserved for the application. */
    #define NUM_RESERVED_FLASH_PAGES   1
    #define RESERVED_FLASH_SIZE        (NUM_RESERVED_FLASH_PAGES * PAGE_SIZE)
    
    /* Check if page alingment with the Stack image is required.  If so, do not link
     * into a page shared by the Stack.
     */
    #ifdef ICALL_STACK0_START
      #ifdef PAGE_ALIGN
        #define ADJ_ICALL_STACK0_START (ICALL_STACK0_START * PAGE_MASK)
      #else
        #define ADJ_ICALL_STACK0_START ICALL_STACK0_START
      #endif /* PAGE_ALIGN */
    
      #define FLASH_END                (ADJ_ICALL_STACK0_START - 1)
    #else
      #define FLASH_END                (FLASH_BASE + FLASH_SIZE - RESERVED_FLASH_SIZE - 1)
    #endif /* ICALL_STACK0_START */
    
    #define FLASH_LAST_PAGE_START      (FLASH_SIZE - PAGE_SIZE)
    
    /*******************************************************************************
     * Stack
     */
    
    /* Create global constant that points to top of stack */
    /* CCS: Change stack size under Project Properties    */
    __STACK_TOP = __stack + __STACK_SIZE;
    
    /*******************************************************************************
     * ROV
     * These symbols are used by ROV2 to extend the valid memory regions on device.
     * Without these defines, ROV will encounter a Java exception when using an
     * autosized heap. This is a posted workaround for a known limitation of
     * RTSC/rta. See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=487894
     *
     * Note: these do not affect placement in RAM or FLASH, they are only used
     * by ROV2, see the BLE Stack User's Guide for more info on a workaround
     * for ROV Classic
     *
     */
    __UNUSED_SRAM_start__ = RAM_BASE;
    __UNUSED_SRAM_end__ = RAM_BASE + RAM_SIZE;
    
    __UNUSED_FLASH_start__ = FLASH_BASE;
    __UNUSED_FLASH_end__ = FLASH_BASE + FLASH_SIZE;
    
    /*******************************************************************************
     * Main arguments
     */
    
    /* Allow main() to take args */
    /* --args 0x8 */
    
    /*******************************************************************************
     * System Memory Map
     ******************************************************************************/
    MEMORY
    {
      /* EDITOR'S NOTE:
       * the FLASH and SRAM lengths can be changed by defining
       * ICALL_STACK0_START or ICALL_RAM0_START in
       * Properties->ARM Linker->Advanced Options->Command File Preprocessing.
       */
    
    #if defined(OAD_APP_OFFCHIP)|| defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT) || defined(OAD_DUAL_IMAGE)
    
        MCUBOOT_SLOT(RX)       : origin = MCUBOOT_BASE        ,length = MCUBOOT_SIZE
        APP_HDR_SLOT(RX)       : origin = APP_HDR_BASE        ,length = MCU_HDR_SIZE
        APP_SLOT (RX)          : origin = APP_BASE            ,length = APP_SIZE
    
    #if defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT)
    
        PERSISTENT_HDR_SLOT(RX) : origin = PERSISTENT_HDR_BASE ,length = MCU_HDR_SIZE
        PERSISTENT_SLOT(RX)     : origin = PERSISTENT_BASE     ,length = PERSISTENT_SIZE
    
    #endif //defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT)
    
    #else //Without mcuboot
    
        FLASH (RX)   : origin = 0x0,      length = (FLASH_SIZE - NVS_SIZE)
    
    #endif //defined(OAD_APP_OFFCHIP)|| defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT)
    
      NVS_SLOT(RX) : origin = NVS_BASE ,length = NVS_SIZE
      /* Application uses internal RAM for data */
      SRAM (RWX) : origin = RAM_START, length = (RAM_END - RAM_START + 1)
    
      CCFG (RW) : origin = CCFG_BASE, length = CCFG_SIZE
    }
    
    /*******************************************************************************
     * Section Allocation in Memory
     ******************************************************************************/
    SECTIONS
    {
    #if defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT) || defined(OAD_DUAL_IMAGE)
    
    	.primary_hdr    :   > APP_HDR_SLOT, type = NOLOAD
    
    #if defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_DUAL_IMAGE)
    
        .resetVecs      :   > APP_BASE
        .text           :   > APP_SLOT
        .const          :   > APP_SLOT
        .constdata      :   > APP_SLOT
        .rodata         :   > APP_SLOT
        .binit          :   > APP_SLOT
        .cinit          :   > APP_SLOT
        .pinit          :   > APP_SLOT
        .init_array     :   > APP_SLOT
        .emb_text       :   > APP_SLOT
    
    #else
    
        .resetVecs      :   > PERSISTENT_BASE
        .text           :   > PERSISTENT_SLOT
        .const          :   > PERSISTENT_SLOT
        .constdata      :   > PERSISTENT_SLOT
        .rodata         :   > PERSISTENT_SLOT
        .binit          :   > PERSISTENT_SLOT
        .cinit          :   > PERSISTENT_SLOT
        .pinit          :   > PERSISTENT_SLOT
        .init_array     :   > PERSISTENT_SLOT
        .emb_text       :   > PERSISTENT_SLOT
    
    #endif //defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_DUAL_IMAGE)
    
    #else
      .resetVecs      :   >  FLASH_START
      .text           :   >> FLASH
      .const          :   >> FLASH
      .constdata      :   >> FLASH
      .rodata         :   >> FLASH
      .cinit          :   >  FLASH
      .pinit          :   >> FLASH
      .init_array     :   >  FLASH
      .emb_text       :   >> FLASH
    
    
    #endif //defined(OAD_APP_OFFCHIP) || defined(OAD_APP_ONCHIP) || defined(OAD_PERSISTENT) || defined(OAD_DUAL_IMAGE)
    
      .ccfg           :   > CCFG
      .ramVecs        :   > SRAM, type = NOLOAD, ALIGN(256)
      .data           :   > SRAM
      .bss            :   > SRAM
      .sysmem         :   > SRAM
      .nonretenvar    :   > SRAM
      .heap           :   > SRAM
      .stack          :   > SRAM (HIGH)
    
    }
    

    /*
     * Copyright (c) 2021-2023, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */ 
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <time.h>
    #include <string.h>
    
    /* Custom Includes */
    #include "Linux_Serial.h"
    #include "sbl_device.h"
    #include "sbl_device_cc2340.h"
    #include "myFile.h"
    
    /* read only variables */
    const char *portName = NULL;
    const char *filename = NULL; /*Path of .bin to be flashed*/
    const char *ccfgFilename= NULL;
    const char *command= NULL;
    static FILE *fPtr = NULL;  
    static FILE *CCFGfPtr= NULL; 
    
    /* CMD line cases */
    enum cmdArgs{
        ONE = 1,
        TWO = 2,
        THREE = 3,
        FOUR =4,
    };
    
    
    int main(int argc, char **argv)
    {
        printf("\n+-----------------------------------\n");
        printf("Serial Bootloader Library for CC2340\n");
        printf("Platform: Linux                     \n");
        printf("Compiler: GCC                       \n");
        printf("ARG0 = %s\n",argv[0]);
        printf("ARG1 = %s\n",argv[1]);
        printf("ARG2 = %s\n",argv[2]);
        printf("ARG3 = %s\n",argv[3]);
        printf("+-----------------------------------\n");
    
        /* Do some initial command line checks */
        switch(argc)
        {
        case FOUR:
            portName = argv[1];
            filename = argv[2];
            ccfgFilename=argv[3];
            printf("SBL Port i/p: %s\r\n", portName);
            printf("Firmware i/p: %s\r\n\n", filename);
            printf("CCFG Filename i/p: %s\r\n\n", ccfgFilename);
            printf("All Good :)\r\n");
            break;
        case TWO:
            if (strcmp(argv[1],"-help")==0){
    			printf("CC2340 -Linux Bootloader- HELP Overview\n");
    			printf("The function SBL.out take a total number of 3 Arguments:\n");
    			printf("To call the function use: \n");
    			printf("SBL.out [Serial Port] [Firmware] [CCFG]\r\n");
    			printf("[Serial Port]...name of serial port connected to CC2340\r\n");
    			printf("[Firmware]......Path of Firmware binary file\r\n");
    			printf("[CCFG]..........Path of CCFG binary file\r\n");
    			printf("+-----------------------------------\n");
    			exit(EXIT_SUCCESS);
    			break;}
        default:
            printf("INVALID ARG'S...EXISTING :(\r\n");
            printf("Valid format of running the SBL is:\r\n");
            printf("SBL.out [Serial Port] [Firmware Image path] [CCFG filepath]\r\n");
            printf("Type: SBL.out -help to get more information\r\n");
            printf("+-----------------------------------\n");
            exit(EXIT_FAILURE);
            break;
        }
    
        /*Start Bootloader 
        Initialize system*/
        printf("\n+-----------------------------------\n");
        uint8_t *memPtr = NULL;                 /* Ptr to hold read data */
        uint8_t *ccfgmemPtr = NULL;                 /* Ptr to hold read data */
        long fileSz = 0;                        /* Holds the size of the .bin file, in bytes */
        uint32_t fileCrc,ccfgCrc;       /* Variables to save CRC checksum */
        uint32_t tmp = 0;
        bool ackChk = false;
    
        uint32_t devCcfgBase=SBL_CC2340_CCFG_START_ADDRESS;      /*CFG start addrass only used for CC2340*/ 
        uint32_t byteCount=2048;       /*file size in bytes*/
        uint32_t ccfgByteCount=0;   /*file size in bytes for CC2340 CCFG*/
        uint32_t devFlashBase;   /*device Flash base*/
        printf("DevCcfgBase: 0x%x\r\n", devCcfgBase);
        printf("DevFlashBase: 0x%x\r\n", devFlashBase);
        uint32_t u32tRuntime_start,u32tRuntime_stop;
        u32tRuntime_start=time(NULL);
        
        printf("\n+-----------------------------------\n");
        /* Open the port */
        openPort(portName);
    
        /* Configure port */
        configPort();
        printf("+-----------------------------------\n");
    
        /* Setup callbacks */
        setupCallbacks();
    
        /* Set flash base for cc2340 */
        setDeviceFlashBase(CC23XX_FLASH_BASE);
    
        /* Detect baud rate */
        if(detectAutoBaud() != SBL_SUCCESS)
        {
            printf("ERROR: baud detect  failed\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
            printf("Baudrate detected !\n");
    
        /* Check if the host is reachable */
        if(ping() != SBL_SUCCESS)
        {
            printf("ERROR: Host unreachable\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
            printf("PING: Host detected !\n");
    
        if(readFlashSize(&tmp) != SBL_SUCCESS)
        {
            printf("ERROR: Unable to read flash size\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
            printf("Flash size: %u\n",getFlashSize());
    
        if(readRamSize(&tmp) != SBL_SUCCESS)
        {
            printf("ERROR: Unable to read RAM size\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
            printf("RAM size: %u\n",getRamSize());
    
        /* Open the file */
        if((fPtr = openFile(filename)) == NULL)
        {
            printf("ERROR: opening file\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("FILE open OK\n");
            if(!(fileSz = getFileSize(fPtr)))
            {
                printf("ERROR: getting file size\n");
                closePort();
                closeFile(fPtr);
                exit(EXIT_FAILURE);
            }
            else
            {
                printf("FILE size OK,\nFile Size: %lu Byte\n",fileSz);
    
                /* Allocate memory to read the file */
                memPtr = (uint8_t*)calloc(fileSz, sizeof(uint8_t));
                if(memPtr)
                {
                    uint32_t fileRd = 0;
    
                    printf(" CALLOC OK\n");
                    if((fileRd = fread(memPtr,1 , fileSz, fPtr)) != fileSz)
                    {
                        printf("ERROR: File read failed\n");
                        free(memPtr);
                        closePort();
                        closeFile(fPtr);
                        exit(EXIT_FAILURE);
                    }
                    else
                        printf("FILE read OK,\n file Read: %u Bytes\n", fileRd);
                }
                else
                {
                    printf("ERROR: calloc failed\n");
                    closePort();
                    closeFile(fPtr);
                    exit(EXIT_FAILURE);
                }
            }
        }/*End of all file operations*/ 
    printf("+-----------------------------------\n");
    /* Calculate file CRC checksum */
    fileCrc = calcCrcLikeChip(memPtr, fileSz);
    
    /*CCFG File Regions:
    ccfg.bootCfg.crc32          0x0000-0x000B
    ccfg.crc32                  0x0010-0x074B
    ccfg.userRecord.crc32       0x0750-0x07FB*/
       
    uint8_t Crc32Value[4];
    uint16_t CcfgRegionStart[4] =   {0x0000, 0x0010,0x075,0x07D0};
    uint16_t CcfgRegionEnd[4]=      {0x00B, 0x074, 0x0CB, 0x07FB};
    uint16_t regionStartAddr;
    uint16_t regionEndAddr;
    uint8_t addrIndex;
    
    if((CCFGfPtr = openFile(ccfgFilename)) == NULL)
        {
            printf("ERROR: opening file\n");
            closePort();
            exit(EXIT_FAILURE);
        }
        else
        {
            printf("FILE open OK\n");
            printf("+-----------------------------------\n");
            printf("Start Updating CCFG....\n");
    
            /*Update CRC32 for 4 regions in CCFG*/
            for(addrIndex=0;addrIndex<4;addrIndex++){
                regionStartAddr=CcfgRegionStart[addrIndex];
                regionEndAddr=CcfgRegionEnd[addrIndex];
    
                /*set Read pointer to the beginning*/
                fseek(CCFGfPtr,regionStartAddr,SEEK_SET);
    
                /*read datra from region start to region end*/
                ccfgByteCount=regionEndAddr-regionStartAddr+1;
            
                /* Allocate memory to read the file */
                ccfgmemPtr = (uint8_t*)calloc(ccfgByteCount, sizeof(uint8_t));
                printf("memory allocated");
                if(ccfgmemPtr)
                {
                    uint32_t fileRd = 0;
                    printf("CALLOC OK\n");
                    if((fileRd = fread(ccfgmemPtr,1 , ccfgByteCount, CCFGfPtr)) != ccfgByteCount)
                    {
                        printf("ERROR: File read failed\n");
                        free(ccfgmemPtr);
                        closePort();
                        closeFile(CCFGfPtr);
                        exit(EXIT_FAILURE);
                    }
                    else
                        printf("FILE read OK, fileRd: %u \n", fileRd);
                }
                else
                {
                    printf("ERROR: calloc failed\n");
                    closePort();
                    closeFile(CCFGfPtr);
                    exit(EXIT_FAILURE);
                }
                /*calculate CRC checksum*/
                uint32_t ccfgfileCrc=calcCrcLikeChip(ccfgmemPtr,ccfgByteCount);
                printf("CRC32 for 0x%x to 0x%x is %x\n",regionStartAddr,regionEndAddr,ccfgfileCrc);
                Crc32Value[0] = (uint8_t)   (ccfgfileCrc&0x000000FF);
                Crc32Value[1] = (uint8_t)   ((ccfgfileCrc&0x0000FF00)>>8);
                Crc32Value[2] = (uint8_t)   ((ccfgfileCrc&0x00FF0000)>>16);
                Crc32Value[3] = (uint8_t)   ((ccfgfileCrc&0xFF000000)>>24);
    
                printf("CRC32Value= [0x%x,0x%x,0x%x,0x%x]\n",Crc32Value[0],Crc32Value[1],Crc32Value[2],Crc32Value[3]);
    
                /*Set write pointe to Byte of region end*/
                fseek(CCFGfPtr,regionEndAddr,SEEK_SET);
                /*Add data to region End*/
                fwrite(&Crc32Value[0],1,4,CCFGfPtr);
                printf("***CRC32 written to file address  %x to %x\n",regionStartAddr,regionEndAddr);
            } /*end of for loop*/
            
            /*Get Overall file size*/
            ccfgByteCount = getFileSize(CCFGfPtr); 
            ccfgmemPtr = (uint8_t*)calloc(ccfgByteCount, sizeof(uint8_t));
            uint32_t fileRd = 0;
            if((fileRd = fread(ccfgmemPtr,1 , ccfgByteCount, CCFGfPtr)) != ccfgByteCount)
                    {
                    printf("ERROR: Erase failed\n");
                    free(memPtr);
                    free(ccfgmemPtr);
                    closePort();
                    closeFile(CCFGfPtr);
                    closeFile(fPtr);
                    exit(EXIT_FAILURE);
                    }
                    else{
                        printf("FILE read OK, fileRd: %u \n", fileRd);
                        ccfgCrc=calcCrcLikeChip(ccfgmemPtr,ccfgByteCount);                    
                        }
        closeFile(CCFGfPtr);        
        }/* End of all file operations*/
        printf("+-----------------------------------\n");
    
        /* Erase flash */
        printf("Erasing flash ...\n");
        if(chipErase()!= SBL_SUCCESS)
        {
            printf("ERROR: Erase failed\n");
            free(memPtr);
            free(ccfgmemPtr);
            closePort();
            closeFile(CCFGfPtr);
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
        else
            printf("ERASE OK\n");
    
    
        /* Write file to device flash memory */
        printf("+-----------------------------------\n");
        printf("Writing flash ...\n");
        if(writeFlashRange(getDeviceFlashBase(), fileSz, (char*)memPtr) != SBL_SUCCESS)
        {
            printf("ERROR: writing failed\n");
            free(memPtr);
            free(ccfgmemPtr);
            closePort();
            closeFile(CCFGfPtr);
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
        else
            printf("\nWRITE OK\n");
    
         /* Write ccfg file to device flash memory */
        printf("+-----------------------------------\n");
        printf("Writing ccfg ...\n");
        if(writeFlashRange(devCcfgBase, ccfgByteCount, (char*)ccfgmemPtr) != SBL_SUCCESS)
        {
            printf("ERROR: Writing failed\n");
            free(memPtr);
            free(ccfgmemPtr);
            closePort();
            closeFile(CCFGfPtr);
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
        else
            printf("WRITE OK\n");  
    
        /* Calculate CRC checksum of flashed content */
        printf("Calculating CRC of flashed content ...\n");
        if(calculateCrc32(getDeviceFlashBase(), fileSz, &fileCrc) != SBL_SUCCESS)
        {
            printf("ERROR: CRC failed\n");
            free(memPtr);
            closePort();
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
        printf("Calculating CRC of CCFG content ...\n");
        if(calculateCrc32(devCcfgBase, ccfgByteCount, &ccfgCrc) != SBL_SUCCESS)
        {
            printf("ERROR: CRC failed\n");
            free(memPtr);
            closePort();
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
    
        /* Reset the device */
        if(reset() != SBL_SUCCESS)
        {
            printf("ERROR: RST failed!\n");
            printf("ERROR: Erase failed\n");
            free(memPtr);
            free(ccfgmemPtr);
            closePort();
            closeFile(CCFGfPtr);
            closeFile(fPtr);
            exit(EXIT_FAILURE);
        }
        else
            printf("RST OK\n");
        u32tRuntime_stop=time(NULL);
        printf("Runtime: %i Seconds\n",u32tRuntime_stop-u32tRuntime_start);	
        /* If we got here, means all succeeded */
        printf("+-----------------------------------\n");
        printf("CC2340 FIRMWARE UPGRADE COMPLETED !-\n");
        printf("+-----------------------------------\n\n");
    
        /* De-allocate the memory */
        free(memPtr);
    
        /* Close all */
        closeFile(fPtr);
        free(ccfgmemPtr);
        closePort();
    
        /* exit on success */
        exit(EXIT_SUCCESS);
    }
    

  • Here is a screenshot from the URL I shared:

    I recommend that you use the default TI_CC2340_Linux_SBL tool provided online.  Your upgrades could very well be successful even if the CRC check fails.  You should check the changes you've made to your application before and after attempting the upgrade.  You could also choose to remove the CCFG area from your binary output generation if you do not need to apply any changes to the default CCFG settings.

    Regards,
    Ryan

  • Hi, TI Engineer

    I currently have the following questions:

    1. The ccfg file exported through the Uniflash tool starts at address 0x4e020000 and ends at address 0x4e0207ff. It cannot be exported to 0x4e020800. How can this be made compatible?

    2. In the screenshot below, the size of the out file starting with data is as shown. When we burn the file, the process fails at the beginning of writing to flash. The file size, after actual calculation, is not an integer multiple of 2048 bytes. How should this be configured? Please provide guidance.

    3. In the screenshot below, the size of the out file starting with uart is as shown. When we burn the file, the process fails during the CRC check after writing to flash. The file size, after actual calculation, is not an integer multiple of 2048 bytes. How should this be configured? Please provide guidance.

    4. The link to the TI_CC2340_Linux_SBL tool provided by your company is inaccessible. Could you please provide the link again?

  • 1.0x4e0207ff is the last byte of CCFG and the last byte you should be reading from Uniflash for the CCFG
    2. You should not use the .out file with the Linux SBL tool as it only accepts binaries.  You should be reading out memory in binary format from Uniflash aligned with the 0x800 sector size.  This will require programming a CC2340R5 device once with the .out file (does not have to be the ultimate target)
    4. Attached is a copy if you cannot access GitHub

    TI_CC2340_Linux_SBL.zip

    Regards,
    Ryan

  • Hi Ryan,
    I have a few questions to confirm with you:

    1. Previously, when we performed Bluetooth firmware upgrades via the emulator, only the FCFG file was required. However, upgrading via UART now requires the CCFG file as well. Is there a way to update the CCFG file without entering bootloader mode to enable programming and proceed with the UART Bluetooth firmware upgrade?
    2. During programming, if there is a random power failure (without programming the CCFG), is it possible that the device will fail to enter bootloader mode?
    3. Does UART programming support encryption? If so, how should we proceed?
    4. Is there a bad block detection mechanism in the programmed flash? If so, what steps should we take to prevent the generation of bad blocks?

    Thank you!

  • Please be sure to read Chapter 8 (Device Boot and Bootloader) of the TRM.

    1. You likely don't mean the FCFG as this is a factory configuration which cannot be altered by users.  Upgrading via UART doesn't require a CCFG file if the default FCFG settings are being used (indicated by a blank CCFG which TI ships devices as the default).  CCFG is stored in flash and it is not recommended that users erase and write this flash during run-time as it could invalidate the CCFG if a power event or device reset occurs.
    2. The BLDR_CMD_CHIP_ERASE command invalidates and then erases CCFG, so this is possible if you are using a custom CCFG that strays from the default FCFG. will not occur unless the power failure occurs during programming of the CCFG.
    3. The ROM Serial Bootloader does not, this would require use of a custom bootloader.  You can start with MCUBoot and develop from there.
    4. This is addressed through the BLDR_CMD_CRC32 command.

    Regards,
    Ryan

  • Hi Ryan

    1.Could you provide a demo or relevant guidance documents regarding encrypted programming using a custom bootloader?

    2.What is the BLDR_CMD_CRC32 command mentioned? How can we verify it ourselves? In the corresponding SBL source code or firmware program, where is this command handled?

    3.During the firmware programming process, what is the specific solution for the bad block detection mechanism? Can we verify it ourselves? How is it handled in the corresponding source code?

    Thank you!

  • 1. It's possible to select "User-specific bootloader" and its Bootloader Vector Table from SysConfig.  Encryption TI Drivers and examples are available for your reference, although there is no full-function custom bootloader solution currently provided by TI publicly.

    2. All bootloader commands are fully described in Chapter 8 (Device Boot and Bootloader) of the TRM so that users can fully operate the ROM Serial Bootloader to upgrade devices within their application.

    3. CRC32 (Cyclic Redundancy Check 32) is a 32-bit error-detecting code that produces a fixed-length checksum from a block of data to verify its integrity.

    Regards,
    Ryan

  • Hi Ryan

    1. After compiling the custom bootloader using the IDE, how can we write it to the corresponding location, and how can we verify whether the modifications have taken effect?
    2. Besides the modifications provided last time, are there any other areas that also need to be modified?

    Thank you!

  • 1. Your custom bootloader project should have its own command linker file (*.cmd in CCS) for which you will set the resetVecs and other sectors of Flash memory.  You can verify whether they have taken effect by stepping through code (see the Debug OAD Code section in a SLA) or adding in debuggable outputs (like GPIOs or UART).
    2. I wouldn't know what else to mention at this point or I would already have done so.

    Regards,
    Ryan

  • Hi Ryan

    Thank you very much for your help,When upgrading Bluetooth firmware, is it possible to update only the firmware without modifying the CCFG? I tried this myself, and although the flash was successfully programmed, I was unable to read the corresponding Bluetooth version number afterward. Additionally, the memory could not be accessed using the Uniflash tool,The debug port has already been enabled.

    Thank you!

  • The BLDR_CMD_CHIP_ERASE command erases CCFG

    This is why you either have to use the default FCFG settings (i.e. blank CCFG) or program a new CCFG at every bootloader programming sequence.  Based on the Uniflash feedback, it would appear that something was incorrectly written to the CCFG which would have caused it to become invalid.

    Regards,
    Ryan

  • Hi Ryan

    When updating the Bluetooth firmware, I only erased and updated the 512k flash without updating the CCFG file to keep it consistent with the previous version. After this operation, the Bluetooth version number could no longer be read, and no content in the memory could be accessed.

    Thank you!

  • Hi Mike,

    I apologize as I believe I have caused some confusion that I need to correct.  The blank CCFG settings only correspond to a blank device, and since you are programming new flash memory you will need to have the CCFG programmed to match as well.  You cannot continue to use the previous CCFG settings since they are invalidated and erased by the bootloader erase command.  I have revised my previous responses as such.  To be clear, the expected ROM Serial Bootloader procedure expects that both flash and CCFG contents will be written since both must be erased at the start of the sequence.

    Regards,
    Ryan

  • Hi Ryan

    I have a few more questions:

    1.When upgrading via the serial port, is there a strict requirement for the programming order of the CCFG and the Bluetooth firmware? Is it acceptable to program the CCFG before the firmware?

    2.Currently, the default baud rate for our host computer to program the flash is 115200. If we change it to another value, the upgrade fails. If we want to change it to 921600 to shorten the erase and programming time, where exactly should this be modified? Additionally, what is the maximum baud rate that can be set when programming firmware with the host computer, and what is the approximate bit error rate at the maximum baud rate?

    3.During non-initial upgrades of the CCFG area, can the host computer program be set to not erase or rewrite the CCFG, and continue using the CCFG file from the previous version? Or is this implemented in the bootloader, making it impossible for us to modify?

    Thank you!

  • 1. Although I don't see anything in the TRM that says you cannot or should not do this, it makes more sense for the CCFG to be the last flash programmed as it would validate the integrity of the ROM serial bootloader.  Otherwise if a reset or power cycle were to occur during firmware programming and the CCFG was already complete then it could cause the device to boot into an incomplete firmware application.

    2. Below is an excerpt from the TRM.  I don't know why you are finding 921600 to be invalid as this should be an acceptable value.  Can you clarify what exactly fails and how it is indicated?  Does 460800 succeed?  If using custom hardware then you may need to check the integrity of the UART lines.  Any bit error should be caught by the CRC check.

    8.5.1.2.1.1 UART Baud Rate Automatic Detection The bootloader provides a method to automatically detect the UART baud rate used to communicate with it. To synchronize with the host, the bootloader must receive 2 bytes with the value of 0x55. If synchronization succeeds, the bootloader returns an acknowledge consisting of 2 bytes with the values of 0x00 and 0xCC. If synchronization fails, the bootloader waits for synchronization attempts. In the automatic-detection function, the UART0 RX pin is monitored for edges using GPIO interrupts. When enough edges are detected, the bootloader determines the ratio of baud rate and frequency needed to program the UART. The UART module system clock must be at least 16 times the baud rate; thus, the maximum baud rate can be no higher than 3Mbaud (48MHz divided by 16). The maximum baud rate is restricted to 1.6Mbaud because of the firmware function that detects the transfer rate of the host.

    3. The only bootloader erase command includes erase of the CCFG, so if updating the application then the CCFG must be programmed as well.  You can likely program the same CCFG contents as before.

    Regards,
    Ryan

  • Hi Ryan

    Here are my two questions:

    1. Currently, only the baud rate of 115200 is available. Other baud rates will result in a baud rate mismatch error. Based on the code shown in the screenshot, it seems that the MCU is not returning `0x00, 0xCC` or `0x00, 0x33`, which causes the issue. Are these return values hardcoded, or can I modify them myself?

    2. In the CCS tool, there is an option to set the baud rate, but it is greyed out and cannot be modified, as shown in the screenshot. Can I modify this setting myself? If so, how can I do it?

    Thanks!

  • 1. The TI_CC2340_Linux_SBL tool supports multiple baud rate settings.  How are you changing the baud rate and have you confirmed the output TX with a logic analyzer or oscilloscope.

    2. You are looking at the SysConfig file for an example application which does not apply to the Serial ROM Bootloader functionality.

    From the TI_CC2340_Linux_SBL README:

    The Serial Boot loader is offering a prebuilt SBL.out file which can be used to run the pre-compiled image.

    In order to optimize the bootloader for your application it is possible to change the C-Code provided within the Source folder.

    The SBL consists mainly of the a set of .c and .h files:

    • Linux_Serial.c | Linux_Serial.h
    • main.c
    • myFile.c|myFile.h
    • sbl_device.c|sbl_device.h
    • sbl_device_cc2340.c|sbl_device_cc2340.h
    • sbl_device.c|sbl_device.h

    These files can be used to adapt the bootloader to custom applications.

    An example change is:

    Adapt baudrate: This can be done following the following steps:

    • Add the desired Baudrate to the baudSet_t enumeration in Linux_Serial.h
    • Add case in setBaudRate() function in Linux_Serial.c
    • Change setBaudRate() in configPort function

    To built the project after changing it is possible to use the makefile which is provided in the TI_CC2340_Linux_SBL folder. This can be done used by calling "make" from the Linux terminal.

    Regards,
    Ryan

  • Hi Ryan

        1.Although we checked the datasheet and found that baud rates between 9600 and 1.6Mbaud can be automatically detected, during debugging, only the baud rates shown in the screenshot can be detected and used normally. Could it be that other higher baud rates have not been configured? Additionally, as shown in the screenshot, why does the programming time not decrease by half when the baud rate is doubled?

        2.Additionally, when writing to flash, why does the total time taken for each write operation vary? What could be the reason for this phenomenon?

        3.When the baud rate is 460800, the programming time exceeds 100 seconds. Is this abnormal? What are the specific reasons causing this?


    Thanks!

  • Please keep in mind that the baud rate can be increased but that writing flash memory and performing other flash commands are static. Thus doubling the baud rate will not inherently halve the download speed. I would imagine if you cannot achieve a baud rate of 921600 then this presents a susceptibility with the host's generation of the baud. I am out of office through Friday of this week, so responses may be delayed.

    Regards,

    Ryan

  • Hi Ryan

    Here is the translation of your questions:

    1. I found that with a baud rate of 460800, the standard transmission speed for serial communication is approximately 30 to 40 seconds. However, in my own tests, it has already exceeded 100 seconds. Why is there such a large discrepancy?
    2. If the process of writing to flash memory and executing flash commands is static, what would be an appropriate download speed when the baud rate is doubled?
    3. During my tests, the maximum baud rate I could use was 460800. Beyond this range, a mismatch error occurs. You mentioned that there might be an issue with the host's generation of the baud rate. Specifically, what kind of issue could this be? Is it possible for us to modify it to increase the baud rate?
    4. When using the same baud rate, why does the time required to flash the memory vary with each attempt when flashing the memory multiple times consecutively?

    Thanks!

  • 1. Are you using the same binary image to program each time, and does the size of the binary ever vary?  Are you certain that there wasn't a CRC mismatch which caused a restart to the procedure?
    2. I haven't run any test but I expect it would be linear to binary image size and baud rate
    3. What is your hardware (TI EVMs, custom design, etc.) and can you provide an oscilloscope or logic analyzer measurement of a failed baud rate detection procedure?
    4. I'm not certain that is the case without further evidence.  By "consecutive" do you mean during each restart into the bootloader or are you flashing the device multiple times int he same bootloader sequence?

    Regards,
    Ryan

  • Hi Ryan

    1. During my debugging process, I used the same binary image with identical sizes, and no CRC checksum failures occurred throughout the entire flashing process.
    2. In my self-tests, when using the same binary image with different baud rates, the flashing time decreased as the baud rate increased within the usable range. However, the total completion time still did not meet the expected performance.
    3. I am using the CC2340R5RGE Bluetooth MCU. Due to current limitations, I am unable to provide the corresponding measurement data at this time.
    4. By "consecutive," I mean each time the bootloader is re-entered for serial flashing.

    Thanks!

  • Thanks for the information.  What is the "expected performance" you are looking to achieve?  Are you using any padding or blank space in your binary image, and if so is it possible to reduce the amount of flash size you write to or is it necessary to write the full 512 kB?

    Regards,
    Ryan

  • Hi Ryan

    Based on the previous question, I would like to add the following points you mentioned:
    1. The expected performance refers to the fact that, at a baud rate of 460800 for the serial port, the standard transmission time for 512 kB of flash should be around 57 seconds. However, our current time exceeds 100 seconds.
    2. We are writing the entire 512 kB of flash. Are there any blocks in the flash that do not need to be erased and rewritten? Or is it possible to skip certain blocks and avoid writing the entire 512 kB of flash?

    Thanks!

  • Hi mike,

    I'm testing with a TTL232R-3V3 FTDI to USB cable, as the XDS110 should not be used with this tool, and able to achieve both baud rates 406800 and 921600 with a full flash 512 kB image (0x7FFFF).  If I only read out the flash from 0x0 to 0x3FFFF in Uniflash (enough flash space for my BLE application according to the output *.map file without the NVS area, thus saved connections are not restored after the update) then the times while using a 406800 baud reduces from 70s to 37s.  If I further remove setProgress and set bExpectAck to false in sbl_device_cc2340.c like instructed in the README then the time is further reduced to 20s.

    Regards,
    Ryan

  • Hi Ryan

    I have made the modifications based on your suggestions, but I still have the following issues:

    1. After only reading the Flash from 0x0 to 0x3FFFF and removing setProgress and setting bExpectAck to false in the sbl_device_cc2340.c file, the programming time has been reduced to around 35 seconds with a baud rate of 460800. However, it still does not reach the 20 seconds you mentioned. What could be the reason for this?
    2. I have provided the source code of my modified sbl_device_cc2340.c and Linux_Serial.c file below. Could you help me check what differences exist compared to the demo code you provided? I mean, why does the same code still result in an additional 15 seconds of programming time? Additionally, this file contains the baud rate parameters we configured ourselves, but 921600 still cannot be used. Could you help check if there are any issues with the parameter configuration?
    3. Could you please provide your contact information? This would make communication more efficient.
      /*sbl_device_cc2340.c write flash*/
      tSblStatus writeFlashRange(uint32_t ui32StartAddress,
                                 uint32_t ui32ByteCount, const char *pcData)
      {
          uint32_t devStatus = CMD_RET_UNKNOWN_CMD;
          tSblStatus retCode = SBL_SUCCESS;
          char u8tCmdStatus[1];
          uint32_t bytesLeft, dataIdx, bytesInTransfer,u32tStatusLength=1;
          uint32_t transferNumber = 1;
          bool bACK=true;
          bool bBlToBeDisabled = false;
          tTransfer pvTransfer[2];
          uint32_t ui32TotChunks = (ui32ByteCount / SBL_CC2340_MAX_BYTES_PER_TRANSFER);
          uint32_t ui32CurrChunk = 0;
          if(ui32ByteCount % SBL_CC2340_MAX_BYTES_PER_TRANSFER) ui32TotChunks++;
      
          /*Init transfer*/
          pvTransfer[0].bExpectAck  = false;           /*Check if operation successfull?*/
          pvTransfer[0].byteCount = ui32ByteCount;   
          pvTransfer[0].startAddr = ui32StartAddress;
          pvTransfer[0].startOffset = 0;
      
          /* For each transfer */
          for(uint32_t i = 0; i < 1; i++)
          {
              /* Sanity check */
              if(pvTransfer[i].byteCount == 0)
                  continue;
      
              /* Set progress */
              //setProgress(addressToPage(pvTransfer[i].startAddr));
      
              /* Send download command */
              if((retCode = cmdDownload(pvTransfer[i].startAddr,
                                        pvTransfer[i].byteCount)) != SBL_SUCCESS)
                  return (retCode);
      
              /* Check status after download command */
              retCode = readStatus(&devStatus);
              if(retCode != SBL_SUCCESS)
              {
                  printf("Error during download initialization. Failed to read device status after sending download command.\n");
                  return (retCode);
              }
      
              /* Send data in chunks */
              bytesLeft = pvTransfer[i].byteCount;
              dataIdx   = pvTransfer[i].startOffset;
              while(bytesLeft)
              {
      			/* Set progress */
                  //setProgress( ((100*(++ui32CurrChunk))/ui32TotChunks) );		
                  /* Limit transfer count */
                  bytesInTransfer = MIN(SBL_CC2340_MAX_BYTES_PER_TRANSFER, bytesLeft);
      
      			/* Send Data command */
                  if((retCode = cmdSendData((const uint8_t*)&pcData[dataIdx], bytesInTransfer)) != SBL_SUCCESS)
                  {
                      printf("Error during flash download. \n- Start address 0x%08X (page %d). \n- Tried to transfer %d bytes. \n- This was transfer %d.\n",
                             (ui32StartAddress+dataIdx),
                             addressToPage(ui32StartAddress+dataIdx),
                             bytesInTransfer,
                             (transferNumber));
                      return (retCode);
                  }
      
                  if(pvTransfer[0].bExpectAck){
                  	if((retCode=sendCmd(CMD_GET_STATUS,NULL,0))!=SBL_SUCCESS){
          			printf("Sending GET_STATUS_CMD failed\n");
          		return(SBL_ERROR);}
      
      			/* Receive command response (ACK/NAK) */
          		if((retCode = getCmdResponse(&bACK, 5)) != SBL_SUCCESS){
          		printf("Device NAKed Status CMD command\n");
          		return (retCode);}
      
          		if(retCode = getResponseData((uint8_t*)u8tCmdStatus,&u32tStatusLength,0) != SBL_SUCCESS){
          			sendCmdResponse(false);
              		return (retCode);}
          		sendCmdResponse(true);
      
          		if(u8tCmdStatus[0]!=0x40){
          		printf("Error during flash download. \n- Start address 0x%08X (page %d). \n- Tried to transfer %d bytes. \n- This was transfer %d.\n",
                             (ui32StartAddress+dataIdx),
                             addressToPage(ui32StartAddress+dataIdx),
                             bytesInTransfer,
                             (transferNumber));
                             return (SBL_ERROR);
          		}
                  }
      			bytesLeft -= bytesInTransfer;
                  dataIdx += bytesInTransfer;
                  transferNumber++;
      			}
              }
          return (SBL_SUCCESS);
      }
      
      
      
      
      /*Linux_Serial.c SetBaudParm*/
      static void setBaudRate(int baud)
      {
          switch(baud)
          {
          case 38400:
              /*Set Baudrate to 38400 Baud*/
              cfsetispeed(&SerialPortSettings,B38400);
              cfsetospeed(&SerialPortSettings,B38400);
              printf("\n  BaudRate = 38400\n");
              break;
          case 57600:
              /*Set Baudrate to 57600 Baud*/
              cfsetispeed(&SerialPortSettings,B57600);
              cfsetospeed(&SerialPortSettings,B57600);
              printf("\n  BaudRate = 57600\n");
              break;
          case 230400:
              /*Set Baudrate to 230400 Baud*/
              cfsetispeed(&SerialPortSettings,B230400);
              cfsetospeed(&SerialPortSettings,B230400);
              printf("\n  BaudRate = 230400\n");
              break;
          case 460800:
              /*Set Baudrate to 460800 Baud*/
              cfsetispeed(&SerialPortSettings,B460800);
              cfsetospeed(&SerialPortSettings,B460800);
              printf("\n  BaudRate = 460800\n");
              break;
          case 9600:
              /*Set Baudrate to 9600 Baud*/
              cfsetispeed(&SerialPortSettings,B9600);
              cfsetospeed(&SerialPortSettings,B9600);
              printf("\n  BaudRate = 9600\n");
              break;
          case 1000000:
              /*Set Baudrate to 1000000 Baud*/
              cfsetispeed(&SerialPortSettings,B1000000);
              cfsetospeed(&SerialPortSettings,B1000000);
              printf("\n  BaudRate = 1000000\n");
              break;
          case 2000000:
              /*Set Baudrate to 2000000 Baud*/
              cfsetispeed(&SerialPortSettings,B2000000);
              cfsetospeed(&SerialPortSettings,B2000000);
              printf("\n  BaudRate = 2000000\n");
              break;
          case 115200:
              /*Set Baudrate to 115200 Baud*/
              cfsetispeed(&SerialPortSettings,B115200);
              cfsetospeed(&SerialPortSettings,B115200);
              printf("\n  BaudRate = 115200\n");
              break;
          case 921600:
              /*Set Baudrate to 921600 Baud*/
              cfsetispeed(&SerialPortSettings,B921600);
              cfsetospeed(&SerialPortSettings,B921600);
              printf("\n  BaudRate = 921600\n");
              break;
          case 1152000:
              /*Set Baudrate to 1152000*/
              cfsetispeed(&SerialPortSettings,B1152000);
              cfsetospeed(&SerialPortSettings,B1152000);
               printf("\n  BaudRate = 1152000\n");
              break;
          case 1500000:
              /*Set Baudrate to 1500000*/
              cfsetispeed(&SerialPortSettings,B1500000);
              cfsetospeed(&SerialPortSettings,B1500000);
               printf("\n  BaudRate = 1500000\n");
              break;
      
          default:
              printf("ERROR: INVALID BAUD\n");
              break;
          }
      }
      
      /****************************************************************
       * Function Name : configPort
       * Description   : Populate the termios structure
       * Returns       : None
       * Params        @None
       ****************************************************************/
      void configPort(int baudspeed)
      {
           /*Using thermios structure to set Serial Port structure*/
          memset(&SerialPortSettings, 0, sizeof(SerialPortSettings));
          setBaudRate(baudspeed);
      
          /*Configure serial port message interpretation */
          /* Enable receiver*/ 
          SerialPortSettings.c_cflag |= (CLOCAL | CREAD);
      
          /* Set Data Size= 8Bit        */
          SerialPortSettings.c_cflag &= ~CSIZE;                           
          SerialPortSettings.c_cflag |= CS8;
      
          /* No Parity   */
          SerialPortSettings.c_cflag &= ~PARENB;
      
          /* 1 Stop bit */
          SerialPortSettings.c_cflag &= ~CSTOPB;
          SerialPortSettings.c_cflag &= ~CRTSCTS;
      
          /* setup for non-canonical mode */
          SerialPortSettings.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);
          SerialPortSettings.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
          SerialPortSettings.c_oflag &= ~OPOST;
      
          /* fetch bytes as they become available */
          SerialPortSettings.c_cc[VMIN] = 0;
          SerialPortSettings.c_cc[VTIME] = 2;
      
          /* Flush out if there is any previously pending shit* */
          clearRxbuffer();
      
          if((tcsetattr(fd,TCSANOW,&SerialPortSettings)) != 0)
              perror("ERROR in Setting attributes |");
          else
              printf("  StopBits = 1 \n  Parity   = none\n");
      }
      
    1. Our times are very similar, mine was only reduced further after modifying the sbl_device_cc2340.c file of the default example as provided from GitHub.
    2. The code sources appear similar.  Did you make sure to re-build the tool after saving changes?  You should no longer see the flash write procedure updating from 0 to 100%, but it will still be progressing in the background.
    3. I believe other forms of communication would provide no further benefit to the resolution of this investigation.

    Regards,
    Ryan

  • Hi Ryan

    I have two more questions.

    **Question 1:**
    As shown in the screenshot of the `main.c` file:
    ```c
    uint16_t CcfgRegionStart[4] = {0x0000, 0x0010, 0x0750, 0x07D0};
    uint16_t CcfgRegionEnd[4] = {0x000B, 0x074B, 0x07CB, 0x07FB};
    ```
    Regarding the start and end addresses of the `ccfg` file, in the function `fseek(CCFGfPtr, regionEndAddr, SEEK_SET);`, does the offset need to add one to the end address? Otherwise, the next write operation might directly overwrite the byte at the end address. Additionally, how can I ensure the accuracy of the CRC checksum value when writing in this way?

    **Question 2:**
    In the function `fwrite(&Crc32Value[0], 1, 4, CCFGfPtr);`, during the writing process, if a power failure or device reboot occurs, will the file be corrupted? Can this be modified to write directly from memory instead?

    Thanks!

  • Regarding the start and end addresses of the `ccfg` file, in the function `fseek(CCFGfPtr, regionEndAddr, SEEK_SET);`, does the offset need to add one to the end address? Otherwise, the next write operation might directly overwrite the byte at the end address. Additionally, how can I ensure the accuracy of the CRC checksum value when writing in this way?

    The CCFGfPtr file is closed before any other bytes are written, so I don't understand the concern.  You've shown where the CRC is calculated, are you trying to read back the value you wrote to CCFGfPtr to verify that it's correct?  I'm sure you can use fread to accomplish that, although I don't understand the intent.

    In the function `fwrite(&Crc32Value[0], 1, 4, CCFGfPtr);`, during the writing process, if a power failure or device reboot occurs, will the file be corrupted? Can this be modified to write directly from memory instead?

    Behavior depends on the CRC32 in question: Ccfg.bootCfg.crc32, Ccfg.crc32, Ccfg.userRecord.crc32, Ccfg.debugCfg.crc32.  If the Ccfg.bootCfg.crc32 is incorrect when the device restarts then the bootloader is disabled then there will be boot configuration issues as mentioned in the TRM.  Otherwise the situation could be recovered by reperforming the bootloader flashing sequence.

    Regards,
    Ryan

  • Hi Ryan

        Our BLE protocol supports cross-platform functionality, such as the iOS system. However, currently, we can only search for the corresponding Bluetooth name using Android devices, while iOS devices are unable to detect it. Does this require reconfiguring the protocol to make it effective?

    Thanks!

  • Hi mike,

    This is not a typical observation as the SimpleLink Connect App works for either Android or iOS for the basic_ble or data_stream projects.  You would need to provide more details about your project changes and iOS versions, however I ask that you start a new E2E post when doing so as this current thread covers a different topic (ROM serial bootloader).

    Regards,
    Ryan