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.

cc2530 acknowledgement

Hi,

I dont know how to process acknowledgement. I have following program, I send "1" to "SWITCH_ADDR", but how can I know, that data was successfully recieved? The other device (SWITCH_ADDR) send acknowledgement, but I dont know how to process it. What is command for this? When I dont recieve acknowledgement I want to resend packet. Thank you for help.

// Config basicRF
basicRfConfig.panId = PAN_ID;
basicRfConfig.channel = RF_CHANNEL;
basicRfConfig.ackRequest = TRUE;

// Initalise board peripherals
halBoardInit();
halJoystickInit();

// Initalise hal_rf
if(halRfInit()==FAILED) {
HAL_ASSERT(FALSE);
}

basicRfConfig.myAddr = OVLADAC_ADDR;
if(basicRfInit(&basicRfConfig)==FAILED) {
HAL_ASSERT(FALSE);
}

// Keep Receiver off when not needed to save power
basicRfReceiveOn();

// Main loop
while (TRUE) {


pTxData[0]=1;
basicRfSendPacket(SWITCH_ADDR, pTxData, APP_PAYLOAD_LENGTH);
pTxData[0]=LIGHT_TOGGLE_CMD;

here I need process acknowledgement//

// Put MCU to sleep. It will wake up on joystick interrupt
halIntOff();
halMcuSetLowPowerMode(HAL_MCU_LPM_3); // Will turn on global
// interrupt enable
halIntOn();

  • Hi,

    Since you have defined basicRfCondfig.ackRequest = TRUE; you just need to check the return value of basicRfSendPacket() function, see the function code as follows:

    uint8 basicRfSendPacket(uint16 destAddr, uint8* pPayload, uint8 length)
    {
        uint8 mpduLength;
        uint8 status;
        // Turn on receiver if its not on
        if(!txState.receiveOn) {
            halRfReceiveOn();
        }
        // Check packet length
        length = min(length, BASIC_RF_MAX_PAYLOAD_SIZE);
        // Wait until the transceiver is idle
        halRfWaitTransceiverReady();
        // Turn off RX frame done interrupt to avoid interference on the SPI interface
        halRfDisableRxInterrupt();
        mpduLength = basicRfBuildMpdu(destAddr, pPayload, length);
        #ifdef SECURITY_CCM
        halRfWriteTxBufSecure(txMpdu, mpduLength, length, BASIC_RF_LEN_AUTH, BASIC_RF_SECURITY_M);
        txState.frameCounter++;     // Increment frame counter field
        #else
        halRfWriteTxBuf(txMpdu, mpduLength);
        #endif
        // Turn on RX frame done interrupt for ACK reception
        halRfEnableRxInterrupt();
        // Send frame with CCA. return FAILED if not successful
        if(halRfTransmit() != SUCCESS) {
            status = FAILED;
        }
        // Wait for the acknowledge to be received, if any
        if (pConfig->ackRequest) {
            txState.ackReceived = FALSE;
            // We'll enter RX automatically, so just wait until we can be sure that the ack reception should have finished
            // The timeout consists of a 12-symbol turnaround time, the ack packet duration, and a small margin
            halMcuWaitUs((12 * BASIC_RF_SYMBOL_DURATION) + (BASIC_RF_ACK_DURATION) + (2 * BASIC_RF_SYMBOL_DURATION) + 10);
            // If an acknowledgment has been received (by RxFrmDoneIsr), the ackReceived flag should be set
            status = txState.ackReceived ? SUCCESS : FAILED;
        } else {
            status = SUCCESS;
        }
        // Turn off the receiver if it should not continue to be enabled
        if (!txState.receiveOn) {
            halRfReceiveOff();
        }
        if(status == SUCCESS) {
            txState.txSeqNumber++;
        }
    #ifdef SECURITY_CCM
        halRfIncNonceTx();          // Increment nonce value
    #endif
        return status;
    }

    The code above shows that when the message is ACK-ed, you will get SUCCESS return value, otherwise FAILED.

  • Is there anything you need to do on the receiver side? I am trying to use the return value from basicRFSendPacket to determine if there was an acknowledgement, but it is always FAILED. I know the other node is receiving the message however because it sends back data, just not an acknowledgement.

    For clarity, here are some code snippets:

    Sender:

    sendIntializationPacket(){

    uint8 status = basicRFSendPacket(CAP_ADDR, START_SYMBOL, 1);

    if(status == SUCCESS){

    LED1 = 1;

    }else{

    LED1 = 0;

    }

    The RXPKTDONE isr on the receiver

    #pragma vector = URX0_VECTOR
    __interrupt void rx_isr(void){
      uint8 symbol = U0DBUF; 
      if(symbol == START_SYMBOL){
          startSensors();
      }else if(symbol == SYNC_SYMBOL){
          synchronizeClocks();
      }
      URX0IF = 0;  // Clear RX interrupt flag.
    }

    LED1 never turns on, and when I use the debugger, the status is always FAILED, however, I know that the message was received because startSensors() is being called. All I am doing for the acknowledgement is setting basicRfConfig.ackRequest = TRUE; on both the sender and receiver. Is there something else that needs to be set? Thank you for any help.

    Katie

  • Katie,

    have you tried to use SmartRF Packet Sniffer to see whether the receiver node really sends out the ACK packet? Have you also made sure that the FRMCTRL0.AUTOACK on the receiver side is set?

  • When I use the packet sniffer, it gets an ACK packet, but only about 5% of the time. Even when an ACK packet is sent, I believe the return status of basicRFSendPacket() is always FAILED because the LED never toggles on.

    FRMCTRL0 is set using FRMCTRL0 = 0X60; so AUTOACK, AUTOCRC are set and RX and TX are in normal operation.

  • Leo,

    Thank you for your help. I figured it out, I was calling the sendInitializationPacket() inside an ISR, so it was waiting for an interrupt inside of this ISR. The received ack interrupt flag was never being set because it was a lower priority. I appreciate your help with my debugging.