Сборка firmware для CC2652 из Makefile

82f9c423db734cf6b5dc257ea1514a25.JPG

Если вы когда-либо работали с микроконтроллерами от компании Texas Instruments (TI), то 70%…90% вероятность, что вы их программировали в GUI-IDE под названием Code Composer Studio (CCS). Как и у любой IDE CCS свойственны недостатки: ручные операции мышкой по настройке конфигураций, зависания GUI, отказ от сборки из консоли, калейдоскоп всяческих раcширений файлов, про которые даже местная техподдержка TI не в курсе, отказ от сборки проекта, если файл проекта находится вне пути на который ссылается переменная окружения WORKSPACE_LOC и прочее. Все эти проблемы можно разом решить, если собирать прошивки из самописных Makefile (ов) при помощи компилятора GNU ARM GCC.

О пользе makefile существует отдельный текст, вот он https://habr.com/ru/post/723054/ . Если коротко, то с makefile (лами) намного проще делать полноценный DevOps, CI/CD и вообще масштабировать кодовую базу на другие процессорные архитектуры. Также сборка из makefile просто не позволяет разработчику производить неосознаных действий подобно тому как это повсеместно происходит в меню IDE.

Сборка прошивки для CC26×2 из Makefile

Фаза 1: подготовка оборудования, документации и софтвера

a--Что надо из оборудования?

#

оборудование

1

LapTop

2

отладочная плата LAUNCHXL-CC26×2R1

3

кабель USB-A-USB micro

В качестве отладочной платы я воспользуюсь платой LAUNCHXL-CC26×2R1. Там заложен микроконтроллер CC2652R1.

LAUNCHXL-CC26X2R1

LAUNCHXL-CC26×2R1

Вот примерная блок-схема платы LAUNCHXL-CC26×2R1. Мы видим, что тут есть сам микроконтроллер CC2652R1F и программатор отладчик XDS110.

ada72860c6ee41a50ec0f7a0ef3efc95.png

Итак, что мы вообще знаем про микроконтроллер CC2652R1FRGZ?

Параметр

значение

Unit

Ядро

Arm Cortex-M4F

--

Архитектура

ARMv7-M

RF Core

Arm Cortex-M0

разрядность

32

bit

FPU

IEEE 754-compliant single-precision

RAM start

0×20000000

hex

GPRAM start

0×11000000

hex

GPRAM size

8

kByte

ROM start

0

hex

FLASH_CCFG start

0×00057fa8 (44тый сектор)

hex

количество секторов Flash памяти

44

dec

RAM size

80

kByte

ROM size

352

kByte

Flash sector size

8

kByte

Cache SRAM size

8

kByte

Peripherals

GPIO DAC UART ADC SPI I2C I2S AES TRNG Bluetooth 5.1, Timers MPU

-

Prog Interface

JTAG

-

CPU clock

48

MHz

Pin number

48

pin

GPIO count

31

pin

Порядок байтов

little Endian

-

Корпус микросхемы

RGZ (7-mm x 7-mm VQFN48)

Шаг между пинами

0.5

мм

Все эти данные об внутреннем устройстве микроконтроллера CC2652R1FRGZ нужны для формирования корректных опций компилятору и для написания корректного скрипта для компоновщика (*.ld файл).

b--Какие нужны доки?

Название дока

количество
страниц

комментарий

1

Using GCC/GDB With SimpleLink CC26xx/CC13xx

33

Перечень состава ToolChain (а) для GCC специально для TI MCU

2

CC2652R SimpleLink Multiprotocol 2.4 GHz Wireless MCU

70

флаер на микроконтроллер

3

CC13×2, CC26×2 SimpleLink Wireless MCU Technical Reference Manual

2083

спецификация микроконтроллера

4

Cortex-M3/M4F Instruction Set

221

Спецификация процессорного ядра

5

WCS037 LAUNCHXL-CC26×2R1

7

схемотехника отладочной платы

c--Что надо из софтвера?

#

Программа

назначение

1

OS Windows

операционная система

2

Eclipse

текстовый редактор

3

GNU Toolchain

компилятор, компоновщик, отладчик

4

UniFlash

прошивальщик

9

SmartRF Flash Programmer 2

еще один прошивальщик

10

XDS Emulation Software (EMUPack) (64-bit Windows)

Набор утилит в котором есть GDB сервер для микроконтроллеров CC26×2

8

C:\ti\simplelink_cc13xx_cc26xx_sdk_5_40_00_40

Исходные коды инициализации периферии микроконтроллеров семейства cc26xx

5

Build tools for Windows

набор вспомогательных консольных утилит для сборки программ. make, rm

12

make

универсальная утилита, которая управляет конвейером последовательности запуска консольных утилит на основе скрипта makefile

13

grep

утилита поиска файлов по ключевому регулярному выражению которое есть внутри найденных файлов

6

gdb_agent_console.exe

утилита GDB сервера для микроконтроллеров от TI

7

arm-none-eabi-gdb.exe

универсальная утилита GDB клиента

11

Tera Term

Терминал последовательного COM порта для диалога с прошивкой по UART

Проверить корректность установки GNU Toolchainможно выполнив команду arm-none-eabi-gcc --version в консоли Windows

b1a54bd743327cbc99b724042981a9ab.png

Нужна утилита make. Её можно взять из состава MinGW.

da2a12abdc38bc8ffb07343d0103c73d.png

Фаза 2: Подготовка скрипта настройки компоновщика.

Обычно сам С-код не особе аппаратно-зависмый. Наиболее аппаратно-зависимые исходники это файл настройки компоновщика. В GCC это *.ld файлы. Где же взять *.ld файл для микроконтроллера cc2652r1frgz? Ответ прост. Надо порыться прямо в SDK. При помощи утилиты grep я вскоре сузил место поиска до папки
C:\ti\simplelink_cc13xx_cc26xx_sdk_5_40_00_40\source\ti\devices\cc13×2_cc26×2\linker_files. Там и лежал подходящий файл разметки компоновщика cc26×2r1f.lds

/*
 @file      cc26x2r1f.lds
 @brief     CC26x2R1F rev2 linker configuration file for GNU compiler.
 */

/* Entry Point */
ENTRY( ResetISR )

/* System memory map */
MEMORY
{
    /* Application is stored in and executes from internal flash */
    FLASH (RX) : ORIGIN = 0x0, LENGTH = 0x57FA8
    /* Customer Configuration Area (CCFG) */
    FLASH_CCFG (RX) : ORIGIN = 0x57FA8, LENGTH = 88
    /* Application uses internal RAM for data */
    SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x14000
    /* Application can use GPRAM region as RAM if cache is disabled in the CCFG
       (DEFAULT_CCFG_SIZE_AND_DIS_FLAGS.SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM = 0) */
    GPRAM (RWX) : ORIGIN = 0x11000000, LENGTH = 0x2000
}

/*. Highest address of the stack. Used in startup file .*/
_estack = ORIGIN(SRAM) + LENGTH(SRAM); /*end of SRAM .*/

/*. Generate a link error if heap and stack does not fit into RAM .*/
_Min_Heap_Size = 0;
_Min_Stack_Size = 0x100;

/* Section allocation in memory */
SECTIONS
{
    .text :
    {
        _text = .;
        KEEP(*(.vectors))
        *(.text*)
        *(.rodata*)
        *(.init)
        *(.fini*)
        *(.eh_frame*)
        _etext = .;
    } > FLASH = 0

   .ARM.exidx :
    {
        __exidx_start = .;
        *(.ARM.exidx* .gnu.linkonce.armexidx.*)
        __exidx_end = .;
    } > FLASH

    .ARM.extab :
    {
        *(.ARM.extab* .gnu.linkonce.armextab.*)
    } > FLASH

    .init_array :
    {
        _init_array = .;
        KEEP(*(SORT(.init_array.*)))
        KEEP(*(.init_array*))
        _einit_array = .;
    } > FLASH

    .data :
    {
        _data = .;
        *(vtable)
        *(.data*)
        _edata = .;
    } > SRAM AT > FLASH
    _ldata = LOADADDR(.data);

    .bss :
    {
        __bss_start__ = .;
        _bss = .;
        *(.bss*)
        *(COMMON)
        _ebss = .;
        __bss_end__ = .;
    } > SRAM

    .ccfg :
    {
        KEEP(*(.ccfg));
    } > FLASH_CCFG

    /* User_heap_stack section, used to check that there is enough SRAM left */
    ._user_heap_stack :
    {
      . = ALIGN(4);
      . = . + _Min_Heap_Size;
      . = . + _Min_Stack_Size;
      . = ALIGN(4);
    } > SRAM

    .gpram :
    {
    } > GPRAM
}

Фаза 3: Подготовка startup кода

До запуска main () должен отрабатывать startup код. Где же найти файл для startup кода? Тут опять поиск grep (оп) внутри SDK по имени микроконтроллера и ключевому слову startup привел меня к файлу startup_gcc.c. У ST обычно startup написан ан assembler, но у TI startup файл написан на С. Это хорошо и понятно. Внутри startup_gcc.c есть функция ResetISR (). Функция ResetISR инициализирует глобальные переменные (rwdata), обнуляет неинициализированные переменные (bss), активирует FPU и запускает функцию main (), а если main дала осечку — запускает зависание в бесконечном цикле. В startup коде также перечислены все обработчики прерываний для микроконтроллеров сс26×2.

/******************************************************************************
*  Filename:       startup_gcc.c
*  Revised:        $Date: 2017-06-01 16:01:48 +0200 (Thu, 01 Jun 2017) $
*  Revision:       $Revision: 17804 $
*
*  Description:    Startup code for CC26x2 device family for use with GCC.
*
******************************************************************************/

//*****************************************************************************
// Check if compiler is GNU Compiler
//*****************************************************************************
#if !(defined(__GNUC__))
#error "startup_gcc.c: Unsupported compiler!"
#endif

#include "../inc/hw_types.h"
#include "../driverlib/setup.h"

//*****************************************************************************
// Macro for weak symbol aliasing
//*****************************************************************************
#define WEAK_ALIAS(x) __attribute__ ((weak, alias(#x)))

//*****************************************************************************
// Forward declaration of the reset ISR and the default fault handlers.
//*****************************************************************************
void        ResetISR( void );
static void NmiSRHandler( void );
static void FaultISRHandler( void );
static void IntDefaultHandler( void );
extern int  main( void );

// Default interrupt handlers
void NmiSR(void) WEAK_ALIAS(NmiSRHandler);
void FaultISR(void) WEAK_ALIAS(FaultISRHandler);
void MPUFaultIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void BusFaultIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void UsageFaultIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void SVCallIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void DebugMonIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void PendSVIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void SysTickIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void GPIOIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void I2CIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void RFCCPE1IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void PKAIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AONRTCIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void UART0IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXSWEvent0IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void SSI0IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void SSI1IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void RFCCPE0IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void RFCHardwareIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void RFCCmdAckIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void I2SIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXSWEvent1IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void WatchdogIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer0AIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer0BIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer1AIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer1BIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer2AIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer2BIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer3AIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void Timer3BIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void CryptoIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void uDMAIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void uDMAErrIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void FlashIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void SWEvent0IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXCombEventIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AONProgIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void DynProgIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXCompAIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXADCIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void TRNGIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void OSCIntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void AUXTimer2IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void UART1IntHandler(void) WEAK_ALIAS(IntDefaultHandler);
void BatMonIntHandler(void) WEAK_ALIAS(IntDefaultHandler);


//*****************************************************************************
// The following are constructs created by the linker, indicating where the
// the "data" and "bss" segments reside in memory.
//*****************************************************************************
extern uint32_t _ldata;
extern uint32_t _data;
extern uint32_t _edata;
extern uint32_t _bss;
extern uint32_t _ebss;
extern uint32_t _estack;

//*****************************************************************************
//! The vector table. Note that the proper constructs must be placed on this to
//! ensure that it ends up at physical address 0x0000.0000 or at the start of
//! the program if located at a start address other than 0.
//*****************************************************************************
__attribute__ ((section(".vectors"), used))
void (* const g_pfnVectors[])(void) =
{
    (void (*)(void))((unsigned long)&_estack),
                                            //  0 The initial stack pointer
    ResetISR,                               //  1 The reset handler
    NmiSR,                                  //  2 The NMI handler
    FaultISR,                               //  3 The hard fault handler
    MPUFaultIntHandler,                     //  4 Memory Management (MemManage) Fault
    BusFaultIntHandler,                     //  5 The bus fault handler
    UsageFaultIntHandler,                   //  6 The usage fault handler
    0,                                      //  7 Reserved
    0,                                      //  8 Reserved
    0,                                      //  9 Reserved
    0,                                      // 10 Reserved
    SVCallIntHandler,                       // 11 Supervisor Call (SVCall)
    DebugMonIntHandler,                     // 12 Debug monitor handler
    0,                                      // 13 Reserved
    PendSVIntHandler,                       // 14 The PendSV handler
    SysTickIntHandler,                      // 15 The SysTick handler
    //--- External interrupts ---
    GPIOIntHandler,                         // 16 AON edge detect
    I2CIntHandler,                          // 17 I2C
    RFCCPE1IntHandler,                      // 18 RF Core Command & Packet Engine 1
    PKAIntHandler,                          // 19 PKA Interrupt event
    AONRTCIntHandler,                       // 20 AON RTC
    UART0IntHandler,                        // 21 UART0 Rx and Tx
    AUXSWEvent0IntHandler,                  // 22 AUX software event 0
    SSI0IntHandler,                         // 23 SSI0 Rx and Tx
    SSI1IntHandler,                         // 24 SSI1 Rx and Tx
    RFCCPE0IntHandler,                      // 25 RF Core Command & Packet Engine 0
    RFCHardwareIntHandler,                  // 26 RF Core Hardware
    RFCCmdAckIntHandler,                    // 27 RF Core Command Acknowledge
    I2SIntHandler,                          // 28 I2S
    AUXSWEvent1IntHandler,                  // 29 AUX software event 1
    WatchdogIntHandler,                     // 30 Watchdog timer
    Timer0AIntHandler,                      // 31 Timer 0 subtimer A
    Timer0BIntHandler,                      // 32 Timer 0 subtimer B
    Timer1AIntHandler,                      // 33 Timer 1 subtimer A
    Timer1BIntHandler,                      // 34 Timer 1 subtimer B
    Timer2AIntHandler,                      // 35 Timer 2 subtimer A
    Timer2BIntHandler,                      // 36 Timer 2 subtimer B
    Timer3AIntHandler,                      // 37 Timer 3 subtimer A
    Timer3BIntHandler,                      // 38 Timer 3 subtimer B
    CryptoIntHandler,                       // 39 Crypto Core Result available
    uDMAIntHandler,                         // 40 uDMA Software
    uDMAErrIntHandler,                      // 41 uDMA Error
    FlashIntHandler,                        // 42 Flash controller
    SWEvent0IntHandler,                     // 43 Software Event 0
    AUXCombEventIntHandler,                 // 44 AUX combined event
    AONProgIntHandler,                      // 45 AON programmable 0
    DynProgIntHandler,                      // 46 Dynamic Programmable interrupt
                                            //    source (Default: PRCM)
    AUXCompAIntHandler,                     // 47 AUX Comparator A
    AUXADCIntHandler,                       // 48 AUX ADC new sample or ADC DMA
                                            //    done, ADC underflow, ADC overflow
    TRNGIntHandler,                         // 49 TRNG event
    OSCIntHandler,                          // 50 Combined event from Oscillator control
    AUXTimer2IntHandler,                    // 51 AUX Timer2 event 0
    UART1IntHandler,                        // 52 UART1 combined interrupt
    BatMonIntHandler                        // 53 Combined event from battery monitor
};


//*****************************************************************************
//! This is the code that gets called when the processor first starts execution
//! following a reset event. Only the absolutely necessary set is performed,
//! after which the application supplied entry() routine is called. Any fancy
//! actions (such as making decisions based on the reset cause register, and
//! resetting the bits in that register) are left solely in the hands of the
//! application.
//*****************************************************************************
void
ResetISR(void){
    uint32_t *pSrc;
    uint32_t *pDest;

    // Final trim of device
    SetupTrimDevice();
    
    // Copy the data segment initializers from FLASH to SRAM.
    pSrc = &_ldata;
    for(pDest = &_data; pDest < &_edata; )    {
        *pDest++ = *pSrc++;
    }

    // Zero fill the bss segment.
    __asm("    ldr     r0, =_bss\n"
          "    ldr     r1, =_ebss\n"
          "    mov     r2, #0\n"
          "    .thumb_func\n"
          "zero_loop:\n"
          "        cmp     r0, r1\n"
          "        it      lt\n"
          "        strlt   r2, [r0], #4\n"
          "        blt     zero_loop");

    // Enable the FPU
    // CPACR is located at address 0xE000ED88
    // Set bits 20-23 in CPACR to enable CP10 and CP11 coprocessors
    __asm("    ldr.w   r0, =0xE000ED88\n"
          "    ldr     r1, [r0]\n"
          "    orr     r1, r1, #(0xF << 20)\n"
          "    str     r1, [r0]\n");

    // Call the application's entry point.
    main();
    // If we ever return signal Error
    FaultISR();
}

//*****************************************************************************
//! This is the code that gets called when the processor receives a NMI. This
//! simply enters an infinite loop, preserving the system state for examination
//! by a debugger.
//*****************************************************************************
static void
NmiSRHandler(void){
    while(1)    {    }
}

//*****************************************************************************
//! This is the code that gets called when the processor receives a fault
//! interrupt. This simply enters an infinite loop, preserving the system state
//! for examination by a debugger.
//*****************************************************************************
static void
FaultISRHandler(void){
    while(1)    {    }
}

//*****************************************************************************
//! This is the code that gets called when the processor receives an unexpected
//! interrupt. This simply enters an infinite loop, preserving the system state
//! for examination by a debugger.
//*****************************************************************************
static void
IntDefaultHandler(void){
    // Go into an infinite loop.
    while(1)    {    }
}

Фаза 4: Подготовка области конфигурации устройства

Микроконтроллеры СС26×2 отличаются тем, что у TI MCU в последнем (43 м) секторе Flash памяти лежит бинарная структура, которая отвечает за аппаратные настройки микросхемы. Там прописаны заводские конфигурации и пользовательские конфигурации. Такие как MAC адрес, настройка загрузчика, мощность излучения RF части. Этот последний сектор надо корректно проинициализировать или вообще не трогать с самой покупки микроконтроллера. За формирование конфигов устройства отвечает файл-исходник ccfg.c.

Если в последнем секторе вдруг окажутся случайные числа, то микроконтроллер просто не заведется при hot reset, а на проводе кварца будет какой-то случайный рваный сигнал.

/******************************************************************************
*  Filename:       ccfg.c
*  Revised:        $Date: 2017-11-02 11:36:28 +0100 (Thu, 02 Nov 2017) $
*  Revision:       $Revision: 18030 $
*  Description:    Customer Configuration for:
*                  CC13x2, CC13x4, CC26x2, CC26x4 device family (HW rev 2).
*****************************************************************************/

#ifndef __CCFC_C__
#define __CCFC_C__

#include 
#include "../inc/hw_types.h"
#include "../inc/hw_ccfg.h"
#include "../inc/hw_ccfg_simple_struct.h"

//*****************************************************************************
// Introduction
// This file contains fields used by Boot ROM, startup code, and SW radio
// stacks to configure chip behavior.
//
// Fields are documented in more details in hw_ccfg.h and CCFG.html in
// DriverLib documentation (doc_overview.html -> CPU Domain Memory Map -> CCFG).
//
// PLEASE NOTE:
// It is not recommended to do modifications inside the ccfg.c file.
// This file is part of the CoreSDK release and future releases may have
// important modifications and new fields added without notice.
// The recommended method to modify the CCFG settings is to have a separate
// .c file that defines the specific CCFG values to be
// overridden and then include the TI provided ccfg.c at the very end,
// giving default values for non-overriden settings.
//
// Example:
// #define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE  0xC5 // Enable ROM boot loader
// #define SET_CCFG_MODE_CONF_SCLK_LF_OPTION     0x3  // LF RCOSC
// //---- Use default values for all others ----
// #include "/source/ti/devices//startup_files/ccfg.c"
//
//*****************************************************************************

//*****************************************************************************
// Internal settings, forcing several bit-fields to be set to a specific value.
//*****************************************************************************

//#####################################
// Force VDDR high setting (Higher output power but also higher power consumption)
// This is also called "boost mode"
// WARNING: CCFG_FORCE_VDDR_HH must not be set to 1 if running in external regulator mode.
//#####################################

#ifndef CCFG_FORCE_VDDR_HH
#define CCFG_FORCE_VDDR_HH                              0x0        // Use default VDDR trim
// #define CCFG_FORCE_VDDR_HH                           0x1        // Force VDDR voltage to the factory HH setting (FCFG1..VDDR_TRIM_HH)
#endif

//*****************************************************************************
// Set the values of the individual bit fields.
//*****************************************************************************

//#####################################
// Alternative DC/DC settings
//#####################################

#ifndef SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING
#define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING    0x0    // Alternative DC/DC setting enabled
// #define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING 0x1    // Alternative DC/DC setting disabled
#endif

#if ( CCFG_FORCE_VDDR_HH )
#define SET_CCFG_MODE_CONF_1_ALT_DCDC_VMIN                  0xC    // Special VMIN level (2.5V) when forced VDDR HH voltage
#else
#ifndef SET_CCFG_MODE_CONF_1_ALT_DCDC_VMIN
#define SET_CCFG_MODE_CONF_1_ALT_DCDC_VMIN                  0x8    // 2.25V
#endif
#endif

#ifndef SET_CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN
#define SET_CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN         0x0        // Dithering disabled
// #define SET_CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN      0x1        // Dithering enabled
#endif

#ifndef SET_CCFG_MODE_CONF_1_ALT_DCDC_IPEAK
#define SET_CCFG_MODE_CONF_1_ALT_DCDC_IPEAK             0x0        // Peak current
#endif

//#####################################
// XOSC override settings
//#####################################

#ifndef SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR
// #define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR     0x0        // Enable override
#define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR        0x1        // Disable override
#endif

#ifndef SET_CCFG_MODE_CONF_1_DELTA_IBIAS_INIT
#define SET_CCFG_MODE_CONF_1_DELTA_IBIAS_INIT           0x0        // Delta = 0
#endif

#ifndef SET_CCFG_MODE_CONF_1_DELTA_IBIAS_OFFSET
#define SET_CCFG_MODE_CONF_1_DELTA_IBIAS_OFFSET         0x0        // Delta = 0
#endif

#ifndef SET_CCFG_MODE_CONF_1_XOSC_MAX_START
#define SET_CCFG_MODE_CONF_1_XOSC_MAX_START             0x10       // 1600us
#endif

//#####################################
// Power settings
//#####################################

#ifndef SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA
#define SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA        0xF        // Signed delta value +1 to apply to the VDDR_TRIM_SLEEP target (0xF=-1=default=no compensation)
#endif

#ifndef SET_CCFG_MODE_CONF_DCDC_RECHARGE
#define SET_CCFG_MODE_CONF_DCDC_RECHARGE                0x0        // Use the DC/DC during recharge in powerdown
// #define SET_CCFG_MODE_CONF_DCDC_RECHARGE             0x1        // Do not use the DC/DC during recharge in powerdown
#endif

#ifndef SET_CCFG_MODE_CONF_DCDC_ACTIVE
#define SET_CCFG_MODE_CONF_DCDC_ACTIVE                  0x0        // Use the DC/DC during active mode
// #define SET_CCFG_MODE_CONF_DCDC_ACTIVE               0x1        // Do not use the DC/DC during active mode
#endif

#if ( CCFG_FORCE_VDDR_HH )
#define SET_CCFG_MODE_CONF_VDDS_BOD_LEVEL               0x1        // Special setting to enable forced VDDR HH voltage
#else
#ifndef SET_CCFG_MODE_CONF_VDDS_BOD_LEVEL
// #define SET_CCFG_MODE_CONF_VDDS_BOD_LEVEL            0x0        // VDDS BOD level is 2.0V
#define SET_CCFG_MODE_CONF_VDDS_BOD_LEVEL               0x1        // VDDS BOD level is 1.8V (or 1.65V for external regulator mode)
#endif
#endif

#ifndef SET_CCFG_MODE_CONF_VDDR_CAP
#define SET_CCFG_MODE_CONF_VDDR_CAP                     0x3A       // Unsigned 8-bit integer representing the min. decoupling capacitance on VDDR in units of 100nF
#endif

#ifndef SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC
#define SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC           0x1        // Temperature compensation on VDDR sleep trim disabled (default)
// #define SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC        0x0        // Temperature compensation on VDDR sleep trim enabled
#endif

//#####################################
// Clock settings
//#####################################

#ifndef SET_CCFG_MODE_CONF_SCLK_LF_OPTION
// #define SET_CCFG_MODE_CONF_SCLK_LF_OPTION            0x0        // LF clock derived from HF clock. Note: using this configuration will block the device from entering Standby mode.
// #define SET_CCFG_MODE_CONF_SCLK_LF_OPTION            0x1        // External LF clock
#define SET_CCFG_MODE_CONF_SCLK_LF_OPTION               0x2        // LF XOSC
// #define SET_CCFG_MODE_CONF_SCLK_LF_OPTION            0x3        // LF RCOSC
#endif

#ifndef SET_CCFG_MODE_CONF_XOSC_CAP_MOD
// #define SET_CCFG_MODE_CONF_XOSC_CAP_MOD              0x0        // Apply cap-array delta
#define SET_CCFG_MODE_CONF_XOSC_CAP_MOD                 0x1        // Don't apply cap-array delta
#endif

#ifndef SET_CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA
#define SET_CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA          0xFF       // Signed 8-bit value, directly modifying trimmed XOSC cap-array value
#endif

#ifndef SET_CCFG_EXT_LF_CLK_DIO
#define SET_CCFG_EXT_LF_CLK_DIO                         0x01       // DIO number if using external LF clock
#endif

#ifndef SET_CCFG_EXT_LF_CLK_RTC_INCREMENT
#define SET_CCFG_EXT_LF_CLK_RTC_INCREMENT               0x800000   // RTC increment representing the external LF clock frequency
#endif

//#####################################
// Special HF clock source setting
//#####################################
#ifndef SET_CCFG_MODE_CONF_XOSC_FREQ
// #define SET_CCFG_MODE_CONF_XOSC_FREQ                 0x0        // HF source is 48 MHz TCXO
// #define SET_CCFG_MODE_CONF_XOSC_FREQ                 0x1        // HF source is HPOSC (BAW) (only valid for CC2652RB)
#define SET_CCFG_MODE_CONF_XOSC_FREQ                    0x2        // HF source is a 48 MHz xtal
// #define SET_CCFG_MODE_CONF_XOSC_FREQ                 0x3        // HF source is a 24 MHz xtal (not supported)
#endif

//#####################################
// Bootloader settings
//#####################################

#ifndef SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE
#define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE            0x00       // Disable ROM boot loader
// #define SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE         0xC5       // Enable ROM boot loader
#endif

#ifndef SET_CCFG_BL_CONFIG_BL_LEVEL
// #define SET_CCFG_BL_CONFIG_BL_LEVEL                  0x0        // Active low to open boot loader backdoor
#define SET_CCFG_BL_CONFIG_BL_LEVEL                     0x1        // Active high to open boot loader backdoor
#endif

#ifndef SET_CCFG_BL_CONFIG_BL_PIN_NUMBER
#define SET_CCFG_BL_CONFIG_BL_PIN_NUMBER                0xFF       // DIO number for boot loader backdoor
#endif

#ifndef SET_CCFG_BL_CONFIG_BL_ENABLE
// #define SET_CCFG_BL_CONFIG_BL_ENABLE                 0xC5       // Enabled boot loader backdoor
#define SET_CCFG_BL_CONFIG_BL_ENABLE                    0xFF       // Disabled boot loader backdoor
#endif

//#####################################
// Debug access settings
//#####################################

#ifndef SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE
#define SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE           0x00       // Disable unlocking of TI FA option.
// #define SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE        0xC5       // Enable unlocking of TI FA option with the unlock code
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE
// #define SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE       0x00       // Access disabled
#define SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE          0xC5       // Access enabled if also enabled in FCFG
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE
//#define SET_CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE    0x00       // Access disabled
#define SET_CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE      0xC5       // Access enabled if also enabled in FCFG
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE
#define SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE         0x00       // Access disabled
//#define SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE       0xC5       // Access enabled if also enabled in FCFG
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE       0x00       // Access disabled
// #define SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE    0xC5       // Access enabled if also enabled in FCFG
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE
#define SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE       0x00       // Access disabled
// #define SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE    0xC5       // Access enabled if also enabled in FCFG
#endif

#ifndef SET_CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE
#define SET_CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE          0x00       // Access disabled
// #define SET_CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE       0xC5       // Access enabled if also enabled in FCFG
#endif

//#####################################
// Alternative IEEE 802.15.4 MAC address
//#####################################
#ifndef SET_CCFG_IEEE_MAC_0
#define SET_CCFG_IEEE_MAC_0                             0xFFFFFFFF // Bits [31:0]
#endif

#ifndef SET_CCFG_IEEE_MAC_1
#define SET_CCFG_IEEE_MAC_1                             0xFFFFFFFF // Bits [63:32]
#endif

//#####################################
// Alternative BLE address
//#####################################
#ifndef SET_CCFG_IEEE_BLE_0
#define SET_CCFG_IEEE_BLE_0                             0xFFFFFFFF // Bits [31:0]
#endif

#ifndef SET_CCFG_IEEE_BLE_1
#define SET_CCFG_IEEE_BLE_1                             0xFFFFFFFF // Bits [63:32]
#endif

//#####################################
// Flash erase settings
//#####################################

#ifndef SET_CCFG_ERASE_CONF_CHIP_ERASE_DIS_N
// #define SET_CCFG_ERASE_CONF_CHIP_ERASE_DIS_N         0x0        // Any chip erase request detected during boot will be ignored
#define SET_CCFG_ERASE_CONF_CHIP_ERASE_DIS_N            0x1        // Any chip erase request detected during boot will be performed by the boot FW
#endif

#ifndef SET_CCFG_ERASE_CONF_BANK_ERASE_DIS_N
// #define SET_CCFG_ERASE_CONF_BANK_ERASE_DIS_N         0x0        // Disable the boot loader bank erase function
#define SET_CCFG_ERASE_CONF_BANK_ERASE_DIS_N            0x1        // Enable the boot loader bank erase function
#endif

//#####################################
// Flash image valid
//#####################################
#ifndef SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID
#define SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID           0x00000000                  // Flash image vector table is at address 0x00000000 (default)
// #define SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID           // Flash image vector table is at address 
// #define SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID         // Flash image vector table address is invalid. ROM boot loader is called.
#endif

//#####################################
// Flash sector write protection
//#####################################
#ifndef SET_CCFG_CCFG_PROT_31_0
#define SET_CCFG_CCFG_PROT_31_0                         0xFFFFFFFF
#endif

#ifndef SET_CCFG_CCFG_PROT_63_32
#define SET_CCFG_CCFG_PROT_63_32                        0xFFFFFFFF
#endif

#ifndef SET_CCFG_CCFG_PROT_95_64
#define SET_CCFG_CCFG_PROT_95_64                        0xFFFFFFFF
#endif

#ifndef SET_CCFG_CCFG_PROT_127_96
#define SET_CCFG_CCFG_PROT_127_96                       0xFFFFFFFF
#endif

//#####################################
// Select between cache or GPRAM
//#####################################
#ifndef SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM
// #define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM        0x0        // Cache is disabled and GPRAM is available at 0x11000000-0x11001FFF
#define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM           0x1        // Cache is enabled and GPRAM is disabled (unavailable)
#endif

//#####################################
// TCXO settings
//#####################################
#ifndef SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_TCXO
#define SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_TCXO            0x1        // Deprecated. Must be set to 0x1.
#endif

#ifndef SET_CCFG_MODE_CONF_1_TCXO_TYPE
#define SET_CCFG_MODE_CONF_1_TCXO_TYPE                  0x1        // 1 = Clipped-sine type.
//#define SET_CCFG_MODE_CONF_1_TCXO_TYPE                0x0        // 0 = CMOS type.
#endif

#ifndef SET_CCFG_MODE_CONF_1_TCXO_MAX_START
#define SET_CCFG_MODE_CONF_1_TCXO_MAX_START             0x7F       // Maximum TCXO startup time in units of 100us.
#endif

//*****************************************************************************
// CCFG values that should not be modified.
//*****************************************************************************
#define SET_CCFG_SIZE_AND_DIS_FLAGS_SIZE_OF_CCFG        0x0058
#define SET_CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS       (CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS_M >> CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS_S)

#if ( CCFG_FORCE_VDDR_HH )
#define SET_CCFG_MODE_CONF_VDDR_EXT_LOAD                0x0        // Special setting to enable forced VDDR HH voltage
#else
#define SET_CCFG_MODE_CONF_VDDR_EXT_LOAD                0x1
#endif

#define SET_CCFG_MODE_CONF_RTC_COMP                     0x1
#define SET_CCFG_MODE_CONF_HF_COMP                      0x1

#define SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP45              0xFF
#define SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP25              0xFF
#define SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP5               0xFF
#define SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TM15              0xFF

#define SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP125             0xFF
#define SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP105             0xFF
#define SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP85              0xFF
#define SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP65              0xFF

#define SET_CCFG_RTC_OFFSET_RTC_COMP_P0                 0xFFFF
#define SET_CCFG_RTC_OFFSET_RTC_COMP_P1                 0xFF
#define SET_CCFG_RTC_OFFSET_RTC_COMP_P2                 0xFF

#define SET_CCFG_FREQ_OFFSET_HF_COMP_P0                 0xFFFF
#define SET_CCFG_FREQ_OFFSET_HF_COMP_P1                 0xFF
#define SET_CCFG_FREQ_OFFSET_HF_COMP_P2                 0xFF

//*****************************************************************************
// Concatenate bit fields to words.
// DO NOT EDIT!
//*****************************************************************************
#define DEFAULT_CCFG_EXT_LF_CLK          ( \
	 ((((uint32_t)( SET_CCFG_EXT_LF_CLK_DIO                          )) << CCFG_EXT_LF_CLK_DIO_S                          ) | ~CCFG_EXT_LF_CLK_DIO_M                          ) & \
	 ((((uint32_t)( SET_CCFG_EXT_LF_CLK_RTC_INCREMENT                )) << CCFG_EXT_LF_CLK_RTC_INCREMENT_S                ) | ~CCFG_EXT_LF_CLK_RTC_INCREMENT_M                ) )

#define DEFAULT_CCFG_MODE_CONF_1         ( \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_TCXO_TYPE                   )) << CCFG_MODE_CONF_1_TCXO_TYPE_S                   ) | ~CCFG_MODE_CONF_1_TCXO_TYPE_M                   ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_TCXO_MAX_START              )) << CCFG_MODE_CONF_1_TCXO_MAX_START_S              ) | ~CCFG_MODE_CONF_1_TCXO_MAX_START_M              ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_ALT_DCDC_VMIN               )) << CCFG_MODE_CONF_1_ALT_DCDC_VMIN_S               ) | ~CCFG_MODE_CONF_1_ALT_DCDC_VMIN_M               ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN          )) << CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN_S          ) | ~CCFG_MODE_CONF_1_ALT_DCDC_DITHER_EN_M          ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_ALT_DCDC_IPEAK              )) << CCFG_MODE_CONF_1_ALT_DCDC_IPEAK_S              ) | ~CCFG_MODE_CONF_1_ALT_DCDC_IPEAK_M              ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_DELTA_IBIAS_INIT            )) << CCFG_MODE_CONF_1_DELTA_IBIAS_INIT_S            ) | ~CCFG_MODE_CONF_1_DELTA_IBIAS_INIT_M            ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_DELTA_IBIAS_OFFSET          )) << CCFG_MODE_CONF_1_DELTA_IBIAS_OFFSET_S          ) | ~CCFG_MODE_CONF_1_DELTA_IBIAS_OFFSET_M          ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_1_XOSC_MAX_START              )) << CCFG_MODE_CONF_1_XOSC_MAX_START_S              ) | ~CCFG_MODE_CONF_1_XOSC_MAX_START_M              ) )

#define DEFAULT_CCFG_SIZE_AND_DIS_FLAGS  ( \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_SIZE_OF_CCFG         )) << CCFG_SIZE_AND_DIS_FLAGS_SIZE_OF_CCFG_S         ) | ~CCFG_SIZE_AND_DIS_FLAGS_SIZE_OF_CCFG_M         ) & \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS        )) << CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS_S        ) | ~CCFG_SIZE_AND_DIS_FLAGS_DISABLE_FLAGS_M        ) & \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_TCXO             )) << CCFG_SIZE_AND_DIS_FLAGS_DIS_TCXO_S             ) | ~CCFG_SIZE_AND_DIS_FLAGS_DIS_TCXO_M             ) & \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM            )) << CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM_S            ) | ~CCFG_SIZE_AND_DIS_FLAGS_DIS_GPRAM_M            ) & \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING )) << CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING_S ) | ~CCFG_SIZE_AND_DIS_FLAGS_DIS_ALT_DCDC_SETTING_M ) & \
	 ((((uint32_t)( SET_CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR         )) << CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR_S         ) | ~CCFG_SIZE_AND_DIS_FLAGS_DIS_XOSC_OVR_M         ) )

#define DEFAULT_CCFG_MODE_CONF           ( \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA         )) << CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_S         ) | ~CCFG_MODE_CONF_VDDR_TRIM_SLEEP_DELTA_M         ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_DCDC_RECHARGE                 )) << CCFG_MODE_CONF_DCDC_RECHARGE_S                 ) | ~CCFG_MODE_CONF_DCDC_RECHARGE_M                 ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_DCDC_ACTIVE                   )) << CCFG_MODE_CONF_DCDC_ACTIVE_S                   ) | ~CCFG_MODE_CONF_DCDC_ACTIVE_M                   ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_VDDR_EXT_LOAD                 )) << CCFG_MODE_CONF_VDDR_EXT_LOAD_S                 ) | ~CCFG_MODE_CONF_VDDR_EXT_LOAD_M                 ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_VDDS_BOD_LEVEL                )) << CCFG_MODE_CONF_VDDS_BOD_LEVEL_S                ) | ~CCFG_MODE_CONF_VDDS_BOD_LEVEL_M                ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_SCLK_LF_OPTION                )) << CCFG_MODE_CONF_SCLK_LF_OPTION_S                ) | ~CCFG_MODE_CONF_SCLK_LF_OPTION_M                ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC            )) << CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC_S            ) | ~CCFG_MODE_CONF_VDDR_TRIM_SLEEP_TC_M            ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_RTC_COMP                      )) << CCFG_MODE_CONF_RTC_COMP_S                      ) | ~CCFG_MODE_CONF_RTC_COMP_M                      ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_XOSC_FREQ                     )) << CCFG_MODE_CONF_XOSC_FREQ_S                     ) | ~CCFG_MODE_CONF_XOSC_FREQ_M                     ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_XOSC_CAP_MOD                  )) << CCFG_MODE_CONF_XOSC_CAP_MOD_S                  ) | ~CCFG_MODE_CONF_XOSC_CAP_MOD_M                  ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_HF_COMP                       )) << CCFG_MODE_CONF_HF_COMP_S                       ) | ~CCFG_MODE_CONF_HF_COMP_M                       ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA           )) << CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_S           ) | ~CCFG_MODE_CONF_XOSC_CAPARRAY_DELTA_M           ) & \
	 ((((uint32_t)( SET_CCFG_MODE_CONF_VDDR_CAP                      )) << CCFG_MODE_CONF_VDDR_CAP_S                      ) | ~CCFG_MODE_CONF_VDDR_CAP_M                      ) )

#define DEFAULT_CCFG_VOLT_LOAD_0         ( \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP45               )) << CCFG_VOLT_LOAD_0_VDDR_EXT_TP45_S               ) | ~CCFG_VOLT_LOAD_0_VDDR_EXT_TP45_M               ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP25               )) << CCFG_VOLT_LOAD_0_VDDR_EXT_TP25_S               ) | ~CCFG_VOLT_LOAD_0_VDDR_EXT_TP25_M               ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TP5                )) << CCFG_VOLT_LOAD_0_VDDR_EXT_TP5_S                ) | ~CCFG_VOLT_LOAD_0_VDDR_EXT_TP5_M                ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_0_VDDR_EXT_TM15               )) << CCFG_VOLT_LOAD_0_VDDR_EXT_TM15_S               ) | ~CCFG_VOLT_LOAD_0_VDDR_EXT_TM15_M               ) )

#define DEFAULT_CCFG_VOLT_LOAD_1         ( \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP125              )) << CCFG_VOLT_LOAD_1_VDDR_EXT_TP125_S              ) | ~CCFG_VOLT_LOAD_1_VDDR_EXT_TP125_M              ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP105              )) << CCFG_VOLT_LOAD_1_VDDR_EXT_TP105_S              ) | ~CCFG_VOLT_LOAD_1_VDDR_EXT_TP105_M              ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP85               )) << CCFG_VOLT_LOAD_1_VDDR_EXT_TP85_S               ) | ~CCFG_VOLT_LOAD_1_VDDR_EXT_TP85_M               ) & \
	 ((((uint32_t)( SET_CCFG_VOLT_LOAD_1_VDDR_EXT_TP65               )) << CCFG_VOLT_LOAD_1_VDDR_EXT_TP65_S               ) | ~CCFG_VOLT_LOAD_1_VDDR_EXT_TP65_M               ) )

#define DEFAULT_CCFG_RTC_OFFSET          ( \
	 ((((uint32_t)( SET_CCFG_RTC_OFFSET_RTC_COMP_P0                  )) << CCFG_RTC_OFFSET_RTC_COMP_P0_S                  ) | ~CCFG_RTC_OFFSET_RTC_COMP_P0_M                  ) & \
	 ((((uint32_t)( SET_CCFG_RTC_OFFSET_RTC_COMP_P1                  )) << CCFG_RTC_OFFSET_RTC_COMP_P1_S                  ) | ~CCFG_RTC_OFFSET_RTC_COMP_P1_M                  ) & \
	 ((((uint32_t)( SET_CCFG_RTC_OFFSET_RTC_COMP_P2                  )) << CCFG_RTC_OFFSET_RTC_COMP_P2_S                  ) | ~CCFG_RTC_OFFSET_RTC_COMP_P2_M                  ) )

#define DEFAULT_CCFG_FREQ_OFFSET         ( \
	 ((((uint32_t)( SET_CCFG_FREQ_OFFSET_HF_COMP_P0                  )) << CCFG_FREQ_OFFSET_HF_COMP_P0_S                  ) | ~CCFG_FREQ_OFFSET_HF_COMP_P0_M                  ) & \
	 ((((uint32_t)( SET_CCFG_FREQ_OFFSET_HF_COMP_P1                  )) << CCFG_FREQ_OFFSET_HF_COMP_P1_S                  ) | ~CCFG_FREQ_OFFSET_HF_COMP_P1_M                  ) & \
	 ((((uint32_t)( SET_CCFG_FREQ_OFFSET_HF_COMP_P2                  )) << CCFG_FREQ_OFFSET_HF_COMP_P2_S                  ) | ~CCFG_FREQ_OFFSET_HF_COMP_P2_M                  ) )

#define DEFAULT_CCFG_IEEE_MAC_0          SET_CCFG_IEEE_MAC_0
#define DEFAULT_CCFG_IEEE_MAC_1          SET_CCFG_IEEE_MAC_1
#define DEFAULT_CCFG_IEEE_BLE_0          SET_CCFG_IEEE_BLE_0
#define DEFAULT_CCFG_IEEE_BLE_1          SET_CCFG_IEEE_BLE_1

#define DEFAULT_CCFG_BL_CONFIG           ( \
	 ((((uint32_t)( SET_CCFG_BL_CONFIG_BOOTLOADER_ENABLE             )) << CCFG_BL_CONFIG_BOOTLOADER_ENABLE_S             ) | ~CCFG_BL_CONFIG_BOOTLOADER_ENABLE_M             ) & \
	 ((((uint32_t)( SET_CCFG_BL_CONFIG_BL_LEVEL                      )) << CCFG_BL_CONFIG_BL_LEVEL_S                      ) | ~CCFG_BL_CONFIG_BL_LEVEL_M                      ) & \
	 ((((uint32_t)( SET_CCFG_BL_CONFIG_BL_PIN_NUMBER                 )) << CCFG_BL_CONFIG_BL_PIN_NUMBER_S                 ) | ~CCFG_BL_CONFIG_BL_PIN_NUMBER_M                 ) & \
	 ((((uint32_t)( SET_CCFG_BL_CONFIG_BL_ENABLE                     )) << CCFG_BL_CONFIG_BL_ENABLE_S                     ) | ~CCFG_BL_CONFIG_BL_ENABLE_M                     ) )

#define DEFAULT_CCFG_ERASE_CONF          ( \
	 ((((uint32_t)( SET_CCFG_ERASE_CONF_CHIP_ERASE_DIS_N             )) << CCFG_ERASE_CONF_CHIP_ERASE_DIS_N_S             ) | ~CCFG_ERASE_CONF_CHIP_ERASE_DIS_N_M             ) & \
	 ((((uint32_t)( SET_CCFG_ERASE_CONF_BANK_ERASE_DIS_N             )) << CCFG_ERASE_CONF_BANK_ERASE_DIS_N_S             ) | ~CCFG_ERASE_CONF_BANK_ERASE_DIS_N_M             ) )

#define DEFAULT_CCFG_CCFG_TI_OPTIONS     ( \
	 ((((uint32_t)( SET_CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE            )) << CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE_S            ) | ~CCFG_CCFG_TI_OPTIONS_TI_FA_ENABLE_M            ) )

#define DEFAULT_CCFG_CCFG_TAP_DAP_0      ( \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE           )) << CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE_S           ) | ~CCFG_CCFG_TAP_DAP_0_CPU_DAP_ENABLE_M           ) & \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE       )) << CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE_S       ) | ~CCFG_CCFG_TAP_DAP_0_PWRPROF_TAP_ENABLE_M       ) & \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE          )) << CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE_S          ) | ~CCFG_CCFG_TAP_DAP_0_TEST_TAP_ENABLE_M          ) )

#define DEFAULT_CCFG_CCFG_TAP_DAP_1      ( \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE        )) << CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE_S        ) | ~CCFG_CCFG_TAP_DAP_1_PBIST2_TAP_ENABLE_M        ) & \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE        )) << CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE_S        ) | ~CCFG_CCFG_TAP_DAP_1_PBIST1_TAP_ENABLE_M        ) & \
	 ((((uint32_t)( SET_CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE           )) << CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE_S           ) | ~CCFG_CCFG_TAP_DAP_1_AON_TAP_ENABLE_M           ) )

#define DEFAULT_CCFG_IMAGE_VALID_CONF    SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID

#define DEFAULT_CCFG_CCFG_PROT_31_0      SET_CCFG_CCFG_PROT_31_0
#define DEFAULT_CCFG_CCFG_PROT_63_32     SET_CCFG_CCFG_PROT_63_32
#define DEFAULT_CCFG_CCFG_PROT_95_64     SET_CCFG_CCFG_PROT_95_64
#define DEFAULT_CCFG_CCFG_PROT_127_96    SET_CCFG_CCFG_PROT_127_96

//*****************************************************************************
// Customer Configuration Area in Lock Page
//*****************************************************************************
#if defined(__IAR_SYSTEMS_ICC__)
__root const ccfg_t __ccfg @ ".ccfg" =
#elif defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(__ccfg, ".ccfg")
#pragma RETAIN(__ccfg)
const ccfg_t __ccfg =
#else
const ccfg_t __ccfg __attribute__((section(".ccfg"))) __attribute__((used)) =
#endif
{                                     // Mapped to address
    DEFAULT_CCFG_EXT_LF_CLK         , // 0x50003FA8 (0x50003xxx maps to last
    DEFAULT_CCFG_MODE_CONF_1        , // 0x50003FAC  sector in FLASH.
    DEFAULT_CCFG_SIZE_AND_DIS_FLAGS , // 0x50003FB0  Independent of FLASH size)
    DEFAULT_CCFG_MODE_CONF          , // 0x50003FB4
    DEFAULT_CCFG_VOLT_LOAD_0        , // 0x50003FB8
    DEFAULT_CCFG_VOLT_LOAD_1        , // 0x50003FBC
    DEFAULT_CCFG_RTC_OFFSET         , // 0x50003FC0
    DEFAULT_CCFG_FREQ_OFFSET        , // 0x50003FC4
    DEFAULT_CCFG_IEEE_MAC_0         , // 0x50003FC8
    DEFAULT_CCFG_IEEE_MAC_1         , // 0x50003FCC
    DEFAULT_CCFG_IEEE_BLE_0         , // 0x50003FD0
    DEFAULT_CCFG_IEEE_BLE_1         , // 0x50003FD4
    DEFAULT_CCFG_BL_CONFIG          , // 0x50003FD8
    DEFAULT_CCFG_ERASE_CONF         , // 0x50003FDC
    DEFAULT_CCFG_CCFG_TI_OPTIONS    , // 0x50003FE0
    DEFAULT_CCFG_CCFG_TAP_DAP_0     , // 0x50003FE4
    DEFAULT_CCFG_CCFG_TAP_DAP_1     , // 0x50003FE8
    DEFAULT_CCFG_IMAGE_VALID_CONF   , // 0x50003FEC
    DEFAULT_CCFG_CCFG_PROT_31_0     , // 0x50003FF0
    DEFAULT_CCFG_CCFG_PROT_63_32    , // 0x50003FF4
    DEFAULT_CCFG_CCFG_PROT_95_64    , // 0x50003FF8
    DEFAULT_CCFG_CCFG_PROT_127_96   , // 0x50003FFC
};

#endif // __CCFC_C__

Фаза 5: Подключить к сборке Hardware Abstraction Layer (HAL)

С настройками системы определились. Теперь можно накропать небольшое приложение. Путь там будет GPIO, LEDs, SysTick, UART, NoRTOS, CLI.

Примеры по настройке периферии можно взять в SimpleLink SDK, например по этим адресам.
C:\ti\simplelink_cc13xx_cc26xx_sdk_5_40_00_40\examples\nortos\CC26×2R1_LAUNCHXL\drivers\gpiointerrupt

Для микроконтроллеров СС26×2 в качестве HAL выступает папка C:/ti/simplelink_cc13xx_cc26xx_sdk_5_40_00_40. Поэтому надо прописать кути к заголовочным файлам. Также производитель распростаняет код HAL в виде предварительно скомпилированных бинарных библиотек (*.a файлики). Поэтому для компоновщика надо прописать пути к библиотекам drivers_cc26×2.a, nortos_cc26×2.a и driverlib.lib

ifneq ($(SIMPLELINK_CC13X2_26X2_SDK_MK_INC),Y)
    SIMPLELINK_CC13X2_26X2_SDK_MK_INC=Y

    mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
    $(info Build  $(mkfile_path) )
    OPT += -DHAS_SIMPLELINK_CC13X2_26X2_SDK

    SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR = C:/ti/simplelink_cc13xx_cc26xx_sdk_5_40_00_40
    #@echo $(error SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR= $(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR))
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib/bin
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/inc
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos
    INCDIR += -I$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos/posix
                                                     
    LIBS += $(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/drivers/lib/gcc/m4f/drivers_cc26x2.a
    LIBS += $(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos/lib/gcc/m4f/nortos_cc26x2.a
    LIBS += $(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc/driverlib.lib

    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos/lib
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos/lib/gcc
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/kernel/nortos/lib/gcc/m4f
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/drivers/lib
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/drivers/lib/gcc
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/drivers/lib/gcc/m4f
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib
    LIBDIR += -L$(SIMPLELINK_CC13X2_26X2_SDK_INSTALL_DIR)/source/ti/devices/cc13x2_cc26x2/driverlib/bin/gcc
endif

Стоит заметить, что для сборки прошивки для СС2652 вообще не нужен оригинальный CMSIS, несмотря на то, что у микроконтроллера ядро ARM Cortex-M4.

Фаза 6: Написание Makefile (ов)

Самый высокоуровневый Makefile может выглядеть так

MK_PATH:=$(dir $(realpath $(lastword $(MAKEFILE_LIST))))
#@echo $(error MK_PATH=$(MK_PATH))
WORKSPACE_LOC:=$(MK_PATH)../../
INCDIR += -I$(MK_PATH)
INCDIR += -I$(WORKSPACE_LOC)

TARGET=launchpad_bootloader_m

include $(MK_PATH)config.mk

ifeq ($(CLI),Y)
    include $(MK_PATH)cli_config.mk
endif

ifeq ($(DIAG),Y)
    include $(MK_PATH)diag_config.mk
endif

include $(WORKSPACE_LOC)code_base.mk
include $(WORKSPACE_LOC)rules.mk
 

Для каждого программного компонента можно составить *.mk файл примерно такой структуры


$(info LED_MONO_MK_INC=$(LED_MONO_MK_INC))

ifneq ($(LED_MONO_MK_INC),Y)
    LED_MONO_MK_INC=Y

    mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
    $(info Build LED Mono)

    #FLASH_FS_DIR = $(WORKSPACE_LOC)Drivers/flash_fs
    LED_MONO_DIR = $(LED_GENERAL_DIR)/led_mono
    #@echo $(error LED_MONO_DIR=$(LED_MONO_DIR))

    ifneq ($(LED),Y)
        @echo $(error Add General LED driver)
    endif

    INCDIR += -I$(LED_MONO_DIR)
    SOURCES_C += $(LED_MONO_DIR)/led_mono_drv.c

    OPT += -DHAS_LED_MONO
    OPT += -DHAS_LED_MONO_PROC
    MATH=Y

    ifeq ($(DIAG),Y)
        ifeq ($(LED_MONO_DIAG),Y)
            OPT += -DHAS_LED_MONO_DIAG
            SOURCES_C += $(LED_MONO_DIR)/led_mono_diag.c
        endif
    endif

    ifeq ($(CLI),Y)
        ifeq ($(LED_MONO_COMMANDS),Y)
            OPT += -DHAS_LED_MONO_COMMANDS
            SOURCES_C += $(LED_MONO_DIR)/led_mono_commands.c
        endif
    endif
endif

Также нужен специфичный *.mk файл для микроконтроллера CC2652R1FRGZ

#protection against repeated include as in C preprocessor
$(info CC2652R1FRGZ_MK_INC=$(CC2652R1FRGZ_MK_INC) )
ifneq ($(CC2652R1FRGZ_MK_INC),Y)
    CC2652R1FRGZ_MK_INC=Y
    CC2652R1FRGZ_DIR = $(MCU_DIR)/cc2652r1f

    ifeq ($(CC2652),Y)
        OPT += -DHAS_CC2652
        CC26X2=Y
        OPT += -DDeviceFamily_CC26X2
        OPT += -DHAS_CC26x2
        OPT += -DHAS_CC26X2
        OPT += -DHAS_CC26XX
        OPT += -DCC26XX
        OPT += -DCC26x2
    endif

    ifeq ($(CC2652R1FRGZ),Y)
        OPT += -DCC2652R1F
        OPT += -DHAS_CC2652R1F
        OPT += -DCC2652R1FRGZ
        OPT += -DHAS_CC2652R1FRGZ
    endif

    mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
    $(info Build  $(mkfile_path) )

    FIRMWARE_TYPE_SELECTED=N
    BOARD=Y

    MICROCONTROLLER=Y
    CC2652R1FRGZ=Y

    INCDIR += -I$(CC2652R1FRGZ_DIR)

    ifeq ($(BOOTLOADER),Y)
        # link script
        FIRMWARE_TYPE_SELECTED=Y
        LDSCRIPT = $(CC2652R1FRGZ_DIR)/cc26x2r1f.lds
    endif

    ifeq ($(GPIO),Y)
        SOURCES_C += $(CC2652R1FRGZ_DIR)/cc2652R1F.c
    endif

    SOURCES_C += $(CC2652R1FRGZ_DIR)/startup_gcc.c
    SOURCES_C += $(CC2652R1FRGZ_DIR)/ccfg.c
    SOURCES_C += $(CC2652R1FRGZ_DIR)/syscalls.c
    
    ifeq ($(SYSTICK),Y)
        SOURCES_C += $(CC2652R1FRGZ_DIR)/syst
    
            

© Habrahabr.ru