打印
[资料分享]

SimpleLink MCU代码移植指南:CC1310从VQFN48(7×7)到VQFN32(5×5)代码...

[复制链接]
743|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
yyller|  楼主 | 2020-9-2 09:24 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
CC1310 是经济高效型、超低功耗无线 MCU 中低于 1GHz 系列的首款器件。CC1310 器件在支持多个物理层和 RF 标准的平台中将灵活的超低功耗 RF 收发器和强大的 48MHz Cortex®-M3 微控制器相结合。专用无线控制器 (Cortex®-M0) 处理 ROM 或 RAM 中存储的低层 RF 协议命令,从而确保超低功耗和灵活度。
针对不同的应用需求,CC1310提供多种不同封装,包括:7mm × 7mm RGZ VQFN48 封装(30 个通用输入/输出 (GPIO)),5mm × 5mm RHB VQFN32 封装(15 个 GPIO),4mm × 4mm RSM VQFN32 封装(10 个 GPIO)。由于CC1310 Launchpad上使用的是7mm × 7mm封装芯片,SDK中附带的示例工程大多是基于7mm × 7mm封装芯片编写的。有些使用5mm × 5mm或4mm × 4mm封装芯片的客户,在CC1310 Launchpad上评估调试都没问题,但是将代码移植到自己的使用了5mm × 5mm或4mm × 4mm封装芯片的板子上后,就出现这样那样的问题了。比如编译报错说找不到变量声明;代码运行效果与之前在Launchpad上不一样;低功耗状态功耗偏高等。其实,这些问题都是在代码移植过程中的板级文件配置不正确导致的。
本文将以SDK(simplelink_cc13x0_sdk_2_20_00_38)中的pinInterrupt例程为例,介绍如何将这个例程从7mm × 7mm封装芯片移植到使用5mm × 5mm封装芯片的目标板上。同时,这种移植方法,同样也适用于TI SimpleLink 平台下的其它芯片,包括:
  • CC1310、CC1312
  • CC1350、CC1352
  • CC2640、CC2640R2F、CC2642
  • CC2650、CC2652
[size=150%]一、从SDK中导入pinInterrupt例程,并在CC1310 Launchpad上进行调试。
如下图所示,从SDK中导入pinInterrupt例程,无需对导入的工程做任何修改,直接进行编译,然后下载到CC1310 Launchpad上。按Launchpad上的BTN-1,红色LED状态会翻转(由亮变灭,或由灭变亮);按Launchpad上的BTN-2,绿色LED状态会翻转。

[size=150%]二、修改板级文件,测得<1uA的standby电流。
1. Board.hBoard.h文件中都是“#define”宏定义,是否修改并不影响代码在不同封装芯片上的运行,可以暂时不做修改。
2. CC1310_LAUNCHXL_fxns.c从2.20版本SDK开始,示例代码中将片外SPI Flash操作API从CC1310_LAUNCHXL.c文件移到了CC1310_LAUNCHXL_fxns.c文件中。使用2.20之前版本SDK的用户可以在CC1310_LAUNCHXL.c中找到这几个API。
如果目标板上没有使用片外SPI Flash,可以将这个几个API的实现代码直接屏蔽。选中需要屏蔽的代码段,按下快捷键“Ctrl + /”即可对代码段整体进行屏蔽。
/*
* ======== CC1310_LAUNCHXL_sendExtFlashByte ========
*/
void CC1310_LAUNCHXL_sendExtFlashByte(PIN_Handle pinHandle, uint8_t byte)
{
//   uint8_t i;
//
//   /* SPI Flash CS */
//   PIN_setOutputValue(pinHandle, IOID_20, 0);
//
//   for (i = 0; i < 8; i++) {
//       PIN_setOutputValue(pinHandle, IOID_10, 0); /* SPI Flash CLK */
//
//       /* SPI Flash MOSI */
//       PIN_setOutputValue(pinHandle, IOID_9, (byte >> (7 - i)) & 0x01);
//       PIN_setOutputValue(pinHandle, IOID_10, 1); /* SPI Flash CLK */
//
//       /*
//         * Waste a few cycles to keep the CLK high for at
//         * least 45% of the period.
//         * 3 cycles per loop: 8 loops @ 48 Mhz = 0.5 us.
//         */
//       CPUdelay(8);
//   }
//
//   PIN_setOutputValue(pinHandle, IOID_10, 0); /* CLK */
//   PIN_setOutputValue(pinHandle, IOID_20, 1); /* CS */
//
//   /*
//     * Keep CS high at least 40 us
//     * 3 cycles per loop: 700 loops @ 48 Mhz ~= 44 us
//     */
//   CPUdelay(700);
}

/*
* ======== CC1310_LAUNCHXL_wakeUpExtFlash ========
*/
void CC1310_LAUNCHXL_wakeUpExtFlash(void)
{
//   PIN_Config extFlashPinTable[] = {
//       /* SPI Flash CS */
//       IOID_20 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL |
//               PIN_INPUT_DIS | PIN_DRVSTR_MED,
//       PIN_TERMINATE
//   };
//   PIN_State extFlashPinState;
//   PIN_Handle extFlashPinHandle = PIN_open(&extFlashPinState, extFlashPinTable);
//
//   /*
//     * To wake up we need to toggle the chip select at
//     * least 20 ns and ten wait at least 35 us.
//     */
//
//   /* Toggle chip select for ~20ns to wake ext. flash */
//   PIN_setOutputValue(extFlashPinHandle, IOID_20, 0);
//   /* 3 cycles per loop: 1 loop @ 48 Mhz ~= 62 ns */
//   CPUdelay(1);
//   PIN_setOutputValue(extFlashPinHandle, IOID_20, 1);
//   /* 3 cycles per loop: 560 loops @ 48 Mhz ~= 35 us */
//   CPUdelay(560);
//
//   PIN_close(extFlashPinHandle);
}

/*
* ======== CC1310_LAUNCHXL_shutDownExtFlash ========
*/
void CC1310_LAUNCHXL_shutDownExtFlash(void)
{
//   /*
//     * To be sure we are putting the flash into sleep and not waking it,
//     * we first have to make a wake up call
//     */
//   CC1310_LAUNCHXL_wakeUpExtFlash();
//
//   PIN_Config extFlashPinTable[] = {
//       /* SPI Flash CS*/
//       IOID_20 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL |
//               PIN_INPUT_DIS | PIN_DRVSTR_MED,
//       /* SPI Flash CLK */
//       IOID_10 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL |
//               PIN_INPUT_DIS | PIN_DRVSTR_MED,
//       /* SPI Flash MOSI */
//       IOID_9 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL |
//               PIN_INPUT_DIS | PIN_DRVSTR_MED,
//       /* SPI Flash MISO */
//       IOID_8 | PIN_INPUT_EN | PIN_PULLDOWN,
//       PIN_TERMINATE
//   };
//   PIN_State extFlashPinState;
//   PIN_Handle extFlashPinHandle = PIN_open(&extFlashPinState, extFlashPinTable);
//
//   uint8_t extFlashShutdown = 0xB9;
//
//   CC1310_LAUNCHXL_sendExtFlashByte(extFlashPinHandle, extFlashShutdown);
//
//   PIN_close(extFlashPinHandle);
}

3. CC1310_LAUNCHXL_TIRTOS.cmd通常,.cmd文件不需要进行修改。如果你使用了包含较小Flash的CC1310芯片,则需要在.cmd文件中设置正确的FLASH_SIZE
/* The starting address of the application. Normally the interrupt vectors */
/* must be located at the beginning of the application.                     */
#define FLASH_BASE             0x0
#define FLASH_SIZE             0x20000         // 0x20000 = 128k, 0x10000 = 64k
#define RAM_BASE               0x20000000
#define RAM_SIZE               0x5000

4. CC1310_LAUNCHXL.cCC1310_LAUNCHXL.c中有很多关于各个片上外设的驱动对应的常量,我们可以先把没有用到的外设对应的定义部分先屏蔽掉,只保留pinInterrupt例程需要用到的PIN和Power模块。
另外,我们在这一阶段只测量standby状态工作电流,不进行按键和LED操作,因此将PIN_Init也屏蔽掉。
/*
* ======== CC1310_LAUNCHXL_initGeneral ========
*/
void CC1310_LAUNCHXL_initGeneral(void)
{
Power_init();

//   if (PIN_init(BoardGpioInitTable) != PIN_SUCCESS) {
//       /* Error with PIN_init */
//       while (1);
//   }

/* Perform board-specific initialization */
Board_initHook();
}

5. CC1310_LAUNCHXL.hCC1310_LAUNCHXL.h文件是引脚分配和片上外设相关的enum变量定义。同样,因为enum变量定义是否修改并不影响代码在不同封装芯片上的运行,可以暂时不做修改。
在CC1310_LAUNCHXL.h文件中,将所有引脚都设置成PIN_UNASSIGNED
/* Mapping of pins to board signals using general board aliases
*     <board signal alias>                 <pin mapping>   <comments>
*/

/* Analog capable DIOs */
#define CC1310_LAUNCHXL_DIO23_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO24_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO25_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO26_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO27_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO28_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO29_ANALOG         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO30_ANALOG         PIN_UNASSIGNED

/* Digital IOs */
#define CC1310_LAUNCHXL_DIO0                 PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO1                 PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO12                 PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO15                 PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO16_TDO             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO17_TDI             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO21                 PIN_UNASSIGNED
#define CC1310_LAUNCHXL_DIO22                 PIN_UNASSIGNED

/* Discrete Inputs */
#define CC1310_LAUNCHXL_PIN_BTN1             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PIN_BTN2             PIN_UNASSIGNED

/* GPIO */
#define CC1310_LAUNCHXL_GPIO_LED_ON           1
#define CC1310_LAUNCHXL_GPIO_LED_OFF         0

/* I2C */
#define CC1310_LAUNCHXL_I2C0_SCL0             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_I2C0_SDA0             PIN_UNASSIGNED

/* LEDs */
#define CC1310_LAUNCHXL_PIN_LED_ON           1
#define CC1310_LAUNCHXL_PIN_LED_OFF           0
#define CC1310_LAUNCHXL_PIN_RLED              PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PIN_GLED             PIN_UNASSIGNED

/* PWM Outputs */
#define CC1310_LAUNCHXL_PWMPIN0               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN1               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN2               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN3               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN4               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN5               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN6               PIN_UNASSIGNED
#define CC1310_LAUNCHXL_PWMPIN7               PIN_UNASSIGNED

/* SPI */
#define CC1310_LAUNCHXL_SPI_FLASH_CS         PIN_UNASSIGNED
#define CC1310_LAUNCHXL_FLASH_CS_ON           0
#define CC1310_LAUNCHXL_FLASH_CS_OFF         1

/* SPI Board */
#define CC1310_LAUNCHXL_SPI0_MISO             PIN_UNASSIGNED         /* RF1.20 */
#define CC1310_LAUNCHXL_SPI0_MOSI             PIN_UNASSIGNED         /* RF1.18 */
#define CC1310_LAUNCHXL_SPI0_CLK             PIN_UNASSIGNED         /* RF1.16 */
#define CC1310_LAUNCHXL_SPI0_CSN             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_SPI1_MISO             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_SPI1_MOSI             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_SPI1_CLK             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_SPI1_CSN             PIN_UNASSIGNED

/* UART Board */
#define CC1310_LAUNCHXL_UART_RX               PIN_UNASSIGNED         /* RXD */
#define CC1310_LAUNCHXL_UART_TX               PIN_UNASSIGNED         /* TXD */
#define CC1310_LAUNCHXL_UART_CTS             PIN_UNASSIGNED         /* CTS */
#define CC1310_LAUNCHXL_UART_RTS             PIN_UNASSIGNED         /* RTS */

6. pinInterrupt.c因为我们把所有的引脚都设置成了PIN_UNASSIGNED,所以在pinInterrupt.c文件中对引脚的操作会报错,我们先暂时将这些语句屏蔽掉。
/*
* Initial LED pin configuration table
*   - LEDs Board_PIN_LED0 is on.
*   - LEDs Board_PIN_LED1 is off.
*/
PIN_Config ledPinTable[] = {
//   Board_PIN_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
//   Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
   PIN_TERMINATE
};

/*
* Application button pin configuration table:
*   - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
//   Board_PIN_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
//   Board_PIN_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
   PIN_TERMINATE
};
/*
* ======== buttonCallbackFxn ========
* Pin interrupt Callback function board buttons configured in the pinTable.
* If Board_PIN_LED3 and Board_PIN_LED4 are defined, then we'll add them to the PIN
* callback function.
*/
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId) {
//   uint32_t currVal = 0;
//
//   /* Debounce logic, only toggle if the button is still pushed (low) */
//   CPUdelay(8000*50);
//   if (!PIN_getInputValue(pinId)) {
//       /* Toggle LED based on the button pressed */
//       switch (pinId) {
//           case Board_PIN_BUTTON0:
//               currVal = PIN_getOutputValue(Board_PIN_LED0);
//               PIN_setOutputValue(ledPinHandle, Board_PIN_LED0, !currVal);
//               break;
//
//           case Board_PIN_BUTTON1:
//               currVal = PIN_getOutputValue(Board_PIN_LED1);
//               PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, !currVal);
//               break;
//
//           default:
//               /* Do nothing */
//               break;
//       }
//   }
}

/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{

/* Open LED pins */
//   ledPinHandle = PIN_open(&ledPinState, ledPinTable);
//   if(!ledPinHandle) {
//       /* Error initializing board LED pins */
//       while(1);
//   }
//
//   buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
//   if(!buttonPinHandle) {
//       /* Error initializing button pins */
//       while(1);
//   }
//
//   /* Setup callback for button pins */
//   if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
//       /* Error registering button callback function */
//       while(1);
//   }

/* Loop forever */
while(1) {
sleep(1000);
   }
}

至此,所有代码修改已经完成,保存所有的源文件,重新编译,然后下载到目标板上。
代码编译结束时,会提示下面警告信息,提示声明的变量没有使用,确实是,但不用管它。

断开JTAG连接,将万用表串入电源与目标板之间,就可以观察到<1uA的工作电流,因为现在代码绝大部分时间都是处于standby状态。
[size=150%]三、按照目标板硬件配置引脚分配。
在我们使用的目标板上,有一个按键和一个LED。按键作为输入连到CC1310的DIO11,然后使用DIO9输出电平控制LED。针对这个配置,在按照上述步骤修改过的代码上继续进行如下修改。
1. CC1310_LAUNCHXL.c取消对PIN_init的 屏蔽。CCS中对某个代码段进行取消屏蔽操作的快捷键还是“Ctrl + /”。
/*
* ======== CC1310_LAUNCHXL_initGeneral ========
*/
void CC1310_LAUNCHXL_initGeneral(void)
{
Power_init();

if (PIN_init(BoardGpioInitTable) != PIN_SUCCESS) {
/* Error with PIN_init */
while (1);
   }

/* Perform board-specific initialization */
   Board_initHook();
}

2. CC1310_LAUNCHXL.h分别设置CC1310_LAUNCHXL_PIN_BTN1CC1310_LAUNCHXL_PIN_RLED对应的引脚,其他仍保持PIN_UNASSIGNED设置。
/* Discrete Inputs */
#define CC1310_LAUNCHXL_PIN_BTN1             IOID_11
#define CC1310_LAUNCHXL_PIN_BTN2             PIN_UNASSIGNED

/* GPIO */
#define CC1310_LAUNCHXL_GPIO_LED_ON           1
#define CC1310_LAUNCHXL_GPIO_LED_OFF         0

/* I2C */
#define CC1310_LAUNCHXL_I2C0_SCL0             PIN_UNASSIGNED
#define CC1310_LAUNCHXL_I2C0_SDA0             PIN_UNASSIGNED

/* LEDs */
#define CC1310_LAUNCHXL_PIN_LED_ON           1
#define CC1310_LAUNCHXL_PIN_LED_OFF           0
#define CC1310_LAUNCHXL_PIN_RLED             IOID_9
#define CC1310_LAUNCHXL_PIN_GLED             PIN_UNASSIGNED

3. pinInterrupt.c取消对Board_PIN_LED0Board_PIN_BUTTON0的屏蔽,取消对Board_PIN_BUTTON0的中断处理部分的屏蔽,取消ledPinHandlebuttonPinHandle的初始化和中断处理函数注册的屏蔽。
/*
* Initial LED pin configuration table
*   - LEDs Board_PIN_LED0 is on.
*   - LEDs Board_PIN_LED1 is off.
*/
PIN_Config ledPinTable[] = {
   Board_PIN_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_HIGH | PIN_PUSHPULL | PIN_DRVSTR_MAX,
//   Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
   PIN_TERMINATE
};

/*
* Application button pin configuration table:
*   - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
   Board_PIN_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
//   Board_PIN_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
   PIN_TERMINATE
};

/*
* ======== buttonCallbackFxn ========
* Pin interrupt Callback function board buttons configured in the pinTable.
* If Board_PIN_LED3 and Board_PIN_LED4 are defined, then we'll add them to the PIN
* callback function.
*/
void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId) {
uint32_t currVal = 0;

/* Debounce logic, only toggle if the button is still pushed (low) */
   CPUdelay(8000*50);
if (!PIN_getInputValue(pinId)) {
/* Toggle LED based on the button pressed */
switch (pinId) {
case Board_PIN_BUTTON0:
               currVal = PIN_getOutputValue(Board_PIN_LED0);
PIN_setOutputValue(ledPinHandle, Board_PIN_LED0, !currVal);
break;

//           case Board_PIN_BUTTON1:
//               currVal = PIN_getOutputValue(Board_PIN_LED1);
//               PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, !currVal);
//               break;

default:
/* Do nothing */
break;
       }
   }
}

/*
* ======== mainThread ========
*/
void *mainThread(void *arg0)
{

/* Open LED pins */
   ledPinHandle = PIN_open(&ledPinState, ledPinTable);
if(!ledPinHandle) {
/* Error initializing board LED pins */
while(1);
   }

   buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
if(!buttonPinHandle) {
/* Error initializing button pins */
while(1);
   }

/* Setup callback for button pins */
if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
/* Error registering button callback function */
while(1);
   }

/* Loop forever */
while(1) {
sleep(1000);
   }
}

至此,所有代码修改已经完成,保存所有的源文件,重新编译,然后下载到目标板上。
每按一次目标板上的按键,LED的状态会翻转一次。
这样,我们就成功的将SDK中基于7mm × 7mm封装的pinInterrupt例程移植到了使用5mm × 5mm封装的目标板上。这个例程比较简单,只使用到了PIN 模块。如果用户需要使用更多片上外设,比如ADC,UART等,只需在CC1310_LAUNCHXL.c文件中取消对应模块代码的屏蔽,并在CC1310_LAUNCHXL.h文件中,按照目标板上的引脚关系,将对应的引脚配置由PIN_UNASSIGNED修改为对应的IO即可。

使用特权

评论回复

相关帖子

沙发
gwsan| | 2020-10-9 09:46 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
板凳
kxsi| | 2020-10-9 09:47 | 只看该作者
这个器件已经很成熟了

使用特权

评论回复
地板
nawu| | 2020-10-9 09:47 | 只看该作者
一定需要跑系统吗 可以裸奔吗

使用特权

评论回复
5
qcliu| | 2020-10-9 09:48 | 只看该作者
代码很不错

使用特权

评论回复
6
tfqi| | 2020-10-9 09:48 | 只看该作者
楼主辛苦了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

132

主题

241

帖子

1

粉丝