FreeCalypso > hg > fc-magnetite
view src/cs/drivers/drv_core/clkm/clkm.c @ 600:8f50b202e81f
board preprocessor conditionals: prep for more FC hw in the future
This change eliminates the CONFIG_TARGET_FCDEV3B preprocessor symbol and
all preprocessor conditionals throughout the code base that tested for it,
replacing them with CONFIG_TARGET_FCFAM or CONFIG_TARGET_FCMODEM. These
new symbols are specified as follows:
CONFIG_TARGET_FCFAM is intended to cover all hardware designs created by
Mother Mychaela under the FreeCalypso trademark. This family will include
modem products (repackagings of the FCDEV3B, possibly with RFFE or even
RF transceiver changes), and also my desired FreeCalypso handset product.
CONFIG_TARGET_FCMODEM is intended to cover all FreeCalypso modem products
(which will be firmware-compatible with the FCDEV3B if they use TI Rita
transceiver, or will require a different fw build if we switch to one of
Silabs Aero transceivers), but not the handset product. Right now this
CONFIG_TARGET_FCMODEM preprocessor symbol is used to conditionalize
everything dealing with MCSI.
At the present moment the future of FC hardware evolution is still unknown:
it is not known whether we will ever have any beyond-FCDEV3B hardware at all
(contingent on uncertain funding), and if we do produce further FC hardware
designs, it is not known whether they will retain the same FIC modem core
(triband), if we are going to have a quadband design that still retains the
classic Rita transceiver, or if we are going to switch to Silabs Aero II
or some other transceiver. If we produce a quadband modem that still uses
Rita, it will run exactly the same fw as the FCDEV3B thanks to the way we
define TSPACT signals for the RF_FAM=12 && CONFIG_TARGET_FCFAM combination,
and the current fcdev3b build target will be renamed to fcmodem. OTOH, if
that putative quadband modem will be Aero-based, then it will require a
different fw build target, the fcdev3b target will stay as it is, and the
two targets will both define CONFIG_TARGET_FCFAM and CONFIG_TARGET_FCMODEM,
but will have different RF_FAM numbers. But no matter which way we are
going to evolve, it is not right to have conditionals on CONFIG_TARGET_FCDEV3B
in places like ACI, and the present change clears the way for future
evolution.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Mon, 01 Apr 2019 01:05:24 +0000 |
parents | 945cf7f506b2 |
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 : clkm.c Description : Set of functions useful to test the Saturn CLKM peripheral Project : drivers Author : pmonteil@tif.ti.com Patrice Monteil. Version number : 1.13 Date : 05/23/03 Previous delta : 10/23/01 14:43:31 Sccs Id (SID) : '@(#) clkm.c 1.11 10/23/01 14:43:31 ' *****************************************************************************/ //############################################################ //############################################################ //### Be careful: this file must be placed in Flash Memory ### //### and compiled in 16 bits length intructions ### //### (CF. the function wait_ARM_cycles() ### //############################################################ //############################################################ #include "l1sw.cfg" #include "chipset.cfg" #include "board.cfg" #include "swconfig.cfg" #if (OP_L1_STANDALONE == 0) #include "main/sys_types.h" #else #include "sys_types.h" #endif #include "clkm.h" #if (CHIPSET == 12) #include "sys_memif.h" #else #include "memif/mem.h" #endif #if (BOARD == 34) #include "armio/armio.h" #include "timer/timer.h" #endif static SYS_UWORD32 ratio_wait_loop = 0; #if (CHIPSET == 12) const double dsp_div_value[CLKM_NB_DSP_DIV_VALUE] = {1, 1.5, 2, 3}; #endif #if (BOARD == 34) /* * CLKM_InitARMClock() * * This init is for VTCX0 = 13 MHz * (use CLKM_VTCXO_26 if VTCX0 is 26 MHz) * Parameters : src : 0x0 means EXT CLK (mpu dpll) selected * 0x1 means VTCX0 selected * div : Division factor applied to clock * source * (div = 3 -> divise by 3/2 in fact) * WARNING : reverse order in comparison to ULYSSE * * Return : none * Functionality :Initialize the ARM Clock frequency */ void CLKM_InitARMClock(int src, int div) { SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; int clk_xp5, clk_div; if (div == 3) clk_xp5 = 1; else clk_xp5 = 0; if (div == 2) clk_div = 1; else if (div == 4) clk_div = 0; else clk_div = 3; cntl &= ~(MASK_ARM_MCLK_1P5 | CLKM_MCLK_DIV); cntl |= ((clk_xp5 << 3) | (clk_div << 4)); * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; if (src) CLKM_EnableDPLL(0); else CLKM_EnableDPLL(1); } /* * CLKM_SetMclkDiv * * Set divider * * Parameter : 2-bit divider as per spec (0-7) * * Side-effect : compute magic delay for busy loops * */ void CLKM_SetMclkDiv(int div) { volatile SYS_UWORD16 clkm_ctrl; clkm_ctrl = *((volatile SYS_UWORD16 *) CLKM_ARM_CLK); // read register clkm_ctrl &= ~CLKM_MCLK_DIV; clkm_ctrl |= (div << 4); *((volatile SYS_UWORD16 *) CLKM_ARM_CLK) = clkm_ctrl; } /* * CLKM_EnableDPLL * * Enable or disable 48mhz PLL for ARM clock * * Parameter : 1 or 0 * * Side-effect : compute magic delay for busy loops * */ void CLKM_EnableDPLL(int enable) { volatile SYS_UWORD16 clkm_ctrl; // read CLKM register clkm_ctrl = *((volatile SYS_UWORD16 *) CLKM_ARM_CLK); if (enable) { // PARAMETERS tuned for the AVENGER 2 reference design // we wait before accessing external memory at wake up // we have 2.5 ms margin before the first IT TDMA, we wait // // 5000 loop cycles // 5000 * 5 arm7 cycles // giving <= 1 ms at 26 MHz // wait_ARM_cycles(5000); } else { // reset bit for VTCXO clkm_ctrl &= ~CLKM_CLKIN_SEL; *((volatile SYS_UWORD16 *) CLKM_ARM_CLK) = clkm_ctrl; // disable clk48mhz AI_ResetBit(6); } } /* * CLKM_EnableSharedMemClock * * Enable or disable shared mem clock * * Parameter : 1 or 0 * */ void CLKM_EnableSharedMemClock(int enable) { if (enable) { // request shared mem clock and wait for MPU HW acknowledge AI_ResetBit(4); while(AI_ReadBit(5)!=1); } else { // disable shared mem clock AI_SetBit(4); } } /* * CLKM_InitLeadClock * * Parameter : onoff, mul, ndiv, div * * onoff -> (1:pll on) (0: pll off) * if div = 0 -> x(plmul+1) * if div = 1 -> x(plmul+1)/2 if plmul is even * x(plmul/4) if plmul is odd * ndiv */ void CLKM_InitLeadClock(int onoff, int mul, int ndiv, int div) { int pldiv, pllndiv ; SYS_UWORD16 value = 0; value |= onoff & CLKM_PLONOFF ; value |= (mul << 1) & CLKM_PLMUL; value |= (ndiv << 5)& CLKM_PLLNDIV; value |= (div << 6) & CLKM_PLDIV; CLKM_INITLEADPLL(value); } #elif ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) /*--------------------------------------------------------------*/ /* CLKM_InitARMClock() */ /*--------------------------------------------------------------*/ /* Parameters : clk_src : 0x00 means DPLL selected */ /* 0x01 means VTCX0 selected */ /* 0x03 means CLKIN selected */ /* clk_xp5 : Enable 1.5 or 2.5 division factor */ /* (0 or 1) */ /* clk_div : Division factor applied to clock */ /* source */ /* WARNING : reverse order in comparison to ULYSSE */ /* */ /* Return : none */ /* Functionality :Initialize the ARM Clock frequency */ /*--------------------------------------------------------------*/ void CLKM_InitARMClock(SYS_UWORD16 clk_src, SYS_UWORD16 clk_div, SYS_UWORD16 clk_xp5) { SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; cntl &= ~(CLKM_CLKIN0 | CLKM_CLKIN_SEL | CLKM_ARM_MCLK_XP5 | CLKM_MCLK_DIV); cntl |= ((clk_src << 1) | (clk_xp5 << 3) | (clk_div << 4)); * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; } #else /*-------------------------------------------------------------- * CLKM_InitARMClock() *-------------------------------------------------------------- * Parameters : clk_src : 0x00 means CLKIN selected * 0x01 means 32 K selected * 0x02 means External clock selected * * Return : none * Functionality :Initialize the ARM Clock frequency *--------------------------------------------------------------*/ void CLKM_InitARMClock(SYS_UWORD16 clk_src, SYS_UWORD16 clk_div) { SYS_UWORD16 cntl = * (volatile SYS_UWORD16 *) CLKM_ARM_CLK; cntl &= ~(CLKM_LOW_FRQ | CLKM_CLKIN_SEL | CLKM_MCLK_DIV); cntl |= ((clk_src << 1) | (clk_div << 4)); * (volatile SYS_UWORD16 *) CLKM_ARM_CLK = cntl; } #endif /*-------------------------------------------------------*/ /* convert_nanosec_to_cycles() */ /*-------------------------------------------------------*/ /* parameter: time in 10E-9 seconds */ /* return: Number of cycles for the wait_ARM_cycles() */ /* function */ /* */ /* Description: */ /* ------------ */ /* convert x nanoseconds in y cycles used by the ASM loop*/ /* function . Before calling this function, call the */ /* initialize_wait_loop() function */ /* Called when the HardWare needs time to wait */ /*-------------------------------------------------------*/ SYS_UWORD32 convert_nanosec_to_cycles(SYS_UWORD32 time) { return( time / ratio_wait_loop); } /*-------------------------------------------------------*/ /* initialize_wait_loop() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* Init the ratio used to convert time->Cycles according */ /* to hardware parameters */ /* measurement time for this function (ARM 39Mhz, 3 waits*/ /* states) = 75 micoseconds */ /*-------------------------------------------------------*/ void initialize_wait_loop(void) { #if (BOARD == 34) unsigned long ulTimeSpent=0; // set up timer 2 for wait_ARM_cycles function calibration TM_EnableTimer (2); TM_ResetTimer (2, 0xFFFF, 0, 0); // run wait_ARM_cycles() for 10000 loops wait_ARM_cycles(10000); // time spent expressed in timer cycles // where 1 timer cycle = 2462 ns with prescale 0 // 13 MHz divided by 16 = timer clkin // prescale 0 -> divided by 2 ulTimeSpent = TM_ReadTimer (2); TM_StopTimer (2); ulTimeSpent = 0xFFFF - ulTimeSpent; ulTimeSpent *= 2462; // compute ratio_wait_loop ratio_wait_loop = (unsigned long)(ulTimeSpent/10000.); #else #define NBR_CYCLES_IN_LOOP 5 // this value is got from an oscilloscope measurement double src_ratio; double final_ratio; SYS_UWORD16 flash_access_size; SYS_UWORD16 flash_wait_state; SYS_UWORD32 nbr; SYS_UWORD32 arm_clock; ////////////////////////////////// // compute the ARM clock used // ////////////////////////////////// { SYS_UWORD16 arm_mclk_xp5; SYS_UWORD16 arm_ratio; SYS_UWORD16 clk_src; SYS_UWORD16 clkm_cntl_arm_clk_reg = * (volatile SYS_UWORD16 *) CLKM_CNTL_ARM_CLK; #if ((CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || (CHIPSET == 11) || (CHIPSET == 12)) clk_src = (clkm_cntl_arm_clk_reg & MASK_CLKIN) >> 1; switch (clk_src) { case 0x00: //DPLL selected // select the DPLL factor #if (CHIPSET == 12) if (((* (volatile SYS_UWORD16 *) C_MAP_DPLL_BASE) & DPLL_LOCK) != 0) #else if (((* (volatile SYS_UWORD16 *) MEM_DPLL_ADDR) & DPLL_LOCK) != 0) #endif { SYS_UWORD16 dpll_div; SYS_UWORD16 dpll_mul; dpll_div=DPLL_READ_DPLL_DIV; dpll_mul=DPLL_READ_DPLL_MUL; src_ratio = (double)(dpll_mul)/(double)(dpll_div+1); } else // DPLL in bypass mode { SYS_UWORD16 dpll_div = DPLL_BYPASS_DIV; src_ratio= (double)(1)/(double)(dpll_div+1); } break; case 0x01: //VTCX0 selected src_ratio = 1; break; case 0x03: //CLKIN selected (external clock) src_ratio = 1; break; } // define the division factor applied to clock source (CLKIN or VTCXO or DPLL) arm_ratio = (clkm_cntl_arm_clk_reg & CLKM_MCLK_DIV) >> 4; // check if the 1.5 or 2.5 division factor is enabled arm_mclk_xp5 = clkm_cntl_arm_clk_reg & CLKM_ARM_MCLK_XP5; if (arm_mclk_xp5 == 0) // division factor enable for ARM clock ? { if (arm_ratio == 0) arm_ratio =1; } else arm_ratio = ((arm_ratio>>1) & 0x0001) == 0 ? 1.5 : 2.5; #else src_ratio = 1; // define the division factor applied to clock source (CLKIN or VTCXO or DPLL) arm_ratio = (clkm_cntl_arm_clk_reg & CLKM_MCLK_DIV) >> 4; // check if the 1.5 or 2.5 division factor is enabled arm_mclk_xp5 = clkm_cntl_arm_clk_reg & MASK_ARM_MCLK_1P5; if (arm_mclk_xp5 == 1) // division factor enable for ARM clock ? arm_ratio = 1.5; else { if (arm_ratio == 0) arm_ratio = 4; else if (arm_ratio == 1 ) arm_ratio = 2; else arm_ratio = 1; } #endif final_ratio = (src_ratio / (double) arm_ratio); } ////////////////////////////////////////// // compute the Flash wait states used // ////////////////////////////////////////// #if (CHIPSET == 12) flash_access_size = 1; #else flash_access_size = *((volatile SYS_UWORD16 *) MEM_REG_nCS0); #endif flash_access_size = (flash_access_size >> 5) & 0x0003; // 0=>8bits, 1=>16 bits, 2 =>32 bits // the loop file is compiled in 16 bits it means // flash 8 bits => 2 loads for 1 16 bits assembler instruction // flash 16 bits => 1 loads for 1 16 bits assembler instruction // flash/internal RAM 32 bits => 1 loads for 1 16 bits assembler instruction (ARM bus 16 bits !!) // !!!!!!!!! be careful: if this file is compile in 32 bits, change these 2 lines here after !!! if (flash_access_size == 0) flash_access_size = 2; else flash_access_size = 1; #if (CHIPSET == 12) /* * loop move to run in internal memory, due to page mode in external memory */ flash_wait_state = 0; #else flash_wait_state = *((volatile SYS_UWORD16 *) MEM_REG_nCS0); flash_wait_state &= 0x001F; #endif ////////////////////////////////////// // compute the length of the loop // ////////////////////////////////////// // Number of flash cycles for the assembler loop nbr = NBR_CYCLES_IN_LOOP; // Number of ARM cycles for the assembler loop nbr = nbr * (flash_wait_state + 1) * (flash_access_size); // time for the assembler loop (unit nanoseconds: 10E-9) arm_clock = final_ratio * 13; // ARM clock in Mhz ratio_wait_loop = (SYS_UWORD32)((nbr*1000) / arm_clock); #endif } #if (CHIPSET != 12) /*-------------------------------------------------------*/ /* wait_ARM_cycles() */ /*-------------------------------------------------------*/ /* */ /* Description: */ /* ------------ */ /* Called when the HardWare needs time to wait. */ /* this function wait x cycles and is used with the */ /* convert_nanosec_to_cycles() & initialize_wait_loop() */ /* */ /* Exemple: wait 10 micro seconds: */ /* initialize_wait_loop(); */ /* wait_ARM_cycles(convert_nanosec_to_cycles(10000)) */ /* */ /* minimum time value with cpt_loop = 0 (estimated) */ /* and C-SAMPLE / flash 6,5Mhz ~ 1,5 micro seconds */ /* */ /* */ /* Be careful : in order to respect the rule about the */ /* conversion "time => number of cylcles in this loop" */ /* (Cf the functions: convert_nanosec_to_cycles() and */ /* initialize_wait_loop() ) respect the following rules: */ /* This function must be placed in Flash Memory and */ /* compiled in 16 bits instructions length */ /*-------------------------------------------------------*/ void wait_ARM_cycles(SYS_UWORD32 cpt_loop) { // C code: // while (cpt_loop -- != 0); asm(" CMP A1, #0"); asm(" BEQ END_FUNCTION"); asm("LOOP_LINE: "); asm(" SUB A1, A1, #1"); asm(" CMP A1, #0"); asm(" BNE LOOP_LINE"); asm("END_FUNCTION: "); } #endif /* (CHIPSET != 12)*/