ADuCM350 FAQ SDK Driver Specific FAQs

Document created by emoloney on Feb 11, 2015
Version 1Show Document
  • View in full screen mode

AFE Driver

 

Q: The v2.2.0 SDK AFE driver (afe.c) has interrupt handlers for the Command FIFO interrupt (AFE_CmdFIFO_Int_Handler) and the Data FIFO interrupt (AFE_DataFIFO_Int_Handler), but not for the Generate or Capture interrupts. Are there handlers available for the Generate and Capture interrupts?

 

A: The v2.3.X SDK is currently under development (at time of print, 11 Feb 2015). The AFE driver in this new revision of the SDK will handle Generate and Capture interrupts and will introduce a new function which can register a callback for any of the 4 AFE interrupts. Preliminary code for the Generate and Capture interrupts and the register callback function are below for reference ahead of the v2.3.X SDK release.

 

/* ANALOG_CAPTURE_INT handler */

ADI_INT_HANDLER(AFE_Capture_Int_Handler) {

    /* Only 1 instance of the AFE in the system */

    ADI_AFE_DEV_HANDLE  hDevice = pAFE_DevData;

    uint32_t            sources;

    uint32_t            enables;

    uint32_t            clear = 0;

    uint32_t            disable = 0;

 

 

    sources = hDevice->pAFE->AFE_ANALOG_CAPTURE_INT;

    enables = hDevice->pAFE->AFE_ANALOG_CAPTURE_IEN;

 

 

    /* Interrupt bit: ADC_RESULT_READY */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_ADC_RESULT_READY) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_RESULT_READY_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_CAPTURE_INT_ADC_RESULT_READY;

    }

 

 

    /* Interrupt bit: DFT_RESULT_READY */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_DFT_RESULT_READY) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_DFT_RESULT_READY_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_CAPTURE_INT_DFT_RESULT_READY;

    }

 

 

    /* Interrupt bit: SUPPLY_LPF_RESULT_READY */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_SUPPLY_LPF_RESULT_READY) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_SUPPLY_LPF_RESULT_READY_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_CAPTURE_INT_SUPPLY_LPF_RESULT_READY;

    }

 

 

    /* Interrupt bit: TEMP_RESULT_READY */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_TEMP_RESULT_READY) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_TEMP_RESULT_READY_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_CAPTURE_INT_TEMP_RESULT_READY;

    }

 

 

    /* Interrupt bit: ADC_MIN_FAIL */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_ADC_MIN_FAIL) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_MIN_FAIL_IEN)) {

        /* Since this is typically an error condition, we don't care if there is one */

        /* or multiple interrupts, so schedule interrupt to be disabled. */

        disable |= BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_MIN_FAIL_IEN;

    }

 

 

    /* Interrupt bit: ADC_MAX_FAIL */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_ADC_MAX_FAIL) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_MAX_FAIL_IEN)) {

        /* Since this is typically an error condition, we don't care if there is one */

        /* or multiple interrupts, so schedule interrupt to be disabled. */

        disable |= BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_MAX_FAIL_IEN;

    }

 

 

    /* Interrupt bit: ADC_DELTA_FAIL */

    if ((sources & BITM_AFE_AFE_ANALOG_CAPTURE_INT_ADC_DELTA_FAIL) &&

        (enables & BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_DELTA_FAIL_IEN)) {

        /* Since this is typically an error condition, we don't care if there is one */

        /* or multiple interrupts, so schedule interrupt to be disabled. */

        disable |= BITM_AFE_AFE_ANALOG_CAPTURE_IEN_ADC_DELTA_FAIL_IEN;

    }

 

 

    /* Check if there is a callback defined */

    if (hDevice->cbCaptureFcn) {

        /* Call the function if the interrupt is watched         */

        /* Need to check both interrupts scheduled to be cleared */

        /* and interrupts scheduled to be disabled to find out   */

        /* what interrupt caused this ISR to be entered          */

        if ((clear | disable) & hDevice->cbCaptureWatch) {

            /* Passing to the callback the bits scheduled for clear or disable */

            hDevice->cbCaptureFcn(hDevice, 0, NULL);

        }

    }

 

 

    adi_AFE_EnableInterruptSource(hDevice, ADI_AFE_INT_GROUP_CAPTURE, disable, false);

    adi_AFE_ClearInterruptSource(hDevice, ADI_AFE_INT_GROUP_CAPTURE, clear);

 

 

}

 

 

/* ANALOG_GEN_INT handler */

ADI_INT_HANDLER(AFE_Generate_Int_Handler) {

    /* Only 1 instance of the AFE in the system */

    ADI_AFE_DEV_HANDLE  hDevice = pAFE_DevData;

    uint32_t            sources;

    uint32_t            enables;

    uint32_t            clear = 0;

 

 

    sources = hDevice->pAFE->AFE_ANALOG_GEN_INT;

    enables = hDevice->pAFE->AFE_ANALOG_GEN_IEN;

 

 

    /* Interrupt bit: DELAY_COMMAND_DONE */

    if ((sources & BITM_AFE_AFE_ANALOG_GEN_INT_DELAY_COMMAND_DONE) &&

        (enables & BITM_AFE_AFE_ANALOG_GEN_IEN_DELAY_COMMAND_DONE_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_GEN_INT_DELAY_COMMAND_DONE;

    }

 

 

    /* Interrupt bit: HARDWARE_SETUP_DONE */

    if ((sources & BITM_AFE_AFE_ANALOG_GEN_INT_HARDWARE_SETUP_DONE) &&

        (enables & BITM_AFE_AFE_ANALOG_GEN_IEN_HARDWARE_SETUP_DONE_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_GEN_INT_HARDWARE_SETUP_DONE;

    }

 

 

    /* Interrupt bit: BREAK_SEQUENCE_ORG */

    if ((sources & BITM_AFE_AFE_ANALOG_GEN_INT_BREAK_SEQUENCE_ORG) &&

        (enables & BITM_AFE_AFE_ANALOG_GEN_IEN_BREAK_SEQUENCE_ORG_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_GEN_INT_BREAK_SEQUENCE_ORG;

    }

 

 

    /* Interrupt bit: CUSTOM_INT */

    if ((sources & BITM_AFE_AFE_ANALOG_GEN_INT_CUSTOM_INT) &&

        (enables & BITM_AFE_AFE_ANALOG_GEN_IEN_CUSTOM_INT_IEN)) {

        /* Schedule interrupt to be cleared */

        clear |= BITM_AFE_AFE_ANALOG_GEN_INT_CUSTOM_INT;

    }

 

 

    /* Check if there is a callback defined */

    if (hDevice->cbGenerateFcn) {

        /* Call the function if the interrupt is watched         */

        /* Need to check both interrupts scheduled to be cleared */

        /* and interrupts scheduled to be disabled to find out   */

        /* what interrupt caused this ISR to be entered          */

        if (clear & hDevice->cbGenerateWatch) {

            /* Passing to the callback the bits scheduled for clear or disable */

            hDevice->cbGenerateFcn(hDevice, 0, NULL);

        }

    }

 

 

    adi_AFE_ClearInterruptSource(hDevice, ADI_AFE_INT_GROUP_GENERATE, clear);

}

 

 

/*!

* @brief       Application callback registration for AFE interrupt handlers.

*

* @param[in]   hDevice                                 Device handle obtained from adi_AFE_Init().

* @param[in]   group                                   AFE interrupt group type identifier.

* @param[in]   cbFunc                                  Application callback address; the function to call.

* @param[in]   cbWatch                                 The interrupts to watch, controlling which interrupts result in a callback.

*

* @return      Status

*              - #ADI_AFE_SUCCESS                      Call completed successfully.

*              - #ADI_AFE_ERR_BAD_DEV_HANDLE           Invalid device handle.

*              - #ADI_AFE_ERR_NOT_INITIALIZED          Device not initialized.

*              - #ADI_AFE_ERR_ACLKOFF                  ACLK disabled from the clock gate.

*              - #ADI_AFE_ERR_WRONG_ACLK_FREQUENCY     Programmed ACLK frequency is not the required 16MHz.

*              - #ADI_AFE_ERR_CALLBACK_OVERWRITE       Attempt to overwrite existing callback.

*

* @details     Registers an application-defined callback function with one of the AFE interrupt handlers.

*              Callbacks are made in response to received AFE interrupts, depending on whether they are enabled

*              and whether the corresponding callback watch bits are set.  This allows the application to control which

*              interrupts it wants to be called back on.

 

 

*              The callback to the application is made in context of the originating interrupt (i.e. the AFE

*              interrupt handler that is registered in the system's interrupt vector table).  Extended processing

*              during the callback (an extension of the AFE interrupt handler) is discouraged so as to avoid lower-priority

*              interrupt blocking.  Also, any register read-modify-write operations should be protected using the

*              ADI_ENTER_CRITICAL_REGION()/ADI_EXIT_CRITICAL_REGION() pair to prevent higher-priority interrupts from modifying

*              said register during the read-modify-write operation.

*

*   @note      CALLBACKS: AFE interrupt callbacks are \a disabled by default during the API initialization (#adi_AFE_Init()).

*              The application may use the #adi_AFE_RegisterCallback() API to register an application-defined

*              callback function with the interrupt handler that will be called in response to selected AFE interrupts.

*              The callback registration API takes an interrupt mask (of type uint32_t) that designates the set of interrupts

*              to watch (upon which to dispatch the callback).  When any of the watched interrupts occur, the appropriate AFE

*              interrupt handler will make the callback to the application for application-based interrupt handling. The application

*              callback should \a avoid \a extended \a processing during the callback as the callback is made context of the initiating

*              interrupt and will block lower-priority interrupts.  If extended application-level interrupt processing is required, the

*              application should schedule it for the main application loop and exit the callback as soon as possible.\n\n

*

*/

ADI_AFE_RESULT_TYPE adi_AFE_RegisterAfeCallback(ADI_AFE_DEV_HANDLE hDevice, ADI_AFE_INT_GROUP_TYPE group, ADI_CALLBACK cbFunc, uint32_t cbWatch) {

    ADI_AFE_RESULT_TYPE result = ADI_AFE_SUCCESS;

 

 

#ifdef ADI_DEBUG

    if (adi_AFE_InvalidHandle(hDevice)) {

        return ADI_AFE_ERR_BAD_DEV_HANDLE;

    }

 

 

    if (adi_AFE_HandleNotInitialized(hDevice)) {

        return ADI_AFE_ERR_NOT_INITIALIZED;

    }

 

 

    if (pADI_SYSCLK->CLKCON5 & BITM_SYSCLK_CLKCON5_ACLKOFF) {

        return ADI_AFE_ERR_ACLKOFF;

    }

 

 

    if (16000000 != SystemGetClockFrequency(ADI_SYS_CLOCK_ACLK)) {

        return ADI_AFE_ERR_WRONG_ACLK_FREQUENCY;

    }

   

    if (!((ADI_AFE_INT_GROUP_CAPTURE == group) || (ADI_AFE_INT_GROUP_GENERATE == group) || (ADI_AFE_INT_GROUP_CMD_FIFO == group) || (ADI_AFE_INT_GROUP_DATA_FIFO == group))) {

        return ADI_AFE_ERR_INVALID_IRQ;

    }

 

 

    if ((cbFunc && hDevice->cbCaptureFcn) || (cbFunc && hDevice->cbGenerateFcn) || (cbFunc && hDevice->cbCmdFifoFcn) || (cbFunc && hDevice->cbDataFifoFcn)) {

        return ADI_AFE_ERR_CALLBACK_OVERWRITE;

    }

#endif

 

 

    switch (group)

    {

        case ADI_AFE_INT_GROUP_CAPTURE:

            hDevice->cbCaptureFcn       = cbFunc;

            hDevice->cbCaptureWatch     = cbWatch;

            break;

 

 

        case ADI_AFE_INT_GROUP_GENERATE:

            hDevice->cbGenerateFcn      = cbFunc;

            hDevice->cbGenerateWatch    = cbWatch;

            break;

 

 

        case ADI_AFE_INT_GROUP_CMD_FIFO:

            hDevice->cbCmdFifoFcn       = cbFunc;

            hDevice->cbCmdFifoWatch     = cbWatch;

            break;

 

 

        case ADI_AFE_INT_GROUP_DATA_FIFO:

            hDevice->cbDataFifoFcn      = cbFunc;

            hDevice->cbDataFifoWatch    = cbWatch;

            break;

    }

   

    return result;

}

Attachments

    Outcomes