/******************************************************************************* * @fn syncReceivedISR * * @brief Function running every time a sync word has been received * * @param none * * @return none */ static void syncReceivedISR(void) { uint8 numRxBytes; uint8 writeByte; // After the sync word is received one needs to wait for the two // length bytes to be put in the RX FIFO do { cc112xSpiReadReg(CC112X_NUM_RXBYTES, &numRxBytes, 1); } while (numRxBytes < 2); // Read the length byte and store it in the packetLength variable cc112xSpiReadRxFifo(rxBuffer, 2); pBufferIndex += 2; packetLength = (uint16)(((uint16)(rxBuffer[0] << 8)) | rxBuffer[1]); // Make sure that the packet length is in the correct range, update // variables and enable interrupt on falling edge of GPIO3 (PKT_SYNC_RXTX) if ((packetLength > MAX_VARIABLE_LENGTH) && (packetLength <= PACKET_LENGTH)) { bytesLeft = packetLength + 2; fixedPacketLength = bytesLeft % (MAX_VARIABLE_LENGTH + 1); writeByte = fixedPacketLength; cc112xSpiWriteReg(CC112X_PKT_LEN, &writeByte, 1); // Clear interrupt flag and enable GPIO3 ioPinIntClear(IO_PIN_PORT_1, GPIO3); ioPinIntEnable(IO_PIN_PORT_1, GPIO3); } else { // Exit RX and flush RX FIFO due to length byte being out of range trxSpiCmdStrobe(CC112X_SIDLE); trxSpiCmdStrobe(CC112X_SFRX); state = RX_START; } // Clear ISR flag ioPinIntClear(IO_PIN_PORT_1, GPIO2); }
static void setDirection(uint8 dir){ uint8 writeByte; //dir = 1 => RX //dir = 0 => TX if (dir) { // Application specific registers // FIFO_THR = 120 // GPIO0 = RXFIFO_THR // GPIO2 = PKT_SYNC_RXTX // GPIO3 = PKT_SYNC_RXTX writeByte = INFINITE_PACKET_LENGTH_MODE; cc112xSpiWriteReg(CC112X_PKT_CFG0, &writeByte, 1); writeByte = 0x78; cc112xSpiWriteReg(CC112X_FIFO_CFG, &writeByte, 1); writeByte = 0x00; cc112xSpiWriteReg(CC112X_IOCFG0, &writeByte, 1); writeByte = 0x06; cc112xSpiWriteReg(CC112X_IOCFG2, &writeByte, 1); writeByte = 0x06; cc112xSpiWriteReg(CC112X_IOCFG3, &writeByte, 1); // Connect ISR function to GPIO0 ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &rxFifoAboveThresholdISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_RISING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO0); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO0); // Connect ISR function to GPIO2 ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &syncReceivedISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_RISING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO2); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO2); // Set up interrupt on GPIO3 (PKT_SYNC_RXTX) ioPinIntRegister(IO_PIN_PORT_1, GPIO3, &packetReceivedISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO3, IO_PIN_FALLING_EDGE); } else { // Application specific registers // FIFO_THR = 120 // GPIO0 = TXFIFO_THR // GPIO2 = PKT_SYNC_RXTX writeByte = INFINITE_PACKET_LENGTH_MODE; cc112xSpiWriteReg(CC112X_PKT_CFG0, &writeByte, 1); writeByte = 0x78; cc112xSpiWriteReg(CC112X_FIFO_CFG, &writeByte, 1); writeByte = 0x02; cc112xSpiWriteReg(CC112X_IOCFG0, &writeByte, 1); writeByte = 0x06; cc112xSpiWriteReg(CC112X_IOCFG2, &writeByte, 1); // Connect ISR function to GPIO0 ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &txFifoBelowThresholdISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_FALLING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO0); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO0); // Connect ISR function to GPIO2 ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &packetSentISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO2); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO2); } }
/******************************************************************************* * @fn runRX * * @brief Puts radio in RX and waits for packets. Function assumes * that status bytes are appended in the RX_FIFO * Update packet counter and display for each packet received. * * @param none * * @return none */ static void runRX(void) { uint8 rxBuffer[128] = {0}; uint8 rxBytes; uint8 marcState; // Connect ISR function to GPIO2 ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &radioRxISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_FALLING_EDGE); // Clear ISR flag ioPinIntClear(IO_PIN_PORT_1, GPIO2); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO2); // Update LCD updateLcd(); // Set radio in RX trxSpiCmdStrobe(CC120X_SRX); // Infinite loop while(TRUE) { // Wait for packet received interrupt if(packetSemaphore == ISR_ACTION_REQUIRED) { // Read number of bytes in RX FIFO cc120xSpiReadReg(CC120X_NUM_RXBYTES, &rxBytes, 1); // Check that we have bytes in FIFO if(rxBytes != 0) { // Read MARCSTATE to check for RX FIFO error cc120xSpiReadReg(CC120X_MARCSTATE, &marcState, 1); // Mask out MARCSTATE bits and check if we have a RX FIFO error if((marcState & 0x1F) == RX_FIFO_ERROR) { // Flush RX FIFO trxSpiCmdStrobe(CC120X_SFRX); } else { // Read n bytes from RX FIFO cc120xSpiReadRxFifo(rxBuffer, rxBytes); // Check CRC ok (CRC_OK: bit7 in second status byte) // This assumes status bytes are appended in RX_FIFO // (PKT_CFG1.APPEND_STATUS = 1) // If CRC is disabled the CRC_OK field will read 1 if(rxBuffer[rxBytes - 1] & 0x80) { // Update packet counter packetCounter++; } } } // Update LCD updateLcd(); // Reset packet semaphore packetSemaphore = ISR_IDLE; // Set radio back in RX trxSpiCmdStrobe(CC120X_SRX); } } }
/******************************************************************************* * @fn main * * @brief Runs the main routine * * @param none * * @return none */ void main(void) { uint8 writeByte; // Initialize MCU and peripherals initMCU(); // Write radio registers (preferred settings from SmartRF Studio) registerConfig(); // Application specific registers // FIFO_THR = 120 // GPIO0 = RXFIFO_THR // GPIO2 = PKT_SYNC_RXTX // GPIO3 = PKT_SYNC_RXTX writeByte = INFINITE_PACKET_LENGTH_MODE; cc112xSpiWriteReg(CC112X_PKT_CFG0, &writeByte, 1); writeByte = 0x78; cc112xSpiWriteReg(CC112X_FIFO_CFG, &writeByte, 1); writeByte = 0x00; cc112xSpiWriteReg(CC112X_IOCFG0, &writeByte, 1); writeByte = 0x06; cc112xSpiWriteReg(CC112X_IOCFG2, &writeByte, 1); writeByte = 0x06; cc112xSpiWriteReg(CC112X_IOCFG3, &writeByte, 1); bspLedSet(BSP_LED_ALL); // Calibrate the radio according to the errata note manualCalibration(); // Connect ISR function to GPIO0 ioPinIntRegister(IO_PIN_PORT_1, GPIO0, &rxFifoAboveThresholdISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO0, IO_PIN_RISING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO0); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO0); // Connect ISR function to GPIO2 ioPinIntRegister(IO_PIN_PORT_1, GPIO2, &syncReceivedISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO2, IO_PIN_RISING_EDGE); // Clear interrupt ioPinIntClear(IO_PIN_PORT_1, GPIO2); // Enable interrupt ioPinIntEnable(IO_PIN_PORT_1, GPIO2); // Set up interrupt on GPIO3 (PKT_SYNC_RXTX) ioPinIntRegister(IO_PIN_PORT_1, GPIO3, &packetReceivedISR); // Interrupt on falling edge ioPinIntTypeSet(IO_PIN_PORT_1, GPIO3, IO_PIN_FALLING_EDGE); printWelcomeMessage(); while (TRUE) { switch (state) { //------------------------------------------------------------------ case RX_START: //------------------------------------------------------------------ trxSpiCmdStrobe(CC112X_SRX); pBufferIndex = rxBuffer; // Disable interrupt on GPIO3 ioPinIntDisable(IO_PIN_PORT_1, GPIO3); state = RX_WAIT; //------------------------------------------------------------------ case RX_WAIT: //------------------------------------------------------------------ if (packetReceived) { packetReceived = FALSE; // Check CRC and update LCD if CRC OK if ((rxBuffer[packetLength + 3]) & CRC_OK) updateLcd(); // Change to infinite packet length mode pktFormat = INFINITE; writeByte = INFINITE_PACKET_LENGTH_MODE; cc112xSpiWriteReg(CC112X_PKT_CFG0, &writeByte, 1); state = RX_START; } break; //------------------------------------------------------------------ default: //------------------------------------------------------------------ break; } } }