AnsweredAssumed Answered

BF 506F adc setup

Question asked by usman384 on Dec 20, 2011
Hi I am doing speed control of the induction motor using the Black fin 506f ez kit lite so for the software development of this processer. i was first sorting out the adc setup as I will be using the potentiometer to vary the speed of the induction motor. So I studied to the examples provided on the visual dsp 10 for the bf 506f adc . as there are two ways to control the adc one is by using acm and the other one is by using the GPIO pins. as there was an example provided for the adc acm control so I continued with that, but when i was analysing the sample code i have difficulty understanding it . so i request you to please help me to sort this out. As given below here is the adc-acm control code.
I have written my comments for the parts of the code which i do not understand. I also have highlighted my comments so that they are easily visual.
/* Handle to the ADC Device */
static ADI_DEV_DEVICE_HANDLE    hAdcDevice; /*why the handle command is used here*/
/* DCB Managed Data */
static u8 anDcbMgrData[ADI_DCB_QUEUE_SIZE + (ADI_DCB_ENTRY_SIZE)*4]; /*what is the function of the command*/
/*what does this command actually mean */
/* DCB Manager Handle */
static ADI_DCB_HANDLE   hDcbManager;
/*why the DCB manager handle has been used here*/
/* Instance to configure ACM Timer */
/*What is this is it a structure?  Where these parameters inside the brackets are going to be stored* /
static ADI_ACM_TMR_CONFIG oAcmTmrConfig =
{
    /* Use Timer 0 */
    0,
    /* Enable Timer */
    true,
    /* Trigger Select (GP Timer 7) */
    3,
    /* Trigger on Raising edge */
    0
};
/*why do we need this event parameter configuration array */
/* ACM Event Parameter configuration array */
static ADI_ACM_EVENT_PARAMS   aoAcmEventParams [ADC_TEST_NUM_ACM_EVENTS];
what does the event configuration table mean?
/* Instance to pass Event Configuration Table */
static ADI_ACM_EVENT_PARAMS_TABLE oEventParamTable =
{
    /* Number of entries */
    ADC_TEST_NUM_ACM_EVENTS,/*why he first wrote ADC test num acm events and then the address of the first element of the array is given*/
    /* First entry in the event-param array */
    &aoAcmEventParams[0]
};
/* ADC Configuration table */
/*how this adc configuration table will configure.  */
static  ADI_DEV_CMD_VALUE_PAIR  aoAdcConfig[] =/*what exactly is is and how the parameters given below will be stored in the structure*/
{
    /* Set ACM Device Number to control ADC */
    { ADI_BF506ADC1_CMD_SET_ACM_DEV_NUMBER,         (void *) ADC_TEST_ACM_DEV_NUM       },
    /* Set SPORT Device number connected to ADC */
    { ADI_BF506ADC1_CMD_SET_SPORT_DEV_NUMBER,       (void *) ADC_TEST_SPORT_DEV_NUM     },
    /* Open ADC Control Device */
    { ADI_BF506ADC1_CMD_OPEN_ADC_CTRL_DEV,          (void *) true                       },
    /* Open SPORT */
    { ADI_BF506ADC1_CMD_OPEN_SPORT_DEV,             (void *) true                       },
    /* Set SPORT Pin Mux Settings - use SPORT DR1SEC on PG8 */
    { ADI_SPORT_CMD_SET_PIN_MUX_MODE,               (void *) ADI_SPORT_PIN_MUX_MODE_1   },
    /* Set Dataflow method for SPORT */
    { ADI_DEV_CMD_SET_DATAFLOW_METHOD,              (void *) ADI_DEV_MODE_CHAINED       },
    /* Set ADC sampling rate / ACLK frequency */
    { ADI_BF506ADC1_CMD_SET_SAMPLE_RATE_ACLK_FREQ,  (void *) ADC_TEST_ACLK_FREQ         },
    /* Set Data Mode */
    { ADI_BF506ADC1_CMD_SET_SERIAL_DATA_MODE,       (void *) ACM_TEST_SERIAL_DATA_MODE  },
    /* Configure ACM Timer */
    { ADI_ACM_CMD_CONFIG_TMR,                       (void *) &oAcmTmrConfig             },
    /* Configure ACM Event parameters */
    { ADI_ACM_CMD_SET_EVENT_PARAMS_TABLE,           (void *) &oEventParamTable          },
    /* End of command table */
    ADI_DEV_CMD_END
};
/* ACM Trigger Timer (GP Timer) configuration table */
/*what is this exactly and where the parameters will be stored and why the void * has been used here*/
Static ADI_TMR_GP_CMD_VALUE_PAIR aoAcmTgrTmrConfig [] =
{
    { ADI_TMR_GP_CMD_SET_PERIOD,            (void *) ADC_TEST_ACM_TGR_TMR_PERIOD},
    { ADI_TMR_GP_CMD_SET_WIDTH,             (void *) ADC_TEST_ACM_TGR_TMR_WIDTH },
    { ADI_TMR_GP_CMD_SET_TIMER_MODE,        (void *) 1                          },
    { ADI_TMR_GP_CMD_SET_COUNT_METHOD,      (void *) 1                          },
    { ADI_TMR_GP_CMD_SET_PULSE_HI,          (void *) false                      },
    { ADI_TMR_GP_CMD_SET_INTERRUPT_ENABLE,  (void *) 1                          },
    { ADI_TMR_GP_CMD_SET_OUTPUT_PAD_DISABLE,(void *) false                      },
    ADI_TMR_GP_CMD_END
};
/* Array to hold ADC Samples */
/*why the array has been declared to stored 50 samples */
static s16  nAdcSamples[50];
/* 1D Buffer to receive ADC samples */
/*how this buffer will receive adc samples*/
static ADI_DEV_1D_BUFFER    oAdcBuffer;
/* Flag to indicate if ADC is enabled or not */
static bool     bIsAdcEnabled = false/*why blsAdcEnabled=false*/;
/* Flag to indicate if all ADC samples are received or not */
static  bool    bSamplesReceived = false/*why bsamplesreceived=false*/;
/*
** Local Function prototypes (why these local function prototypes are declared here)
*/
/* Acm Device callback */
static void AcmCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
);
/* ADC Device callback */
static void AdcCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
);
/* GP Timer (ACM Trigger Timer) callback */
static void TimerCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
);
static void AdcCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
/*why three arguments has been passed in this function as we are only one of them is required for the switch statements using in the switch statements */
)
{
    /* Callback is valid only when ADC dataflow is enabled */
    if (bIsAdcEnabled == true) /*where the blsAdcEnabled has been declared */
    {
        /* CASEOF (Event) */
        switch (nEvent)
        {
            /* CASE (Buffer processed event) */
            case ADI_DEV_EVENT_BUFFER_PROCESSED: /*how this buffer will receive the samples*/
                bSamplesReceived = true;
                break;
            /* default */
            default:
                break;
        }
    }
}
  Function: AcmCallback
        Callback from ACM Device.
        Each type of callback event has it's own unique ID
        so we can use a single callback function for all
        callback events.  The switch statement tells us
        which event has occurred.
*****************************************************************************/
static void AcmCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
)
{
    /* CASEOF (Event) */
    switch (nEvent)
    {
        /* CASE (Event Complete) */
        case ADI_ACM_EVENT_EVENT_COMPLETE:
            break;
        /* CASE (Event Missed) */
        case ADI_ACM_EVENT_EVENT_MISS:
            break;
        /* default */
        default:
            break;
    }
}
static void TimerCallback(
    void    *pAppHandle,
    u32     nEvent,
    void    *pArg
)
{
    /* Disble timer */
    adi_tmr_GPControl (ADC_TEST_ACM_TGR_GP_TIMER,
                       ADI_TMR_GP_CMD_ENABLE_TIMER,
                       (void *) false);
}
How does the call back for the gp timer works?
In the main function there is comment *populate ACM event parameter array * then there is a loop which runs until ADC_TEST_NUM_ACM_EVENTS. Then there is a structure in the loop. How does that structure works. Where this structure has been declared. Then there is a do while loop which has all these statements given below.
do
    {

/*What kind of the sytem services it will initialize*/
        /* Initialise System Services */
        if ((nResult = adi_ssl_Init ()) != 0)
        {
            break;
        }

        /* Hook the Exception interrupt*/
        if((nResult = adi_int_CECHook (3,
                                       ExceptionHandler,
                                       NULL,
                                       false))
                                    != ADI_INT_RESULT_SUCCESS)
        {
            break;
        }

        /* Hook the Hardware error interrupt */
        if((nResult = adi_int_CECHook (5,
                                       HWErrorHandler,
                                       NULL,
                                       false))
                                    != ADI_INT_RESULT_SUCCESS)
        {
            break;
        }

/* IF (DCB selected, open the DCB manager & setup a queue) */
#if defined(USE_DEFERRED_CALLBACKS)

        /* Open the DCB manager & setup a queue */
        if((Result = adi_dcb_Open(14, &anDcbMgrData[ADI_DCB_QUEUE_SIZE],
                                  (ADI_DCB_ENTRY_SIZE)*4, &ResponseCount, &hDcbManager))!=0) /*what this function call is for i cannot understand the parameters inside this function call*/
        {
            break;
        }

/* ELSE (Callbacks are live) */
#else

        hDcbManager = NULL;

#endif

        /* Open GP Timer connected to ACM Trigger */
        if((nResult = (u32)(adi_tmr_Open(ADC_TEST_ACM_TGR_GP_TIMER))) != 0)
        {
            break;
        }

        /* Install callback for GP Timer connected to ACM Trigger */
        if((nResult = (u32)(adi_tmr_InstallCallback(ADC_TEST_ACM_TGR_GP_TIMER,
                                                    0,
                                                    0,
                                                    hDcbManager,
                                                    TimerCallback))) != 0) /*i cannot understand the arguments inside this function call and how this function call works and where the prototype of this function is given */
        {
            break;
        }

        /* Configure GP Timer connected to ACM Trigger */
        if((nResult = (u32)(adi_tmr_GPControl(ADC_TEST_ACM_TGR_GP_TIMER,
                                              ADI_TMR_GP_CMD_TABLE,
                                              &aoAcmTgrTmrConfig))) != 0)    /*i cannot understand the arguments inside this function call and how this function call works and where the prototype of this function is given */
        {
            break;
        }

        /* Open BF506F ADC Device */ 
        if((nResult = adi_dev_Open(adi_dev_ManagerHandle,
                                   &ADI_BF506ADC1_EntryPoint,
                                   0,
                                   NULL,
                                   &hAdcDevice,
                                   ADI_DEV_DIRECTION_INBOUND,
                                   adi_dma_ManagerHandle,
                                   hDcbManager,
                                   AdcCallback))
                                != ADI_DEV_RESULT_SUCCESS)  
        {
            break;
        }

        /* Configure ADC driver and ACM/SPORT Device registers */
        if ((nResult = (adi_dev_Control (hAdcDevice,
                                         ADI_DEV_CMD_TABLE,
                                         (void *) &aoAdcConfig[0]))) != ADI_DEV_RESULT_SUCCESS) /*i cannot understand the arguments for this function call */
        {
            break;
        }

most of these functions below i cannot understand there arguments and what these functions will return.

        /*
        ** Submit a dummy data buffer so that we could power-up the ADC
        ** Without a buffer, SPORT will get into an infinite loop since
        ** DMA manager doesn't find a valid buffer to store data from sport.
        ** Ignore the callback for this buffer
        **   - Program uses a flag to check if ADC dataflow is enabled
        **     when it tries to process a callback event
        */
        if((nResult = adi_dev_Read (hAdcDevice,
                                    ADI_DEV_1D,
                                    (ADI_DEV_BUFFER *)&oAdcBuffer))
                                 != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Set ADC in Normal Mode */
        if ((nResult = adi_dev_Control (hAdcDevice,
                                        ADI_BF506ADC1_CMD_SET_OPERATING_MODE,
                                        (void *) ADI_BF506ADC1_MODE_NORMAL))
                                     != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Configure ACM for interrupt mode */
        if ((nResult = adi_dev_Control (hAdcDevice,
                                        ADI_ACM_CMD_SET_CALLBACK_FN,
                                        (void *) AcmCallback))
                                     != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Enable event complete interrupt for the last-but-one event */
        if ((nResult = adi_dev_Control (hAdcDevice,
                                        ADI_ACM_CMD_ENABLE_EVENT_COMPLETE_INT,
                                        (void *) (ADC_TEST_NUM_ACM_EVENTS - 2)))
                                     != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Enable event miss Interrupt for all events */
        for (i = 0;
             i < ADC_TEST_NUM_ACM_EVENTS;
            i++)
        {
            /* Enable event miss interrupt */
            if ((nResult = adi_acm_Control (hAdcDevice,
                                            ADI_ACM_CMD_ENABLE_EVENT_MISS_INT,
                                            (void *) i))
                                         != ADI_DEV_RESULT_SUCCESS)
            {
                break;
            }
        }

        /* Configure 1D buffer to receive ADC samples */
        oAdcBuffer.Data                 = (void *) nAdcSamples;
        oAdcBuffer.ElementCount         = ADC_TEST_NUM_SAMPLES;
        oAdcBuffer.ElementWidth         = ADC_TEST_SPORT_DMA_BUS_WIDTH;
        oAdcBuffer.CallbackParameter    = (void *) &oAdcBuffer;
        oAdcBuffer.pNext                = NULL;

        /* Submit data buffer(s) to ADC */
        if((nResult = adi_dev_Read (hAdcDevice,
                                    ADI_DEV_1D,
                                    (ADI_DEV_BUFFER *)&oAdcBuffer))
                                 != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Enable GP Timer to generate ACM Trigger */
        if ((nResult = (u32)(adi_tmr_GPControl (ADC_TEST_ACM_TGR_GP_TIMER,
                                                ADI_TMR_GP_CMD_ENABLE_TIMER,
                                                (void *) true))) != 0)
        {
            break;
        }

        /* Enable ADC dataflow */
        if ((nResult = adi_dev_Control (hAdcDevice,
                                        ADI_DEV_CMD_SET_DATAFLOW,
                                        (void *) true))
                                     != ADI_DEV_RESULT_SUCCESS)
        {
            break;
        }

        /* Update flag as ADC enabled */
        bIsAdcEnabled = true;

    } while (0);

    if (nResult == 0)
    {
        /* Wait until all samples are received */
        while (!bSamplesReceived)
        {
            asm("nop;");
        }

        /* Disable ADC dataflow */
        adi_dev_Control (hAdcDevice,
                         ADI_DEV_CMD_SET_DATAFLOW,
                         (void *) false);

        /* Close ADC */
        adi_dev_Close (hAdcDevice);
    }
    else
    {
        while (1);
    }
}

/*****/

/*
**
** EOF:
**
*/

Until now I am still not clear how I will use this code for the ADC setup and how it will fit into my project. Is there any way that I can vary the speed just by the software by changing certain parameters. Do i have to use all of this code or some of the parts needs to be eliminated? 
i hope that you will help me in setting up the ADC.
Thank you

Outcomes