Tool/software: TI-RTOS
I am trying to get UART and RF working together. Specifically, I need to listen for a RF packet, and transmit it over UART whenever a packet is received. I have tried to use the example provided here for the CC1350 as a base, but I do not receive my RF packet if my UartTxTask is initiallized.
Here is my code:
/***** 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 <ti/drivers/UART.h> #include <ti/sysbios/knl/Mailbox.h> #include <ti/sysbios/knl/Semaphore.h> #include <ti/sysbios/knl/Task.h> #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Clock.h> #include <ti/devices/DeviceFamily.h> #include DeviceFamily_constructPath(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_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 }; enum rf_mode { RX_MODE, TX_MODE, }; volatile enum rf_mode mode = RX_MODE; /* Packet RX Configuration */ #define DATA_ENTRY_HEADER_SIZE 8 /* Constant header size of a Generic Data Entry */ #define MAX_LENGTH 2 /* 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 RX_TASK_STACK_SIZE 1024 #define RX_TASK_PRIORITY 1 #define UART_TX_TASK_STACK_SIZE 1024 #define UART_TX_TASK_PRIORITY 2 /***** Prototypes *****/ static void rxTaskFunction(UArg arg0, UArg arg1); static void callback(RF_Handle h, RF_CmdHandle ch, RF_EventMask e); static void uartTxTaskFunction(UArg arg0, UArg arg1); /***** 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 uartTxTaskParams; Task_Struct uartTxTask; /* not static so you can see in ROV */ static uint8_t uartTxTaskStack[UART_TX_TASK_STACK_SIZE]; Semaphore_Struct semRxStruct; Semaphore_Handle semRxHandle; Semaphore_Struct semUartTxStruct; Semaphore_Handle semUartTxHandle; static RF_Object rfObject; static RF_Handle rfHandle; static RF_CmdHandle rfRxCmd; UART_Handle uart = NULL; UART_Params uartParams; /* 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 */ static dataQueue_t dataQueue; static rfc_dataEntryGeneral_t* currentDataEntry; uint8_t packetReady = 0; static uint8_t packetLength; static uint8_t* packetDataPointer; //uint32_t time; 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); } void UartTxTask_init(PIN_Handle ledPinHandle) { pinHandle = ledPinHandle; Task_Params_init(&uartTxTaskParams); uartTxTaskParams.stackSize = UART_TX_TASK_STACK_SIZE; uartTxTaskParams.priority = UART_TX_TASK_PRIORITY; uartTxTaskParams.stack = &uartTxTaskStack; uartTxTaskParams.arg0 = (UInt)1000000; Task_construct(&uartTxTask, uartTxTaskFunction, &uartTxTaskParams, 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 = 1; RF_cmdPropRx.pktConf.bRepeatNok = 1; 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_PIN_LED2,!PIN_getOutputValue(Board_PIN_LED2)); /* 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(packet, packetDataPointer, (packetLength + 1)); packetReady = 1; RFQueue_nextEntry(); Semaphore_post(semUartTxHandle); } } #define UART_TX_BUFFER_SIZE 256 char uartTxBuffer[UART_TX_BUFFER_SIZE]; static void uartTxTaskFunction(UArg arg0, UArg arg1) { int readShift; uint8_t input[packetLength]; for(readShift = 0; readShift < 2; readShift++) { input[readShift] = packet[readShift]; } /* Open UART if not already open */ if (uart == NULL) { /* Create a UART with data processing off. */ 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) { System_abort("Error opening the UART"); } } while (1) { Semaphore_pend(semUartTxHandle, BIOS_WAIT_FOREVER); UART_write(uart, input, 3); /* Cancel Rx */ // RF_cancelCmd(rfHandle, rfRxCmd, 0); Semaphore_post(semRxHandle); } } /* * ======== main ======== */ int main(void) { Semaphore_Params semParams; /* Call driver 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(&semRxStruct, 0, &semParams); /* Obtain instance handle */ semUartTxHandle = Semaphore_handle(&semUartTxStruct); /* Construct a Semaphore object to be used as a resource lock, inital count 0 */ //Semaphore_Params_init(&semParams); Semaphore_construct(&semUartTxStruct, 0, &semParams); /* Initialize task */ RxTask_init(ledPinHandle); UartTxTask_init(ledPinHandle); /* Start BIOS */ BIOS_start(); return (0); }
If I comment out my UartTxTask_init in my main (line 294) RF Rx works again. Any ideas as to why I can only seem to run one task at a time? I'm pretty sure I've got my Semaphores set up properly, so I don't think it's that.