Other Parts Discussed in Post:CC1310, CC1350, CC2640, CC2640R2F, CC2650
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
一、從SDK中導入pinInterrupt例程,并在CC1310 Launchpad上進行調試。
如下圖所示,從SDK中導入pinInterrupt例程,無需對導入的工程做任何修改,直接進行編譯,然后下載到CC1310 Launchpad上。按Launchpad上的BTN-1,紅色LED狀態會翻轉(由亮變滅,或由滅變亮);按Launchpad上的BTN-2,綠色LED狀態會翻轉。
二、修改板級文件,測得<1uA的standby電流。
1. Board.h
Board.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 ========
*/
voidCC1310_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 ========
*/
voidCC1310_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 ========
*/
voidCC1310_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. */
#defineFLASH_BASE 0x0
#defineFLASH_SIZE 0x20000 // 0x20000 = 128k, 0x10000 = 64k
#defineRAM_BASE 0x20000000
#defineRAM_SIZE 0x5000
4. CC1310_LAUNCHXL.c
CC1310_LAUNCHXL.c中有很多關于各個片上外設的驅動對應的常量,我們可以先把沒有用到的外設對應的定義部分先屏蔽掉,只保留pinInterrupt例程需要用到的PIN和Power模塊。
另外,我們在這一階段只測量standby狀態工作電流,不進行按鍵和LED操作,因此將PIN_Init也屏蔽掉。
/*
* ======== CC1310_LAUNCHXL_initGeneral ========
*/
voidCC1310_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.h
CC1310_LAUNCHXL.h文件是引腳分配和片上外設相關的enum變量定義。同樣,因為enum變量定義是否修改并不影響代碼在不同封裝芯片上的運行,可以暫時不做修改。
在CC1310_LAUNCHXL.h文件中,將所有引腳都設置成PIN_UNASSIGNED。
/* Mapping of pins to board signals using general board aliases
*
*/
/* Analog capable DIOs */
#defineCC1310_LAUNCHXL_DIO23_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO24_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO25_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO26_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO27_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO28_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO29_ANALOG PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO30_ANALOG PIN_UNASSIGNED
/* Digital IOs */
#defineCC1310_LAUNCHXL_DIO0 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO1 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO12 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO15 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO16_TDO PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO17_TDI PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO21 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_DIO22 PIN_UNASSIGNED
/* Discrete Inputs */
#defineCC1310_LAUNCHXL_PIN_BTN1 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PIN_BTN2 PIN_UNASSIGNED
/* GPIO */
#defineCC1310_LAUNCHXL_GPIO_LED_ON 1
#defineCC1310_LAUNCHXL_GPIO_LED_OFF 0
/* I2C */
#defineCC1310_LAUNCHXL_I2C0_SCL0 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_I2C0_SDA0 PIN_UNASSIGNED
/* LEDs */
#defineCC1310_LAUNCHXL_PIN_LED_ON 1
#defineCC1310_LAUNCHXL_PIN_LED_OFF 0
#defineCC1310_LAUNCHXL_PIN_RLED PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PIN_GLED PIN_UNASSIGNED
/* PWM Outputs */
#defineCC1310_LAUNCHXL_PWMPIN0 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN1 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN2 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN3 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN4 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN5 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN6 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_PWMPIN7 PIN_UNASSIGNED
/* SPI */
#defineCC1310_LAUNCHXL_SPI_FLASH_CS PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_FLASH_CS_ON 0
#defineCC1310_LAUNCHXL_FLASH_CS_OFF 1
/* SPI Board */
#defineCC1310_LAUNCHXL_SPI0_MISO PIN_UNASSIGNED /* RF1.20 */
#defineCC1310_LAUNCHXL_SPI0_MOSI PIN_UNASSIGNED /* RF1.18 */
#defineCC1310_LAUNCHXL_SPI0_CLK PIN_UNASSIGNED /* RF1.16 */
#defineCC1310_LAUNCHXL_SPI0_CSN PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_SPI1_MISO PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_SPI1_MOSI PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_SPI1_CLK PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_SPI1_CSN PIN_UNASSIGNED
/* UART Board */
#defineCC1310_LAUNCHXL_UART_RX PIN_UNASSIGNED /* RXD */
#defineCC1310_LAUNCHXL_UART_TX PIN_UNASSIGNED /* TXD */
#defineCC1310_LAUNCHXL_UART_CTS PIN_UNASSIGNED /* CTS */
#defineCC1310_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.
*/
voidbuttonCallbackFxn(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狀態。
三、按照目標板硬件配置引腳分配。
在我們使用的目標板上,有一個按鍵和一個LED。按鍵作為輸入連到CC1310的DIO11,然后使用DIO9輸出電平控制LED。針對這個配置,在按照上述步驟修改過的代碼上繼續進行如下修改。
1. CC1310_LAUNCHXL.c
取消對PIN_init的 屏蔽。CCS中對某個代碼段進行取消屏蔽操作的快捷鍵還是“Ctrl + /”。
/*
* ======== CC1310_LAUNCHXL_initGeneral ========
*/
voidCC1310_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_BTN1和CC1310_LAUNCHXL_PIN_RLED對應的引腳,其他仍保持PIN_UNASSIGNED設置。
/* Discrete Inputs */
#defineCC1310_LAUNCHXL_PIN_BTN1 IOID_11
#defineCC1310_LAUNCHXL_PIN_BTN2 PIN_UNASSIGNED
/* GPIO */
#defineCC1310_LAUNCHXL_GPIO_LED_ON 1
#defineCC1310_LAUNCHXL_GPIO_LED_OFF 0
/* I2C */
#defineCC1310_LAUNCHXL_I2C0_SCL0 PIN_UNASSIGNED
#defineCC1310_LAUNCHXL_I2C0_SDA0 PIN_UNASSIGNED
/* LEDs */
#defineCC1310_LAUNCHXL_PIN_LED_ON 1
#defineCC1310_LAUNCHXL_PIN_LED_OFF 0
#defineCC1310_LAUNCHXL_PIN_RLED IOID_9
#defineCC1310_LAUNCHXL_PIN_GLED PIN_UNASSIGNED
3. pinInterrupt.c
取消對Board_PIN_LED0和Board_PIN_BUTTON0的屏蔽,取消對Board_PIN_BUTTON0的中斷處理部分的屏蔽,取消ledPinHandle和buttonPinHandle的初始化和中斷處理函數注冊的屏蔽。
/*
* 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.
*/
voidbuttonCallbackFxn(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) {
caseBoard_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即可。
審核編輯:何安
-
嵌入式處理
+關注
關注
0文章
341瀏覽量
10012
發布評論請先 登錄
相關推薦
評論