view src/cs/drivers/drv_core/dma/sys_dma.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
children
line wrap: on
line source

/*                @(#) nom : sys_dma.c SID: 1.2 date : 05/23/03               */
/* Filename:      sys_dma.c                                                   */
/* Version:       1.2                                                         */
/******************************************************************************
 *                   WIRELESS COMMUNICATION SYSTEM DEVELOPMENT
 *
 *             (C) 2002 Texas Instruments France. All rights reserved
 *
 *                          Author : Guillaume Leterrier
 *                                   Francois Amand
 *
 *
 *  Important Note
 *  --------------
 *
 *  This S/W is a preliminary version. It contains information on a product 
 *  under development and is issued for evaluation purposes only. Features 
 *  characteristics, data and other information are subject to change.
 *
 *  The S/W is furnished under Non Disclosure Agreement and may be used or
 *  copied only in accordance with the terms of the agreement. It is an offence
 *  to copy the software in any way except as specifically set out in the 
 *  agreement. No part of this document may be reproduced or transmitted in any
 *  form or by any means, electronic or mechanical, including photocopying and
 *  recording, for any purpose without the express written permission of Texas
 *  Instruments Inc.
 *
 ******************************************************************************
 *
 *  FILE NAME: sys_dma.c
 *
 *
 *  PURPOSE:  DMA drivers for CALYPSO PLUS.
 *            The drivers allows DMA module configuration and control.
 *
 *
 *  FILE REFERENCES:
 *
 *  Name                  IO      Description
 *  -------------         --      ---------------------------------------------
 *  
 *
 *
 *  EXTERNAL VARIABLES:
 *
 *  Source:
 *
 *  Name                  Type              IO   Description
 *  -------------         ---------------   --   ------------------------------
 *
 *
 *
 *  EXTERNAL REFERENCES:
 *
 *  Name                Description
 *  ------------------  -------------------------------------------------------
 *
 *
 *
 *  ABNORMAL TERMINATION CONDITIONS, ERROR AND WARNING MESSAGES:
 *  
 *
 *
 *  ASSUMPTION, CONSTRAINTS, RESTRICTIONS:
 *  
 *
 *
 *  NOTES:
 *  
 *
 *
 *  REQUIREMENTS/FUNCTIONAL SPECIFICATION REFERENCES:
 *
 *
 *
 *
 *  DEVELOPMENT HISTORY:
 *
 *  Date         Name(s)         Version  Description
 *  -----------  --------------  -------  -------------------------------------
 *  23-Oct-2002  G.Leterrier    0.0.1    First implementation
 *   6-Feb-2003  G.Leterrier    0.0.2    Reset HW request to 0, before new setup in function "f_dma_channel_parameter_set"
 *  20-Feb-2003  G.Leterrier    0.0.3    f_dma_global_parameter_set correction on API priority bit
 *                                        disable and clear status register channel before re-configuration
 *  ALGORITHM: 
 *
 *
 *****************************************************************************/

#include "chipset.cfg"

#if (CHIPSET == 12)

    #include "sys_dma.h"


    /***************************************************************************/
    /*          global variable
    *****************************************************************************/

    extern T_DMA_CALL_BACK pf_dma_call_back_address[C_DMA_NUMBER_OF_CHANNEL];

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_get_version_driver
    *    This functionis used to get to DMA driver software version.
    *
    *  ARGUMENT LIST:
    *
    *  Argument     Type         IO  Description
    *  ----------   ----------   --  -------------------------------------------
    *  none
    *
    *
    * RETURN VALUE: SYS_UWORD16
    *
    *****************************************************************************/
    SYS_UWORD16 f_dma_get_version_driver(void)
      {
      return(C_DMA_VERSION_DRIVER);
      } /*f_dma_get_version_driver()*/

    /******************************************************************************
    *
    *  FUNCTION NAME:f_dma_global_parameter_set
    *    The function is used to setup the DMA global configuration.
    *
    *
    *  ARGUMENT LIST:
    *
    *  Argument          Type                 IO  Description
    *  ----------         ----------             --  -------------------------------------------
    *  p_dma_global_parameter  T_DMA_TYPE_GLOBAL_PARAMETER*   I    Pointer on data structure containing all global parameter of DMA configuration
    *
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_global_parameter_set(T_DMA_TYPE_GLOBAL_PARAMETER  *p_dma_global_parameter)
      {
      if (p_dma_global_parameter->d_dma_global_auto_gate==C_DMA_AUTO_GATE_ON)
        {
        C_DMA_GCR_REG |= (C_DMA_AUTO_GATE_ON << C_DMA_GCR_AUTO_GATE_POS );
        }

      else
        {
        C_DMA_GCR_REG &= ~( C_DMA_GCR_AUTO_GATE_MASK << C_DMA_GCR_AUTO_GATE_POS );
        }

      C_DMA_AR_REG = ( 
                        (p_dma_global_parameter->d_dma_global_api_prio <<  C_DMA_AR_API_PRIO_POS) 
                      | (p_dma_global_parameter->d_dma_global_rhea_prio << C_DMA_AR_RHEA_PRIO_POS) 
                      | (p_dma_global_parameter->d_dma_global_imif_prio << C_DMA_AR_IMIF_PRIO_POS)
                      );
      } /*f_dma_global_parameter_set() */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_allocation_set
    *    This function defines the allocation of a channel.
    *  This function is used to set which channel can be configured through the ARM and which one can be configured through the DSP.
    *
    *
    *
    *  ARGUMENT LIST:
    *
    *  Argument            Type                IO  Description
    *  ----------          ----------            --  -------------------------------------------
    *  d_dma_channel_number    T_DMA_TYPE_CHANNEL_NUMBER    I  Variable providing the channel number
    *  d_dma_channel_allocation  T_DMA_TYPE_CHANNEL_ALLOCATION  I  Variable defining if the channel allocated to the ARM or the DSP.
    *
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_allocation_set(T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number, T_DMA_TYPE_CHANNEL_ALLOCATION d_dma_channel_allocation)
       {
       if (d_dma_channel_allocation==C_DMA_CHANNEL_DSP)
          {
            C_DMA_CAR_REG |= (C_DMA_CHANNEL_DSP << d_dma_channel_number);
          }

       else
          {
            C_DMA_CAR_REG &= ~( C_DMA_CHANNEL_DSP << d_dma_channel_number );
          }


      } /*f_dma_channel_allocation_set */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_parameter_set
    *  The function is used to setup a DMA channel configuration.
    *
    *
    *  ARGUMENT LIST:
    *
    *  Argument              Type                 IO  Description
    *  ----------          ----------               --  -------------------------------------------
    *  p_dma_channel_parameter    T_DMA_TYPE_CHANNEL_PARAMETER *     I  Pointer on data structure containing all the parameter to setup a channel  
    *
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_parameter_set(T_DMA_TYPE_CHANNEL_PARAMETER    *p_dma_channel_parameter)
       {
        SYS_UWORD16 d_temp_register;

        F_DMA_CHANNEL_DISABLE(p_dma_channel_parameter->d_dma_channel_number);

        d_temp_register=F_DMA_GET_CHANNEL_IT_STATUS(p_dma_channel_parameter->d_dma_channel_number);
        
        pf_dma_call_back_address[p_dma_channel_parameter->d_dma_channel_number]=p_dma_channel_parameter->pf_dma_call_back_address;



        if (p_dma_channel_parameter->d_dma_channel_secured==C_DMA_CHANNEL_SECURED)
          {
            C_DMA_SCR_REG |= (C_DMA_CHANNEL_SECURED << p_dma_channel_parameter->d_dma_channel_number);
          }

        else
          {
            C_DMA_SCR_REG &= ~( C_DMA_CHANNEL_SECURED << p_dma_channel_parameter->d_dma_channel_number );
          }

        C_DMA_CSDP_REG(p_dma_channel_parameter->d_dma_channel_number) = (

          (p_dma_channel_parameter->d_dma_channel_data_type    << C_DMA_CSDP_DATA_TYPE_POS )
        | (p_dma_channel_parameter->d_dma_channel_src_port    << C_DMA_CSDP_SRC_POS )
        | (p_dma_channel_parameter->d_dma_src_channel_packed  << C_DMA_CSDP_SRC_PACK_POS )
        | (p_dma_channel_parameter->d_dma_src_channel_burst_en  << C_DMA_CSDP_SRC_BURST_EN_POS )
        | (p_dma_channel_parameter->d_dma_channel_dst_port    << C_DMA_CSDP_DST_POS )
        | (p_dma_channel_parameter->d_dma_dst_channel_packed  << C_DMA_CSDP_DST_PACK_POS )
        | (p_dma_channel_parameter->d_dma_dst_channel_burst_en  << C_DMA_CSDP_DST_BURST_EN_POS )
                                 );

        C_DMA_CCR_REG(p_dma_channel_parameter->d_dma_channel_number) &= ~C_DMA_CCR_SYNC_MASK;



        C_DMA_CCR_REG(p_dma_channel_parameter->d_dma_channel_number) = (

          (p_dma_channel_parameter->d_dma_channel_hw_synch     << C_DMA_CCR_SYNC_POS  )
        | (p_dma_channel_parameter->d_dma_channel_priority     << C_DMA_CCR_PRIO_POS  )
        | (p_dma_channel_parameter->d_dma_channel_auto_init    << C_DMA_CCR_AUTO_INIT_POS  )
        | (p_dma_channel_parameter->d_dma_channel_fifo_flush   << C_DMA_CCR_FIFO_FLUSH_POS )
        | (p_dma_channel_parameter->d_dma_src_channel_addr_mode  << C_DMA_CCR_SRC_AMODE_POS  )
        | (p_dma_channel_parameter->d_dma_dst_channel_addr_mode  << C_DMA_CCR_DST_AMODE_POS  )
                                );

        C_DMA_CICR_REG(p_dma_channel_parameter->d_dma_channel_number) = (  

          (p_dma_channel_parameter->d_dma_channel_it_time_out  << C_DMA_CICR_TOUT_IE_POS  )
        | (p_dma_channel_parameter->d_dma_channel_it_drop      << C_DMA_CICR_DROP_IE_POS  )
        | (p_dma_channel_parameter->d_dma_channel_it_frame     <<C_DMA_CICR_FRAME_IE_POS  )                     
        | (p_dma_channel_parameter->d_dma_channel_it_block     << C_DMA_CICR_BLOCK_IE_POS  )
        | (p_dma_channel_parameter->d_dma_channel_it_half_block  << C_DMA_CICR_HALF_BLOCK_IE_POS  )
                                );

        C_DMA_CSSA_L_REG(p_dma_channel_parameter->d_dma_channel_number)= (p_dma_channel_parameter->d_dma_channel_src_address ); /* is a mask requested ? */


        C_DMA_CSSA_U_REG(p_dma_channel_parameter->d_dma_channel_number)= (p_dma_channel_parameter->d_dma_channel_src_address >> 16 ); /* is a mask requested ? */


        C_DMA_CDSA_L_REG(p_dma_channel_parameter->d_dma_channel_number)= (p_dma_channel_parameter->d_dma_channel_dst_address); /* is a mask requested ? */


        C_DMA_CDSA_U_REG(p_dma_channel_parameter->d_dma_channel_number)=  (p_dma_channel_parameter->d_dma_channel_dst_address >> 16 ); /* is a mask requested ? */

        C_DMA_CEN_REG(p_dma_channel_parameter->d_dma_channel_number) = (p_dma_channel_parameter->d_dma_channel_element_number );

        C_DMA_CFN_REG(p_dma_channel_parameter->d_dma_channel_number) = (p_dma_channel_parameter->d_dma_channel_frame_number );


        } /*f_dma_channel_parameter_set() */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_enable 
    *    This function is used to enable a DMA transfer of a channel which could be depending on a hardware request.
    *  If there is no hardware request, the transfer starts immediately.
    *
    *  ARGUMENT LIST:
    *
    *  Argument          Type            IO  Description
    *  ----------        ----------          --  -------------------------------------------
    *  d_dma_channel_number  T_DMA_TYPE_CHANNEL_NUMBER  I  Variable to define which channel is enabled.
    *
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_enable (T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number)  
      {
      F_DMA_CHANNEL_ENABLE(d_dma_channel_number);
      }/* f_dma_channel_enable() */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_disable
    *   This function is used to disable a DMA transfer of a channel
    *
    *
    *  ARGUMENT LIST:
    *
    *  Argument          Type            IO  Description
    *  ----------        ----------          --  -------------------------------------------
    *  d_dma_channel_number  T_DMA_TYPE_CHANNEL_NUMBER  I  Variable to define which channel is disabled.
    *
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_disable(T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number)  
      {
      F_DMA_CHANNEL_DISABLE(d_dma_channel_number);
      } /*f_dma_channel_disable() */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_auto_init_disable
    *    This function is disabling the auto-initialization mode of the channel.
    *    The channel completes the current transfer and stops.
    *
    *  ARGUMENT LIST:
    *
    *  Argument          Type            IO  Description
    *  ----------        ----------          --  -------------------------------------------
    *  d_dma_channel_number  T_DMA_TYPE_CHANNEL_NUMBER  I  Variable to define which channel is disabled from auto-init mode.
    *
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_auto_init_disable(T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number)
      {
      F_DMA_CHANNEL_AUTO_INIT_DISABLE(d_dma_channel_number);
      } /* f_dma_channel_auto_init_disable */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_get_channel_counter
    *      This function can be used to monitor address
    *    where the last data of a frame has been written.
    *    This function provides only the lowest16 bits of the address.
    *
    *
    *  ARGUMENT LIST:
    *
    *  Argument           Type              IO  Description
    *  ----------         ----------            --  -------------------------------------------
    *  d_dma_channel_number  T_DMA_TYPE_CHANNEL_NUMBER    I    Variable to define from which channel, we get the counter.    
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    SYS_UWORD16  f_dma_get_channel_counter(T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number)
        {
        return(F_DMA_GET_CHANNEL_COUNTER(d_dma_channel_number));
        } /*f_dma_get_channel_counter() */

    /******************************************************************************
    *
    *  FUNCTION NAME: f_dma_channel_soft_reset
    *      perform a soft reset of the following parameter of the channel :
    *      Source address,Destination address,Element number,Frame number,Channel counter
    *  
    * 
    *
    *  ARGUMENT LIST:
    *
    *  Argument          Type              IO  Description
    *  ----------        ----------            --  -------------------------------------------
    *  d_dma_channel_number       T_DMA_TYPE_CHANNEL_NUMBER    I   Variable to define which channel is soft reset.
    *  
    *
    * RETURN VALUE: None
    *
    *****************************************************************************/
    void f_dma_channel_soft_reset(T_DMA_TYPE_CHANNEL_NUMBER d_dma_channel_number)
       {
       C_DMA_SRR_REG |= ( 0x1 << d_dma_channel_number);

       while (C_DMA_SRR_REG & ( 0x1 << d_dma_channel_number))   /* wait for the reset is completed */
            {
            }

       } /*f_dma_channel_soft_reset() */
  #endif /* (CHIPSET == 12) */