主题中讨论的其他器件:CC1310、
团队成员、您好。
我希望能生成一个程序、利用 SCS 的 UART 通过 RS485与器件通信、并使用 RF 的 TX 传输数据。
现在我已经确定 SCS 的 UART 可以使用 scifWaitOnNbl(5000000);来降低5秒的功耗。
但我不知道如何关闭 Cortex-M3。 我已经在 TI 驱动程序示例中查看了 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_PACKET 0 #define PACKET_RECEIVED 1 volatile uint8_t packetRxCb; volatile size_t bytesReadCount; /* Packet RX Configuration */ #define MAX_LENGTH 240 /* Max length byte the radio will accept */ #define NUM_DATA_ENTRIES 2 /* NOTE: Only two data entries supported at the moment */ #define NUM_APPENDED_BYTES 2 /* 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_BYTES 1000 #define MAX_NUM_UART_TX_BYTES 1000 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 ¤tDataEntry->data: * - Length is the first byte with the current configuration * - Data starts from the second byte */ rfRxPacketLength = *(uint8_t*)(¤tDataEntry->data); //gets the packet length (send over with packet) rfRxPacketDataPointer = (uint8_t*)(¤tDataEntry->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 source scifClearAlertIntSource(); // Echo all characters currently in the RX FIFO int rxFifoCount = scifUartGetRxFifoCount(); uartRxCount = rxFifoCount; i = 0; while (rxFifoCount--) { UartRxBuf[i] = (char)scifUartRxGetChar(); i++; } // Clear the events that triggered this scifUartClearEvents(); // Acknowledge the alert event scifAckAlertEvents(); if(uartRxCount > 0) { //開啟rf tx Semaphore_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 Controller scifOsalInit(); 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 emulator scifResetTaskStructs((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 generation scifUartSetBaudRate(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 timeout scifUartSetEventMask(BV_SCIF_UART_ALERT_RX_FIFO_ABOVE_THR | BV_SCIF_UART_ALERT_RX_BYTE_TIMEOUT); //printf("wait 0.5s\n"); scifWaitOnNbl(500000); // 使用循環將整個帶CRC檢驗碼的數據報文傳輸到UART for (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 semaphore Semaphore_construct(&uartTaskSem, 0, NULL); uartTaskSemHandle = Semaphore_handle(&uartTaskSem); // Configure the Uart task Task_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 semaphore Semaphore_construct(&rfTxTaskSem, 0, NULL); rfTxTaskSemHandle = Semaphore_handle(&rfTxTaskSem); // Configure the RFTx task Task_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(); }
此致、
银河