Freescale Semiconductor Inc.
Main Page | Data Structures | File List | Data Fields | Globals

etpu_as.c

Go to the documentation of this file.
00001 /*******************************************************************************
00002 *
00003 * Freescale Semiconductor Inc.
00004 * (c) Copyright 2004-2012 Freescale Semiconductor, Inc.
00005 * ALL RIGHTS RESERVED.
00006 *
00007 ****************************************************************************//*!
00008 *
00009 * @file    etpu_as.c
00010 *
00011 * @author  Milan Brejl [r54529]
00012 * 
00013 * @version 1.0
00014 * 
00015 * @date    17-May-2012
00016 *
00017 * @brief   This file contains API for using the eTPU function
00018 *          Analog Sensing (AS).
00019 * 
00020 ****************************************************************************//*!
00021 *
00022 * @mainpage
00023 *
00024 * The eTPU AS APIs @ref etpu_as.c/.h includes API functions for eTPU
00025 * function Analog Sensing.
00026 * 
00027 *******************************************************************************/
00028 /*******************************************************************************
00029 * Includes
00030 *******************************************************************************/
00031 #include "etpu_as.h"      /* private header file */
00032 #include "etpu_util.h"    /* utility routines for working with the eTPU */
00033 #include "etpu_pwmm.h"    /* access to PWMM parameter offsets */
00034 
00035 /*******************************************************************************
00036 * Global variables
00037 *******************************************************************************/
00038 extern uint32_t fs_etpu_data_ram_start;
00039 extern uint32_t fs_etpu_data_ram_ext;
00040 
00041 /*******************************************************************************
00042 * FUNCTION: fs_etpu_as_init
00043 ****************************************************************************//*!
00044 * @brief   This function initializes eTPU channels to run AS function.
00045 *
00046 * @note    The following actions are performed in order:
00047 *          -# Use user-defined CPBA or allocate new eTPU DATA RAM
00048 *          -# Write chan config registers and FM bits
00049 *          -# Write channel parameters
00050 *          -# Write HSR
00051 *          -# Set channel priority
00052 *
00053 * @warning The PWMM channel eTPU DATA RAM allocation must be done 
00054 *          before the AS channel initialization (using fs_etpu_as_init).
00055 *          On AS initialization, pointers to PWMM parameters are created.
00056 *          This is required only when mode is FS_ETPU_AS_MODE_PWMM_SLAVE,
00057 *          FS_ETPU_AS_PHASE_CURRENTS_ON is set or any of
00058 *          AS_CFIFO_FRAME/CENTER_PULSE_START/END is set. 
00059 *
00060 * @param   *p_as_instance - This is a pointer to the instance structure 
00061 *            @ref as_instance_t.
00062 * @param   *p_pwmm_instance - This is a pointer to the instance structure 
00063 *            @ref pwmm_instance_t. It is used in case there is any interaction
00064 *            between AS and PWMM eTPU functions - if running AS in synchronized
00065 *            more or if reading PWMM sector for phase current processing.
00066 * @param   *p_as_config - This is a pointer to the structure of configuration
00067 *            parameters @ref as_config_t.
00068 *
00069 * @return  Error codes that can be returned are:
00070 *          - @ref FS_ETPU_ERROR_NONE - No error
00071 *          - @ref FS_ETPU_ERROR_CODESIZE - When the code is too big for the
00072 *            available memory
00073 *          - @ref FS_ETPU_ERROR_VIS_BIT_NOT_SET - When the SCM Visibility cannot
00074 *            be set and SCM cannot be written.
00075 *
00076 * @warning This function does not configure the pins, only the eTPU channels.
00077 *******************************************************************************/
00078 uint32_t fs_etpu_as_init(
00079   struct as_instance_t   *p_as_instance,
00080   struct pwmm_instance_t *p_pwmm_instance,
00081   struct as_config_t     *p_as_config)
00082 {
00083   uint8_t  chan_num;
00084   uint8_t  priority;
00085   uint32_t *cpba;
00086   uint32_t *cpba_signals;
00087   uint32_t cpba_pwmm_local;
00088   uint8_t  signal_count;
00089   uint32_t cr;
00090   uint8_t  i;
00091 
00092   chan_num     = p_as_instance->chan_num;   
00093   priority     = p_as_instance->priority;                
00094   cpba         = p_as_instance->cpba;
00095   cpba_signals = p_as_instance->cpba_signals;
00096   signal_count = p_as_instance->signal_count;                       
00097   cpba_pwmm_local = (uint32_t)p_pwmm_instance->cpba - fs_etpu_data_ram_start;
00098   
00099   /* Use user-defined CPBA or allocate new eTPU DATA RAM */
00100   if(cpba == 0)
00101   {
00102     cpba = fs_etpu_malloc(FS_ETPU_AS_NUM_PARMS);
00103     if(cpba == 0)
00104     {
00105       return(FS_ETPU_ERROR_MALLOC);
00106     }
00107     else
00108     {
00109       p_as_instance->cpba = cpba;
00110     }
00111   }
00112   if(cpba_signals == 0)
00113   {
00114     cpba_signals = fs_etpu_malloc(FS_ETPU_AS_SIGNAL_STRUCT_SIZE*signal_count);
00115     if(cpba_signals == 0)
00116     {
00117       return(FS_ETPU_ERROR_MALLOC);
00118     }
00119     else
00120     {
00121       p_as_instance->cpba_signals = cpba_signals;
00122     }
00123   }
00124   
00125   /* Write chan config registers and FM bits */
00126   cr = (FS_ETPU_AS_TABLE_SELECT << 24) +
00127        (FS_ETPU_AS_FUNCTION_NUMBER << 16) +
00128        (((uint32_t)cpba - fs_etpu_data_ram_start) >> 3);
00129   eTPU->CHAN[chan_num].CR.R = cr; 
00130   eTPU->CHAN[chan_num].SCR.R = (uint32_t)p_as_config->pulse_selection;
00131 
00132   /* Write channel parameters */
00133   /* 24-bit */
00134   *(cpba + ((FS_ETPU_AS_OFFSET_START_OFFSET            - 1)>>2)) = p_as_config->start_offset;
00135   *(cpba + ((FS_ETPU_AS_OFFSET_PERIOD                  - 1)>>2)) = p_as_config->period;
00136   *(cpba + ((FS_ETPU_AS_OFFSET_PULSE_ADJUSTMENT_FRAME  - 1)>>2)) = p_as_config->pulse_adjustment_frame;
00137   *(cpba + ((FS_ETPU_AS_OFFSET_PULSE_ADJUSTMENT_CENTER - 1)>>2)) = p_as_config->pulse_adjustment_center;
00138   *(cpba + ((FS_ETPU_AS_OFFSET_PULSE_WIDTH             - 1)>>2)) = p_as_config->pulse_width;
00139   *(cpba + ((FS_ETPU_AS_OFFSET_FRAME_TIME              - 1)>>2)) = 0;
00140   *(cpba + ((FS_ETPU_AS_OFFSET_CENTER_TIME             - 1)>>2)) = 0;
00141   *(cpba + ((FS_ETPU_AS_OFFSET_PWMM_SECTOR             - 1)>>2)) = cpba_pwmm_local + FS_ETPU_PWMM_OFFSET_SECTOR;
00142   *(cpba + ((FS_ETPU_AS_OFFSET_PWMM_FRAME_TIME         - 1)>>2)) = cpba_pwmm_local + FS_ETPU_PWMM_OFFSET_FRAMETIME;
00143   *(cpba + ((FS_ETPU_AS_OFFSET_PWMM_CENTER_TIME        - 1)>>2)) = cpba_pwmm_local + FS_ETPU_PWMM_OFFSET_CENTERTIME;
00144   *(cpba + ((FS_ETPU_AS_OFFSET_RESULT_QUEUE            - 1)>>2)) = (uint32_t)p_as_config->p_result_queue;
00145   *(cpba + ((FS_ETPU_AS_OFFSET_COMMAND_QUEUE           - 1)>>2)) = (uint32_t)p_as_config->p_cfifo;
00146 
00147   /* 8-bit */
00148   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_POLARITY      ) = p_as_instance->polarity;
00149   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_LINK          ) = p_as_config->link_options;
00150   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_IRQ           ) = p_as_config->irq_dma_options;
00151   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_CFIFO         ) = p_as_config->cfifo_update;
00152   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_MASK_FRAME     ) = p_as_config->signal_mask_frame;
00153   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_MASK_CENTER    ) = p_as_config->signal_mask_center;
00154   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_MASK_DC_OFFSET ) = 0;
00155   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SECTOR                ) = 0;
00156   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_PHASE_CURRENT_A_IDX   ) = p_as_config->phase_current_idx_a;
00157   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_PHASE_CURRENT_B_IDX   ) = p_as_config->phase_current_idx_b;
00158   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_PHASE_CURRENT_C_IDX   ) = p_as_config->phase_current_idx_c;
00159   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_PHASE_CURRENTS) = p_as_config->phase_current_processing; 
00160   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_COUNT          ) = signal_count;
00161 
00162   /* 32-bit */
00163   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_FRAME_START  >>2)) = p_as_config->link_chans_frame_start;
00164   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_FRAME_END    >>2)) = p_as_config->link_chans_frame_end;
00165   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_CENTER_START >>2)) = p_as_config->link_chans_center_start;
00166   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_CENTER_END   >>2)) = p_as_config->link_chans_center_end;
00167   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IA_ADC0             >>2)) = p_as_config->cmd_ia_adc_0;
00168   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IA_ADC1             >>2)) = p_as_config->cmd_ia_adc_1;
00169   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IB_ADC0             >>2)) = p_as_config->cmd_ib_adc_0;
00170   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IB_ADC1             >>2)) = p_as_config->cmd_ib_adc_1;
00171   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IC_ADC0             >>2)) = p_as_config->cmd_ic_adc_0;
00172   *(cpba + (FS_ETPU_AS_OFFSET_CMD_IC_ADC1             >>2)) = p_as_config->cmd_ic_adc_0;
00173   *(cpba + (FS_ETPU_AS_OFFSET_SIGNAL                  >>2)) = (uint32_t)cpba_signals - fs_etpu_data_ram_start;
00174 
00175   /* Write signal array parameters */
00176   for(i=0; i<signal_count; i++)
00177   {
00178     *(cpba_signals + ((FS_ETPU_AS_OFFSET_GAIN          - 1)>>2)) = p_as_config->signal_config[i].gain;
00179     *(cpba_signals + ((FS_ETPU_AS_OFFSET_DC_OFFSET     - 1)>>2)) = p_as_config->signal_config[i].dc_offset;
00180     *(cpba_signals + ((FS_ETPU_AS_OFFSET_FORGET_FACTOR - 1)>>2)) = p_as_config->signal_config[i].forget_factor;
00181     *(cpba_signals + ((FS_ETPU_AS_OFFSET_VALUE         - 1)>>2)) = 0;
00182     *((uint8_t*)cpba_signals + FS_ETPU_AS_OFFSET_QUEUE_OFFSET  ) = p_as_config->signal_config[i].queue_offset >> 2;
00183     cpba_signals += FS_ETPU_AS_SIGNAL_STRUCT_SIZE >> 2;    
00184   }
00185 
00186   /* Write HSR */  
00187   eTPU->CHAN[chan_num].HSRR.R = p_as_instance->mode;
00188   
00189   /* Set channel priority */
00190   fs_etpu_enable(chan_num, priority);
00191   
00192   return(FS_ETPU_ERROR_NONE);
00193 }
00194 
00195 /*******************************************************************************
00196 * FUNCTION: fs_etpu_as_config
00197 ****************************************************************************//*!
00198 * @brief   This function changes the AS configuration.
00199 *
00200 * @note    The following actions are performed in order:
00201 *          -# Write configuration parameter values to eTPU DATA RAM
00202 *          -# Write AS channel FM bits
00203 *
00204 * @param   *p_as_instance - This is a pointer to the instance structure 
00205 *            @ref as_instance_t.
00206 * @param   *p_as_config - This is a pointer to the structure of configuration
00207 *            parameters @ref as_config_t.
00208 *
00209 * @return  Error codes that can be returned are:
00210 *          - @ref FS_ETPU_ERROR_NONE - No error
00211 *
00212 *******************************************************************************/
00213 uint32_t fs_etpu_as_config(
00214   struct as_instance_t *p_as_instance,
00215   struct as_config_t   *p_as_config)
00216 {
00217   uint32_t *cpba;
00218   uint32_t *cpbae;
00219   uint32_t *cpbae_signals;
00220   uint8_t  signal_count;
00221   uint8_t  i;
00222 
00223   cpba = p_as_instance->cpba;                       
00224   cpbae = cpba + (0x4000 >> 2); /* sign-extended memory area */
00225   cpbae_signals = p_as_instance->cpba_signals + (0x4000 >> 2); /* sign-extended memory area */
00226   signal_count = p_as_instance->signal_count;                       
00227 
00228   /* Write channel parameters */
00229   /* 24-bit - use cpbae to prevent from overwriting bits 31:24 */
00230   *(cpbae + ((FS_ETPU_AS_OFFSET_PERIOD                  - 1)>>2)) = p_as_config->period;
00231   *(cpbae + ((FS_ETPU_AS_OFFSET_PULSE_ADJUSTMENT_FRAME  - 1)>>2)) = p_as_config->pulse_adjustment_frame;
00232   *(cpbae + ((FS_ETPU_AS_OFFSET_PULSE_ADJUSTMENT_CENTER - 1)>>2)) = p_as_config->pulse_adjustment_center;
00233   *(cpbae + ((FS_ETPU_AS_OFFSET_PULSE_WIDTH             - 1)>>2)) = p_as_config->pulse_width;
00234 
00235   /* 8-bit */
00236   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_LINK          ) = p_as_config->link_options;
00237   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_IRQ           ) = p_as_config->irq_dma_options;
00238   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_CFIFO         ) = p_as_config->cfifo_update;
00239   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_MASK_FRAME     ) = p_as_config->signal_mask_frame;
00240   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_SIGNAL_MASK_CENTER    ) = p_as_config->signal_mask_center;
00241   *((uint8_t*)cpba + FS_ETPU_AS_OFFSET_OPTIONS_PHASE_CURRENTS) = p_as_config->phase_current_processing; 
00242 
00243   /* 32-bit */
00244   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_FRAME_START  >>2)) = p_as_config->link_chans_frame_start;
00245   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_FRAME_END    >>2)) = p_as_config->link_chans_frame_end;
00246   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_CENTER_START >>2)) = p_as_config->link_chans_center_start;
00247   *(cpba + (FS_ETPU_AS_OFFSET_LINK_CHANS_CENTER_END   >>2)) = p_as_config->link_chans_center_end;
00248 
00249   /* Write signal array parameters */
00250   for(i=0; i<signal_count; i++)
00251   {
00252     *(cpbae_signals + ((FS_ETPU_AS_OFFSET_GAIN          - 1)>>2)) = p_as_config->signal_config[i].gain;
00253     *(cpbae_signals + ((FS_ETPU_AS_OFFSET_DC_OFFSET     - 1)>>2)) = p_as_config->signal_config[i].dc_offset;
00254     *(cpbae_signals + ((FS_ETPU_AS_OFFSET_FORGET_FACTOR - 1)>>2)) = p_as_config->signal_config[i].forget_factor;
00255     cpbae_signals += FS_ETPU_AS_SIGNAL_STRUCT_SIZE >> 2;     
00256   }
00257   
00258   /* Write  */
00259   eTPU->CHAN[p_as_instance->chan_num].SCR.R = (uint32_t)p_as_config->pulse_selection;
00260 
00261   return(FS_ETPU_ERROR_NONE);
00262 }
00263 
00264 /*******************************************************************************
00265 * FUNCTION: fs_etpu_as_get_outputs
00266 ****************************************************************************//*!
00267 * @brief   This function reads output values of the AS function.
00268 *
00269 * @note    The following actions are performed in order:
00270 *          -# Read output parameter values from eTPU DATA RAM
00271 *
00272 * @param   *p_as_instance - This is a pointer to the instance structure 
00273 *            @ref as_instance_t.
00274 * @param   *p_as_outputs - This is a pointer to the structure of states
00275 *            @ref as_outputs_t.
00276 *
00277 * @return  Error codes that can be returned are:
00278 *          - @ref FS_ETPU_ERROR_NONE - No error
00279 *
00280 *******************************************************************************/
00281 uint32_t fs_etpu_as_get_outputs(
00282   struct as_instance_t *p_as_instance,
00283   struct as_outputs_t  *p_as_outputs)
00284 {
00285   uint32_t *cpbae_signals;
00286   uint8_t  signal_count;
00287   uint8_t  i;
00288 
00289   cpbae_signals = p_as_instance->cpba_signals + (0x4000 >> 2); /* sign-extended memory area */
00290   signal_count  = p_as_instance->signal_count;                       
00291   
00292   /* Read signal value from signal array */
00293   for(i=0; i<signal_count; i++)
00294   {
00295     p_as_outputs->signal_value[i] = *(cpbae_signals + ((FS_ETPU_AS_OFFSET_VALUE - 1)>>2));
00296     cpbae_signals += FS_ETPU_AS_SIGNAL_STRUCT_SIZE >> 2;     
00297   }
00298 
00299   return(FS_ETPU_ERROR_NONE);
00300 }
00301 
00302 /*******************************************************************************
00303 * FUNCTION: fs_etpu_as_measure_dc_offsets
00304 ****************************************************************************//*!
00305 * @brief   This function uses the signal output values to set the signal 
00306 *          dc-offsets. It is presummed the current physical signal value 
00307 *          corresponds to what a zero value is.
00308 *
00309 * @note    The following actions are performed in order:
00310 *          -# Read output parameter values from eTPU DATA RAM
00311 *
00312 * @param   *p_as_instance - This is a pointer to the instance structure 
00313 *            @ref as_instance_t.
00314 * @param   *p_as_config - This is a pointer to the structure of outputs
00315 *            @ref as_config_t. The signal dc_offsets are updated in this 
00316 *            structure.
00317 * @param   signal_mask - this mask defines which signal dc_offsets are measured.
00318 *            Bit 0 (0x01) corresponds to signal[0].
00319 *
00320 * @return  Error codes that can be returned are:
00321 *          - @ref FS_ETPU_ERROR_NONE - No error
00322 *
00323 *******************************************************************************/
00324 uint32_t fs_etpu_as_measure_dc_offsets(
00325   struct as_instance_t *p_as_instance,
00326   struct as_config_t   *p_as_config,
00327          uint8_t       signal_mask)
00328 {
00329   uint32_t *cpbae_signals;
00330   uint8_t  signal_count;
00331   int24_t  dc_offset;
00332   uint8_t  i;
00333 
00334   cpbae_signals = p_as_instance->cpba_signals + (0x4000 >> 2); /* sign-extended memory area */
00335   signal_count  = p_as_instance->signal_count;                       
00336   
00337   for(i=0; i<signal_count; i++)
00338   {
00339     if(signal_mask & (1<<i))
00340     {
00341       dc_offset = *(cpbae_signals + ((FS_ETPU_AS_OFFSET_DC_OFFSET - 1)>>2));
00342       dc_offset += *(cpbae_signals + ((FS_ETPU_AS_OFFSET_VALUE - 1)>>2));
00343       *(cpbae_signals + ((FS_ETPU_AS_OFFSET_DC_OFFSET - 1)>>2)) = dc_offset;
00344       p_as_config->signal_config[i].dc_offset = dc_offset;
00345     }
00346     cpbae_signals += FS_ETPU_AS_SIGNAL_STRUCT_SIZE >> 2;     
00347   } 
00348 
00349   return(FS_ETPU_ERROR_NONE);
00350 }
00351 
00352 /*******************************************************************************
00353  *
00354  * Copyright:
00355  *  Freescale Semiconductor, INC. All Rights Reserved.
00356  *  You are hereby granted a copyright license to use, modify, and
00357  *  distribute the SOFTWARE so long as this entire notice is
00358  *  retained without alteration in any modified and/or redistributed
00359  *  versions, and that such modified versions are clearly identified
00360  *  as such. No licenses are granted by implication, estoppel or
00361  *  otherwise under any patents or trademarks of Freescale
00362  *  Semiconductor, Inc. This software is provided on an "AS IS"
00363  *  basis and without warranty.
00364  *
00365  *  To the maximum extent permitted by applicable law, Freescale
00366  *  Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
00367  *  INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
00368  *  PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
00369  *  REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
00370  *  AND ANY ACCOMPANYING WRITTEN MATERIALS.
00371  *
00372  *  To the maximum extent permitted by applicable law, IN NO EVENT
00373  *  SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
00374  *  (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
00375  *  BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
00376  *  PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
00377  *
00378  *  Freescale Semiconductor assumes no responsibility for the
00379  *  maintenance and support of this software
00380  ******************************************************************************/
00381 /*******************************************************************************
00382  *
00383  * REVISION HISTORY:
00384  *
00385  * FILE OWNER: Milan Brejl [r54529]
00386  *
00387  * Revision 1.0  2012/05/17  r54529
00388  * Initial version of file.
00389  ******************************************************************************/