TI中文支持网
TI专业的中文技术问题搜集分享网站

CC1350:如何實現低功耗的RF和SCS uart

Part Number:CC1350Other Parts Discussed in Thread:CC1310,

我希望能產出一支程式,使用SCS的uart與設備透過RS485進行溝通,並將數據利用RF的TX傳送出去,我目前已經確定SCS的uart能夠利用scifWaitOnNbl(5000000);降低功耗5秒,但是我不知道如何關閉Cortex-M3,我有查看ti Driver 範例中的pinstanby,但是似乎sleep();無法滿足我的需求,希望能得到一些建議,或者SCS的uart的休眠如果有錯誤再麻煩告訴我。

謝謝,以下提供程式碼,希望能得到最好的建議。
說明一下,主要是通過uartTaskInit和rfTxTaskInit之間交互

/*
 * Copyright (c) 2019, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *notice, this list of conditions and the following disclaimer in the
 *documentation and/or other materials provided with the distribution.
 *
 * *  Neither the name of Texas Instruments Incorporated nor the names of
 *its contributors may be used to endorse or promote products derived
 *from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/***** Includes *****/
/* Standard C Libraries */
#include <stdlib.h>
#include <unistd.h>

/* TI Drivers */
#include <ti/drivers/rf/RF.h>
#include <ti/drivers/PIN.h>
#include <ti/drivers/UART.h>
#include <ti/drivers/uart/UARTCC26XX.h>
/* Driverlib Header files */
#include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)

/* Board Header files */
#include "Board.h"

/* Application Header files */
#include "RFQueue.h"
#include "smartrf_settings/smartrf_settings.h"
//#include DeviceFamily_constructPath(inc/hw_fcfg1.h)

//SCS include
#include <ti/devices/DeviceFamily.h>
#include "scif.h"
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/BIOS.h>

/***** Defines *****/
#define NO_PACKET0
#define PACKET_RECEIVED1

volatile uint8_t packetRxCb;
volatile size_t bytesReadCount;

/* Packet RX Configuration */
#define MAX_LENGTH240 /* Max length byte the radio will accept */
#define NUM_DATA_ENTRIES2  /* NOTE: Only two data entries supported at the moment */
#define NUM_APPENDED_BYTES2  /* The Data Entries data field will contain:* 1 Header byte (RF_cmdPropRx.rxConf.bIncludeHdr = 0x1)* Max 30 payload bytes* 1 status byte (RF_cmdPropRx.rxConf.bAppendStatus = 0x1) */

/* RFQueue */
static dataQueue_t dataQueue;
static rfc_dataEntryGeneral_t* currentDataEntry;
static uint8_t rfRxPacketLength;
static uint8_t* rfRxPacketDataPointer;
static uint8_t rfRxPacket[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
static uint8_t rfTxPacket[MAX_LENGTH + NUM_APPENDED_BYTES - 1];

#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN (rxDataEntryBuffer, 4);
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)];
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment = 4
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)];
#elif defined(__GNUC__)
static uint8_t
rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,MAX_LENGTH,NUM_APPENDED_BYTES)]__attribute__((aligned(4)));
#else
#error This compiler is not supported.
#endif

/* UART */
#define MAX_NUM_UART_RX_BYTES1000
#define MAX_NUM_UART_TX_BYTES1000

static int uartRxCount;
uint8_t UartRxBuf[MAX_NUM_UART_RX_BYTES];// Receive buffer
uint8_t UartTxBuf[MAX_NUM_UART_TX_BYTES];// Transmit buffer

UART_Handle uart;
UART_Params uartParams;

static char input[MAX_NUM_UART_RX_BYTES];
static char output[MAX_NUM_UART_TX_BYTES];
int32_t UARTwrite_semStatus;
int_fast16_t status = UART_STATUS_SUCCESS;
static int i,j;

// Uart TASK DATA
// Task data
static Task_Params uartTaskParams,rfTxTaskParams,rfRxTaskParams;
static Task_Struct uartTaskStruct,rfTxTaskStruct,rfRxTaskStruct;
static Char uartTaskStack[1024],rfTxTaskStack[1024],rfRxTaskStack[1024];


Semaphore_Struct uartTaskSem, rfTxTaskSem, rfRxTaskSem;
Semaphore_Handle uartTaskSemHandle, rfTxTaskSemHandle, rfRxTaskSemHandle;

/* RF handle */
static RF_Object rfObject;
static RF_Handle rfHandle;
static RF_CmdHandle rfTxPostHandle,rfRxPostHandle;
static RF_Params rfParams;

/* LED */
static PIN_Handle ledPinHandle;
static PIN_State ledPinState;

PIN_Config pinTable[] =
{Board_PIN_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,Board_PIN_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,PIN_TERMINATE
};

/***** Function definitions *****/
void ReceiveonUARTcallback(UART_Handle handle, void *UartRxBuf, size_t count, void *userArg, int_fast16_t status)
{bytesReadCount = count;
}

void led_init()
{ledPinHandle = PIN_open(&ledPinState, pinTable);PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));usleep(300000);PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1));PIN_setOutputValue(ledPinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));usleep(300000);PIN_setOutputValue(ledPinHandle, Board_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2));if (ledPinHandle == NULL){while(1);}
}

void uartTxRfRxPacket()
{printf("uartTxRfRxPacket\n");if(packetRxCb){for(i=0;i<rfRxPacketLength;i++){scifUartTxPutChar((char)rfRxPacket[i]);}packetRxCb = NO_PACKET;Semaphore_post(rfRxTaskSemHandle);}
}

void ReceivedOnRFcallback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
{if (e & RF_EventRxEntryDone){PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 1);/* Get current unhandled data entry */currentDataEntry = RFQueue_getDataEntry(); //loads data from entry/* Handle the packet data, located at &currentDataEntry->data:* - Length is the first byte with the current configuration* - Data starts from the second byte */rfRxPacketLength= *(uint8_t*)(&currentDataEntry->data); //gets the packet length (send over with packet)rfRxPacketDataPointer = (uint8_t*)(&currentDataEntry->data + 1); //data starts from 2nd byte/* Copy the payload + the status byte to the packet variable */memcpy(rfRxPacket, rfRxPacketDataPointer, (rfRxPacketLength + 1));/* Move read entry pointer to next entry */RFQueue_nextEntry();packetRxCb = PACKET_RECEIVED;PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 0);uartTxRfRxPacket();}
}

void scCtrlReadyCallback(void) {printf("scCtrlReadyCallback\n");
} // scCtrlReadyCallback

void scTaskAlertCallback(void) {printf("scTaskAlertCallback\n");// Clear the ALERT interrupt sourcescifClearAlertIntSource();// Echo all characters currently in the RX FIFOint rxFifoCount = scifUartGetRxFifoCount();uartRxCount = rxFifoCount;i = 0;while (rxFifoCount--){UartRxBuf[i] = (char)scifUartRxGetChar();i++;}// Clear the events that triggered thisscifUartClearEvents();// Acknowledge the alert eventscifAckAlertEvents();if(uartRxCount > 0){//開啟rf txSemaphore_post(rfTxTaskSemHandle);}// Wake up the OS task//Semaphore_post(uartTaskSemHandle);
} // scTaskAlertCallback

// CRC計算函數
uint16_t calculateCRC(uint8_t *data, int length) {uint16_t crc = 0xFFFF;for (i = 0; i < length; i++) {crc ^= data[i];for (j = 0; j < 8; j++) {if (crc & 0x0001) {crc >>= 1;crc ^= 0xA001; // 16位CRC多項式} else {crc >>= 1;}}}return crc;
}

void scUartTask(UArg a0, UArg a1) {printf("scUartTask start\n");// Initialize the Sensor ControllerscifOsalInit();scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);scifInit(&scifDriverSetup);//scifStartRtcTicksNow(0x00010000 / 8);uint8_t command[] = { 0x01, 0x04, 0x00, 0x00, 0x00, 0x0A};int commandLength = sizeof(command) / sizeof(command[0]);uint16_t crc = calculateCRC(command, commandLength);// 將CRC檢驗碼附加到數據報文command[commandLength] = crc & 0xFF; // 低位字節command[commandLength + 1] = (crc >> 8) & 0xFF; // 高位字節int newCommandLength = commandLength + 2;while(1){//printf("Uart restart\n");// Start the UART emulatorscifResetTaskStructs((1 << SCIF_UART_EMULATOR_TASK_ID), (1 << SCIF_STRUCT_CFG) | (1 << SCIF_STRUCT_INPUT) | (1 << SCIF_STRUCT_OUTPUT));scifExecuteTasksOnceNbl(1 << SCIF_UART_EMULATOR_TASK_ID);// Enable baud rate generationscifUartSetBaudRate(9600);// Enable RX (10 idle bit periods required before enabling start bit detection)scifUartSetRxFifoThr(SCIF_UART_RX_FIFO_MAX_COUNT / 2);scifUartSetRxTimeout(10 * 2);scifUartSetRxEnableReqIdleCount(10 * 2);scifUartRxEnable(1);// Enable events (half full RX FIFO or 10 bit period timeoutscifUartSetEventMask(BV_SCIF_UART_ALERT_RX_FIFO_ABOVE_THR | BV_SCIF_UART_ALERT_RX_BYTE_TIMEOUT);//printf("wait 0.5s\n");scifWaitOnNbl(500000);// 使用循環將整個帶CRC檢驗碼的數據報文傳輸到UARTfor (i = 0; i < newCommandLength; i++) {scifUartTxPutChar(command[i]);}//printf("scUartTask wait for semaphore post\n");// Wait for an ALERT callback//Semaphore_pend(uartTaskSemHandle, BIOS_WAIT_FOREVER);//printf("wait 0.5s\n");scifWaitOnNbl(500000);//printf("scifUartStopEmulator\n");scifUartStopEmulator();scifUartSetBaudRate(0);//printf("wait 5s\n");scifWaitOnNbl(500000);}

} // taskFxn

void uartTaskInit()
{//Initialize Uart semaphoreSemaphore_construct(&uartTaskSem, 0, NULL);uartTaskSemHandle = Semaphore_handle(&uartTaskSem);// Configure the Uart taskTask_Params_init(&uartTaskParams);uartTaskParams.stack = uartTaskStack;uartTaskParams.stackSize = sizeof(uartTaskStack);uartTaskParams.priority = 2;Task_construct(&uartTaskStruct, scUartTask, &uartTaskParams, NULL);
}

void rfTxTask()
{//RF_Params_init(&rfTxParams);// TX指令參數設定RF_cmdPropTx.pPkt = rfTxPacket;RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;//rfTxHandle = RF_open(&rfTxObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfTxParams);//設定頻率//RF_postCmd(rfTxHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);while(1){printf("rfTxTask wait for semaphore post\n");Semaphore_pend(rfTxTaskSemHandle, BIOS_WAIT_FOREVER);if(uartRxCount > 0){RF_cmdPropTx.pktLen = uartRxCount;int i;for(i=0; i<uartRxCount; i++){rfTxPacket[i] = UartRxBuf[i];}/*for(i=0;i<sizeof(rfTxPacket);i++){printf("%c\n",rfTxPacket[i]);}*/RF_cancelCmd(rfHandle, rfRxPostHandle, 1);PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, 1);RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);PIN_setOutputValue(ledPinHandle, Board_PIN_LED1, 0);rfRxPostHandle = RF_postCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,RF_PriorityNormal, &ReceivedOnRFcallback,RF_EventRxEntryDone);uartRxCount = 0;for(i=0;i<sizeof(UartRxBuf);i++){UartRxBuf[i] = '\0';}}}
}

void rfTxTaskInit()
{//Initialize RFTx semaphoreSemaphore_construct(&rfTxTaskSem, 0, NULL);rfTxTaskSemHandle = Semaphore_handle(&rfTxTaskSem);// Configure the RFTx taskTask_Params_init(&rfTxTaskParams);rfTxTaskParams.stack = rfTxTaskStack;rfTxTaskParams.stackSize = sizeof(rfTxTaskStack);rfTxTaskParams.priority = 1;Task_construct(&rfTxTaskStruct, rfTxTask, &rfTxTaskParams, NULL);
}

void rfInit()
{RF_Params_init(&rfParams);rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);//設定頻率RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
}

void *mainThread(void *arg0)
{while(ledPinHandle == NULL){led_init();}uartTaskInit();rfInit();rfTxTaskInit();
}

Galaxy Yue:

您好,您的问题已跟进,有进展会及时通知您的。

,

Galaxy Yue:

您好,

1.您正在使用哪个版本的SimpleLink CC13x0 SDK和SCS studio?

2.当你说sleep ()不能满足你的需求,你能慎重考虑一下吗? 当设备处于睡眠状态时,您在测量多少?

3.如果M3没有任何活动任务,并且电源配置文件设置为待机(Power_safing预定义符号),则设备将进入睡眠状态。

4.通常,当使用UART时,您不能允许设备完全进入休眠状态,因为它正在等待收到的事务。 您使用的是UART阻塞模式还是回调模式?

,

YI SHEN:

您好,Galaxy:1.我目前使用的SDK是SimpleLink CC13x0 SDK (4.20.02.07),SCS的版本是2.9.0.2082.與其說不能滿足我的需求,更正確的應該是不知道如何只用sleep滿足我的需求,我希望能夠每60S,由uart向設備發送一次訊號,並等待回傳後,由RF透過TX發送給另一個cc1310設備,且RF的RX也能定時接收訊號,但是我目前想先達到UART和RFTX部分就好,等完成後再繼續完成其他的項目。

3.目前還沒有了解到先關於電源設定檔的資料,目前看到其他人有使用power_sleep()等相關的語法,但並不是很了解。

4.目前是透過callback去觸發,SCS的觸發好像與cc1310上的uart echo不太一樣,好像scs的uart比較省電。

目前我的需求就如同第二點所描述的,但是目前還不太了解如何解決,可以的話,希望您能給我一些建議與方向,主要就是固定時間由A主機與設備利用uart溝通,並將uart回傳內容由RFTX給B主機

,

Galaxy Yue:

您好,已经收到您补充的信息,将继续为您跟进。

,

Galaxy Yue:

您好,

CC13xx 的电源模式在 TRM 第 6.6 章中进行了解释(CC13x0, CC26x0 SimpleLinkTm Wireless MCU Technical Reference Manual (Rev. I) (ti.com))

请参阅下表,了解模式列表以及该模式下活动的外设:

每种模式的预期电流消耗可以从数据表的第 5.4 章中获取,如下所示:

您在待机用例中是否遇到高于 0.8μA 的电流消耗?

使用待机模式时,传感器控制器仍然可用,您可以通过 UART 接收数据来唤醒设备。

,

YI SHEN:

您好 Galaxy  : 

我與我的夥伴最近有進行測試,並了解到rfSynchronizedPacketTx/RX與WORTX/RX測量出來都是有進行省電的,最近我在研究rfSynchronizedPacketTx/RX,因為此功能與我們的需求最符合。1.想請教在rfSynchronizedPacketTx/RX中,睡眠省電的部分是否可以跟我說明一下,當然我也會自己去研究,只是希望聽聽您的解說,以避免我對於程式的誤解。2.rfSynchronizedPacketTx/RX與WORTX/RX都不會像其他範例一樣有使用mainThread,請問這個和睡眠省電有相關聯嗎

,

Galaxy Yue:

好的,已经了解您的需求,有进展了会告知您的。

,

Galaxy Yue:

您好 YI SHEN,

1. 顾名思义,这些示例是发送同步数据包,这意味着发送方和接收方都知道发送数据包的时隙。 因此,RF 核心会在每个发送数据包之间断电,从而节省电量。 在此示例中,间隔设置为 500ms。然而,控制器本身不会在这些时隙中自动休眠。在编译之前,您必须在项目设置中设置预定义的“POWER_SAVING”符号,就像 Marie 之前描述的那样。

2. 我猜这是由于使用 RTOS 与非 RTOS 示例的差异造成的。 在这个案例中你使用了哪些?

,

YI SHEN:

1.請問“POWER_SAVING”在那裡可以找到,是否有截圖能讓我看看2.我都是使用RTOS

,

Galaxy Yue:

需要一些时间来处理,有进展会立马告知您的。

,

Galaxy Yue:

rfSynchronizedPacketTx/Rx 不使用 POWER_SAVING 预定义。 (对于误解,这在 SDK 示例项目之间有所不同。)

相反,电源策略是在板文件 (CC1350_LAUNCHXL.c) 中设置的。 向下滚动到电源驱动程序定义。 policyFxn 应设置为 PowerCC26XX_standbyPolicy 以允许设备进入待机状态。

/**=============================== Power ===============================*/
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>const PowerCC26XX_Config PowerCC26XX_config = {.policyInitFxn= NULL,.policyFxn= &PowerCC26XX_standbyPolicy,.calibrateFxn= &PowerCC26XX_calibrate,.enablePolicy= true,.calibrateRCOSC_LF= true,.calibrateRCOSC_HF= true,
};

,

Yi Shen:

Galaxy 您好 : 

非常感謝您,您回覆訊息的速度非常的快速,且回答也很準確,我需要再測試研究看看。

,

Galaxy Yue:

Yi Shen 您好,

不用客气,祝顺利!

赞(0)
未经允许不得转载:TI中文支持网 » CC1350:如何實現低功耗的RF和SCS uart
分享到: 更多 (0)

© 2024 TI中文支持网   网站地图 鲁ICP备2022002796号-1