This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

关于CC1352P的收发切换

  我的程序是基于rfPacketRx例程上修改的,工程师提供的收发切换是基于easylink的程序,因此不是很适用于我的代码。

  我的程序整体逻辑为,板子先处于接收状态,接收到无线数据后,切换为发送模式发送数据。目前接收数据正常,但是在调用 RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx,RF_PriorityNormal, NULL, 0);将模式切换为发送模式发送数据包时,程序会意外复位,复位后又处于接收模式,若接收到数据后又会意外复位,如此循环,且无法切换到发送模式发送数据。

我目前只是想知道,以我下图的切换方式,将接收切换为发送是否是合理的

  • rfPacket上进行TX/RX切换的一般做法是,收到数据包后,添加逻辑以运行Tx命令。这部分可参考rfPacketTX,或者通过合并rfPacketTX中的任务来创建新的TX任务。 然后在RX回调函数中触发TX任务(使用信号量post)。 需要注意的一点是,rfPacketRX默认设置为在RX模式下重复运行。 你需要修改如下代码使其不再重复:
    RF_cmdPropRx.pktConf.bRepeatOk = 1; //从1更改为0
    RF_cmdPropRx.pktConf.bRepeatNok = 1; //从1更改为0
  • 感谢你的回答,但是我依然还有疑问:
    1. 上图这个函数即为接收到数据包后,调用的函数,在这个函数中切换为发送模式,我的逻辑为在接收到数据包后切换为发送,发送完后,又继续一直处于接收状态,如此循环,因此我认为RF_cmdPropRx.pktConf.bRepeatOk = 1; RF_cmdPropRx.pktConf.bRepeatNok = 1; 这样的配置是必要的,不需要改为0,这个理解正确吗?
    2. 如1所说,我没有开启两个任务,而是只在一个任务中当接收到特定数据后实现的收发切换,只以一个任务来实现此功能是合理的吗?
  • 附上个实现切换的代码吧,基于rfPacket

    rfPacketRxTX.c
    /*
     * Copyright (c) 2015, 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 *****/
    #include <stdlib.h>
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <driverlib/rf_prop_mailbox.h>
    
    /* Board Header files */
    #include "Board.h"
    
    #include "RFQueue.h"
    #include "smartrf_settings/smartrf_settings.h"
    
    #include <stdlib.h>
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        Board_LED4 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        Board_LED3 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    
    /***** Defines *****/
    #define RX_TASK_STACK_SIZE 1024
    #define RX_TASK_PRIORITY   2
    
    /* TX Configuration */
    #define DATA_ENTRY_HEADER_SIZE 8  /* Constant header size of a Generic Data Entry */
    #define MAX_LENGTH             30 /* 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) */
    
    
    /***** Defines *****/
    #define TX_TASK_STACK_SIZE 1024
    #define TX_TASK_PRIORITY   3
    
    /* TX Configuration */
    #define PAYLOAD_LENGTH      30
    #define PACKET_INTERVAL     (uint32_t)(4000000*0.5f) /* Set packet interval to 500ms */
    
    
    /***** Prototypes *****/
    static void txTaskFunction(UArg arg0, UArg arg1);
    static void rxTaskFunction(UArg arg0, UArg arg1);
    static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e);
    
    /***** Variable declarations *****/
    static Task_Params rxTaskParams;
    Task_Struct rxTask;    /* not static so you can see in ROV */
    static uint8_t rxTaskStack[RX_TASK_STACK_SIZE];
    static Task_Params txTaskParams;
    Task_Struct txTask;    /* not static so you can see in ROV */
    static uint8_t txTaskStack[TX_TASK_STACK_SIZE];
    
    Semaphore_Struct semTxStruct;
    Semaphore_Handle semTxHandle;
    
    Semaphore_Struct semRxStruct;
    Semaphore_Handle semRxHandle;
    
    
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    
    #if defined(__TI_COMPILER_VERSION__)
    #pragma DATA_ALIGN (rxDataEntryBuffer, 4);
    #elif defined(__IAR_SYSTEMS_ICC__)
    #pragma data_alignment = 4
    #endif
    static uint8_t rxDataEntryBuffer[RF_QUEUE_DATA_ENTRY_BUFFER_SIZE(NUM_DATA_ENTRIES,
                                                                     MAX_LENGTH,
                                                                     NUM_APPENDED_BYTES)];
    
    /* Receive dataQueue for RF Core to fill in data */
    static dataQueue_t dataQueue;
    static rfc_dataEntryGeneral_t* currentDataEntry;
    static uint8_t packetLength;
    static uint8_t* packetDataPointer;
    uint32_t time;
    static uint8_t txPacket[PAYLOAD_LENGTH];
    static uint16_t seqNumber;
    
    static PIN_Handle pinHandle;
    
    static uint8_t packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */
    
    
    /***** Function definitions *****/
    void RxTask_init(PIN_Handle ledPinHandle) {
        pinHandle = ledPinHandle;
    
        Task_Params_init(&rxTaskParams);
        rxTaskParams.stackSize = RX_TASK_STACK_SIZE;
        rxTaskParams.priority = RX_TASK_PRIORITY;
        rxTaskParams.stack = &rxTaskStack;
        rxTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&rxTask, rxTaskFunction, &rxTaskParams, NULL);
    }
    
    static void rxTaskFunction(UArg arg0, UArg arg1)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        if( RFQueue_defineQueue(&dataQueue,
                                rxDataEntryBuffer,
                                sizeof(rxDataEntryBuffer),
                                NUM_DATA_ENTRIES,
                                MAX_LENGTH + NUM_APPENDED_BYTES))
        {
            /* Failed to allocate space for all data entries */
            while(1);
        }
    
        /* Modify CMD_PROP_RX command for application needs */
        RF_cmdPropRx.pQueue = &dataQueue;           /* Set the Data Entity queue for received data */
        RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1;  /* Discard ignored packets from Rx queue */
        RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1;   /* Discard packets with CRC error from Rx queue */
        RF_cmdPropRx.maxPktLen = MAX_LENGTH;        /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */
        RF_cmdPropRx.pktConf.bRepeatOk = 0;
        RF_cmdPropRx.pktConf.bRepeatNok = 0;
    
        if (!rfHandle) {
        	/* Request access to the radio */
        	rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        	/* Set the frequency */
        	RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
        }
    
        while (1) {
            /* Enter RX mode and stay forever in RX */
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx, RF_PriorityNormal, &callback, IRQ_RX_ENTRY_DONE);
            Semaphore_pend(semRxHandle, BIOS_WAIT_FOREVER);
        }
    
    }
    
    void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e)
    {
        if (e & RF_EventRxEntryDone)
        {
            /* Toggle pin to indicate RX */
            PIN_setOutputValue(pinHandle, Board_LED3,!PIN_getOutputValue(Board_LED3));
    
            /* Get current unhandled data entry */
            currentDataEntry = RFQueue_getDataEntry();
    
            /* Handle the packet data, located at &currentDataEntry->data:
             * - Length is the first byte with the current configuration
             * - Data starts from the second byte */
            packetLength      = *(uint8_t*)(&currentDataEntry->data);
            packetDataPointer = (uint8_t*)(&currentDataEntry->data + 1);
    
            /* Copy the payload + the status byte to the packet variable */
            memcpy(packet, packetDataPointer, (packetLength + 1));
    
            Semaphore_post(semTxHandle);
    
            RFQueue_nextEntry();
        }
    }
    
    #if 1
    /***** Function definitions *****/
    void TxTask_init(PIN_Handle inPinHandle)
    {
        pinHandle = inPinHandle;
    
        Task_Params_init(&txTaskParams);
        txTaskParams.stackSize = TX_TASK_STACK_SIZE;
        txTaskParams.priority = TX_TASK_PRIORITY;
        txTaskParams.stack = &txTaskStack;
        txTaskParams.arg0 = (UInt)1000000;
    
        Task_construct(&txTask, txTaskFunction, &txTaskParams, NULL);
    }
    
    
    static void txTaskFunction(UArg arg0, UArg arg1)
    {
        uint32_t time;
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        RF_cmdPropTx.pktLen = PAYLOAD_LENGTH;
        RF_cmdPropTx.pPkt = txPacket;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_ABSTIME;
        RF_cmdPropTx.startTrigger.pastTrig = 1;
        RF_cmdPropTx.startTime = 0;
    
        if (!rfHandle) {
        	/* Request access to the radio */
        	rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        	/* Set the frequency */
        	RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
        }
    
        /* Get current time */
        time = RF_getCurrentTime();
        while(1)
        {
            Semaphore_pend(semTxHandle, BIOS_WAIT_FOREVER);
    
            /* Create packet with incrementing sequence number and random payload */
        	txPacket[0] = (uint8_t)(seqNumber >> 8);
        	txPacket[1] = (uint8_t)(seqNumber++);
            uint8_t i;
            for (i = 2; i < PAYLOAD_LENGTH; i++)
            {
            	txPacket[i] = rand();
            }
    
            /* Set absolute TX time to utilize automatic power management */
            time += PACKET_INTERVAL;
            RF_cmdPropTx.startTime = time;
    
            /* Send packet */
            RF_EventMask result = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
            if (!(result & RF_EventLastCmdDone))
            {
                /* Error */
                while(1);
            }
    
            PIN_setOutputValue(pinHandle, Board_LED4,!PIN_getOutputValue(Board_LED4));
            Semaphore_post(semRxHandle);
    
        }
    }
    #endif
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        Semaphore_Params semParams;
    
        /* Call board init functions. */
        Board_initGeneral();
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if(!ledPinHandle)
        {
            System_abort("Error initializing board LED pins\n");
        }
    
        /* Construct a Semaphore object to be used as a resource lock, inital count 0 */
        Semaphore_Params_init(&semParams);
        Semaphore_construct(&semTxStruct, 0, &semParams);
        Semaphore_construct(&semRxStruct, 0, &semParams);
    
    
        /* Obtain instance handle */
        semTxHandle = Semaphore_handle(&semTxStruct);
        semRxHandle = Semaphore_handle(&semRxStruct);
    
        /* Initialize task */
        RxTask_init(ledPinHandle);
    
        /* Initialize task */
        TxTask_init(ledPinHandle);
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }