view src/cs/drivers/drv_core/spi/spi_drv.h @ 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

/**********************************************************************************/
/*            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION              */
/*                                                                                */
/*   Property of Texas Instruments -- For  Unrestricted  Internal  Use  Only      */
/*   Unauthorized reproduction and/or distribution is strictly prohibited.  This  */
/*   product  is  protected  under  copyright  law  and  trade  secret law as an  */
/*   unpublished work.  Created 1987, (C) Copyright 1997 Texas Instruments.  All  */
/*   rights reserved.                                                             */
/*                                                                                */
/*                                                                                */
/*   Filename          : spi_drv.h                                                */
/*                                                                                */
/*   Description       : SPI registers and bits definitions.					  */
/*                       Functions and macros to drive the SPI module.            */
/*                       The Serial Port Interface is a bidirectional 3 lines 	  */
/*                       interface dedicated to the transfer of data to and 	  */
/*                       from up to 5 external devices offering a 3 lines 		  */
/*                       serial interface.										  */
/*						 In this project, it is only used to connect the TI 	  */
/*						 Analog BaseBand (ABB).				    				  */
/*						 It is assumed that the ABB is connected as the SPI       */																				  
/*                       device 0.                                                */																				  
/*																				  */
/*                       This interface is specified to be compatible with 		  */
/*                       the UMA1018M Philips, the FUJITSU MB15F02, the 		  */
/*                       SIEMENS PMB2306T synthesizers and the TI ABB.			  */
/*																				  */
/*                       This serial port is based on a looped shift-register 	  */
/*                       thus allowing both transmit (PISO) and receive (SIPO) 	  */
/*                       modes.													  */
/*																				  */
/*                                                                                */
/*   Author            : Pascal PUEL                                              */
/*                                                                                */
/*   Version number   : 1.28                                                       */
/*                                                                                */
/*   Date and time    : 07/01/03                                                       */
/*                                                                                */
/*   Previous delta   : Rework                                                    */
/*                                                                                */
/**********************************************************************************/

#ifndef __SPI_DRV_H__
#define __SPI_DRV_H__

#include "l1sw.cfg"
#include "chipset.cfg"

#include "memif/mem.h" 
#if (OP_L1_STANDALONE == 0)
  #include "main/sys_types.h"
#else
  #include "sys_types.h"
#endif

// SPI module registers definition
#define SPI_REG_SET1	(MEM_SPI + 0x00)
#define SPI_REG_SET2	(MEM_SPI + 0x02)
#define SPI_REG_CTRL	(MEM_SPI + 0x04)
#define SPI_REG_STATUS	(MEM_SPI + 0x06)
#define SPI_REG_TX_LSB	(MEM_SPI + 0x08)
#define SPI_REG_TX_MSB	(MEM_SPI + 0x0A)
#define SPI_REG_RX_LSB	(MEM_SPI + 0x0C)
#define SPI_REG_RX_MSB	(MEM_SPI + 0x0E)


// SPI module bits definition of register SPI_REG_SET1
#define SPI_CLK_OFF          0x0000   // default value 
#define SPI_CLK_ON           0x0001
#define SPI_CLOCK_DIV_1      0x0000   // default value
#define SPI_CLOCK_DIV_2      0x0002
#define SPI_CLOCK_DIV_4      0x0004
#define SPI_CLOCK_DIV_8      0x0006
#define SPI_CLOCK_DIV_16     0x0008
#if (CHIPSET == 12)
#define SPI_CLOCK_DIV_32     0x000A
#define SPI_CLOCK_DIV_64     0x000C
#define SPI_CLOCK_DIV_128    0x000E
#endif
#define SPI_IT_MASK_0        0x0010   // default value
#define SPI_IT_DEMASK_0      0x0000
#define SPI_IT_MASK_1        0x0020   // default value   
#define SPI_IT_DEMASK_1      0x0000


// SPI module bits definition of register SPI_REG_SET2
#define SPI_CLK_EDG_FALL     	  0x0000   // default value	for device 0
#define SPI_CLK_EDG_RISE     	  0x0001
#define SPI_CLK_EDG_FALL_1   	  0x0000   // default value	for device 1
#define SPI_CLK_EDG_RISE_1   	  0x0002
#define SPI_CLK_EDG_FALL_2   	  0x0000   // default value	for device 2
#define SPI_CLK_EDG_RISE_2   	  0x0004
#define SPI_CLK_EDG_FALL_3   	  0x0000   // default value	for device 3
#define SPI_CLK_EDG_RISE_3   	  0x0008
#define SPI_CLK_EDG_FALL_4   	  0x0000   // default value for device 4
#define SPI_CLK_EDG_RISE_4   	  0x0010
#define SPI_NTSPEN_NEG_LEV   	  0x0000   // default value	for device 0
#define SPI_NTSPEN_POS_LEV   	  0x0020
#define SPI_NTSPEN_NEG_LEV_1 	  0x0000   // default value	for device 1
#define SPI_NTSPEN_POS_LEV_1 	  0x0040
#define SPI_NTSPEN_NEG_LEV_2 	  0x0000   // default value	for device 2
#define SPI_NTSPEN_POS_LEV_2 	  0x0080
#define SPI_NTSPEN_NEG_LEV_3 	  0x0000   // default value	for device 3
#define SPI_NTSPEN_POS_LEV_3 	  0x0100
#define SPI_NTSPEN_NEG_LEV_4 	  0x0000   // default value for device 4
#define SPI_NTSPEN_POS_LEV_4 	  0x0200
#define SPI_NTSPEN_LEV_TRIG  	  0x0000   // default value	for device 0
#define SPI_NTSPEN_EDG_TRIG  	  0x0400
#define SPI_NTSPEN_LEV_TRIG_1	  0x0000   // default value	for device 1
#define SPI_NTSPEN_EDG_TRIG_1	  0x0800
#define SPI_NTSPEN_LEV_TRIG_2	  0x0000   // default value	for device 2
#define SPI_NTSPEN_EDG_TRIG_2	  0x1000
#define SPI_NTSPEN_LEV_TRIG_3	  0x0000   // default value	for device 3
#define SPI_NTSPEN_EDG_TRIG_3	  0x2000
#define SPI_NTSPEN_LEV_TRIG_4	  0x0000   // default value for device 4
#define SPI_NTSPEN_EDG_TRIG_4	  0x4000


// SPI module bits definition of register SPI_REG_CTRL
#define SPI_RDWR_DEACTIV   0x0000      // default value
#define SPI_RDWR_ACTIV     0x0001
#define SPI_WR_DEACTIV     0x0000      // default value
#define SPI_WR_ACTIV       0x0002
#define SPI_WNB_0          0x0000      // default value  
#define SPI_WNB_1          0x0004  
#define SPI_WNB_2          0x0008  
#define SPI_WNB_3          0x000c  
#define SPI_WNB_4          0x0010  
#define SPI_WNB_5          0x0014  
#define SPI_WNB_6          0x0018  
#define SPI_WNB_7          0x001c  
#define SPI_WNB_8          0x0020  
#define SPI_WNB_9          0x0024  
#define SPI_WNB_10         0x0028  
#define SPI_WNB_11         0x002c  
#define SPI_WNB_12         0x0030  
#define SPI_WNB_13         0x0034  
#define SPI_WNB_14         0x0038  
#define SPI_WNB_15         0x003c  
#define SPI_WNB_16         0x0040  
#define SPI_WNB_17         0x0044  
#define SPI_WNB_18         0x0048  
#define SPI_WNB_19         0x004c  
#define SPI_WNB_20         0x0050  
#define SPI_WNB_21         0x0054  
#define SPI_WNB_22         0x0058  
#define SPI_WNB_23         0x005c  
#define SPI_WNB_24         0x0060  
#define SPI_WNB_25         0x0064  
#define SPI_WNB_26         0x0068  
#define SPI_WNB_27         0x006c  
#define SPI_WNB_28         0x0070  
#define SPI_WNB_29         0x0074
#define SPI_WNB_30         0x0078  
#define SPI_WNB_31         0x007c 


// SPI possible device IDs
#define SPI_DEV0   0x0000 
#define SPI_DEV1   0x0080   
#define SPI_DEV2   0x0100   
#define SPI_DEV3   0x0180   
#define SPI_DEV4   0x0200   

// ABB should be mapped as device 0
#define ABB		SPI_DEV0


// SPI module bits definition of register SPI_REG_STATUS
#define RE_ST   0x0001   // bit 0
#define WE_ST   0x0002   // bit 1


/* The ARM emulator requires the spi clock always ON to be able to access */
/* spi registers through a window.*/ 
/* But it's better to stop the SPI clock in the GSM application to reduce the power consumption. */
/* Validate the next line to reduce power consumption */
//#define SPI_CLK_LOW_POWER



// STRUCTURES
typedef struct
{
    SYS_UWORD16 PrescVal;
    SYS_UWORD16 DataTrLength;
    SYS_UWORD16 DevAddLength;
    SYS_UWORD16 DevId;
    SYS_UWORD16 ClkEdge; 
    SYS_UWORD16 TspEnLevel; 
    SYS_UWORD16 TspEnForm; 
}T_SPI_DEV;      // T_SPI_DEV is used to define an SPI device


// MACROS
#define SPI_WRITE_TX_LSB(TxLsb) { \
* (volatile SYS_UWORD16 *) SPI_REG_TX_LSB = TxLsb;  }

#define SPI_WRITE_TX_MSB(TxMsb) { \
* (volatile SYS_UWORD16 *) SPI_REG_TX_MSB = TxMsb;  }

#define SPI_START_WRITE {* (volatile SYS_UWORD16 *) SPI_REG_CTRL |= SPI_WR_ACTIV; }

#define SPI_START_READ {* (volatile SYS_UWORD16 *) SPI_REG_CTRL |= SPI_RDWR_ACTIV; }

#define SPI_CLK_DISABLE	{ \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 &= ~SPI_CLK_ON;  }

#define SPI_CLK_ENABLE	{ \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= SPI_CLK_ON;  }

#define SPI_MaskIT_WR { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= SPI_IT_MASK_0;  }

#define SPI_MaskIT_RD { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= SPI_IT_MASK_1;  }

#define SPI_Mask_All_IT { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= (SPI_IT_MASK_0 | SPI_IT_MASK_1);  }

#define SPI_UnmaskIT_WR { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 &= ~SPI_IT_MASK_0;  }

#define SPI_UnmaskIT_RD { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 &= ~SPI_IT_MASK_1;  }

#define SPI_Unmask_All_IT { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 &= ~(SPI_IT_MASK_0 | SPI_IT_MASK_1);  }

#define SPI_Ready_for_WR { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= (SPI_CLK_ON | SPI_IT_MASK_0); }

#define SPI_Ready_for_RD { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= (SPI_CLK_ON | SPI_IT_MASK_1); }

#define SPI_Ready_for_RDWR { \
* (volatile SYS_UWORD16 *) SPI_REG_SET1 |= (SPI_CLK_ON | SPI_IT_MASK_0 | SPI_IT_MASK_1); }   



// INLINE FUNCTIONS
/*-----------------------------------------------------------------------*/
/* SPI_ReadRX_LSB()                                                      */
/*                                                                       */
/* This function returns the value of SPI_REG_RX_LSB register            */
/*                                                                       */
/*-----------------------------------------------------------------------*/
static inline SYS_UWORD16 SPI_ReadRX_LSB(void)
{
  return * (volatile SYS_UWORD16 *) SPI_REG_RX_LSB;
}


/*-----------------------------------------------------------------------*/
/* SPI_ReadRX_MSB()                                                      */
/*                                                                       */
/* This function returns the value of SPI_REG_RX_MSB register            */
/*                                                                       */
/*-----------------------------------------------------------------------*/
static inline SYS_UWORD16 SPI_ReadRX_MSB(void)
{
  return * (volatile SYS_UWORD16 *) SPI_REG_RX_MSB;
}



/*-----------------------------------------------------------------------*/
/* SPI_ReadStatus()                                                      */
/*                                                                       */
/* This function returns the value of SPI_REG_STATUS register            */
/*                                                                       */
/*-----------------------------------------------------------------------*/
static inline SYS_UWORD16 SPI_ReadStatus(void)
{
  return * (volatile SYS_UWORD16 *) SPI_REG_STATUS;
}



// PROTOTYPES
void SPI_InitDev(T_SPI_DEV *Device);

#endif   //  __SPI_DRV_H__