Если вы когда-либо работали с микроконтроллерами от компании 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.
Сборка прошивки для CC26x2 из Makefile
Фаза 1: подготовка оборудования, документации и софтвера
a--Что надо из оборудования?
# | оборудование |
1 | LapTop |
2 | отладочная плата LAUNCHXL-CC26X2R1 |
3 | кабель USB-A-USB micro |
В качестве отладочной платы я воспользуюсь платой LAUNCHXL-CC26X2R1. Там заложен микроконтроллер CC2652R1.
Вот примерная блок-схема платы LAUNCHXL-CC26X2R1. Мы видим, что тут есть сам микроконтроллер CC2652R1F и программатор отладчик XDS110.
Итак, что мы вообще знаем про микроконтроллер CC2652R1FRGZ?
Параметр | значение | Unit |
Ядро | Arm Cortex-M4F | -- |
Архитектура | ARMv7-M | |
RF Core | Arm Cortex-M0 | |
разрядность | 32 | bit |
FPU | IEEE 754-compliant single-precision | |
RAM start | 0x20000000 | hex |
GPRAM start | 0x11000000 | hex |
GPRAM size | 8 | kByte |
ROM start | 0 | hex |
FLASH_CCFG start | 0x00057fa8 (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 | CC13x2, CC26x2 SimpleLink Wireless MCU Technical Reference Manual | 2083 | спецификация микроконтроллера |
4 | Cortex-M3/M4F Instruction Set | 221 | Спецификация процессорного ядра |
5 | WCS037 LAUNCHXL-CC26X2R1 | 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 сервер для микроконтроллеров CC26x2 |
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
Нужна утилита make. Её можно взять из состава MinGW.
Фаза 2: Подготовка скрипта настройки компоновщика.
Обычно сам С-код не особе аппаратно-зависмый. Наиболее аппаратно-зависимые исходники это файл настройки компоновщика. В GCC это *.ld файлы. Где же взять *.ld файл для микроконтроллера cc2652r1frgz? Ответ прост. Надо порыться прямо в SDK. При помощи утилиты grep я вскоре сузил место поиска до папки
C:\ti\simplelink_cc13xx_cc26xx_sdk_5_40_00_40\source\ti\devices\cc13x2_cc26x2\linker_files. Там и лежал подходящий файл разметки компоновщика cc26x2r1f.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 коде также перечислены все обработчики прерываний для микроконтроллеров сс26x2.
/******************************************************************************
* 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: Подготовка области конфигурации устройства
Микроконтроллеры СС26x2 отличаются тем, что у 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 <stdint.h>
#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
// <customer_ccfg>.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 "<project-path>/source/ti/devices/<device>/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 <valid_vector_table_addr> // Flash image vector table is at address <valid_vector_table_addr>
// #define SET_CCFG_IMAGE_VALID_CONF_IMAGE_VALID <invalid_vector_table_addr> // 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\CC26X2R1_LAUNCHXL\drivers\gpiointerrupt
Для микроконтроллеров СС26x2 в качестве HAL выступает папка C:/ti/simplelink_cc13xx_cc26xx_sdk_5_40_00_40. Поэтому надо прописать кути к заголовочным файлам. Также производитель распростаняет код HAL в виде предварительно скомпилированных бинарных библиотек (*.a файлики). Поэтому для компоновщика надо прописать пути к библиотекам drivers_cc26x2.a, nortos_cc26x2.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)/systick_general_config.c
endif
MCU_SELECTED=Y
endif
И, конечно же, основной rules.mk файл с правилами сборки можно написать примерно так
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
$(info Build $(mkfile_path) )
BUILD_DIR = build
INCDIR := $(subst /cygdrive/c/,C:/, $(INCDIR))
#@echo $(error INCDIR=$(INCDIR))
SOURCES_C := $(subst /cygdrive/c/,C:/, $(SOURCES_C))
#@echo $(error SOURCES_C=$(SOURCES_C))
SOURCES_ASM := $(subst /cygdrive/c/,C:/, $(SOURCES_ASM))
#@echo $(error SOURCES_ASM=$(SOURCES_ASM))
LIBS := $(subst /cygdrive/c/,C:/, $(LIBS))
LDSCRIPT := $(subst /cygdrive/c/,C:/, $(LDSCRIPT))
#@echo $(error SOURCES_ASM=$(SOURCES_ASM))
include $(WORKSPACE_LOC)/toolchain.mk
# CFLAGS
#https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html
FLOAT-ABI = -mfloat-abi=hard
MCU = $(CPU) -mthumb $(FPU) $(FLOAT-ABI)
# macros for gcc
#CSTANDARD = -std=c11
CSTANDARD = -std=gnu99
AS_DEFS =
AS_INCLUDES =
ifeq ($(DEBUG), Y)
CFLAGS += -g3 -ggdb -gdwarf-2
OPT += -O0
else
OPT += -Os
endif
OPT += -fmessage-length=0
OPT += -fsigned-char
OPT += -fno-common
OPT += -fstack-usage
OPT += -finline-small-functions
#Perform dead code elimination
OPT += -fdce
#Perform dead store elimination
OPT += -fdse
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += $(CSTANDARD)
CFLAGS += -Wall
#CFLAGS += -Wformat-overflow=1
CFLAGS += $(MCU) $(OPT) -fdata-sections -ffunction-sections $(INCDIR)
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# libraries
LINKER_FLAGS += -Xlinker --gc-sections
ifeq ($(MBR), Y)
LIBS += -lnosys
LDFLAGS += -specs=nano.specs
else
LINKER_FLAGS += -u _scanf_float
LINKER_FLAGS += -u _printf_float
endif
ifeq ($(LIBC), Y)
LIBS += -lc
endif
ifeq ($(MATH), Y)
LIBS += -lm
endif
#@echo $(error LDSCRIPT=$(LDSCRIPT))
LIBDIR =
LDFLAGS += $(MCU) -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections $(LINKER_FLAGS)
# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin
# build the application
# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_C:.c=.o)))
vpath %.c $(sort $(dir $(SOURCES_C)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(SOURCES_ASM:.S=.o)))
vpath %.S $(sort $(dir $(SOURCES_ASM)))
$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@
$(BUILD_DIR)/%.o: %.S Makefile | $(BUILD_DIR)
$(AS) -c $(CFLAGS) $< -o $@
$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
$(SZ) $@
$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(HEX) $< $@
$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
$(BIN) $< $@
$(BUILD_DIR):
mkdir $@
# clean up
clean:
-rm -fR $(BUILD_DIR)
# dependencies
-include $(wildcard $(BUILD_DIR)/*.d)
# *** EOF ***
Прелесть make файлов в том, что для инициализации сборки достаточно открыть консоль и набрать make all. Затем, через пару минут в соседней папке появятся артефакты. При этом можно еще сохранить в файл полный лог для анализа, а не разглядывать последние 4 экрана как в CCS.
echo off
cls
make clean 2>&1 | tee clean_log.txt
make 2>&1 | tee build_log.txt
Итак, прошивка собирается.
вот такие получились артефакты: *.bin, *.hex, *.map, *.elf
Фаза 7: Запись прошивки в on-chip NOR Flash память
Записать прошивку в микроконтроллер СС2652 тоже можно из консоли утилитой srfprog.exe. Эта утилита входит в состав программы SmartRF Flash Programmer 2. Обычно после установки утилита srfprog живет по адресу
C:\Program Files (x86)\Texas Instruments\SmartRF Tools\Flash Programmer 2\bin\srfprog.exe
Но если забыли, то всегда можно набрать запрос в Win консоли where srfprog.
Вот этот скрипт загружает прошивку в on-chip NOR Flash память микроконтроллера.
echo off
cls
set project_dir=%~dp0
set FLASH_TOOL=srfprog.exe
set BIN_PATH=%project_dir%build\launchpad_bootloader_m.bin
call %FLASH_TOOL% --list all
call %FLASH_TOOL% --help
call %FLASH_TOOL% --target lsidx(0) --erase all --program --file %BIN_PATH% --address 0
Обычно такой вывод информирует об успешной загрузке бинаря
Texas Instruments SmartRF Flash Programmer 2 v1.8.2-windows
-------------------------------------------------------------------------------
Connected over 2-pin cJTAG.
Reading file: C:\....\code_base_firmware\source\projects\launchpad_bootloader_m\build\launchpad_bootloader_m.bin.
2%le size: 360448 bytes.
Number of assigned pages: 44.
About 34 percent of the file contain assigned code.
Start flash erase ...
OK
Start flash programming ...
100%
OK
Reset target ...
OK
C:\....\code_base_firmware\source\projects\launchpad_bootloader_m>
Однако 80..97% вероятность, что после первой же записи бинаря во flash прошивка где-нибудь зависнет, устройство превратится в тыкву. Причем прошивка зависнет где-то в инициализации, еще до запуска суперцикла. Поэтому надо сразу настроить пошаговую отладку через JTAG.
Фаза 8: Запуск GDB сервера
В качестве GDB сервера у TI выступает утилита gdb_agent_console.exe. Для корректного запуска утилиты gdb_agent_console ей надо передать конфигурационный *.dat файл для настройки конкретного отладчика. В случае с платой LAUNCHXL-CC26X2R1 надо выбрать отладчик XDS110. В очередной раз путем grep(ания) на жестком диске, я наткнулся вот на такой файл CC2652_XDS110_JTAG.dat. Причем *.dat файл оказался в папке пользователя а не в SDK.
# config version=3.5
$ sepk
pod_drvr=jioxds110.dll
pod_port=0
pod_supply=1
pod_voltage_selection=1
pod_voltage=3.3
$ /
$ product
title="Texas Instruments XDS110 USB"
alias=TI_XDS110_USB
name=XDS110
$ /
$ uscif
tdoedge=FALL
tclk_program=DEFAULT
tclk_frequency=2.5MHz
jtag_isolate=disable
$ /
$ dot7
dts_usage=enable
dts_type=xds110
dts_program=emulator
dts_frequency=1.0MHz
ts_format=jscan0
ts_pin_width=all_four
$ /
$ swd
swd_debug=disabled
swo_data=aux_uart
$ /
@ icepick_c family=icepick_c irbits=6 drbits=1 subpaths=2
& subpath_2 address=0 default=no custom=yes force=yes pseudo=no
@ bypass_0 family=bypass irbits=4 drbits=1
& subpath_0 address=16 default=no custom=yes force=yes pseudo=no
@ cs_dap_0 family=cs_dap irbits=4 drbits=1 subpaths=1 identify=0x4BA00477 revision=Legacy systemresetwhileconnected=1
& subpath_1 type=debug address=0 default=no custom=yes force=yes pseudo=no
@ cortex_m4_0 family=cortex_mxx irbits=0 drbits=0 identify=0x02000000 traceid=0x0
& /
& /
# /
Вот скрипт для запуска GDB сервера.
set GDB_SERVER=C:\ti\ccs_base\common\uscif\gdb_agent_console.exe
set USB_JTAG_CONFIG=%CUR_DIR%\CC2652_XDS110_JTAG.dat
%GDB_SERVER% --help
%GDB_SERVER% %USB_JTAG_CONFIG%
В консоли появляется лог сообщения об ожидании подключения на порте 55000
Вот такой текст вывалится в консоль как только GDB клиент подключится к GDB серверу
Фаза 9: GDB клиент
Для запуска GDB клиента надо открыть Win консоль и запустить утилиту arm-none-eabi-gdb.exe, передав ей путь к *.elf файлу с прошивкой. При этом прошивку надо было предварительно собрать с опцией -g.
cls
set GDB_CLIENT="C:\Program Files (x86)\GNU Arm Embedded Toolchain\10 2021.10\bin\arm-none-eabi-gdb.exe"
%GDB_CLIENT% --help
set ELF_FILE=%CUR_DIR%\build\launchpad_bootloader_m.elf
%GDB_CLIENT% --nw %ELF_FILE%
Чтобы подключится к микроконтроллеру надо внутри GDB клиента исполнить команду
target remote localhost:55000
Это нужно для того, чтобы подключиться к локальному порту с номеров 55000. И вот началась пошаговая отладка. Если вы спросите:
какая команда GBD клиента оказывается самой полезной?
, то я бы сказал, что это команда backtrace (bt). Именно команда backtrace покажет вам по какой причине прошивка свалилась в FaultISRHandler().
Вообще все известные полезные GDB команды у меня перечислены тут
https://docs.google.com/spreadsheets/d/1AWD8GsDfaA9dtdsfqgbB1klagou1yrREc1AAK9CRUik/edit#gid=0
Взаимодействие отладочных утилит можно показать вот такой блок-схемой
Как понять что прошивка завелась?
Достаточно посмотреть на Heartbeat LED. Если мигает значит суперцикл прошивки вертится. Удалось настроить окружение для разработки артефактов и собрать NoRTOS-прошивку для микроконтроллера СС2652 с GPIO, SysTick, LED, UART, CLI. Вот примерный лог загрузки и отладочная CLI в UART. Отладочная консоль отвечает на команды. Значит прошивка завелась. Успех!
То что вы сейчас видели (Debug CLI Terminal) это UART-CLI. Про это есть отдельная хорошая история тут https://habr.com/ru/articles/694408/
Итак, всё вышесказанное можно упаковать в одну ёмкую схему ToolChain(на). Это и есть вся система сборки для СС26x2 на основе ARM GCC. Всё на одном листике.
Вывод
Удалось научиться собирать артефакты для микроконтроллеров компании Texas Instruments CC2652 компилятором ARM GCC непосредственно из Makefile(ов). Это является альтернативным и более классическим способом сборки артефактов по отношению к сборке из GUI-IDE CCS. При этом оказалось, что версионному контролю надо подвергнуть всего-навсего 6 расширений файлов *.с *.h *.lds *.mk *.makefile, *.dat. Сборка из Makefile помогает легко и эффективно масштабировать, мигрировать и конфигурировать общую кодовую базу.
Cловарь
Акроним | Расшифровка |
CDT | C/C++ Development Tooling |
RAM | random access memory |
HAL | Hardware Abstraction Layer |
OS | operating system |
SRAM | static RAM |
RISC | reduced instruction set computer |
ARM | Advanced RISC Machines |
CMSIS | Cortex Microcontroller Software Interface |
SDK | software development kit |
GNU | GNU’s Not UNIX |
CPU | central processing unit |
ROM | Read-only memory |
GCC | The GNU Compiler Collection |
GDB | The GNU Project Debugger |
IDE | Integrated Development Environment |
JTAG | Joint Test Action Group |
JRE | Java Runtime Environment |
CCA | Customer Configuration Area |
UNIX | UNiplexed Information Computing System |
CCFG | Customer Configuration section |
TI | Texas Instruments |
FPU | Floating Point Unit |
Links
https://developer.arm.com/Tools and Software/GNU Toolchain
https://github.com/wufucious/sensortag-blink/tree/f65459dbc182a7c6e2d356f7de033e93d0b7f05b
https://electrolama.com/radio-docs/flash-ti-flash-prog/
https://wiki.st.com/stm32mpu/wiki/GDB_commands
https://habr.com/ru/companies/unwds/articles/390815/
https://habr.com/ru/articles/430732/
https://habr.com/ru/articles/148169/
https://habr.com/ru/articles/162737/
https://docs.google.com/spreadsheets/d/1AWD8GsDfaA9dtdsfqgbB1klagou1yrREc1AAK9CRUik/edit#gid=0
Контрольные вопросы:
1--Что происходит до запуска функции main()?
2--Какие расширения файлов надо подвергать версионному контролю при сборке через GCC и MakeFile?
3--Что является артефактами при сборке прошивки для микроконтроллера?
4--Какой путь проходит код с момента написания до попадания в flash память?
5--Какие доки(спеки) нужны для того, чтобы разрабатывать встраиваемый софт? Назовите минимум 4 дока.
6--Компилятору подали 5 *.с файликов и 20 *.h файликов. Сколько будет *.o файликов?
7--В каких случаях артефакты в *.hex файликах предпочтительнее артефактов в *.bin файликах?