主题中讨论的其他器件:CC1350
大家好、
以下是客户的请求:
客户正在集成 RX 和 UART、主要是为了允许两个器件通过 UART 进行无线通信(UART 输入数据存储在数据包[2]中、 并转换为 INT、然后转换为 TX、RX 位于 callback_packet[2]中)、目前使用 SmartRF stdio 测试 TX 应该没有问题、但 RX 遇到以下问题:
- 测试以发送"123456789"、如果在 RX 接收成功时执行 UART_WRITE 的第一个字、则大部分时间都无法接收(客户操作 RX callbaclk 中的 printf 进行测试)。
- 目前、RX 结束时间用于关闭 RX、因为先使用 RX、但如果需要 TX、则当前执行的 RX 无法关闭、TX 需要等待接收到 RX 信号。 他们不知道用这个超时关闭 RX 的方法是正确的还是标准的。
程序根据 RfpacketRX 进行修改、 如下图所示:
/***** Includes *****/ /* Standard C Libraries */ #include <stdlib.h> /* TI Drivers */ #include <ti/drivers/rf/RF.h> #include <ti/drivers/PIN.h> #include <ti/drivers/UART.h> #include <ti/sysbios/knl/Task.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" /***** Defines *****/ /* Packet RX 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) */ /***** Prototypes *****/ static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e); /***** Variable declarations *****/ static RF_Object rfObject; static RF_Handle rfHandle; /* Pin driver handle */ static PIN_Handle ledPinHandle; static PIN_State ledPinState; /* Buffer which contains all Data Entries for receiving data. * Pragmas are needed to make sure this buffer is 4 byte aligned (requirement from the RF Core) */ #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 /* Receive dataQueue for RF Core to fill in data */ /*RX*/ static dataQueue_t dataQueue; static rfc_dataEntryGeneral_t* currentDataEntry; static uint8_t packetLength; static uint8_t* packetDataPointer; static uint8_t callback_packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /* The length byte is stored in a separate variable */ #define timeout (uint32_t)(4000000*0.1f) /*RX*/ /*RX Task*/ static Task_Struct rxTask; #define RX_TASK_STACK_SIZE 1024 static uint8_t rxTaskStack[RX_TASK_STACK_SIZE]; /*RX Task*/ /*TX*/ #define PAYLOAD_LENGTH 30 static uint8_t packet[PAYLOAD_LENGTH]; static uint16_t seqNumber; int tx_sending = 0; static uint8_t send_packet[MAX_LENGTH + NUM_APPENDED_BYTES - 1]; /*TX*/ /*TX Task*/ static Task_Struct txTask; #define TX_TASK_STACK_SIZE 1024 static uint8_t txTaskStack[TX_TASK_STACK_SIZE]; /*TX Task*/ /*Uart*/ UART_Handle uart; UART_Params uartParams; char input,output; /*Uart*/ /* * Application LED pin configuration table: * - All LEDs board LEDs are off. */ 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 led_init() { puts("led_init start"); 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 rfhandle_init() { puts("rfhandle_init"); 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); } rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams); int i = 0; while(i<10) { PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1)); usleep(100000); i++; } PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,0); } void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e) { if (e & RF_EventRxEntryDone) { /* Toggle pin to indicate RX */ PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 1); /* Get current unhandled data entry */ currentDataEntry = RFQueue_getDataEntry(); /* Handle the packet data, located at ¤tDataEntry->data: * - Length is the first byte with the current configuration * - Data starts from the second byte */ packetLength = *(uint8_t*)(¤tDataEntry->data); packetDataPointer = (uint8_t*)(¤tDataEntry->data + 1); /* Copy the payload + the status byte to the packet variable */ memcpy(callback_packet, packetDataPointer, (packetLength + 1)); printf("%d",callback_packet[2]); RFQueue_nextEntry(); } } void rx_init() { puts("rx_init"); /* Modify CMD_PROP_RX command for application needs */ /* Set the Data Entity queue for received data */ RF_cmdPropRx.pQueue = &dataQueue; /* Discard ignored packets from Rx queue */ RF_cmdPropRx.rxConf.bAutoFlushIgnored = 1; /* Discard packets with CRC error from Rx queue */ RF_cmdPropRx.rxConf.bAutoFlushCrcErr = 1; /* Implement packet length filtering to avoid PROP_ERROR_RXBUF */ RF_cmdPropRx.maxPktLen = MAX_LENGTH; RF_cmdPropRx.pktConf.bRepeatOk = 0; RF_cmdPropRx.endTrigger.triggerType = TRIG_REL_START; RF_cmdPropRx.endTime = timeout; /* Set the frequency */ RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0); while(1) { if(tx_sending == 0) { /* Enter RX mode and stay forever in RX */ RF_EventMask terminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropRx,RF_PriorityNormal, &callback,RF_EventRxEntryDone); switch(terminationReason) { case RF_EventLastCmdDone: // A stand-alone radio operation command or the last radio // operation command in a chain finished. //puts("RF_EventLastCmdDone"); break; default: // Uncaught error event puts("error1"); while(1); } uint32_t cmdStatus = ((volatile RF_Op*)&RF_cmdPropRx)->status; switch(cmdStatus) { case PROP_DONE_OK: // Packet received with CRC OK //puts("PROP_DONE_OK"); PIN_setOutputValue(ledPinHandle, Board_PIN_LED2, 0); output = callback_packet[2]; UART_write(uart,&output,1); break; default: // Uncaught error event - these could come from the // pool of states defined in rf_mailbox.h break; } } } } void uart_init() { UART_init(); UART_Params_init(&uartParams); uartParams.writeDataMode = UART_DATA_BINARY; uartParams.readDataMode = UART_DATA_BINARY; uartParams.readReturnMode = UART_RETURN_FULL; uartParams.readEcho = UART_ECHO_OFF; uartParams.baudRate = 9600; uart = UART_open(Board_UART0, &uartParams); if (uart == NULL) { /* UART_open() failed */ while (1); } } void rx_task_init() { puts("rx_task_init"); Task_Params rxTaskParams; // TI-RTOS 用來初始化 Task_Params 的API ,這邊會給部分變數預設值 Task_Params_init(&rxTaskParams); // 有些變數沒有預設值,必須要自行設定 rxTaskParams.stack = rxTaskStack; // 規劃給任務使用的Stack位址 rxTaskParams.stackSize = RX_TASK_STACK_SIZE; rxTaskParams.priority = 2; // 任務的優先級,數字越大代表該任務越重要 Task_construct(&rxTask, rx_init, &rxTaskParams, NULL); } void task_init() { puts("tx_init"); RF_cmdPropTx.pktLen = PAYLOAD_LENGTH; RF_cmdPropTx.pPkt = packet; RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW; while(1) { UART_read(uart,&input,1); tx_sending = 1; PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,1); RF_yield(rfHandle); packet[0] = (uint8_t)(seqNumber >> 8); packet[1] = (uint8_t)(seqNumber++); uint8_t i; for (i = 2; i < MAX_LENGTH; i++) { packet[i] = rand(); } packet[2] = input; RF_EventMask TXterminationReason = RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0); switch(TXterminationReason) { case RF_EventLastCmdDone: //puts("TX RF_EventLastCmdDone"); break; default: // Uncaught error event //puts("TX error1"); while(1); } uint32_t TXcmdStatus = ((volatile RF_Op*)&RF_cmdPropTx)->status; switch(TXcmdStatus) { case PROP_DONE_OK: //puts("TX PROP_DONE_OK"); PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,!PIN_getOutputValue(Board_PIN_LED1)); break; default: //puts("TX error2"); while(1); } tx_sending = 0; PIN_setOutputValue(ledPinHandle, Board_PIN_LED1,0); } } void tx_task_init() { puts("tx_task_init"); Task_Params txTaskParams; // TI-RTOS 用來初始化 Task_Params 的API ,這邊會給部分變數預設值 Task_Params_init(&txTaskParams); // 有些變數沒有預設值,必須要自行設定 txTaskParams.stack = txTaskStack; // 規劃給任務使用的Stack位址 txTaskParams.stackSize = TX_TASK_STACK_SIZE; txTaskParams.priority = 3; // 任務的優先級,數字越大代表該任務越重要 Task_construct(&txTask, task_init, &txTaskParams, NULL); } void *mainThread(void *arg0) { while(ledPinHandle == NULL) { led_init(); } while(rfHandle == NULL) { rfhandle_init(); } while(uart == NULL) { uart_init(); } rx_task_init(); tx_task_init(); }
您可以帮助检查此案例吗? 谢谢。
此致、
Nick