///////////////////////////////////////////////////////////////////////////////
//                                                                            /
// IAR ANSI C/C++ Compiler V6.30.1.53127/W32 for ARM    08/Mar/2012  18:18:19 /
// Copyright 1999-2011 IAR Systems AB.                                        /
//                                                                            /
//    Cpu mode     =  thumb                                                   /
//    Endian       =  little                                                  /
//    Source file  =  D:\Profiles\b01252\My Documents\Freescale\P0\software\s /
//                    ample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_ /
//                    sc\src\drivers\mcg\mcg.c                                /
//    Command line =  "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\src\drivers\mcg\mcg.c" -D IAR -D TOWER -D           /
//                    TWR_K20D50M -lCN "D:\Profiles\b01252\My                 /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\FLASH_128KB_PFLASH\List\" -lB         /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\FLASH_128KB_PFLASH\List\" /
//                     -o "D:\Profiles\b01252\My                              /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\FLASH_128KB_PFLASH\Obj\" --no_cse     /
//                    --no_unroll --no_inline --no_code_motion --no_tbaa      /
//                    --no_clustering --no_scheduling --debug                 /
//                    --endian=little --cpu=Cortex-M4 -e --fpu=None           /
//                    --dlib_config "C:\Program Files\IAR Systems\Embedded    /
//                    Workbench 6.0_5\arm\INC\c\DLib_Config_Normal.h" -I      /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\common\" -I  /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\cpu\" -I     /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\cpu\headers\ /
//                    " -I "D:\Profiles\b01252\My                             /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\drivers\uart\" -I        /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\drivers\mcg\ /
//                    " -I "D:\Profiles\b01252\My                             /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\drivers\wdog\" -I        /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\drivers\rcm\ /
//                    " -I "D:\Profiles\b01252\My                             /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\drivers\lptmr\" -I       /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\platforms\"  /
//                    -I "D:\Profiles\b01252\My Documents\Freescale\P0\softwa /
//                    re\sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50 /
//                    MHz_sc\build\iar\TWRK20D50M_Demo\..\" -I                /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\projects\TWR /
//                    K20D50M_Demo\" -I "D:\Profiles\b01252\My                /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \dma\" -I "D:\Profiles\b01252\My                        /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \adc16\" -I "D:\Profiles\b01252\My                      /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \i2c\" -I "D:\Profiles\b01252\My                        /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \tsi\" -I "D:\Profiles\b01252\My                        /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \adc_test\" -I "D:\Profiles\b01252\My                   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \angle_calculation\" -I "D:\Profiles\b01252\My          /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \buzzer\" -I "D:\Profiles\b01252\My                     /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \fft_test\" -I "D:\Profiles\b01252\My                   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \irda_test\" -I "D:\Profiles\b01252\My                  /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \cmt_test\" -I "D:\Profiles\b01252\My                   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \protocol\" -I "D:\Profiles\b01252\My                   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \task_mgr\" -I "D:\Profiles\b01252\My                   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \TWRK20_specific\" -I "D:\Profiles\b01252\My            /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\projects\TWRK20D50M_Demo /
//                    \rtc\" -I "D:\Profiles\b01252\My                        /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\CMSIS\DSP_Lib\Lib\interm /
//                    ediateFiles\" -I "D:\Profiles\b01252\My                 /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\CMSIS\DSP_Lib\Include\"  /
//                    -I "D:\Profiles\b01252\My Documents\Freescale\P0\softwa /
//                    re\sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50 /
//                    MHz_sc\build\iar\TWRK20D50M_Demo\..\..\..\src\CMSIS\CM4 /
//                    \DeviceSupport\ARM\ARMCM4\" -I "D:\Profiles\b01252\My   /
//                    Documents\Freescale\P0\software\sample code             /
//                    cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\build\ia /
//                    r\TWRK20D50M_Demo\..\..\..\src\CMSIS\CM4\CoreSupport\"  /
//                    -I "D:\Profiles\b01252\My Documents\Freescale\P0\softwa /
//                    re\sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50 /
//                    MHz_sc\build\iar\TWRK20D50M_Demo\..\..\..\src\CMSIS\CM4 /
//                    \CoreSupportLiker Options-Library\" -I                  /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\src\CMSIS\DSP_Li /
//                    b\Lib\intermediateFiles\arm_cortexM4_math.lib\" -I      /
//                    "D:\Profiles\b01252\My Documents\Freescale\P0\software\ /
//                    sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz /
//                    _sc\build\iar\TWRK20D50M_Demo\..\..\..\build\" -Ol      /
//                    --use_c++_inline -I "C:\Program Files\IAR               /
//                    Systems\Embedded Workbench 6.0_5\arm\CMSIS\Include\"    /
//                    -D ARM_MATH_CM4                                         /
//    List file    =  D:\Profiles\b01252\My Documents\Freescale\P0\software\s /
//                    ample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_ /
//                    sc\build\iar\TWRK20D50M_Demo\FLASH_128KB_PFLASH\List\mc /
//                    g.s                                                     /
//                                                                            /
//                                                                            /
///////////////////////////////////////////////////////////////////////////////

        NAME mcg

        #define SHT_PROGBITS 0x1

        EXTERN __aeabi_f2iz
        EXTERN __aeabi_fdiv
        EXTERN __aeabi_fmul
        EXTERN __aeabi_i2f
        EXTERN rtc_as_refclk

        PUBLIC atc
        PUBLIC blpe_fbe
        PUBLIC blpe_pbe
        PUBLIC blpi_fbi
        PUBLIC clk_monitor_0
        PUBLIC fbe_blpe
        PUBLIC fbe_fbi
        PUBLIC fbe_fee
        PUBLIC fbe_fei
        PUBLIC fbe_pbe
        PUBLIC fbi_blpi
        PUBLIC fbi_fbe
        PUBLIC fbi_fee
        PUBLIC fbi_fei
        PUBLIC fee_fbe
        PUBLIC fee_fbi
        PUBLIC fee_fei
        PUBLIC fei_fbe
        PUBLIC fei_fbi
        PUBLIC fei_fee
        PUBLIC fll_freq
        PUBLIC fll_rtc_init
        PUBLIC pbe_blpe
        PUBLIC pbe_fbe
        PUBLIC pbe_pee
        PUBLIC pee_pbe
        PUBLIC pll_init
        PUBLIC what_mcg_mode

// D:\Profiles\b01252\My Documents\Freescale\P0\software\sample code cesar\TWR-K20D50M_LABS_AND_CE\kinetis_50MHz_sc\src\drivers\mcg\mcg.c
//    1 /*
//    2  * File:    mcg.c
//    3  *
//    4  * Notes:
//    5  * Assumes the MCG mode is in the default FEI mode out of reset
//    6  */
//    7 
//    8 #include "common.h"
//    9 #include "mcg.h"
//   10 #include "lptmr.h"
//   11 
//   12 // global variables
//   13 extern int core_clk_khz;
//   14 //extern int slow_irc_freq = 32768; // default slow irc frequency is 32768Hz
//   15 //extern int fast_irc_freq = 4000000; // default fast irc frequency is 4MHz
//   16 
//   17 extern char drs_val, dmx32_val;
//   18 
//   19 
//   20 
//   21 
//   22 
//   23 /*********************************************************************************************/
//   24 /* Functon name : pll_init
//   25  *
//   26  * Mode transition: Option to move from FEI to PEE mode or to just initialize the PLL
//   27  *
//   28  * This function initializess either PLL0 or PLL1. Either OSC0 or OSC1 can be selected for the
//   29  * reference clock source. The oscillators can be configured to use a crystal or take in an
//   30  * external square wave clock.
//   31  * NOTE : This driver does not presently (as of Sept 9 2011) support the use of OSC1 as the
//   32  * reference clock for the MCGOUT clock used for the system clocks.
//   33  * The PLL outputs a PLLCLK and PLLCLK2X. PLLCLK2X is the actual PLL frequency and PLLCLK is
//   34  * half this frequency. PLLCLK is used for MCGOUT and is also typically used by the
//   35  * peripherals that can select the PLL as a clock source. So the PLL frequency generated will
//   36  * be twice the desired frequency.
//   37  * Using the function parameter names the PLL frequency is calculated as follows:
//   38  * PLL freq = ((crystal_val / prdiv_val) * vdiv_val)
//   39  * Refer to the readme file in the mcg driver directory for examples of pll_init configurations.
//   40  * All parameters must be provided, for example crystal_val must be provided even if the
//   41  * oscillator associated with that parameter is already initialized.
//   42  * The various passed parameters are checked to ensure they are within the allowed range. If any
//   43  * of these checks fail the driver will exit and return a fail/error code. An error code will
//   44  * also be returned if any error occurs during the PLL initialization sequence. Refer to the
//   45  * readme file in the mcg driver directory for a list of all these codes.
//   46  *
//   47  * Parameters: crystal_val - external clock frequency in Hz either from a crystal or square
//   48  *                           wave clock source
//   49  *             hgo_val     - selects whether low power or high gain mode is selected
//   50  *                           for the crystal oscillator. This has no meaning if an
//   51  *                           external clock is used.
//   52  *             erefs_val   - selects external clock (=0) or crystal osc (=1)
//   53  *             prdiv_val   - value to divide the external clock source by to create the desired
//   54  *                           PLL reference clock frequency
//   55  *             vdiv_val    - value to multiply the PLL reference clock frequency by
//   56  *             mcgout_select  - 0 if the PLL is just to be enabled, non-zero if the PLL is used
//   57  *                              to provide the MCGOUT clock for the system.
//   58  *
//   59  * Return value : PLL frequency (Hz) divided by 2 or error code
//   60  */
//   61 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//   62 int pll_init(int crystal_val, unsigned char hgo_val, unsigned char erefs_val, signed char prdiv_val, signed char vdiv_val, unsigned char mcgout_select)
//   63 {
pll_init:
        PUSH     {R4-R6}
        LDRSB    R4,[SP, #+12]
//   64   unsigned char frdiv_val;
//   65   unsigned char temp_reg;
//   66   unsigned char prdiv, vdiv;
//   67   short i;
//   68   int ref_freq;
//   69   int pll_freq;
//   70 
//   71   // check if in FEI mode
//   72   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
//   73       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
//   74       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
        LDR.W    R5,??DataTable13  ;; 0x40064006
        LDRB     R5,[R5, #+0]
        UBFX     R5,R5,#+2,#+2
        UXTB     R5,R5            ;; ZeroExt  R5,R5,#+24,#+24
        CMP      R5,#+0
        BNE.N    ??pll_init_0
        LDR.W    R5,??DataTable13  ;; 0x40064006
        LDRB     R5,[R5, #+0]
        LSLS     R5,R5,#+27
        BPL.N    ??pll_init_0
        LDR.W    R5,??DataTable13  ;; 0x40064006
        LDRB     R5,[R5, #+0]
        LSLS     R5,R5,#+26
        BPL.N    ??pll_init_1
//   75   {
//   76     return 0x1;                                                     // return error code
??pll_init_0:
        MOVS     R0,#+1
        B.N      ??pll_init_2
//   77   }
//   78 
//   79   // check external frequency is less than the maximum frequency
//   80   if  (crystal_val > 50000000) {return 0x21;}
??pll_init_1:
        LDR.W    R5,??DataTable12  ;; 0x2faf081
        CMP      R0,R5
        BLT.N    ??pll_init_3
        MOVS     R0,#+33
        B.N      ??pll_init_2
//   81 
//   82   // check crystal frequency is within spec. if crystal osc is being used as PLL ref
//   83   if (erefs_val)
??pll_init_3:
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??pll_init_4
//   84   {
//   85     if ((crystal_val < 3000000) || (crystal_val > 32000000)) {return 0x22;} // return 1 if one of the available crystal options is not available
        LDR.W    R5,??DataTable12_1  ;; 0x2dc6c0
        SUBS     R5,R0,R5
        LDR.W    R6,??DataTable12_2  ;; 0x1ba8141
        CMP      R5,R6
        BCC.N    ??pll_init_4
        MOVS     R0,#+34
        B.N      ??pll_init_2
//   86   }
//   87 
//   88   // make sure HGO will never be greater than 1. Could return an error instead if desired.
//   89   if (hgo_val > 0)
??pll_init_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BCC.N    ??pll_init_5
//   90   {
//   91     hgo_val = 1; // force hgo_val to 1 if > 0
        MOVS     R1,#+1
//   92   }
//   93 
//   94   // Check PLL divider settings are within spec.
//   95   if ((prdiv_val < 1) || (prdiv_val > 25)) {return 0x41;}
??pll_init_5:
        SUBS     R5,R3,#+1
        UXTB     R5,R5            ;; ZeroExt  R5,R5,#+24,#+24
        CMP      R5,#+25
        BCC.N    ??pll_init_6
        MOVS     R0,#+65
        B.N      ??pll_init_2
//   96   if ((vdiv_val < 24) || (vdiv_val > 55)) {return 0x42;}
??pll_init_6:
        SUBS     R5,R4,#+24
        UXTB     R5,R5            ;; ZeroExt  R5,R5,#+24,#+24
        CMP      R5,#+32
        BCC.N    ??pll_init_7
        MOVS     R0,#+66
        B.N      ??pll_init_2
//   97 
//   98   // Check PLL reference clock frequency is within spec.
//   99   ref_freq = crystal_val / prdiv_val;
??pll_init_7:
        SXTB     R3,R3            ;; SignExt  R3,R3,#+24,#+24
        SDIV     R5,R0,R3
//  100   if ((ref_freq < 2000000) || (ref_freq > 4000000)) {return 0x43;}
        LDR.W    R6,??DataTable12_3  ;; 0x1e8480
        SUBS     R5,R5,R6
        LDR.W    R6,??DataTable12_4  ;; 0x1e8481
        CMP      R5,R6
        BCC.N    ??pll_init_8
        MOVS     R0,#+67
        B.N      ??pll_init_2
//  101 
//  102   // Check PLL output frequency is within spec.
//  103   pll_freq = (crystal_val / prdiv_val) * vdiv_val;
??pll_init_8:
        SXTB     R3,R3            ;; SignExt  R3,R3,#+24,#+24
        SDIV     R5,R0,R3
        SXTB     R4,R4            ;; SignExt  R4,R4,#+24,#+24
        MULS     R5,R4,R5
//  104   if ((pll_freq < 48000000) || (pll_freq > 100000000)) {return 0x45;}
        LDR.W    R6,??DataTable12_5  ;; 0x2dc6c00
        SUBS     R5,R5,R6
        LDR.W    R6,??DataTable12_6  ;; 0x3197501
        CMP      R5,R6
        BCC.N    ??pll_init_9
        MOVS     R0,#+69
        B.N      ??pll_init_2
//  105 
//  106   // configure the MCG_C2 register
//  107   // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
//  108   // it still needs to be set correctly even if the oscillator is not being used
//  109       
//  110   temp_reg = MCG_C2;
??pll_init_9:
        LDR.W    R5,??DataTable12_7  ;; 0x40064001
        LDRB     R5,[R5, #+0]
//  111   temp_reg &= ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); // clear fields before writing new values
        ANDS     R5,R5,#0xC3
//  112     
//  113   if (crystal_val <= 3000000)
        LDR.W    R6,??DataTable12_8  ;; 0x2dc6c1
        CMP      R0,R6
        BGE.N    ??pll_init_10
//  114   {
//  115     temp_reg |= (MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R6,R2,#+2
        ORRS     R1,R6,R1
        ORRS     R1,R1,#0x10
        ORRS     R5,R1,R5
        B.N      ??pll_init_11
//  116   }
//  117   else
//  118   {
//  119     temp_reg |= (MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
??pll_init_10:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R6,R2,#+2
        ORRS     R1,R6,R1
        ORRS     R1,R1,#0x20
        ORRS     R5,R1,R5
//  120   }
//  121   MCG_C2 = temp_reg;
??pll_init_11:
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        STRB     R5,[R1, #+0]
//  122   
//  123   // determine FRDIV based on reference clock frequency
//  124   // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
//  125   if (crystal_val <= 1250000) {frdiv_val = 0;}
        LDR.W    R1,??DataTable13_1  ;; 0x1312d1
        CMP      R0,R1
        BGE.N    ??pll_init_12
        MOVS     R1,#+0
        B.N      ??pll_init_13
//  126   else if (crystal_val <= 2500000) {frdiv_val = 1;}
??pll_init_12:
        LDR.W    R1,??DataTable13_2  ;; 0x2625a1
        CMP      R0,R1
        BGE.N    ??pll_init_14
        MOVS     R1,#+1
        B.N      ??pll_init_13
//  127   else if (crystal_val <= 5000000) {frdiv_val = 2;}
??pll_init_14:
        LDR.W    R1,??DataTable13_3  ;; 0x4c4b41
        CMP      R0,R1
        BGE.N    ??pll_init_15
        MOVS     R1,#+2
        B.N      ??pll_init_13
//  128   else if (crystal_val <= 10000000) {frdiv_val = 3;}
??pll_init_15:
        LDR.W    R1,??DataTable13_4  ;; 0x989681
        CMP      R0,R1
        BGE.N    ??pll_init_16
        MOVS     R1,#+3
        B.N      ??pll_init_13
//  129   else if (crystal_val <= 20000000) {frdiv_val = 4;}
??pll_init_16:
        LDR.W    R1,??DataTable13_5  ;; 0x1312d01
        CMP      R0,R1
        BGE.N    ??pll_init_17
        MOVS     R1,#+4
        B.N      ??pll_init_13
//  130   else {frdiv_val = 5;}
??pll_init_17:
        MOVS     R1,#+5
//  131 
//  132   // Select external oscillator and Reference Divider and clear IREFS to start ext osc
//  133   // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
//  134   // CLKS=2, FRDIV=frdiv_val, IREFS=0, IRCLKEN=0, IREFSTEN=0
//  135   temp_reg = MCG_C1;
??pll_init_13:
        LDR.W    R5,??DataTable13_6  ;; 0x40064000
        LDRB     R5,[R5, #+0]
//  136   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear values in these fields
        ANDS     R5,R5,#0x3
//  137   temp_reg = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
        LSLS     R1,R1,#+3
        ANDS     R1,R1,#0x38
        ORRS     R1,R1,#0x80
        MOVS     R5,R1
//  138   MCG_C1 = temp_reg;
        LDR.W    R1,??DataTable13_6  ;; 0x40064000
        STRB     R5,[R1, #+0]
//  139 
//  140   // if the external oscillator is used need to wait for OSCINIT to set
//  141   if (erefs_val)
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??pll_init_18
//  142   {
//  143     for (i = 0 ; i < 10000 ; i++)
        MOVS     R1,#+0
        B.N      ??pll_init_19
??pll_init_20:
        ADDS     R1,R1,#+1
??pll_init_19:
        MOVW     R2,#+10000
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,R2
        BGE.N    ??pll_init_21
//  144     {
//  145       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
        LDR.W    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??pll_init_20
//  146     }
//  147   if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
??pll_init_21:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??pll_init_18
        MOVS     R0,#+35
        B.N      ??pll_init_2
//  148   }
//  149 /* THIS CHECK IS REMOVED DUE TO BUG WITH SLOW IRC IN REV. 1.0
//  150   // wait for Reference clock Status bit to clear
//  151   for (i = 0 ; i < 2000 ; i++)
//  152   {
//  153     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
//  154   }
//  155   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
//  156 */
//  157   // Wait for clock status bits to show clock source is ext ref clk
//  158   for (i = 0 ; i < 2000 ; i++)
??pll_init_18:
        MOVS     R1,#+0
        B.N      ??pll_init_22
??pll_init_23:
        ADDS     R1,R1,#+1
??pll_init_22:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pll_init_24
//  159   {
//  160     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.W    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??pll_init_23
//  161   }
//  162   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
??pll_init_24:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BEQ.N    ??pll_init_25
        MOVS     R0,#+26
        B.N      ??pll_init_2
//  163 
//  164   // Now in FBE
//  165   // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
//  166   // It is enabled here but can be removed if this is not required.
//  167   MCG_C6 |= MCG_C6_CME_MASK;
??pll_init_25:
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x20
        LDR.W    R2,??DataTable13_7  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  168   
//  169   // Configure PLL
//  170   // Configure MCG_C5
//  171   // If the PLL is to run in STOP mode then the PLLSTEN bit needs to be OR'ed in here or in user code.
//  172   temp_reg = MCG_C5;
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        LDRB     R5,[R1, #+0]
//  173   temp_reg &= ~MCG_C5_PRDIV_MASK;
        ANDS     R5,R5,#0xE0
//  174   temp_reg |= MCG_C5_PRDIV(prdiv_val - 1);    //set PLL ref divider
        SUBS     R1,R3,#+1
        ANDS     R1,R1,#0x1F
        ORRS     R5,R1,R5
//  175   MCG_C5 = temp_reg;
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        STRB     R5,[R1, #+0]
//  176 
//  177   // Configure MCG_C6
//  178   // The PLLS bit is set to enable the PLL, MCGOUT still sourced from ext ref clk
//  179   // The loss of lock interrupt can be enabled by seperately OR'ing in the LOLIE bit in MCG_C6
//  180   temp_reg = MCG_C6; // store present C6 value
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R5,[R1, #+0]
//  181   temp_reg &= ~MCG_C6_VDIV_MASK; // clear VDIV settings
        ANDS     R5,R5,#0xE0
//  182   temp_reg |= MCG_C6_PLLS_MASK | MCG_C6_VDIV(vdiv_val - 24); // write new VDIV and enable PLL
        SUBS     R1,R4,#+24
        ANDS     R1,R1,#0x1F
        ORRS     R1,R1,#0x40
        ORRS     R5,R1,R5
//  183   MCG_C6 = temp_reg; // update MCG_C6
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        STRB     R5,[R1, #+0]
//  184 
//  185   // wait for PLLST status bit to set
//  186   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??pll_init_26
??pll_init_27:
        ADDS     R1,R1,#+1
??pll_init_26:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pll_init_28
//  187   {
//  188     if (MCG_S & MCG_S_PLLST_MASK) break; // jump out early if PLLST sets before loop finishes
        LDR.W    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??pll_init_27
//  189   }
//  190   if (!(MCG_S & MCG_S_PLLST_MASK)) return 0x16; // check bit is really set and return with error if not set
??pll_init_28:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??pll_init_29
        MOVS     R0,#+22
        B.N      ??pll_init_2
//  191 
//  192   // Wait for LOCK bit to set
//  193   for (i = 0 ; i < 2000 ; i++)
??pll_init_29:
        MOVS     R1,#+0
        B.N      ??pll_init_30
??pll_init_31:
        ADDS     R1,R1,#+1
??pll_init_30:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pll_init_32
//  194   {
//  195     if (MCG_S & MCG_S_LOCK_MASK) break; // jump out early if LOCK sets before loop finishes
        LDR.W    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+25
        BPL.N    ??pll_init_31
//  196   }
//  197   if (!(MCG_S & MCG_S_LOCK_MASK)) return 0x44; // check bit is really set and return with error if not set
??pll_init_32:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+25
        BMI.N    ??pll_init_33
        MOVS     R0,#+68
        B.N      ??pll_init_2
//  198 
//  199   // Use actual PLL settings to calculate PLL frequency
//  200   prdiv = ((MCG_C5 & MCG_C5_PRDIV_MASK) + 1);
??pll_init_33:
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0x1F
        ADDS     R2,R1,#+1
//  201   vdiv = ((MCG_C6 & MCG_C6_VDIV_MASK) + 24);
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0x1F
        ADDS     R3,R1,#+24
//  202 
//  203   // now in PBE
//  204 
//  205   MCG_C1 &= ~MCG_C1_CLKS_MASK; // clear CLKS to switch CLKS mux to select PLL as MCG_OUT
        LDR.W    R1,??DataTable13_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0x3F
        LDR.W    R4,??DataTable13_6  ;; 0x40064000
        STRB     R1,[R4, #+0]
//  206 
//  207   // Wait for clock status bits to update
//  208   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??pll_init_34
??pll_init_35:
        ADDS     R1,R1,#+1
??pll_init_34:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pll_init_36
//  209   {
//  210     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x3) break; // jump out early if CLKST = 3 before loop finishes
        LDR.W    R4,??DataTable13  ;; 0x40064006
        LDRB     R4,[R4, #+0]
        UBFX     R4,R4,#+2,#+2
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+3
        BNE.N    ??pll_init_35
//  211   }
//  212   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3) return 0x1B; // check CLKST is set correctly and return with error if not
??pll_init_36:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+3
        BEQ.N    ??pll_init_37
        MOVS     R0,#+27
        B.N      ??pll_init_2
//  213 
//  214   // Now in PEE
//  215   
//  216   return ((crystal_val / prdiv) * vdiv); //MCGOUT equals PLL output frequency
??pll_init_37:
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        SDIV     R0,R0,R2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        MULS     R0,R3,R0
??pll_init_2:
        POP      {R4-R6}
        BX       LR               ;; return
//  217 } // pll_init
//  218 
//  219 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  220 unsigned char fll_rtc_init(unsigned char clk_option, unsigned char crystal_val)
//  221 {
fll_rtc_init:
        PUSH     {R7,LR}
//  222   unsigned char pll_freq;
//  223 
//  224   rtc_as_refclk();
        BL       rtc_as_refclk
//  225   pll_freq = 24;
        MOVS     R0,#+24
//  226   return pll_freq;
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        POP      {R1,PC}          ;; return
//  227 }
//  228 
//  229 
//  230 
//  231 
//  232 
//  233 /********************************************************************/
//  234 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  235 int pee_pbe(int crystal_val)
//  236 {
//  237   short i;
//  238   
//  239 // Check MCG is in PEE mode
//  240   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x3) && // check CLKS mux has selcted PLL output
//  241       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  242       (MCG_S & MCG_S_PLLST_MASK)))                                    // check PLLS mux has selected PLL 
pee_pbe:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+3
        BNE.N    ??pee_pbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??pee_pbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??pee_pbe_1
//  243   {
//  244     return 0x8;                                                       // return error code
??pee_pbe_0:
        MOVS     R0,#+8
        B.N      ??pee_pbe_2
//  245   } 
//  246   
//  247 // As we are running from the PLL by default the PLL and external clock settings are valid
//  248 // To move to PBE from PEE simply requires the switching of the CLKS mux to select the ext clock 
//  249 // As CLKS is already 0 the CLKS value can simply be OR'ed into the register 
//  250   MCG_C1 |= MCG_C1_CLKS(2); // switch CLKS mux to select external reference clock as MCG_OUT
??pee_pbe_1:
        LDR.W    R1,??DataTable13_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x80
        LDR.W    R2,??DataTable13_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
//  251   
//  252 // Wait for clock status bits to update 
//  253   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??pee_pbe_3
??pee_pbe_4:
        ADDS     R1,R1,#+1
??pee_pbe_3:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pee_pbe_5
//  254   {
//  255     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??pee_pbe_4
//  256   }
//  257   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
??pee_pbe_5:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BEQ.N    ??pee_pbe_6
        MOVS     R0,#+26
        B.N      ??pee_pbe_2
//  258 
//  259 // Now in PBE mode  
//  260   return crystal_val; // MCGOUT frequency equals external clock frequency
??pee_pbe_6:
??pee_pbe_2:
        BX       LR               ;; return
//  261 } // pee_pbe
//  262 
//  263 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  264 int pbe_pee(int crystal_val)
//  265 {
pbe_pee:
        PUSH     {R4}
//  266   unsigned char prdiv, vdiv;
//  267   short i;
//  268 
//  269   // Check MCG is in PBE mode
//  270   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  271       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  272       (MCG_S & MCG_S_PLLST_MASK) &&                                   // check PLLS mux has selected PLL
//  273       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??pbe_pee_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??pbe_pee_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??pbe_pee_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??pbe_pee_1
//  274   {
//  275     return 0x7;                                                       // return error code
??pbe_pee_0:
        MOVS     R0,#+7
        B.N      ??pbe_pee_2
//  276   }
//  277 
//  278   // As the PLL settings have already been checked when PBE mode was enterred they are not checked here
//  279 
//  280   // Check the PLL state before transitioning to PEE mode
//  281   
//  282   // Check LOCK bit is set before transitioning MCG to PLL output (already checked in fbe_pbe but good practice
//  283   // to re-check before switch to use PLL)
//  284   for (i = 0 ; i < 2000 ; i++)
??pbe_pee_1:
        MOVS     R3,#+0
        B.N      ??pbe_pee_3
??pbe_pee_4:
        ADDS     R3,R3,#+1
??pbe_pee_3:
        SXTH     R3,R3            ;; SignExt  R3,R3,#+16,#+16
        CMP      R3,#+2000
        BGE.N    ??pbe_pee_5
//  285   {
//  286     if (MCG_S & MCG_S_LOCK_MASK) break; // jump out early if LOCK sets before loop finishes
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+25
        BPL.N    ??pbe_pee_4
//  287   }
//  288   if (!(MCG_S & MCG_S_LOCK_MASK)) return 0x44; // check bit is really set and return with error if not set
??pbe_pee_5:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+25
        BMI.N    ??pbe_pee_6
        MOVS     R0,#+68
        B.N      ??pbe_pee_2
//  289   // Use actual PLL settings to calculate PLL frequency
//  290   prdiv = ((MCG_C5 & MCG_C5_PRDIV_MASK) + 1);
??pbe_pee_6:
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0x1F
        ADDS     R1,R1,#+1
//  291   vdiv = ((MCG_C6 & MCG_C6_VDIV_MASK) + 24);
        LDR.W    R2,??DataTable13_7  ;; 0x40064005
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0x1F
        ADDS     R2,R2,#+24
//  292   
//  293   MCG_C1 &= ~MCG_C1_CLKS_MASK; // clear CLKS to switch CLKS mux to select PLL as MCG_OUT
        LDR.W    R3,??DataTable13_6  ;; 0x40064000
        LDRB     R3,[R3, #+0]
        ANDS     R3,R3,#0x3F
        LDR.W    R4,??DataTable13_6  ;; 0x40064000
        STRB     R3,[R4, #+0]
//  294 
//  295   // Wait for clock status bits to update
//  296   for (i = 0 ; i < 2000 ; i++)
        MOVS     R3,#+0
        B.N      ??pbe_pee_7
??pbe_pee_8:
        ADDS     R3,R3,#+1
??pbe_pee_7:
        SXTH     R3,R3            ;; SignExt  R3,R3,#+16,#+16
        CMP      R3,#+2000
        BGE.N    ??pbe_pee_9
//  297   {
//  298     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x3) break; // jump out early if CLKST = 3 before loop finishes
        LDR.W    R4,??DataTable16  ;; 0x40064006
        LDRB     R4,[R4, #+0]
        UBFX     R4,R4,#+2,#+2
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+3
        BNE.N    ??pbe_pee_8
//  299   }
//  300   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3) return 0x1B; // check CLKST is set correctly and return with error if not
??pbe_pee_9:
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+3
        BEQ.N    ??pbe_pee_10
        MOVS     R0,#+27
        B.N      ??pbe_pee_2
//  301 
//  302   // Now in PEE
//  303   return ((crystal_val / prdiv) * vdiv); //MCGOUT equals PLL output frequency
??pbe_pee_10:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        MULS     R0,R2,R0
??pbe_pee_2:
        POP      {R4}
        BX       LR               ;; return
//  304   
//  305 }  // pbe_pee
//  306 
//  307 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  308 int pbe_fbe(int crystal_val)
//  309 {
//  310   short i;
//  311   
//  312 // Check MCG is in PBE mode
//  313   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  314       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  315       (MCG_S & MCG_S_PLLST_MASK) &&                                   // check PLLS mux has selected PLL
//  316       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
pbe_fbe:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??pbe_fbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??pbe_fbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??pbe_fbe_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??pbe_fbe_1
//  317   {
//  318     return 0x7;                                                       // return error code
??pbe_fbe_0:
        MOVS     R0,#+7
        B.N      ??pbe_fbe_2
//  319   }
//  320 
//  321 // As we are running from the ext clock, by default the external clock settings are valid
//  322 // To move to FBE from PBE simply requires the switching of the PLLS mux to disable the PLL 
//  323   
//  324   MCG_C6 &= ~MCG_C6_PLLS_MASK; // clear PLLS to disable PLL, still clocked from ext ref clk
??pbe_fbe_1:
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xBF
        LDR.W    R2,??DataTable13_7  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  325   
//  326 // wait for PLLST status bit to set
//  327   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??pbe_fbe_3
??pbe_fbe_4:
        ADDS     R1,R1,#+1
??pbe_fbe_3:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??pbe_fbe_5
//  328   {
//  329     if (!(MCG_S & MCG_S_PLLST_MASK)) break; // jump out early if PLLST clears before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??pbe_fbe_4
//  330   }
//  331   if (MCG_S & MCG_S_PLLST_MASK) return 0x15; // check bit is really clear and return with error if not clear  
??pbe_fbe_5:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??pbe_fbe_6
        MOVS     R0,#+21
        B.N      ??pbe_fbe_2
//  332 
//  333 // Now in FBE mode  
//  334   return crystal_val; // MCGOUT frequency equals external clock frequency 
??pbe_fbe_6:
??pbe_fbe_2:
        BX       LR               ;; return
//  335 } // pbe_fbe
//  336 
//  337 
//  338 /********************************************************************/
//  339 /* Functon name : fbe_pbe
//  340  *
//  341  * Mode transition: FBE to PBE mode
//  342  *
//  343  * This function transitions the MCG from FBE mode to PBE mode. 
//  344  * This function presently only supports OSC0 and PLL0. Support for OSC1 and PLL1 will be added soon 
//  345  * The function requires the desired OSC and PLL be passed in to it for compatibility with the
//  346  * future support of OSC/PLL selection
//  347  *
//  348  * Parameters: crystal_val - external clock frequency in Hz
//  349  *             prdiv_val   - value to divide the external clock source by to create the desired
//  350  *                           PLL reference clock frequency
//  351  *             vdiv_val    - value to multiply the PLL reference clock frequency by
//  352  *
//  353  * Return value : MCGCLKOUT frequency (Hz) or error code
//  354  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  355 int fbe_pbe(int crystal_val, signed char prdiv_val, signed char vdiv_val)
//  356 {
fbe_pbe:
        PUSH     {R4}
//  357   unsigned char temp_reg;
//  358   short i;
//  359   int pll_freq;
//  360   
//  361 // Check MCG is in FBE mode
//  362   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  363       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  364       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  365       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+2
        BNE.N    ??fbe_pbe_0
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BMI.N    ??fbe_pbe_0
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+26
        BMI.N    ??fbe_pbe_0
        LDR.W    R3,??DataTable12_7  ;; 0x40064001
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+30
        BPL.N    ??fbe_pbe_1
//  366   {
//  367     return 0x4;                                                       // return error code
??fbe_pbe_0:
        MOVS     R0,#+4
        B.N      ??fbe_pbe_2
//  368   }
//  369   
//  370 // As the external frequency has already been checked when FBE mode was enterred it is not checked here
//  371 
//  372 // Check PLL divider settings are within spec.
//  373   if ((prdiv_val < 1) || (prdiv_val > 25)) {return 0x41;}
??fbe_pbe_1:
        SUBS     R3,R1,#+1
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+25
        BCC.N    ??fbe_pbe_3
        MOVS     R0,#+65
        B.N      ??fbe_pbe_2
//  374   if ((vdiv_val < 24) || (vdiv_val > 55)) {return 0x42;} 
??fbe_pbe_3:
        SUBS     R3,R2,#+24
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+32
        BCC.N    ??fbe_pbe_4
        MOVS     R0,#+66
        B.N      ??fbe_pbe_2
//  375   
//  376 // Check PLL reference clock frequency is within spec.
//  377   if (((crystal_val / prdiv_val) < 2000000) || ((crystal_val / prdiv_val) > 4000000)) {return 0x43;}
??fbe_pbe_4:
        SXTB     R1,R1            ;; SignExt  R1,R1,#+24,#+24
        SDIV     R3,R0,R1
        LDR.W    R4,??DataTable12_3  ;; 0x1e8480
        SUBS     R3,R3,R4
        LDR.W    R4,??DataTable12_4  ;; 0x1e8481
        CMP      R3,R4
        BCC.N    ??fbe_pbe_5
        MOVS     R0,#+67
        B.N      ??fbe_pbe_2
//  378        
//  379 // Check PLL output frequency is within spec.
//  380   pll_freq = (crystal_val / prdiv_val) * vdiv_val;
??fbe_pbe_5:
        SXTB     R1,R1            ;; SignExt  R1,R1,#+24,#+24
        SDIV     R3,R0,R1
        SXTB     R2,R2            ;; SignExt  R2,R2,#+24,#+24
        MULS     R3,R2,R3
//  381   if ((pll_freq < 48000000) || (pll_freq > 100000000)) {return 0x45;}
        LDR.W    R4,??DataTable12_5  ;; 0x2dc6c00
        SUBS     R3,R3,R4
        LDR.W    R4,??DataTable12_6  ;; 0x3197501
        CMP      R3,R4
        BCC.N    ??fbe_pbe_6
        MOVS     R0,#+69
        B.N      ??fbe_pbe_2
//  382 
//  383   // Configure MCG_C5
//  384   // If the PLL is to run in STOP mode then the PLLSTEN bit needs to be OR'ed in here or in user code.       
//  385   temp_reg = MCG_C5;
??fbe_pbe_6:
        LDR.W    R3,??DataTable13_8  ;; 0x40064004
        LDRB     R3,[R3, #+0]
//  386   temp_reg &= ~MCG_C5_PRDIV_MASK;
        ANDS     R3,R3,#0xE0
//  387   temp_reg |= MCG_C5_PRDIV(prdiv_val - 1);    //set PLL ref divider
        SUBS     R1,R1,#+1
        ANDS     R1,R1,#0x1F
        ORRS     R3,R1,R3
//  388   MCG_C5 = temp_reg;
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        STRB     R3,[R1, #+0]
//  389 
//  390   // Configure MCG_C6
//  391   // The PLLS bit is set to enable the PLL, MCGOUT still sourced from ext ref clk 
//  392   // The clock monitor is not enabled here as it has likely been enabled previously and so the value of CME
//  393   // is not altered here.
//  394   // The loss of lock interrupt can be enabled by seperately OR'ing in the LOLIE bit in MCG_C6
//  395   temp_reg = MCG_C6; // store present C6 value
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R3,[R1, #+0]
//  396   temp_reg &= ~MCG_C6_VDIV_MASK; // clear VDIV settings
        ANDS     R3,R3,#0xE0
//  397   temp_reg |= MCG_C6_PLLS_MASK | MCG_C6_VDIV(vdiv_val - 24); // write new VDIV and enable PLL
        SUBS     R1,R2,#+24
        ANDS     R1,R1,#0x1F
        ORRS     R1,R1,#0x40
        ORRS     R3,R1,R3
//  398   MCG_C6 = temp_reg; // update MCG_C6
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        STRB     R3,[R1, #+0]
//  399   
//  400   // wait for PLLST status bit to set
//  401   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbe_pbe_7
??fbe_pbe_8:
        ADDS     R1,R1,#+1
??fbe_pbe_7:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbe_pbe_9
//  402   {
//  403     if (MCG_S & MCG_S_PLLST_MASK) break; // jump out early if PLLST sets before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??fbe_pbe_8
//  404   }
//  405   if (!(MCG_S & MCG_S_PLLST_MASK)) return 0x16; // check bit is really set and return with error if not set
??fbe_pbe_9:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??fbe_pbe_10
        MOVS     R0,#+22
        B.N      ??fbe_pbe_2
//  406 
//  407   // Wait for LOCK bit to set
//  408   for (i = 0 ; i < 2000 ; i++)
??fbe_pbe_10:
        MOVS     R1,#+0
        B.N      ??fbe_pbe_11
??fbe_pbe_12:
        ADDS     R1,R1,#+1
??fbe_pbe_11:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbe_pbe_13
//  409   {
//  410     if (MCG_S & MCG_S_LOCK_MASK) break; // jump out early if LOCK sets before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+25
        BPL.N    ??fbe_pbe_12
//  411   }
//  412   if (!(MCG_S & MCG_S_LOCK_MASK)) return 0x44; // check bit is really set and return with error if not set
??fbe_pbe_13:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+25
        BMI.N    ??fbe_pbe_14
        MOVS     R0,#+68
        B.N      ??fbe_pbe_2
//  413     
//  414 // now in PBE 
//  415   return crystal_val; // MCGOUT frequency equals external clock frequency
??fbe_pbe_14:
??fbe_pbe_2:
        POP      {R4}
        BX       LR               ;; return
//  416 } // fbe_pbe
//  417 
//  418 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  419 int pbe_blpe(int crystal_val)
//  420 {
//  421 // Check MCG is in PBE mode
//  422   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  423       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  424       (MCG_S & MCG_S_PLLST_MASK) &&                                   // check PLLS mux has selected PLL
//  425       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
pbe_blpe:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??pbe_blpe_0
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??pbe_blpe_0
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??pbe_blpe_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??pbe_blpe_1
//  426   {
//  427     return 0x7;                                                       // return error code
??pbe_blpe_0:
        MOVS     R0,#+7
        B.N      ??pbe_blpe_2
//  428   }
//  429   
//  430 // To enter BLPE mode the LP bit must be set, disabling the PLL  
//  431   MCG_C2 |= MCG_C2_LP_MASK;
??pbe_blpe_1:
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x2
        LDR.W    R2,??DataTable12_7  ;; 0x40064001
        STRB     R1,[R2, #+0]
//  432   
//  433 // Now in BLPE mode
//  434   return crystal_val;  
??pbe_blpe_2:
        BX       LR               ;; return
//  435 } // pbe_blpe
//  436 
//  437 
//  438 // ************************************************************************************************
//  439 // Since PBE mode can be enterred via FBE -> BLPE modes, it cannot be assumed that the PLL has been 
//  440 // previously configured correctly. That is why this general purpose driver has the PLL settings as
//  441 // passed parameters.
//  442 // ************************************************************************************************

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  443 int blpe_pbe(int crystal_val, signed char prdiv_val, signed char vdiv_val)
//  444 {
blpe_pbe:
        PUSH     {R4}
//  445   unsigned char temp_reg;
//  446   short i;
//  447   
//  448 // Check MCG is in BLPE mode
//  449   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  450       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  451       (MCG_C2 & MCG_C2_LP_MASK)))                                     // check MCG_C2[LP] bit is set   
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+2
        BNE.N    ??blpe_pbe_0
        LDR.W    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BMI.N    ??blpe_pbe_0
        LDR.W    R3,??DataTable12_7  ;; 0x40064001
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+30
        BMI.N    ??blpe_pbe_1
//  452   {
//  453     return 0x6;                                                       // return error code
??blpe_pbe_0:
        MOVS     R0,#+6
        B.N      ??blpe_pbe_2
//  454   }
//  455   
//  456 // As the external frequency has already been checked when FBE mode was enterred it is not checked here
//  457 
//  458 // Check PLL divider settings are within spec.
//  459   if ((prdiv_val < 1) || (prdiv_val > 25)) {return 0x41;}
??blpe_pbe_1:
        SUBS     R3,R1,#+1
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+25
        BCC.N    ??blpe_pbe_3
        MOVS     R0,#+65
        B.N      ??blpe_pbe_2
//  460   if ((vdiv_val < 24) || (vdiv_val > 55)) {return 0x42;} 
??blpe_pbe_3:
        SUBS     R3,R2,#+24
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+32
        BCC.N    ??blpe_pbe_4
        MOVS     R0,#+66
        B.N      ??blpe_pbe_2
//  461   
//  462 // Check PLL reference clock frequency is within spec.
//  463   if (((crystal_val / prdiv_val) < 2000000) || ((crystal_val / prdiv_val) > 4000000)) {return 0x43;}
??blpe_pbe_4:
        SXTB     R1,R1            ;; SignExt  R1,R1,#+24,#+24
        SDIV     R3,R0,R1
        LDR.W    R4,??DataTable12_3  ;; 0x1e8480
        SUBS     R3,R3,R4
        LDR.W    R4,??DataTable12_4  ;; 0x1e8481
        CMP      R3,R4
        BCC.N    ??blpe_pbe_5
        MOVS     R0,#+67
        B.N      ??blpe_pbe_2
//  464        
//  465 // If PRDIV, VDIV and the PLL ref clock are in spec. then the PLL frequency is within spec.
//  466 
//  467 // Configure MCG_C5
//  468 // If the PLL is to run in STOP mode then the PLLSTEN bit needs to be OR'ed in here or in user code.       
//  469   temp_reg = MCG_C5;
??blpe_pbe_5:
        LDR.W    R3,??DataTable13_8  ;; 0x40064004
        LDRB     R3,[R3, #+0]
//  470   temp_reg &= ~MCG_C5_PRDIV_MASK;
        ANDS     R3,R3,#0xE0
//  471   temp_reg |= MCG_C5_PRDIV(prdiv_val - 1);    //set PLL ref divider
        SUBS     R1,R1,#+1
        ANDS     R1,R1,#0x1F
        ORRS     R3,R1,R3
//  472   MCG_C5 = temp_reg;
        LDR.W    R1,??DataTable13_8  ;; 0x40064004
        STRB     R3,[R1, #+0]
//  473 
//  474 // Configure MCG_C6
//  475 // The PLLS bit is set to enable the PLL, MCGOUT still sourced from ext ref clk 
//  476 // The clock monitor is not enabled here as it has likely been enabled previously and so the value of CME
//  477 // is not altered here.
//  478 // The loss of lock interrupt can be enabled by seperately OR'ing in the LOLIE bit in MCG_C6
//  479   temp_reg = MCG_C6; // store present C6 value
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R3,[R1, #+0]
//  480   temp_reg &= ~MCG_C6_VDIV_MASK; // clear VDIV settings
        ANDS     R3,R3,#0xE0
//  481   temp_reg |= MCG_C6_PLLS_MASK | MCG_C6_VDIV(vdiv_val - 24); // write new VDIV and enable PLL
        SUBS     R1,R2,#+24
        ANDS     R1,R1,#0x1F
        ORRS     R1,R1,#0x40
        ORRS     R3,R1,R3
//  482   MCG_C6 = temp_reg; // update MCG_C6
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        STRB     R3,[R1, #+0]
//  483   
//  484 // Now that PLL is configured, LP is cleared to enable the PLL
//  485   MCG_C2 &= ~MCG_C2_LP_MASK;
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xFD
        LDR.W    R2,??DataTable12_7  ;; 0x40064001
        STRB     R1,[R2, #+0]
//  486   
//  487 // wait for PLLST status bit to set
//  488   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??blpe_pbe_6
??blpe_pbe_7:
        ADDS     R1,R1,#+1
??blpe_pbe_6:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??blpe_pbe_8
//  489   {
//  490     if (MCG_S & MCG_S_PLLST_MASK) break; // jump out early if PLLST sets before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??blpe_pbe_7
//  491   }
//  492   if (!(MCG_S & MCG_S_PLLST_MASK)) return 0x16; // check bit is really set and return with error if not set
??blpe_pbe_8:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??blpe_pbe_9
        MOVS     R0,#+22
        B.N      ??blpe_pbe_2
//  493 
//  494 // Wait for LOCK bit to set
//  495   for (i = 0 ; i < 2000 ; i++)
??blpe_pbe_9:
        MOVS     R1,#+0
        B.N      ??blpe_pbe_10
??blpe_pbe_11:
        ADDS     R1,R1,#+1
??blpe_pbe_10:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??blpe_pbe_12
//  496   {
//  497     if (MCG_S & MCG_S_LOCK_MASK) break; // jump out early if LOCK sets before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+25
        BPL.N    ??blpe_pbe_11
//  498   }
//  499   if (!(MCG_S & MCG_S_LOCK_MASK)) return 0x44; // check bit is really set and return with error if not set
??blpe_pbe_12:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+25
        BMI.N    ??blpe_pbe_13
        MOVS     R0,#+68
        B.N      ??blpe_pbe_2
//  500 
//  501 // now in PBE 
//  502   return crystal_val; // MCGOUT frequency equals external clock frequency  
??blpe_pbe_13:
??blpe_pbe_2:
        POP      {R4}
        BX       LR               ;; return
//  503 } // blpe_pbe
//  504 
//  505 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  506 int blpe_fbe(int crystal_val)
//  507 {
//  508   short i;
//  509   
//  510 // Check MCG is in BLPE mode
//  511   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  512       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  513       (MCG_C2 & MCG_C2_LP_MASK)))                                     // check MCG_C2[LP] bit is set   
blpe_fbe:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??blpe_fbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??blpe_fbe_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??blpe_fbe_1
//  514   {
//  515     return 0x6;                                                       // return error code
??blpe_fbe_0:
        MOVS     R0,#+6
        B.N      ??blpe_fbe_2
//  516   }
//  517  
//  518 // To move from BLPE to FBE the PLLS mux be set to select the FLL output and the LP bit must be cleared
//  519   MCG_C6 &= ~MCG_C6_PLLS_MASK; // clear PLLS to select the FLL
??blpe_fbe_1:
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xBF
        LDR.W    R2,??DataTable13_7  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  520   MCG_C2 &= ~MCG_C2_LP_MASK; // clear LP bit  
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xFD
        LDR.W    R2,??DataTable12_7  ;; 0x40064001
        STRB     R1,[R2, #+0]
//  521 
//  522 // wait for PLLST status bit to set
//  523   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??blpe_fbe_3
??blpe_fbe_4:
        ADDS     R1,R1,#+1
??blpe_fbe_3:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??blpe_fbe_5
//  524   {
//  525     if (!(MCG_S & MCG_S_PLLST_MASK)) break; // jump out early if PLLST clears before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??blpe_fbe_4
//  526   }
//  527   if (MCG_S & MCG_S_PLLST_MASK) return 0x15; // check bit is really clear and return with error if not clear  
??blpe_fbe_5:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??blpe_fbe_6
        MOVS     R0,#+21
        B.N      ??blpe_fbe_2
//  528   
//  529 // now in FBE mode
//  530   return crystal_val; // MCGOUT frequency equals external clock frequency     
??blpe_fbe_6:
??blpe_fbe_2:
        BX       LR               ;; return
//  531 } // blpe_fbe
//  532 
//  533 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  534 int fbe_blpe(int crystal_val)
//  535 {
//  536 // Check MCG is in FBE mode
//  537   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  538       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  539       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  540       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
fbe_blpe:
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??fbe_blpe_0
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fbe_blpe_0
        LDR.W    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??fbe_blpe_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??fbe_blpe_1
//  541   {
//  542     return 0x4;                                                       // return error code
??fbe_blpe_0:
        MOVS     R0,#+4
        B.N      ??fbe_blpe_2
//  543   }
//  544  
//  545 // To move from FBE to BLPE the LP bit must be set
//  546   MCG_C2 |= MCG_C2_LP_MASK; // set LP bit  
??fbe_blpe_1:
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x2
        LDR.W    R2,??DataTable12_7  ;; 0x40064001
        STRB     R1,[R2, #+0]
//  547  
//  548 // now in FBE mode
//  549   return crystal_val; // MCGOUT frequency equals external clock frequency     
??fbe_blpe_2:
        BX       LR               ;; return
//  550 } // fbe_blpe
//  551 
//  552 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  553 int fbe_fei(int slow_irc_freq)
//  554 {
fbe_fei:
        PUSH     {R7,LR}
//  555   unsigned char temp_reg;
//  556   short i;
//  557   int mcg_out;
//  558   
//  559 // Check MCG is in FBE mode
//  560   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  561       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  562       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  563       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??fbe_fei_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fbe_fei_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??fbe_fei_0
        LDR.W    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??fbe_fei_1
//  564   {
//  565     return 0x4;                                                       // return error code
??fbe_fei_0:
        MOVS     R0,#+4
        B.N      ??fbe_fei_2
//  566   }
//  567 
//  568 // Check IRC frequency is within spec.
//  569   if ((slow_irc_freq < 31250) || (slow_irc_freq > 39063))
??fbe_fei_1:
        MOVW     R1,#+31250
        SUBS     R1,R0,R1
        MOVW     R2,#+7814
        CMP      R1,R2
        BCC.N    ??fbe_fei_3
//  570   {
//  571     return 0x31;
        MOVS     R0,#+49
        B.N      ??fbe_fei_2
//  572   }
//  573   
//  574 // Check resulting FLL frequency 
//  575   mcg_out = fll_freq(slow_irc_freq); 
??fbe_fei_3:
        BL       fll_freq
//  576   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fbe_fei_2
//  577 
//  578 // Need to make sure the clockmonitor is disabled before moving to an "internal" clock mode
//  579   MCG_C6 &= ~MCG_C6_CME_MASK; //This assumes OSC0 is used as the external clock source
??fbe_fei_4:
        LDR.W    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xDF
        LDR.W    R2,??DataTable13_7  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  580   
//  581 // Move to FEI by setting CLKS to 0 and enabling the slow IRC as the FLL reference clock
//  582   temp_reg = MCG_C1;
        LDR.W    R1,??DataTable13_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
//  583   temp_reg &= ~MCG_C1_CLKS_MASK; // clear CLKS to select FLL output
        ANDS     R1,R1,#0x3F
//  584   temp_reg |= MCG_C1_IREFS_MASK; // select internal reference clock
        ORRS     R1,R1,#0x4
//  585   MCG_C1 = temp_reg; // update MCG_C1 
        LDR.W    R2,??DataTable13_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
//  586   
//  587 // wait for Reference clock Status bit to set
//  588   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbe_fei_5
??fbe_fei_6:
        ADDS     R1,R1,#+1
??fbe_fei_5:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbe_fei_7
//  589   {
//  590     if (MCG_S & MCG_S_IREFST_MASK) break; // jump out early if IREFST sets before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fbe_fei_6
//  591   }
//  592   if (!(MCG_S & MCG_S_IREFST_MASK)) return 0x12; // check bit is really set and return with error if not set
??fbe_fei_7:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fbe_fei_8
        MOVS     R0,#+18
        B.N      ??fbe_fei_2
//  593   
//  594 // Wait for clock status bits to show clock source is ext ref clk
//  595   for (i = 0 ; i < 2000 ; i++)
??fbe_fei_8:
        MOVS     R1,#+0
        B.N      ??fbe_fei_9
??fbe_fei_10:
        ADDS     R1,R1,#+1
??fbe_fei_9:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbe_fei_11
//  596   {
//  597     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fbe_fei_10
//  598   }
//  599   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0) return 0x18; // check EXT CLK is really selected and return with error if not
??fbe_fei_11:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbe_fei_12
        MOVS     R0,#+24
        B.N      ??fbe_fei_2
//  600 
//  601 // Now in FEI mode
//  602   return mcg_out;
??fbe_fei_12:
??fbe_fei_2:
        POP      {R1,PC}          ;; return
//  603 } // fbe_fei
//  604 
//  605 
//  606 /********************************************************************/
//  607 /* Functon name : fei_fbe
//  608  *
//  609  * Mode transition: FEI to FBE mode
//  610  *
//  611  * This function transitions the MCG from FEI mode to FBE mode. This is
//  612  * achieved by setting the MCG_C2[LP] bit. There is no status bit to 
//  613  * check so 0 is always returned if the function was called with the MCG
//  614  * in FBI mode. The MCGCLKOUT frequency does not change
//  615  *
//  616  * Parameters: crystal_val - external clock frequency in Hz
//  617  *             hgo_val     - selects whether low power or high gain mode is selected
//  618  *                           for the crystal oscillator. This has no meaning if an 
//  619  *                           external clock is used.
//  620  *             erefs_val   - selects external clock (=0) or crystal osc (=1)
//  621  *
//  622  * Return value : MCGCLKOUT frequency (Hz) or error code
//  623  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  624 int fei_fbe(int crystal_val, unsigned char hgo_val, unsigned char erefs_val)
//  625 {
fei_fbe:
        PUSH     {R4}
//  626   unsigned char frdiv_val;
//  627   unsigned char temp_reg;
//  628   short i;
//  629   
//  630 // check if in FEI mode
//  631   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
//  632       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
//  633       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
        LDR.W    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+0
        BNE.N    ??fei_fbe_0
        LDR.W    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BPL.N    ??fei_fbe_0
        LDR.W    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+26
        BPL.N    ??fei_fbe_1
//  634   {
//  635     return 0x1;                                                     // return error code
??fei_fbe_0:
        MOVS     R0,#+1
        B.N      ??fei_fbe_2
//  636   }
//  637 
//  638 // check external frequency is less than the maximum frequency
//  639   if  (crystal_val > 60000000) {return 0x21;}
??fei_fbe_1:
        LDR.W    R3,??DataTable19  ;; 0x3938701
        CMP      R0,R3
        BLT.N    ??fei_fbe_3
        MOVS     R0,#+33
        B.N      ??fei_fbe_2
//  640   
//  641 // check crystal frequency is within spec. if crystal osc is being used
//  642   if (erefs_val)
??fei_fbe_3:
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??fei_fbe_4
//  643   {
//  644     if ((crystal_val < 30000) ||
//  645         ((crystal_val > 40000) && (crystal_val < 3000000)) ||
//  646         (crystal_val > 32000000)) {return 0x22;} // return error if one of the available crystal options is not available
        MOVW     R3,#+30000
        CMP      R0,R3
        BLT.N    ??fei_fbe_5
        MOVW     R3,#+40001
        SUBS     R3,R0,R3
        LDR.W    R4,??DataTable19_1  ;; 0x2d2a7f
        CMP      R3,R4
        BCC.N    ??fei_fbe_5
        LDR.W    R3,??DataTable19_2  ;; 0x1e84801
        CMP      R0,R3
        BLT.N    ??fei_fbe_4
??fei_fbe_5:
        MOVS     R0,#+34
        B.N      ??fei_fbe_2
//  647   }
//  648 
//  649 // make sure HGO will never be greater than 1. Could return an error instead if desired.  
//  650   if (hgo_val > 0)
??fei_fbe_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BCC.N    ??fei_fbe_6
//  651   {
//  652     hgo_val = 1; // force hgo_val to 1 if > 0
        MOVS     R1,#+1
//  653   }
//  654 
//  655 // configure the MCG_C2 register
//  656 // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
//  657 // it still needs to be set correctly even if the oscillator is not being used
//  658   temp_reg = MCG_C2;
??fei_fbe_6:
        LDR.N    R3,??DataTable12_7  ;; 0x40064001
        LDRB     R3,[R3, #+0]
//  659   temp_reg &= ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); // clear fields before writing new values
        ANDS     R3,R3,#0xC3
//  660   if (crystal_val <= 40000)
        MOVW     R4,#+40001
        CMP      R0,R4
        BGE.N    ??fei_fbe_7
//  661   {
//  662     temp_reg |= (MCG_C2_RANGE(0) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R3,R1,R3
        B.N      ??fei_fbe_8
//  663   }
//  664   else if (crystal_val <= 8000000)
??fei_fbe_7:
        LDR.W    R4,??DataTable19_3  ;; 0x7a1201
        CMP      R0,R4
        BGE.N    ??fei_fbe_9
//  665   {
//  666     temp_reg |= (MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R1,R1,#0x10
        ORRS     R3,R1,R3
        B.N      ??fei_fbe_8
//  667   }
//  668   else
//  669   {
//  670     temp_reg |= (MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
??fei_fbe_9:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R1,R1,#0x20
        ORRS     R3,R1,R3
//  671   }
//  672   MCG_C2 = temp_reg;
??fei_fbe_8:
        LDR.N    R1,??DataTable12_7  ;; 0x40064001
        STRB     R3,[R1, #+0]
//  673 // determine FRDIV based on reference clock frequency
//  674 // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
//  675   if (crystal_val <= 1250000) {frdiv_val = 0;}
        LDR.W    R1,??DataTable13_1  ;; 0x1312d1
        CMP      R0,R1
        BGE.N    ??fei_fbe_10
        MOVS     R1,#+0
        B.N      ??fei_fbe_11
//  676   else if (crystal_val <= 2500000) {frdiv_val = 1;}
??fei_fbe_10:
        LDR.W    R1,??DataTable13_2  ;; 0x2625a1
        CMP      R0,R1
        BGE.N    ??fei_fbe_12
        MOVS     R1,#+1
        B.N      ??fei_fbe_11
//  677   else if (crystal_val <= 5000000) {frdiv_val = 2;}
??fei_fbe_12:
        LDR.W    R1,??DataTable13_3  ;; 0x4c4b41
        CMP      R0,R1
        BGE.N    ??fei_fbe_13
        MOVS     R1,#+2
        B.N      ??fei_fbe_11
//  678   else if (crystal_val <= 10000000) {frdiv_val = 3;}
??fei_fbe_13:
        LDR.W    R1,??DataTable13_4  ;; 0x989681
        CMP      R0,R1
        BGE.N    ??fei_fbe_14
        MOVS     R1,#+3
        B.N      ??fei_fbe_11
//  679   else if (crystal_val <= 20000000) {frdiv_val = 4;}
??fei_fbe_14:
        LDR.W    R1,??DataTable13_5  ;; 0x1312d01
        CMP      R0,R1
        BGE.N    ??fei_fbe_15
        MOVS     R1,#+4
        B.N      ??fei_fbe_11
//  680   else {frdiv_val = 5;}
??fei_fbe_15:
        MOVS     R1,#+5
//  681   
//  682 // Select external oscilator and Reference Divider and clear IREFS to start ext osc
//  683 // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
//  684 // CLKS=2, FRDIV=frdiv_val, IREFS=0, IRCLKEN=0, IREFSTEN=0
//  685   temp_reg = MCG_C1;
??fei_fbe_11:
        LDR.W    R3,??DataTable13_6  ;; 0x40064000
        LDRB     R3,[R3, #+0]
//  686   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear values in these fields
        ANDS     R3,R3,#0x3
//  687   temp_reg = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
        LSLS     R1,R1,#+3
        ANDS     R1,R1,#0x38
        ORRS     R1,R1,#0x80
        MOVS     R3,R1
//  688   MCG_C1 = temp_reg;
        LDR.W    R1,??DataTable13_6  ;; 0x40064000
        STRB     R3,[R1, #+0]
//  689 
//  690 // if the external oscillator is used need to wait for OSCINIT to set
//  691   if (erefs_val)
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??fei_fbe_16
//  692   {
//  693     for (i = 0 ; i < 10000 ; i++)
        MOVS     R1,#+0
        B.N      ??fei_fbe_17
??fei_fbe_18:
        ADDS     R1,R1,#+1
??fei_fbe_17:
        MOVW     R2,#+10000
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,R2
        BGE.N    ??fei_fbe_19
//  694     {
//  695       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fei_fbe_18
//  696     }
//  697     if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
??fei_fbe_19:
        LDR.N    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??fei_fbe_16
        MOVS     R0,#+35
        B.N      ??fei_fbe_2
//  698   }
//  699 
//  700 // wait for Reference clock Status bit to clear
//  701   for (i = 0 ; i < 2000 ; i++)
??fei_fbe_16:
        MOVS     R1,#+0
        B.N      ??fei_fbe_20
??fei_fbe_21:
        ADDS     R1,R1,#+1
??fei_fbe_20:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fei_fbe_22
//  702   {
//  703     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fei_fbe_21
//  704   }
//  705   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
??fei_fbe_22:
        LDR.N    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BPL.N    ??fei_fbe_23
        MOVS     R0,#+17
        B.N      ??fei_fbe_2
//  706   
//  707 // Wait for clock status bits to show clock source is ext ref clk
//  708   for (i = 0 ; i < 2000 ; i++)
??fei_fbe_23:
        MOVS     R1,#+0
        B.N      ??fei_fbe_24
??fei_fbe_25:
        ADDS     R1,R1,#+1
??fei_fbe_24:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fei_fbe_26
//  709   {
//  710     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??fei_fbe_25
//  711   }
//  712   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
??fei_fbe_26:
        LDR.N    R1,??DataTable13  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BEQ.N    ??fei_fbe_27
        MOVS     R0,#+26
        B.N      ??fei_fbe_2
//  713  
//  714 // Now in FBE  
//  715 // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
//  716 // It is enabled here but can be removed if this is not required.
//  717   MCG_C6 |= MCG_C6_CME_MASK;
??fei_fbe_27:
        LDR.N    R1,??DataTable13_7  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x20
        LDR.N    R2,??DataTable13_7  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  718   
//  719   return crystal_val; // MCGOUT frequency equals external clock frequency
??fei_fbe_2:
        POP      {R4}
        BX       LR               ;; return
//  720 } // fei_fbe
//  721 
//  722 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  723 int fbe_fee(int crystal_val)
//  724 {
fbe_fee:
        PUSH     {R7,LR}
//  725   short i, fll_ref_freq;
//  726   int mcg_out;
//  727 
//  728 // Check MCG is in FBE mode
//  729   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  730       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  731       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  732       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BNE.N    ??fbe_fee_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fbe_fee_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??fbe_fee_0
        LDR.N    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??fbe_fee_1
//  733   {
//  734     return 0x4;                                                       // return error code
??fbe_fee_0:
        MOVS     R0,#+4
        B.N      ??fbe_fee_2
//  735   }
//  736   
//  737   // The FLL ref clk divide value depends on FRDIV and the RANGE value
//  738   if (((MCG_C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) > 0)
??fbe_fee_1:
        LDR.N    R1,??DataTable12_7  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+4,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbe_fee_3
//  739   {
//  740     fll_ref_freq = (crystal_val / (32 << ((MCG_C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT)));
        MOVS     R1,#+32
        LDR.N    R2,??DataTable13_6  ;; 0x40064000
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+3,#+3
        LSLS     R1,R1,R2
        SDIV     R0,R0,R1
        B.N      ??fbe_fee_4
//  741   }
//  742   else
//  743   {
//  744     fll_ref_freq = ((crystal_val) / (1 << (((MCG_C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT))));
??fbe_fee_3:
        MOVS     R1,#+1
        LDR.N    R2,??DataTable12_7  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+4,#+2
        LSLS     R1,R1,R2
        SDIV     R0,R0,R1
//  745   }
//  746   
//  747 // Check resulting FLL frequency 
//  748   mcg_out = fll_freq(fll_ref_freq); // FLL reference frequency calculated from ext ref freq and FRDIV
??fbe_fee_4:
        SXTH     R0,R0            ;; SignExt  R0,R0,#+16,#+16
        BL       fll_freq
//  749   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fbe_fee_2
//  750   
//  751 // Clear CLKS field to switch CLKS mux to select FLL output
//  752   MCG_C1 &= ~MCG_C1_CLKS_MASK; // clear CLKS to select FLL output
??fbe_fee_5:
        LDR.N    R1,??DataTable13_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0x3F
        LDR.N    R2,??DataTable13_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
//  753 
//  754 // Wait for clock status bits to show clock source is FLL
//  755   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbe_fee_6
??fbe_fee_7:
        ADDS     R1,R1,#+1
??fbe_fee_6:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbe_fee_8
//  756   {
//  757     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) break; // jump out early if CLKST shows FLL selected before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fbe_fee_7
//  758   }
//  759   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0) return 0x18; // check FLL is really selected and return with error if not
??fbe_fee_8:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbe_fee_9
        MOVS     R0,#+24
        B.N      ??fbe_fee_2
//  760   
//  761 // Now in FEE mode
//  762   return mcg_out;
??fbe_fee_9:
??fbe_fee_2:
        POP      {R1,PC}          ;; return
//  763 } // fbe_fee
//  764 
//  765 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  766 int fee_fbe(int crystal_val)
//  767 { 
//  768   short i;
//  769   
//  770 // Check MCG is in FEE mode
//  771   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL
//  772       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  773       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
fee_fbe:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fee_fbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fee_fbe_0
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??fee_fbe_1
//  774   {
//  775     return 0x2;                                                       // return error code
??fee_fbe_0:
        MOVS     R0,#+2
        B.N      ??fee_fbe_2
//  776   }
//  777   
//  778 // Set CLKS field to 2 to switch CLKS mux to select ext ref clock
//  779 // MCG is current in FEE mode so CLKS field = 0 so can just OR in new value
//  780   MCG_C1 |= MCG_C1_CLKS(2); // set CLKS to select ext ref clock
??fee_fbe_1:
        LDR.N    R1,??DataTable13_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x80
        LDR.N    R2,??DataTable13_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
//  781 
//  782 /// Wait for clock status bits to show clock source is ext ref clk
//  783   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fee_fbe_3
??fee_fbe_4:
        ADDS     R1,R1,#+1
??fee_fbe_3:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fee_fbe_5
//  784   {
//  785     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.W    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??fee_fbe_4
//  786   }
//  787   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
??fee_fbe_5:
        LDR.W    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BEQ.N    ??fee_fbe_6
        MOVS     R0,#+26
        B.N      ??fee_fbe_2
//  788   
//  789 // Now in FBE mode
//  790   return crystal_val;
??fee_fbe_6:
??fee_fbe_2:
        BX       LR               ;; return
//  791 } // fee_fbe

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12:
        DC32     0x2faf081

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_1:
        DC32     0x2dc6c0

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_2:
        DC32     0x1ba8141

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_3:
        DC32     0x1e8480

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_4:
        DC32     0x1e8481

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_5:
        DC32     0x2dc6c00

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_6:
        DC32     0x3197501

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_7:
        DC32     0x40064001

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable12_8:
        DC32     0x2dc6c1
//  792 
//  793 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  794 int fbe_fbi(int irc_freq, unsigned char irc_select)
//  795 {
//  796   unsigned char temp_reg;
//  797   unsigned char fcrdiv_val;
//  798   short i;
//  799   
//  800 // Check MCG is in FBE mode
//  801   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
//  802       (!(MCG_S & MCG_S_IREFST_MASK)) &&                               // check FLL ref is external ref clk
//  803       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  804       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check MCG_C2[LP] bit is not set   
fbe_fbi:
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??fbe_fbi_0
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fbe_fbi_0
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??fbe_fbi_0
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fbe_fbi_1
//  805   {
//  806     return 0x4;                                                       // return error code
??fbe_fbi_0:
        MOVS     R0,#+4
        B.N      ??fbe_fbi_2
//  807   }
//  808 
//  809 // Check that the irc frequency matches the selected IRC 
//  810   if (!(irc_select))
??fbe_fbi_1:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fbe_fbi_3
//  811   {    
//  812     if ((irc_freq < 31250) || (irc_freq > 39063)) {return 0x31;}
        MOVW     R2,#+31250
        SUBS     R2,R0,R2
        MOVW     R3,#+7814
        CMP      R2,R3
        BCC.N    ??fbe_fbi_4
        MOVS     R0,#+49
        B.N      ??fbe_fbi_2
//  813   }
//  814   else
//  815   {
//  816     if ((irc_freq < 3000000) || (irc_freq > 5000000)) {return 0x32;} // Fast IRC freq
??fbe_fbi_3:
        LDR.W    R2,??DataTable22_1  ;; 0x2dc6c0
        SUBS     R2,R0,R2
        LDR.W    R3,??DataTable22_2  ;; 0x1e8481
        CMP      R2,R3
        BCC.N    ??fbe_fbi_4
        MOVS     R0,#+50
        B.N      ??fbe_fbi_2
//  817   }
//  818   
//  819 // Select the required IRC
//  820   if (irc_select)
??fbe_fbi_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbe_fbi_5
//  821   {
//  822     MCG_C2 |= MCG_C2_IRCS_MASK; // select fast IRC by setting IRCS
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ORRS     R2,R2,#0x1
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
        B.N      ??fbe_fbi_6
//  823   }
//  824   else
//  825   {
//  826     MCG_C2 &= ~MCG_C2_IRCS_MASK; // select slow IRC by clearing IRCS
??fbe_fbi_5:
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xFE
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
//  827   }
//  828   
//  829 // Make sure the clock monitor is disabled before switching modes otherwise it will trigger
//  830   MCG_C6 &= ~MCG_C6_CME_MASK;
??fbe_fbi_6:
        LDR.N    R2,??DataTable13_7  ;; 0x40064005
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xDF
        LDR.N    R3,??DataTable13_7  ;; 0x40064005
        STRB     R2,[R3, #+0]
//  831   
//  832 // Select the IRC as the CLKS mux selection
//  833   temp_reg = MCG_C1;
        LDR.N    R2,??DataTable13_6  ;; 0x40064000
        LDRB     R2,[R2, #+0]
//  834   temp_reg &= ~MCG_C1_CLKS_MASK;
        ANDS     R2,R2,#0x3F
//  835   temp_reg |= MCG_C1_CLKS(1) | MCG_C1_IREFS_MASK; // select IRC as MCGOUT and enable IREFS
        ORRS     R2,R2,#0x44
//  836   MCG_C1 = temp_reg; // update MCG_C1
        LDR.N    R3,??DataTable13_6  ;; 0x40064000
        STRB     R2,[R3, #+0]
//  837   
//  838 // wait until internal reference switches to requested irc.
//  839   if (!(irc_select))
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fbe_fbi_7
//  840   {
//  841     for (i = 0 ; i < 2000 ; i++)
        MOVS     R2,#+0
        B.N      ??fbe_fbi_8
??fbe_fbi_9:
        ADDS     R2,R2,#+1
??fbe_fbi_8:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fbe_fbi_10
//  842     {
//  843       if (!(MCG_S & MCG_S_IRCST_MASK)) break; // jump out early if IRCST clears before loop finishes
        LDR.N    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BMI.N    ??fbe_fbi_9
//  844     }
//  845     if (MCG_S & MCG_S_IRCST_MASK) return 0x13; // check bit is really clear and return with error if set
??fbe_fbi_10:
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BPL.N    ??fbe_fbi_11
        MOVS     R0,#+19
        B.N      ??fbe_fbi_2
//  846   }
//  847   else
//  848   {
//  849     for (i = 0 ; i < 2000 ; i++)
??fbe_fbi_7:
        MOVS     R2,#+0
        B.N      ??fbe_fbi_12
??fbe_fbi_13:
        ADDS     R2,R2,#+1
??fbe_fbi_12:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fbe_fbi_14
//  850     {
//  851       if (MCG_S & MCG_S_IRCST_MASK) break; // jump out early if IRCST sets before loop finishes
        LDR.N    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BPL.N    ??fbe_fbi_13
//  852     }
//  853     if (!(MCG_S & MCG_S_IRCST_MASK)) return 0x14; // check bit is really set and return with error if not set
??fbe_fbi_14:
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BMI.N    ??fbe_fbi_11
        MOVS     R0,#+20
        B.N      ??fbe_fbi_2
//  854   }
//  855  
//  856 // Wait for clock status bits to update
//  857   for (i = 0 ; i < 2000 ; i++)
??fbe_fbi_11:
        MOVS     R2,#+0
        B.N      ??fbe_fbi_15
??fbe_fbi_16:
        ADDS     R2,R2,#+1
??fbe_fbi_15:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fbe_fbi_17
//  858   {
//  859     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) break; // jump out early if CLKST shows IRC slected before loop finishes
        LDR.N    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+1
        BNE.N    ??fbe_fbi_16
//  860   }
//  861   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1) return 0x19; // check IRC is really selected and return with error if not
??fbe_fbi_17:
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BEQ.N    ??fbe_fbi_18
        MOVS     R0,#+25
        B.N      ??fbe_fbi_2
//  862  
//  863 //GPIOC_PSOR = 0x00020000; //set bit 17 of port C  
//  864   // wait for Reference clock Status bit to set
//  865   for (i = 0 ; i < 2000 ; i++)
??fbe_fbi_18:
        MOVS     R2,#+0
        B.N      ??fbe_fbi_19
??fbe_fbi_20:
        ADDS     R2,R2,#+1
??fbe_fbi_19:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fbe_fbi_21
//  866   {
//  867     if (MCG_S & MCG_S_IREFST_MASK) break; // jump out early if IREFST sets before loop finishes
        LDR.N    R3,??DataTable13  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BPL.N    ??fbe_fbi_20
//  868   }
//  869   if (!(MCG_S & MCG_S_IREFST_MASK)) return 0x12; // check bit is really set and return with error if not set
??fbe_fbi_21:
        LDR.N    R2,??DataTable13  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fbe_fbi_22
        MOVS     R0,#+18
        B.N      ??fbe_fbi_2
//  870 //GPIOC_PCOR = 0x00020000; // clear bit 17 of port C   
//  871 // Now in FBI mode
//  872   
//  873   if (irc_select)
??fbe_fbi_22:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbe_fbi_23
//  874   {
//  875     fcrdiv_val = (1 << ((MCG_SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); // calculate the fast IRC divder factor
        MOVS     R1,#+1
        LDR.W    R2,??DataTable23  ;; 0x40064008
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+1,#+3
        LSLS     R1,R1,R2
//  876     return (irc_freq / fcrdiv_val); // MCGOUT frequency equals fast IRC frequency divided by FCRDIV factor
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        B.N      ??fbe_fbi_2
//  877   }
//  878   else
//  879   {
//  880     return irc_freq; // MCGOUT frequency equals slow IRC frequency
??fbe_fbi_23:
??fbe_fbi_2:
        BX       LR               ;; return
//  881   }
//  882 } //fbe_fbi

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13:
        DC32     0x40064006

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_1:
        DC32     0x1312d1

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_2:
        DC32     0x2625a1

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_3:
        DC32     0x4c4b41

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_4:
        DC32     0x989681

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_5:
        DC32     0x1312d01

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_6:
        DC32     0x40064000

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_7:
        DC32     0x40064005

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable13_8:
        DC32     0x40064004
//  883 
//  884 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
//  885 int fbi_fbe(int crystal_val, unsigned char hgo_val, unsigned char erefs_val)
//  886 {
fbi_fbe:
        PUSH     {R4}
//  887   unsigned char temp_reg;
//  888   unsigned char frdiv_val;
//  889   short i;
//  890   
//  891 // check if in FBI mode
//  892   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
//  893       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
//  894       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
//  895       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check LP bit is clear
        LDR.N    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+1
        BNE.N    ??fbi_fbe_0
        LDR.N    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BPL.N    ??fbi_fbe_0
        LDR.N    R3,??DataTable16  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+26
        BMI.N    ??fbi_fbe_0
        LDR.W    R3,??DataTable22  ;; 0x40064001
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+30
        BPL.N    ??fbi_fbe_1
//  896   {  
//  897     return 0x3;                                                       // MCG not in correct mode return fail code 
??fbi_fbe_0:
        MOVS     R0,#+3
        B.N      ??fbi_fbe_2
//  898   }
//  899  
//  900 // check external frequency is less than the maximum frequency
//  901   if  (crystal_val > 60000000) {return 0x21;}
??fbi_fbe_1:
        LDR.W    R3,??DataTable19  ;; 0x3938701
        CMP      R0,R3
        BLT.N    ??fbi_fbe_3
        MOVS     R0,#+33
        B.N      ??fbi_fbe_2
//  902   
//  903 // check crystal frequency is within spec. if crystal osc is being used
//  904   if (erefs_val)
??fbi_fbe_3:
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??fbi_fbe_4
//  905   {
//  906     if ((crystal_val < 30000) ||
//  907         ((crystal_val > 40000) && (crystal_val < 3000000)) ||
//  908         (crystal_val > 32000000)) {return 0x22;} // return error if one of the available crystal options is not available
        MOVW     R3,#+30000
        CMP      R0,R3
        BLT.N    ??fbi_fbe_5
        MOVW     R3,#+40001
        SUBS     R3,R0,R3
        LDR.W    R4,??DataTable19_1  ;; 0x2d2a7f
        CMP      R3,R4
        BCC.N    ??fbi_fbe_5
        LDR.W    R3,??DataTable19_2  ;; 0x1e84801
        CMP      R0,R3
        BLT.N    ??fbi_fbe_4
??fbi_fbe_5:
        MOVS     R0,#+34
        B.N      ??fbi_fbe_2
//  909   }
//  910 
//  911 // make sure HGO will never be greater than 1. Could return an error instead if desired.  
//  912   if (hgo_val > 0)
??fbi_fbe_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BCC.N    ??fbi_fbe_6
//  913   {
//  914     hgo_val = 1; // force hgo_val to 1 if > 0
        MOVS     R1,#+1
//  915   }
//  916 
//  917 // configure the MCG_C2 register
//  918 // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
//  919 // it still needs to be set correctly even if the oscillator is not being used
//  920   temp_reg = MCG_C2;
??fbi_fbe_6:
        LDR.W    R3,??DataTable22  ;; 0x40064001
        LDRB     R3,[R3, #+0]
//  921   temp_reg &= ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); // clear fields before writing new values
        ANDS     R3,R3,#0xC3
//  922   if (crystal_val <= 40000)
        MOVW     R4,#+40001
        CMP      R0,R4
        BGE.N    ??fbi_fbe_7
//  923   {
//  924     temp_reg |= (MCG_C2_RANGE(0) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R3,R1,R3
        B.N      ??fbi_fbe_8
//  925   }
//  926   else if (crystal_val <= 8000000)
??fbi_fbe_7:
        LDR.W    R4,??DataTable19_3  ;; 0x7a1201
        CMP      R0,R4
        BGE.N    ??fbi_fbe_9
//  927   {
//  928     temp_reg |= (MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R1,R1,#0x10
        ORRS     R3,R1,R3
        B.N      ??fbi_fbe_8
//  929   }
//  930   else
//  931   {
//  932     temp_reg |= (MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
??fbi_fbe_9:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSLS     R4,R2,#+2
        ORRS     R1,R4,R1
        ORRS     R1,R1,#0x20
        ORRS     R3,R1,R3
//  933   }
//  934   MCG_C2 = temp_reg;
??fbi_fbe_8:
        LDR.W    R1,??DataTable22  ;; 0x40064001
        STRB     R3,[R1, #+0]
//  935 
//  936 // determine FRDIV based on reference clock frequency
//  937 // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
//  938   if (crystal_val <= 1250000) {frdiv_val = 0;}
        LDR.W    R1,??DataTable23_1  ;; 0x1312d1
        CMP      R0,R1
        BGE.N    ??fbi_fbe_10
        MOVS     R1,#+0
        B.N      ??fbi_fbe_11
//  939   else if (crystal_val <= 2500000) {frdiv_val = 1;}
??fbi_fbe_10:
        LDR.W    R1,??DataTable23_2  ;; 0x2625a1
        CMP      R0,R1
        BGE.N    ??fbi_fbe_12
        MOVS     R1,#+1
        B.N      ??fbi_fbe_11
//  940   else if (crystal_val <= 5000000) {frdiv_val = 2;}
??fbi_fbe_12:
        LDR.W    R1,??DataTable23_3  ;; 0x4c4b41
        CMP      R0,R1
        BGE.N    ??fbi_fbe_13
        MOVS     R1,#+2
        B.N      ??fbi_fbe_11
//  941   else if (crystal_val <= 10000000) {frdiv_val = 3;}
??fbi_fbe_13:
        LDR.W    R1,??DataTable23_4  ;; 0x989681
        CMP      R0,R1
        BGE.N    ??fbi_fbe_14
        MOVS     R1,#+3
        B.N      ??fbi_fbe_11
//  942   else if (crystal_val <= 20000000) {frdiv_val = 4;}
??fbi_fbe_14:
        LDR.W    R1,??DataTable23_5  ;; 0x1312d01
        CMP      R0,R1
        BGE.N    ??fbi_fbe_15
        MOVS     R1,#+4
        B.N      ??fbi_fbe_11
//  943   else {frdiv_val = 5;}
??fbi_fbe_15:
        MOVS     R1,#+5
//  944   
//  945 // Select external oscilator and Reference Divider and clear IREFS to start ext osc
//  946 // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
//  947 // CLKS=2, FRDIV=frdiv_val, IREFS=0, IRCLKEN=0, IREFSTEN=0
//  948   temp_reg = MCG_C1;
??fbi_fbe_11:
        LDR.W    R3,??DataTable23_6  ;; 0x40064000
        LDRB     R3,[R3, #+0]
//  949   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear values in these fields
        ANDS     R3,R3,#0x3
//  950   temp_reg = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
        LSLS     R1,R1,#+3
        ANDS     R1,R1,#0x38
        ORRS     R1,R1,#0x80
        MOVS     R3,R1
//  951   MCG_C1 = temp_reg;
        LDR.W    R1,??DataTable23_6  ;; 0x40064000
        STRB     R3,[R1, #+0]
//  952 
//  953 // if the external oscillator is used need to wait for OSCINIT to set
//  954   if (erefs_val)
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BEQ.N    ??fbi_fbe_16
//  955   {
//  956     for (i = 0 ; i < 10000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbi_fbe_17
??fbi_fbe_18:
        ADDS     R1,R1,#+1
??fbi_fbe_17:
        MOVW     R2,#+10000
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,R2
        BGE.N    ??fbi_fbe_19
//  957     {
//  958       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fbi_fbe_18
//  959     }
//  960     if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
??fbi_fbe_19:
        LDR.N    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??fbi_fbe_16
        MOVS     R0,#+35
        B.N      ??fbi_fbe_2
//  961   }
//  962 
//  963 // wait for Reference clock Status bit to clear
//  964   for (i = 0 ; i < 2000 ; i++)
??fbi_fbe_16:
        MOVS     R1,#+0
        B.N      ??fbi_fbe_20
??fbi_fbe_21:
        ADDS     R1,R1,#+1
??fbi_fbe_20:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fbe_22
//  965   {
//  966     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fbi_fbe_21
//  967   }
//  968   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
??fbi_fbe_22:
        LDR.N    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BPL.N    ??fbi_fbe_23
        MOVS     R0,#+17
        B.N      ??fbi_fbe_2
//  969   
//  970 // Wait for clock status bits to show clock source is ext ref clk
//  971   for (i = 0 ; i < 2000 ; i++)
??fbi_fbe_23:
        MOVS     R1,#+0
        B.N      ??fbi_fbe_24
??fbi_fbe_25:
        ADDS     R1,R1,#+1
??fbi_fbe_24:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fbe_26
//  972   {
//  973     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+2
        BNE.N    ??fbi_fbe_25
//  974   }
//  975   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
??fbi_fbe_26:
        LDR.N    R1,??DataTable16  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+2
        BEQ.N    ??fbi_fbe_27
        MOVS     R0,#+26
        B.N      ??fbi_fbe_2
//  976  
//  977 // Now in FBE  
//  978 // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
//  979 // It is enabled here but can be removed if this is not required.
//  980   MCG_C6 |= MCG_C6_CME_MASK;
??fbi_fbe_27:
        LDR.W    R1,??DataTable24  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x20
        LDR.W    R2,??DataTable24  ;; 0x40064005
        STRB     R1,[R2, #+0]
//  981   
//  982   return crystal_val; // MCGOUT frequency equals external clock frequency  
??fbi_fbe_2:
        POP      {R4}
        BX       LR               ;; return
//  983 } // fbi_fbe
//  984 
//  985 
//  986 /********************************************************************/
//  987 /* Functon name : fbi_blpi
//  988  *
//  989  * Mode transition: FBI to BLPI mode
//  990  *
//  991  * This function transitions the MCG from FBI mode to BLPI mode. This is
//  992  * achieved by setting the MCG_C2[LP] bit. There is no status bit to 
//  993  * check so 0 is always returned if the function was called with the MCG
//  994  * in FBI mode. 
//  995  *
//  996  * Parameters: irc_freq - internal reference clock frequency
//  997  *             ircs_select - 0 if slow irc, 1 if fast irc
//  998  *
//  999  * Return value : MCGOUT frequency or error code 0x13
// 1000  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1001 int fbi_blpi(int irc_freq, unsigned char irc_select)
// 1002 {
// 1003   unsigned char fcrdiv_val;
// 1004   
// 1005 // check if in FBI mode
// 1006   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1007       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1008       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
// 1009       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check LP bit is clear
fbi_blpi:
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BNE.N    ??fbi_blpi_0
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fbi_blpi_0
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??fbi_blpi_0
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fbi_blpi_1
// 1010   {  
// 1011     return 0x3;                                                       // MCG not in correct mode return fail code 
??fbi_blpi_0:
        MOVS     R0,#+3
        B.N      ??fbi_blpi_2
// 1012   }
// 1013 
// 1014 // Set LP bit to disable the FLL and enter BLPI
// 1015   MCG_C2 |= MCG_C2_LP_MASK;
??fbi_blpi_1:
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ORRS     R2,R2,#0x2
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
// 1016   
// 1017 // Now in BLPI
// 1018   if (irc_select)
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbi_blpi_3
// 1019   {
// 1020     fcrdiv_val = (1 << ((MCG_SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); // calculate the fast IRC divder factor
        MOVS     R1,#+1
        LDR.W    R2,??DataTable23  ;; 0x40064008
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+1,#+3
        LSLS     R1,R1,R2
// 1021     return (irc_freq / fcrdiv_val); // MCGOUT frequency equals fast IRC frequency divided by 2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        B.N      ??fbi_blpi_2
// 1022   }
// 1023   else
// 1024   {
// 1025     return irc_freq; // MCGOUT frequency equals slow IRC frequency
??fbi_blpi_3:
??fbi_blpi_2:
        BX       LR               ;; return
// 1026   }   
// 1027 } // fbi_blpi
// 1028 
// 1029 
// 1030 
// 1031 /********************************************************************/
// 1032 /* Functon name : blpi_fbi
// 1033  *
// 1034  * Mode transition: BLPI to FBI mode
// 1035  *
// 1036  * This function transitions the MCG from BLPI mode to FBI mode. This is
// 1037  * achieved by clearing the MCG_C2[LP] bit. There is no status bit to 
// 1038  * check so 0 is always returned if the function was called with the MCG
// 1039  * in BLPI mode. 
// 1040  *
// 1041  * Parameters: irc_freq - internal reference clock frequency
// 1042  *             ircs_select - 0 if slow irc, 1 if fast irc
// 1043  *
// 1044  * Return value : MCGOUT frequency or error code 0x15
// 1045  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1046 int blpi_fbi(int irc_freq, unsigned char irc_select)
// 1047 {
// 1048   unsigned char fcrdiv_val;
// 1049   // check if in BLPI mode
// 1050   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1051       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1052       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
// 1053       (MCG_C2 & MCG_C2_LP_MASK)))                                     // check LP bit is set
blpi_fbi:
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BNE.N    ??blpi_fbi_0
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??blpi_fbi_0
        LDR.N    R2,??DataTable16  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??blpi_fbi_0
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BMI.N    ??blpi_fbi_1
// 1054   {
// 1055     return 0x5;                                                       // MCG not in correct mode return fail code
??blpi_fbi_0:
        MOVS     R0,#+5
        B.N      ??blpi_fbi_2
// 1056   }
// 1057 
// 1058 // Clear LP bit to enable the FLL and enter FBI mode   
// 1059   MCG_C2 &= ~MCG_C2_LP_MASK;
??blpi_fbi_1:
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xFD
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
// 1060   
// 1061 // Now in FBI mode
// 1062   if (irc_select)
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??blpi_fbi_3
// 1063   {
// 1064     fcrdiv_val = (1 << ((MCG_SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); // calculate the fast IRC divder factor
        MOVS     R1,#+1
        LDR.W    R2,??DataTable26  ;; 0x40064008
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+1,#+3
        LSLS     R1,R1,R2
// 1065     return (irc_freq / fcrdiv_val); // MCGOUT frequency equals fast IRC frequency divided by 2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        B.N      ??blpi_fbi_2
// 1066   }
// 1067   else
// 1068   {
// 1069     return irc_freq; // MCGOUT frequency equals slow IRC frequency
??blpi_fbi_3:
??blpi_fbi_2:
        BX       LR               ;; return
// 1070   }
// 1071 } // blpi_fbi

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable16:
        DC32     0x40064006
// 1072 
// 1073 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1074 int fbi_fee(int crystal_val, unsigned char hgo_val, unsigned char erefs_val)
// 1075 {
fbi_fee:
        PUSH     {R3-R5,LR}
        MOVS     R4,R2
// 1076   unsigned char temp_reg;
// 1077   unsigned char frdiv_val;
// 1078   short i;
// 1079   int mcg_out, fll_ref_freq;
// 1080 
// 1081 // check if in FBI mode
// 1082   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1083       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1084       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
// 1085       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check LP bit is clear
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BNE.N    ??fbi_fee_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fbi_fee_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BMI.N    ??fbi_fee_0
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fbi_fee_1
// 1086   {  
// 1087     return 0x3;                                                       // MCG not in correct mode return fail code 
??fbi_fee_0:
        MOVS     R0,#+3
        B.N      ??fbi_fee_2
// 1088   }
// 1089   
// 1090 // check external frequency is less than the maximum frequency
// 1091   if  (crystal_val > 60000000) {return 0x21;}
??fbi_fee_1:
        LDR.W    R2,??DataTable19  ;; 0x3938701
        CMP      R0,R2
        BLT.N    ??fbi_fee_3
        MOVS     R0,#+33
        B.N      ??fbi_fee_2
// 1092   
// 1093 // check crystal frequency is within spec. if crystal osc is being used
// 1094   if (erefs_val)
??fbi_fee_3:
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BEQ.N    ??fbi_fee_4
// 1095   {
// 1096     if ((crystal_val < 30000) ||
// 1097         ((crystal_val > 40000) && (crystal_val < 3000000)) ||
// 1098         (crystal_val > 32000000)) {return 0x22;} // return error if one of the available crystal options is not available
        MOVW     R2,#+30000
        CMP      R0,R2
        BLT.N    ??fbi_fee_5
        MOVW     R2,#+40001
        SUBS     R2,R0,R2
        LDR.W    R3,??DataTable19_1  ;; 0x2d2a7f
        CMP      R2,R3
        BCC.N    ??fbi_fee_5
        LDR.W    R2,??DataTable19_2  ;; 0x1e84801
        CMP      R0,R2
        BLT.N    ??fbi_fee_4
??fbi_fee_5:
        MOVS     R0,#+34
        B.N      ??fbi_fee_2
// 1099   }
// 1100 
// 1101 // make sure HGO will never be greater than 1. Could return an error instead if desired.  
// 1102   if (hgo_val > 0)
??fbi_fee_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BCC.N    ??fbi_fee_6
// 1103   {
// 1104     hgo_val = 1; // force hgo_val to 1 if > 0
        MOVS     R1,#+1
// 1105   }
// 1106 
// 1107 // configure the MCG_C2 register
// 1108 // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
// 1109 // it still needs to be set correctly even if the oscillator is not being used
// 1110   temp_reg = MCG_C2;
??fbi_fee_6:
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
// 1111   temp_reg &= ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); // clear fields before writing new values
        ANDS     R2,R2,#0xC3
// 1112   if (crystal_val <= 40000)
        MOVW     R3,#+40001
        CMP      R0,R3
        BGE.N    ??fbi_fee_7
// 1113   {
// 1114     temp_reg |= (MCG_C2_RANGE(0) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R2,R1,R2
        B.N      ??fbi_fee_8
// 1115   }
// 1116   else if (crystal_val <= 8000000)
??fbi_fee_7:
        LDR.W    R3,??DataTable19_3  ;; 0x7a1201
        CMP      R0,R3
        BGE.N    ??fbi_fee_9
// 1117   {
// 1118     temp_reg |= (MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R1,R1,#0x10
        ORRS     R2,R1,R2
        B.N      ??fbi_fee_8
// 1119   }
// 1120   else
// 1121   {
// 1122     temp_reg |= (MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
??fbi_fee_9:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R1,R1,#0x20
        ORRS     R2,R1,R2
// 1123   }
// 1124   MCG_C2 = temp_reg;
??fbi_fee_8:
        LDR.W    R1,??DataTable22  ;; 0x40064001
        STRB     R2,[R1, #+0]
// 1125 
// 1126 // determine FRDIV based on reference clock frequency
// 1127 // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
// 1128   if (crystal_val <= 1250000) {frdiv_val = 0;}
        LDR.W    R1,??DataTable23_1  ;; 0x1312d1
        CMP      R0,R1
        BGE.N    ??fbi_fee_10
        MOVS     R5,#+0
        B.N      ??fbi_fee_11
// 1129   else if (crystal_val <= 2500000) {frdiv_val = 1;}
??fbi_fee_10:
        LDR.W    R1,??DataTable23_2  ;; 0x2625a1
        CMP      R0,R1
        BGE.N    ??fbi_fee_12
        MOVS     R5,#+1
        B.N      ??fbi_fee_11
// 1130   else if (crystal_val <= 5000000) {frdiv_val = 2;}
??fbi_fee_12:
        LDR.W    R1,??DataTable23_3  ;; 0x4c4b41
        CMP      R0,R1
        BGE.N    ??fbi_fee_13
        MOVS     R5,#+2
        B.N      ??fbi_fee_11
// 1131   else if (crystal_val <= 10000000) {frdiv_val = 3;}
??fbi_fee_13:
        LDR.W    R1,??DataTable23_4  ;; 0x989681
        CMP      R0,R1
        BGE.N    ??fbi_fee_14
        MOVS     R5,#+3
        B.N      ??fbi_fee_11
// 1132   else if (crystal_val <= 20000000) {frdiv_val = 4;}
??fbi_fee_14:
        LDR.W    R1,??DataTable23_5  ;; 0x1312d01
        CMP      R0,R1
        BGE.N    ??fbi_fee_15
        MOVS     R5,#+4
        B.N      ??fbi_fee_11
// 1133   else {frdiv_val = 5;}
??fbi_fee_15:
        MOVS     R5,#+5
// 1134 // The FLL ref clk divide value depends on FRDIV and the RANGE value
// 1135   if (((MCG_C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) > 0)
??fbi_fee_11:
        LDR.W    R1,??DataTable22  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+4,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbi_fee_16
// 1136   {
// 1137     fll_ref_freq = ((crystal_val) / (32 << frdiv_val));
        MOVS     R1,#+32
        LSLS     R1,R1,R5
        SDIV     R0,R0,R1
        B.N      ??fbi_fee_17
// 1138   }
// 1139   else
// 1140   {
// 1141     fll_ref_freq = ((crystal_val) / (1 << frdiv_val));
??fbi_fee_16:
        MOVS     R1,#+1
        LSLS     R1,R1,R5
        SDIV     R0,R0,R1
// 1142   }
// 1143   
// 1144 // Check resulting FLL frequency 
// 1145   mcg_out = fll_freq(fll_ref_freq); // FLL reference frequency calculated from ext ref freq and FRDIV
??fbi_fee_17:
        BL       fll_freq
// 1146   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fbi_fee_2
// 1147   
// 1148 // Select external oscilator and Reference Divider and clear IREFS to start ext osc
// 1149 // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
// 1150 // CLKS=0, FRDIV=frdiv_val, IREFS=0, IRCLKEN=?, IREFSTEN=?
// 1151   temp_reg = MCG_C1;
??fbi_fee_18:
        LDR.W    R1,??DataTable23_6  ;; 0x40064000
        LDRB     R2,[R1, #+0]
// 1152   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear CLKS, FRDIV and IREFS fields
        ANDS     R2,R2,#0x3
// 1153   temp_reg = MCG_C1_CLKS(0) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
        LSLS     R1,R5,#+3
        ANDS     R1,R1,#0x38
        MOVS     R2,R1
// 1154   MCG_C1 = temp_reg;
        LDR.W    R1,??DataTable23_6  ;; 0x40064000
        STRB     R2,[R1, #+0]
// 1155 
// 1156 // if the external oscillator is used need to wait for OSCINIT to set
// 1157   if (erefs_val)
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BEQ.N    ??fbi_fee_19
// 1158   {
// 1159     for (i = 0 ; i < 10000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbi_fee_20
??fbi_fee_21:
        ADDS     R1,R1,#+1
??fbi_fee_20:
        MOVW     R2,#+10000
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,R2
        BGE.N    ??fbi_fee_22
// 1160     {
// 1161       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fbi_fee_21
// 1162     }
// 1163     if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
??fbi_fee_22:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??fbi_fee_19
        MOVS     R0,#+35
        B.N      ??fbi_fee_2
// 1164   }
// 1165 
// 1166 // wait for Reference clock Status bit to clear
// 1167   for (i = 0 ; i < 2000 ; i++)
??fbi_fee_19:
        MOVS     R1,#+0
        B.N      ??fbi_fee_23
??fbi_fee_24:
        ADDS     R1,R1,#+1
??fbi_fee_23:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fee_25
// 1168   {
// 1169     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fbi_fee_24
// 1170   }
// 1171   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
??fbi_fee_25:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BPL.N    ??fbi_fee_26
        MOVS     R0,#+17
        B.N      ??fbi_fee_2
// 1172   
// 1173 // Wait for clock status bits to show clock source is ext ref clk
// 1174   for (i = 0 ; i < 2000 ; i++)
??fbi_fee_26:
        MOVS     R1,#+0
        B.N      ??fbi_fee_27
??fbi_fee_28:
        ADDS     R1,R1,#+1
??fbi_fee_27:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fee_29
// 1175   {
// 1176     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) break; // jump out early if CLKST shows FLL selected before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fbi_fee_28
// 1177   }
// 1178   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0) return 0x18; // check FLLK is really selected and return with error if not
??fbi_fee_29:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbi_fee_30
        MOVS     R0,#+24
        B.N      ??fbi_fee_2
// 1179  
// 1180 // Now in FEE  
// 1181 // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
// 1182 // It is enabled here but can be removed if this is not required.
// 1183 // The clock monitor MUST be disabled when returning to a non-external clock mode (FEI, FBI and BLPI)
// 1184   MCG_C6 |= MCG_C6_CME_MASK;
??fbi_fee_30:
        LDR.W    R1,??DataTable26_1  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x20
        LDR.W    R2,??DataTable26_1  ;; 0x40064005
        STRB     R1,[R2, #+0]
// 1185   
// 1186   return mcg_out; // MCGOUT frequency equals FLL frequency
??fbi_fee_2:
        POP      {R1,R4,R5,PC}    ;; return
// 1187 } //fbi_fee
// 1188 
// 1189 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1190 int fee_fbi(int irc_freq, unsigned char irc_select)
// 1191 { 
// 1192   unsigned char fcrdiv_val;
// 1193   short i;
// 1194   
// 1195 // Check MCG is in FEE mode
// 1196   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
// 1197       (!(MCG_S & MCG_S_IREFST_MASK)) &&                             // check FLL ref is external ref clk
// 1198       (!(MCG_S & MCG_S_PLLST_MASK))))                               // check PLLS mux has selected FLL
fee_fbi:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fee_fbi_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fee_fbi_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??fee_fbi_1
// 1199   {
// 1200     return 0x2;                                                     // return error code
??fee_fbi_0:
        MOVS     R0,#+2
        B.N      ??fee_fbi_2
// 1201   }
// 1202   
// 1203   // Check that the irc frequency matches the selected IRC 
// 1204   if (!(irc_select))
??fee_fbi_1:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fee_fbi_3
// 1205   {    
// 1206     if ((irc_freq < 31250) || (irc_freq > 39063)) {return 0x31;}
        MOVW     R2,#+31250
        SUBS     R2,R0,R2
        MOVW     R3,#+7814
        CMP      R2,R3
        BCC.N    ??fee_fbi_4
        MOVS     R0,#+49
        B.N      ??fee_fbi_2
// 1207   }
// 1208   else
// 1209   {
// 1210     if ((irc_freq < 3000000) || (irc_freq > 5000000)) {return 0x32;} // Fast IRC freq
??fee_fbi_3:
        LDR.W    R2,??DataTable22_1  ;; 0x2dc6c0
        SUBS     R2,R0,R2
        LDR.W    R3,??DataTable22_2  ;; 0x1e8481
        CMP      R2,R3
        BCC.N    ??fee_fbi_4
        MOVS     R0,#+50
        B.N      ??fee_fbi_2
// 1211   }
// 1212   
// 1213 // Select the required IRC
// 1214   if (irc_select)
??fee_fbi_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fee_fbi_5
// 1215   {
// 1216     MCG_C2 |= MCG_C2_IRCS_MASK; // select fast IRC by setting IRCS
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ORRS     R2,R2,#0x1
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
        B.N      ??fee_fbi_6
// 1217   }
// 1218   else
// 1219   {
// 1220     MCG_C2 &= ~MCG_C2_IRCS_MASK; // select slow IRC by clearing IRCS
??fee_fbi_5:
        LDR.W    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xFE
        LDR.W    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
// 1221   }
// 1222   
// 1223 // Make sure the clock monitor is disabled before switching modes otherwise it will trigger
// 1224   MCG_C6 &= ~MCG_C6_CME_MASK;
??fee_fbi_6:
        LDR.W    R2,??DataTable24  ;; 0x40064005
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xDF
        LDR.W    R3,??DataTable24  ;; 0x40064005
        STRB     R2,[R3, #+0]
// 1225   
// 1226 // Select the IRC as the CLKS mux selection
// 1227   MCG_C1 |= MCG_C1_CLKS(1) | MCG_C1_IREFS_MASK; // set IREFS and select IRC as MCGOUT
        LDR.W    R2,??DataTable23_6  ;; 0x40064000
        LDRB     R2,[R2, #+0]
        ORRS     R2,R2,#0x44
        LDR.W    R3,??DataTable23_6  ;; 0x40064000
        STRB     R2,[R3, #+0]
// 1228  
// 1229 // wait until internal reference switches to requested irc.
// 1230   if (!(irc_select))
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fee_fbi_7
// 1231   {
// 1232     for (i = 0 ; i < 2000 ; i++)
        MOVS     R2,#+0
        B.N      ??fee_fbi_8
??fee_fbi_9:
        ADDS     R2,R2,#+1
??fee_fbi_8:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fee_fbi_10
// 1233     {
// 1234       if (!(MCG_S & MCG_S_IRCST_MASK)) break; // jump out early if IRCST clears before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BMI.N    ??fee_fbi_9
// 1235     }
// 1236     if (MCG_S & MCG_S_IRCST_MASK) return 0x13; // check bit is really clear and return with error if set
??fee_fbi_10:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BPL.N    ??fee_fbi_11
        MOVS     R0,#+19
        B.N      ??fee_fbi_2
// 1237   }
// 1238   else
// 1239   {
// 1240     for (i = 0 ; i < 2000 ; i++)
??fee_fbi_7:
        MOVS     R2,#+0
        B.N      ??fee_fbi_12
??fee_fbi_13:
        ADDS     R2,R2,#+1
??fee_fbi_12:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fee_fbi_14
// 1241     {
// 1242       if (MCG_S & MCG_S_IRCST_MASK) break; // jump out early if IRCST sets before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BPL.N    ??fee_fbi_13
// 1243     }
// 1244     if (!(MCG_S & MCG_S_IRCST_MASK)) return 0x14; // check bit is really set and return with error if not set
??fee_fbi_14:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BMI.N    ??fee_fbi_11
        MOVS     R0,#+20
        B.N      ??fee_fbi_2
// 1245   }
// 1246   
// 1247 // Wait for clock status bits to update
// 1248   for (i = 0 ; i < 2000 ; i++)
??fee_fbi_11:
        MOVS     R2,#+0
        B.N      ??fee_fbi_15
??fee_fbi_16:
        ADDS     R2,R2,#+1
??fee_fbi_15:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fee_fbi_17
// 1249   {
// 1250     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) break; // jump out early if CLKST shows IRC slected before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+1
        BNE.N    ??fee_fbi_16
// 1251   }
// 1252   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1) return 0x19; // check IRC is really selected and return with error if not
??fee_fbi_17:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BEQ.N    ??fee_fbi_18
        MOVS     R0,#+25
        B.N      ??fee_fbi_2
// 1253   
// 1254 // wait for Reference clock Status bit to set
// 1255   for (i = 0 ; i < 2000 ; i++)
??fee_fbi_18:
        MOVS     R2,#+0
        B.N      ??fee_fbi_19
??fee_fbi_20:
        ADDS     R2,R2,#+1
??fee_fbi_19:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fee_fbi_21
// 1256   {
// 1257     if (MCG_S & MCG_S_IREFST_MASK) break; // jump out early if IREFST sets before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+27
        BPL.N    ??fee_fbi_20
// 1258   }
// 1259   if (!(MCG_S & MCG_S_IREFST_MASK)) return 0x12; // check bit is really set and return with error if not set  
??fee_fbi_21:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fee_fbi_22
        MOVS     R0,#+18
        B.N      ??fee_fbi_2
// 1260   
// 1261 // Now in FBI mode
// 1262   if (irc_select)
??fee_fbi_22:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fee_fbi_23
// 1263   {
// 1264     fcrdiv_val = (1 << ((MCG_SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); // calculate the fast IRC divder factor
        MOVS     R1,#+1
        LDR.W    R2,??DataTable26  ;; 0x40064008
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+1,#+3
        LSLS     R1,R1,R2
// 1265     return (irc_freq / fcrdiv_val); // MCGOUT frequency equals fast IRC frequency divided by 2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        B.N      ??fee_fbi_2
// 1266   }
// 1267   else
// 1268   {
// 1269     return irc_freq; // MCGOUT frequency equals slow IRC frequency
??fee_fbi_23:
??fee_fbi_2:
        BX       LR               ;; return
// 1270   }
// 1271 } // fee_fbi 
// 1272 
// 1273 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1274 int fbi_fei(int slow_irc_freq)
// 1275 {
fbi_fei:
        PUSH     {R7,LR}
// 1276   unsigned char temp_reg;
// 1277   short i;
// 1278   int mcg_out;
// 1279 
// 1280 // check if in FBI mode
// 1281   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1282       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1283       (!(MCG_S & MCG_S_PLLST_MASK)) &&                                // check PLLS mux has selected FLL
// 1284       (!(MCG_C2 & MCG_C2_LP_MASK))))                                  // check LP bit is clear
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BNE.N    ??fbi_fei_0
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BPL.N    ??fbi_fei_0
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BMI.N    ??fbi_fei_0
        LDR.W    R1,??DataTable22  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BPL.N    ??fbi_fei_1
// 1285   {  
// 1286     return 0x3;                                                       // MCG not in correct mode return fail code 
??fbi_fei_0:
        MOVS     R0,#+3
        B.N      ??fbi_fei_2
// 1287   }
// 1288 
// 1289 // Check IRC frequency is within spec.
// 1290   if ((slow_irc_freq < 31250) || (slow_irc_freq > 39063))
??fbi_fei_1:
        MOVW     R1,#+31250
        SUBS     R1,R0,R1
        MOVW     R2,#+7814
        CMP      R1,R2
        BCC.N    ??fbi_fei_3
// 1291   {
// 1292     return 0x31;
        MOVS     R0,#+49
        B.N      ??fbi_fei_2
// 1293   }
// 1294 
// 1295 // Check resulting FLL frequency 
// 1296   mcg_out = fll_freq(slow_irc_freq); 
??fbi_fei_3:
        BL       fll_freq
// 1297   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fbi_fei_2
// 1298   
// 1299 // Change the CLKS mux to select the FLL output as MCGOUT  
// 1300   temp_reg = MCG_C1;
??fbi_fei_4:
        LDR.W    R1,??DataTable23_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
// 1301   temp_reg &= ~MCG_C1_CLKS_MASK; // clear CLKS field
        ANDS     R1,R1,#0x3F
// 1302   temp_reg |= MCG_C1_CLKS(0); // select FLL as MCGOUT
// 1303   temp_reg |= MCG_C1_IREFS_MASK; // make sure IRC is FLL reference
        ORRS     R1,R1,#0x4
// 1304   MCG_C1 = temp_reg; // update MCG_C1
        LDR.W    R2,??DataTable23_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
// 1305   
// 1306 // wait for Reference clock Status bit to clear
// 1307   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fbi_fei_5
??fbi_fei_6:
        ADDS     R1,R1,#+1
??fbi_fei_5:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fei_7
// 1308   {
// 1309     if (MCG_S & MCG_S_IREFST_MASK) break; // jump out early if IREFST clears before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fbi_fei_6
// 1310   }
// 1311   if (!(MCG_S & MCG_S_IREFST_MASK)) return 0x12; // check bit is really set and return with error if not set
??fbi_fei_7:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fbi_fei_8
        MOVS     R0,#+18
        B.N      ??fbi_fei_2
// 1312   
// 1313 // Wait for clock status bits to show clock source is ext ref clk
// 1314   for (i = 0 ; i < 2000 ; i++)
??fbi_fei_8:
        MOVS     R1,#+0
        B.N      ??fbi_fei_9
??fbi_fei_10:
        ADDS     R1,R1,#+1
??fbi_fei_9:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fbi_fei_11
// 1315   {
// 1316     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) break; // jump out early if CLKST shows FLL slected before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fbi_fei_10
// 1317   }
// 1318   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x0) return 0x18; // check FLL is really selected and return with error if not
??fbi_fei_11:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fbi_fei_12
        MOVS     R0,#+24
        B.N      ??fbi_fei_2
// 1319 
// 1320 // Now in FEI mode
// 1321   return mcg_out;  
??fbi_fei_12:
??fbi_fei_2:
        POP      {R1,PC}          ;; return
// 1322 } // fbi_fei

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable19:
        DC32     0x3938701

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable19_1:
        DC32     0x2d2a7f

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable19_2:
        DC32     0x1e84801

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable19_3:
        DC32     0x7a1201
// 1323 
// 1324 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1325 int fei_fbi(int irc_freq, unsigned char irc_select)
// 1326 {
// 1327   unsigned char temp_reg;
// 1328   unsigned char fcrdiv_val;
// 1329   short i;
// 1330   
// 1331 // Check MCG is in FEI mode
// 1332   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
// 1333       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1334       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
fei_fbi:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fei_fbi_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fei_fbi_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??fei_fbi_1
// 1335   {
// 1336     return 0x1;                                                       // return error code
??fei_fbi_0:
        MOVS     R0,#+1
        B.N      ??fei_fbi_2
// 1337   } 
// 1338 
// 1339 // Check that the irc frequency matches the selected IRC 
// 1340   if (!(irc_select))
??fei_fbi_1:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fei_fbi_3
// 1341   {    
// 1342     if ((irc_freq < 31250) || (irc_freq > 39063)) {return 0x31;}
        MOVW     R2,#+31250
        SUBS     R2,R0,R2
        MOVW     R3,#+7814
        CMP      R2,R3
        BCC.N    ??fei_fbi_4
        MOVS     R0,#+49
        B.N      ??fei_fbi_2
// 1343   }
// 1344   else
// 1345   {
// 1346     if ((irc_freq < 3000000) || (irc_freq > 5000000)) {return 0x32;} // Fast IRC freq
??fei_fbi_3:
        LDR.N    R2,??DataTable22_1  ;; 0x2dc6c0
        SUBS     R2,R0,R2
        LDR.N    R3,??DataTable22_2  ;; 0x1e8481
        CMP      R2,R3
        BCC.N    ??fei_fbi_4
        MOVS     R0,#+50
        B.N      ??fei_fbi_2
// 1347   }
// 1348   
// 1349 // Select the desired IRC
// 1350   if (irc_select)
??fei_fbi_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fei_fbi_5
// 1351   {
// 1352     MCG_C2 |= MCG_C2_IRCS_MASK; // select fast IRCS
        LDR.N    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ORRS     R2,R2,#0x1
        LDR.N    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
        B.N      ??fei_fbi_6
// 1353   }
// 1354   else
// 1355   {
// 1356     MCG_C2 &= ~MCG_C2_IRCS_MASK; // select slow IRCS
??fei_fbi_5:
        LDR.N    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
        ANDS     R2,R2,#0xFE
        LDR.N    R3,??DataTable22  ;; 0x40064001
        STRB     R2,[R3, #+0]
// 1357   }
// 1358   
// 1359 // Change the CLKS mux to select the IRC as the MCGOUT
// 1360   temp_reg = MCG_C1;
??fei_fbi_6:
        LDR.W    R2,??DataTable23_6  ;; 0x40064000
        LDRB     R2,[R2, #+0]
// 1361   temp_reg &= ~MCG_C1_CLKS_MASK; // clear CLKS
        ANDS     R2,R2,#0x3F
// 1362   temp_reg |= MCG_C1_CLKS(1); // select IRC as the MCG clock sourse
        ORRS     R2,R2,#0x40
// 1363   MCG_C1 = temp_reg;
        LDR.W    R3,??DataTable23_6  ;; 0x40064000
        STRB     R2,[R3, #+0]
// 1364 
// 1365 // wait until internal reference switches to requested irc.
// 1366   if (!(irc_select))
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fei_fbi_7
// 1367   {
// 1368     for (i = 0 ; i < 2000 ; i++)
        MOVS     R2,#+0
        B.N      ??fei_fbi_8
??fei_fbi_9:
        ADDS     R2,R2,#+1
??fei_fbi_8:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fei_fbi_10
// 1369     {
// 1370       if (!(MCG_S & MCG_S_IRCST_MASK)) break; // jump out early if IRCST clears before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BMI.N    ??fei_fbi_9
// 1371     }
// 1372     if (MCG_S & MCG_S_IRCST_MASK) return 0x13; // check bit is really clear and return with error if set
??fei_fbi_10:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BPL.N    ??fei_fbi_11
        MOVS     R0,#+19
        B.N      ??fei_fbi_2
// 1373   }
// 1374   else
// 1375   {
// 1376     for (i = 0 ; i < 2000 ; i++)
??fei_fbi_7:
        MOVS     R2,#+0
        B.N      ??fei_fbi_12
??fei_fbi_13:
        ADDS     R2,R2,#+1
??fei_fbi_12:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fei_fbi_14
// 1377     {
// 1378       if (MCG_S & MCG_S_IRCST_MASK) break; // jump out early if IRCST sets before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        LSLS     R3,R3,#+31
        BPL.N    ??fei_fbi_13
// 1379     }
// 1380     if (!(MCG_S & MCG_S_IRCST_MASK)) return 0x14; // check bit is really set and return with error if not set
??fei_fbi_14:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+31
        BMI.N    ??fei_fbi_11
        MOVS     R0,#+20
        B.N      ??fei_fbi_2
// 1381   }
// 1382   
// 1383 // Wait for clock status bits to update
// 1384   for (i = 0 ; i < 2000 ; i++)
??fei_fbi_11:
        MOVS     R2,#+0
        B.N      ??fei_fbi_15
??fei_fbi_16:
        ADDS     R2,R2,#+1
??fei_fbi_15:
        SXTH     R2,R2            ;; SignExt  R2,R2,#+16,#+16
        CMP      R2,#+2000
        BGE.N    ??fei_fbi_17
// 1385   {
// 1386     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) break; // jump out early if CLKST shows IRC slected before loop finishes
        LDR.W    R3,??DataTable24_1  ;; 0x40064006
        LDRB     R3,[R3, #+0]
        UBFX     R3,R3,#+2,#+2
        UXTB     R3,R3            ;; ZeroExt  R3,R3,#+24,#+24
        CMP      R3,#+1
        BNE.N    ??fei_fbi_16
// 1387   }
// 1388   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x1) return 0x19; // check IRC is really selected and return with error if not
??fei_fbi_17:
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+1
        BEQ.N    ??fei_fbi_18
        MOVS     R0,#+25
        B.N      ??fei_fbi_2
// 1389   
// 1390 // Now in FBI mode
// 1391   if (irc_select)
??fei_fbi_18:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fei_fbi_19
// 1392   {
// 1393     fcrdiv_val = (1 << ((MCG_SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT)); // calculate the fast IRC divder factor
        MOVS     R1,#+1
        LDR.W    R2,??DataTable26  ;; 0x40064008
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+1,#+3
        LSLS     R1,R1,R2
// 1394     return (irc_freq / fcrdiv_val); // MCGOUT frequency equals fast IRC frequency divided by 2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        SDIV     R0,R0,R1
        B.N      ??fei_fbi_2
// 1395   }
// 1396   else
// 1397   {
// 1398     return irc_freq; // MCGOUT frequency equals slow IRC frequency
??fei_fbi_19:
??fei_fbi_2:
        BX       LR               ;; return
// 1399   }   
// 1400 } // fei_fbi
// 1401 
// 1402 
// 1403 /********************************************************************/
// 1404 /* Functon name : fei_fee
// 1405  *
// 1406  * Mode transition: FEI to FEE mode
// 1407  *
// 1408  * This function transitions the MCG from FEI mode to FEE mode. This is
// 1409  * achieved by setting the MCG_C2[LP] bit. There is no status bit to 
// 1410  * check so 0 is always returned if the function was called with the MCG
// 1411  * in FBI mode. The MCGCLKOUT frequency does not change
// 1412  *
// 1413  * Parameters: crystal_val - external clock frequency in Hz
// 1414  *             hgo_val     - selects whether low power or high gain mode is selected
// 1415  *                           for the crystal oscillator. This has no meaning if an 
// 1416  *                           external clock is used.
// 1417  *             erefs_val   - selects external clock (=0) or crystal osc (=1)
// 1418  *
// 1419  * Return value : MCGCLKOUT frequency (Hz) or error code
// 1420  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1421 int fei_fee(int crystal_val, unsigned char hgo_val, unsigned char erefs_val)
// 1422 {
fei_fee:
        PUSH     {R3-R5,LR}
        MOVS     R4,R2
// 1423   unsigned char frdiv_val;
// 1424   unsigned char temp_reg;
// 1425  // short i;
// 1426   int mcg_out, fll_ref_freq, i;
// 1427   
// 1428 // check if in FEI mode
// 1429   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
// 1430       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1431       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        UBFX     R2,R2,#+2,#+2
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        CMP      R2,#+0
        BNE.N    ??fei_fee_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fei_fee_0
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+26
        BPL.N    ??fei_fee_1
// 1432   {
// 1433     return 0x1;                                                     // return error code
??fei_fee_0:
        MOVS     R0,#+1
        B.N      ??fei_fee_2
// 1434   }
// 1435 
// 1436 // check external frequency is less than the maximum frequency
// 1437   if  (crystal_val > 60000000) {return 0x21;}
??fei_fee_1:
        LDR.W    R2,??DataTable26_2  ;; 0x3938701
        CMP      R0,R2
        BLT.N    ??fei_fee_3
        MOVS     R0,#+33
        B.N      ??fei_fee_2
// 1438   
// 1439 // check crystal frequency is within spec. if crystal osc is being used
// 1440   if (erefs_val)
??fei_fee_3:
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BEQ.N    ??fei_fee_4
// 1441   {
// 1442     if ((crystal_val < 30000) ||
// 1443         ((crystal_val > 40000) && (crystal_val < 3000000)) ||
// 1444         (crystal_val > 32000000)) {return 0x22;} // return error if one of the available crystal options is not available
        MOVW     R2,#+30000
        CMP      R0,R2
        BLT.N    ??fei_fee_5
        MOVW     R2,#+40001
        SUBS     R2,R0,R2
        LDR.W    R3,??DataTable26_3  ;; 0x2d2a7f
        CMP      R2,R3
        BCC.N    ??fei_fee_5
        LDR.W    R2,??DataTable26_4  ;; 0x1e84801
        CMP      R0,R2
        BLT.N    ??fei_fee_4
??fei_fee_5:
        MOVS     R0,#+34
        B.N      ??fei_fee_2
// 1445   }
// 1446 
// 1447 // make sure HGO will never be greater than 1. Could return an error instead if desired.  
// 1448   if (hgo_val > 0)
??fei_fee_4:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+1
        BCC.N    ??fei_fee_6
// 1449   {
// 1450     hgo_val = 1; // force hgo_val to 1 if > 0
        MOVS     R1,#+1
// 1451   }
// 1452 
// 1453 // configure the MCG_C2 register
// 1454 // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
// 1455 // it still needs to be set correctly even if the oscillator is not being used
// 1456   temp_reg = MCG_C2;
??fei_fee_6:
        LDR.N    R2,??DataTable22  ;; 0x40064001
        LDRB     R2,[R2, #+0]
// 1457   temp_reg &= ~(MCG_C2_RANGE_MASK | MCG_C2_HGO_MASK | MCG_C2_EREFS_MASK); // clear fields before writing new values
        ANDS     R2,R2,#0xC3
// 1458   if (crystal_val <= 40000)
        MOVW     R3,#+40001
        CMP      R0,R3
        BGE.N    ??fei_fee_7
// 1459   {
// 1460     temp_reg |= (MCG_C2_RANGE(0) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R2,R1,R2
        B.N      ??fei_fee_8
// 1461   }
// 1462   else if (crystal_val <= 8000000)
??fei_fee_7:
        LDR.W    R3,??DataTable26_5  ;; 0x7a1201
        CMP      R0,R3
        BGE.N    ??fei_fee_9
// 1463   {
// 1464     temp_reg |= (MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R1,R1,#0x10
        ORRS     R2,R1,R2
        B.N      ??fei_fee_8
// 1465   }
// 1466   else
// 1467   {
// 1468     temp_reg |= (MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT));
??fei_fee_9:
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        LSLS     R1,R1,#+3
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R3,R4,#+2
        ORRS     R1,R3,R1
        ORRS     R1,R1,#0x20
        ORRS     R2,R1,R2
// 1469   }
// 1470   MCG_C2 = temp_reg;
??fei_fee_8:
        LDR.N    R1,??DataTable22  ;; 0x40064001
        STRB     R2,[R1, #+0]
// 1471 
// 1472 // determine FRDIV based on reference clock frequency
// 1473 // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
// 1474   if (crystal_val <= 1250000) {frdiv_val = 0;}
        LDR.N    R1,??DataTable23_1  ;; 0x1312d1
        CMP      R0,R1
        BGE.N    ??fei_fee_10
        MOVS     R5,#+0
        B.N      ??fei_fee_11
// 1475   else if (crystal_val <= 2500000) {frdiv_val = 1;}
??fei_fee_10:
        LDR.N    R1,??DataTable23_2  ;; 0x2625a1
        CMP      R0,R1
        BGE.N    ??fei_fee_12
        MOVS     R5,#+1
        B.N      ??fei_fee_11
// 1476   else if (crystal_val <= 5000000) {frdiv_val = 2;}
??fei_fee_12:
        LDR.N    R1,??DataTable23_3  ;; 0x4c4b41
        CMP      R0,R1
        BGE.N    ??fei_fee_13
        MOVS     R5,#+2
        B.N      ??fei_fee_11
// 1477   else if (crystal_val <= 10000000) {frdiv_val = 3;}
??fei_fee_13:
        LDR.N    R1,??DataTable23_4  ;; 0x989681
        CMP      R0,R1
        BGE.N    ??fei_fee_14
        MOVS     R5,#+3
        B.N      ??fei_fee_11
// 1478   else if (crystal_val <= 20000000) {frdiv_val = 4;}
??fei_fee_14:
        LDR.N    R1,??DataTable23_5  ;; 0x1312d01
        CMP      R0,R1
        BGE.N    ??fei_fee_15
        MOVS     R5,#+4
        B.N      ??fei_fee_11
// 1479   else {frdiv_val = 5;}
??fei_fee_15:
        MOVS     R5,#+5
// 1480    
// 1481   // The FLL ref clk divide value depends on FRDIV and the RANGE value
// 1482   if (((MCG_C2 & MCG_C2_RANGE_MASK) >> MCG_C2_RANGE_SHIFT) > 0)
??fei_fee_11:
        LDR.N    R1,??DataTable22  ;; 0x40064001
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+4,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BEQ.N    ??fei_fee_16
// 1483   {
// 1484     fll_ref_freq = ((crystal_val) / (32 << frdiv_val));
        MOVS     R1,#+32
        LSLS     R1,R1,R5
        SDIV     R0,R0,R1
        B.N      ??fei_fee_17
// 1485   }
// 1486   else
// 1487   {
// 1488     fll_ref_freq = ((crystal_val) / (1 << frdiv_val));
??fei_fee_16:
        MOVS     R1,#+1
        LSLS     R1,R1,R5
        SDIV     R0,R0,R1
// 1489   }
// 1490   
// 1491 // Check resulting FLL frequency 
// 1492   mcg_out = fll_freq(fll_ref_freq); // FLL reference frequency calculated from ext ref freq and FRDIV
??fei_fee_17:
        BL       fll_freq
// 1493   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fei_fee_2
// 1494   
// 1495 // Select external oscilator and Reference Divider and clear IREFS to start ext osc
// 1496 // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
// 1497 // CLKS=0, FRDIV=frdiv_val, IREFS=0, IRCLKEN=0, IREFSTEN=0
// 1498   temp_reg = MCG_C1;
??fei_fee_18:
        LDR.N    R1,??DataTable23_6  ;; 0x40064000
        LDRB     R2,[R1, #+0]
// 1499   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear values in these fields
        ANDS     R2,R2,#0x3
// 1500   temp_reg = MCG_C1_CLKS(0) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
        LSLS     R1,R5,#+3
        ANDS     R1,R1,#0x38
        MOVS     R2,R1
// 1501   MCG_C1 = temp_reg;
        LDR.N    R1,??DataTable23_6  ;; 0x40064000
        STRB     R2,[R1, #+0]
// 1502 
// 1503 // if the external oscillator is used need to wait for OSCINIT to set
// 1504   if (erefs_val)
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BEQ.N    ??fei_fee_19
// 1505   {
// 1506     for (i = 0 ; i < 20000000 ; i++)
        MOVS     R1,#+0
        B.N      ??fei_fee_20
??fei_fee_21:
        ADDS     R1,R1,#+1
??fei_fee_20:
        LDR.W    R2,??DataTable26_6  ;; 0x1312d00
        CMP      R1,R2
        BGE.N    ??fei_fee_22
// 1507     {
// 1508       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+30
        BPL.N    ??fei_fee_21
// 1509     }
// 1510     if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
??fei_fee_22:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+30
        BMI.N    ??fei_fee_19
        MOVS     R0,#+35
        B.N      ??fei_fee_2
// 1511   }
// 1512 
// 1513 // wait for Reference clock Status bit to clear
// 1514   for (i = 0 ; i < 2000 ; i++)
??fei_fee_19:
        MOVS     R1,#+0
        B.N      ??fei_fee_23
??fei_fee_24:
        ADDS     R1,R1,#+1
??fei_fee_23:
        CMP      R1,#+2000
        BGE.N    ??fei_fee_25
// 1515   {
// 1516     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BMI.N    ??fei_fee_24
// 1517   }
// 1518   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
??fei_fee_25:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BPL.N    ??fei_fee_26
        MOVS     R0,#+17
        B.N      ??fei_fee_2
// 1519   
// 1520 // Now in FBE  
// 1521 // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
// 1522 // It is enabled here but can be removed if this is not required.
// 1523   MCG_C6 |= MCG_C6_CME_MASK;
??fei_fee_26:
        LDR.W    R1,??DataTable26_1  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x20
        LDR.W    R2,??DataTable26_1  ;; 0x40064005
        STRB     R1,[R2, #+0]
// 1524   
// 1525   return mcg_out; // MCGOUT frequency equals FLL frequency
??fei_fee_2:
        POP      {R1,R4,R5,PC}    ;; return
// 1526 } // fei_fee
// 1527 
// 1528 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1529 int fee_fei(int slow_irc_freq)
// 1530 {
fee_fei:
        PUSH     {R7,LR}
// 1531   short i;
// 1532   int mcg_out;
// 1533 
// 1534 // Check MCG is in FEE mode
// 1535   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL
// 1536       (!(MCG_S & MCG_S_IREFST_MASK)) &&                             // check FLL ref is external ref clk
// 1537       (!(MCG_S & MCG_S_PLLST_MASK))))                               // check PLLS mux has selected FLL
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        UBFX     R1,R1,#+2,#+2
        UXTB     R1,R1            ;; ZeroExt  R1,R1,#+24,#+24
        CMP      R1,#+0
        BNE.N    ??fee_fei_0
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fee_fei_0
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+26
        BPL.N    ??fee_fei_1
// 1538   {
// 1539     return 0x2;                                                     // return error code
??fee_fei_0:
        MOVS     R0,#+2
        B.N      ??fee_fei_2
// 1540   } 
// 1541       
// 1542 // Check IRC frequency is within spec.
// 1543   if ((slow_irc_freq < 31250) || (slow_irc_freq > 39063))
??fee_fei_1:
        MOVW     R1,#+31250
        SUBS     R1,R0,R1
        MOVW     R2,#+7814
        CMP      R1,R2
        BCC.N    ??fee_fei_3
// 1544   {
// 1545     return 0x31;
        MOVS     R0,#+49
        B.N      ??fee_fei_2
// 1546   }
// 1547 
// 1548   // Check resulting FLL frequency 
// 1549   mcg_out = fll_freq(slow_irc_freq); 
??fee_fei_3:
        BL       fll_freq
// 1550   if (mcg_out < 0x5B) {return mcg_out;} // If error code returned, return the code to calling function
        CMP      R0,#+91
        BLT.N    ??fee_fei_2
// 1551   
// 1552 // Ensure clock monitor is disabled before switching to FEI otherwise a loss of clock will trigger
// 1553   MCG_C6 &= ~MCG_C6_CME_MASK;
??fee_fei_4:
        LDR.W    R1,??DataTable24  ;; 0x40064005
        LDRB     R1,[R1, #+0]
        ANDS     R1,R1,#0xDF
        LDR.W    R2,??DataTable24  ;; 0x40064005
        STRB     R1,[R2, #+0]
// 1554 
// 1555 // Change FLL reference clock from external to internal by setting IREFS bit
// 1556   MCG_C1 |= MCG_C1_IREFS_MASK; // select internal reference
        LDR.N    R1,??DataTable23_6  ;; 0x40064000
        LDRB     R1,[R1, #+0]
        ORRS     R1,R1,#0x4
        LDR.N    R2,??DataTable23_6  ;; 0x40064000
        STRB     R1,[R2, #+0]
// 1557   
// 1558 // wait for Reference clock to switch to internal reference 
// 1559   for (i = 0 ; i < 2000 ; i++)
        MOVS     R1,#+0
        B.N      ??fee_fei_5
??fee_fei_6:
        ADDS     R1,R1,#+1
??fee_fei_5:
        SXTH     R1,R1            ;; SignExt  R1,R1,#+16,#+16
        CMP      R1,#+2000
        BGE.N    ??fee_fei_7
// 1560   {
// 1561     if (MCG_S & MCG_S_IREFST_MASK) break; // jump out early if IREFST sets before loop finishes
        LDR.W    R2,??DataTable24_1  ;; 0x40064006
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+27
        BPL.N    ??fee_fei_6
// 1562   }
// 1563   if (!(MCG_S & MCG_S_IREFST_MASK)) return 0x12; // check bit is really set and return with error if not set  
??fee_fei_7:
        LDR.W    R1,??DataTable24_1  ;; 0x40064006
        LDRB     R1,[R1, #+0]
        LSLS     R1,R1,#+27
        BMI.N    ??fee_fei_8
        MOVS     R0,#+18
        B.N      ??fee_fei_2
// 1564   
// 1565 // Now in FEI mode  
// 1566   return mcg_out;  
??fee_fei_8:
??fee_fei_2:
        POP      {R1,PC}          ;; return
// 1567 } // fee_fei

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable22:
        DC32     0x40064001

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable22_1:
        DC32     0x2dc6c0

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable22_2:
        DC32     0x1e8481
// 1568 
// 1569 
// 1570 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1571 unsigned char atc(unsigned char irc_select, int irc_freq, int mcg_out_freq)
// 1572 {
atc:
        PUSH     {R3-R7,LR}
        MOVS     R4,R0
        MOVS     R5,R1
        MOVS     R7,R2
// 1573   unsigned char mcg_mode;
// 1574   unsigned short atcv;
// 1575   int bus_clock_freq;
// 1576   int  bus_clk_div_val;
// 1577   int orig_div;
// 1578   int temp_reg;
// 1579   
// 1580   if (irc_select > 0) // force irc to 1 if greater than 0
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+1
        BCC.N    ??atc_0
// 1581   {
// 1582     irc_select = 1;
        MOVS     R4,#+1
// 1583   }
// 1584   
// 1585   mcg_mode = what_mcg_mode(); // get present MCG mode
??atc_0:
        BL       what_mcg_mode
// 1586   if ((mcg_mode != PEE) && (mcg_mode != PBE) && (mcg_mode != FBE))
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+8
        BEQ.N    ??atc_1
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+7
        BEQ.N    ??atc_1
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+5
        BEQ.N    ??atc_1
// 1587   {
// 1588     return 1; // return error code if not in PEE, PBE or FBE modes
        MOVS     R0,#+1
        B.N      ??atc_2
// 1589   }
// 1590   
// 1591   orig_div = SIM_CLKDIV1; //store present clock divider values
??atc_1:
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        LDR      R6,[R0, #+0]
// 1592   
// 1593   bus_clk_div_val = mcg_out_freq / 16000000; // calculate bus clock divider to generate fastest allowed bus clock for autotrim
        LDR.W    R0,??DataTable26_8  ;; 0xf42400
        SDIV     R0,R7,R0
// 1594   temp_reg = SIM_CLKDIV1;
        LDR.W    R1,??DataTable26_7  ;; 0x40048044
        LDR      R1,[R1, #+0]
// 1595   temp_reg &= ~(SIM_CLKDIV1_OUTDIV2_MASK | SIM_CLKDIV1_OUTDIV4_MASK); // clear dividers except core
        LDR.W    R2,??DataTable26_9  ;; 0xf0f0ffff
        ANDS     R1,R2,R1
// 1596   // set all bus and flash dividers to same value to ensure clocking restrictions are met
// 1597   temp_reg |= (SIM_CLKDIV1_OUTDIV2(bus_clk_div_val) | SIM_CLKDIV1_OUTDIV4(bus_clk_div_val));
        LSLS     R2,R0,#+24
        ANDS     R2,R2,#0xF000000
        ORRS     R1,R2,R1
        LSLS     R0,R0,#+16
        ANDS     R0,R0,#0xF0000
        ORRS     R1,R0,R1
// 1598   SIM_CLKDIV1 = temp_reg; // set actual dividers
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R1,[R0, #+0]
// 1599   
// 1600   bus_clock_freq = mcg_out_freq / (((SIM_CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >> 24)+ 1);
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        LDR      R0,[R0, #+0]
        UBFX     R0,R0,#+24,#+4
        ADDS     R0,R0,#+1
        UDIV     R0,R7,R0
// 1601   if ((bus_clock_freq < 8000000) || (bus_clock_freq > 16000000))
        LDR.W    R1,??DataTable26_10  ;; 0x7a1200
        SUBS     R1,R0,R1
        LDR.W    R2,??DataTable26_5  ;; 0x7a1201
        CMP      R1,R2
        BCC.N    ??atc_3
// 1602   {
// 1603     SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1604     return 3; // error, bus clock frequency is not within 8MHz to 16MHz
        MOVS     R0,#+3
        B.N      ??atc_2
// 1605   }
// 1606                 
// 1607   if(!irc_select) //determine if slow or fast IRC to be trimmed
??atc_3:
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BNE.N    ??atc_4
// 1608   {
// 1609     if (irc_freq < 31250) // check frequency is above min spec.
        MOVW     R1,#+31250
        CMP      R5,R1
        BGE.N    ??atc_5
// 1610     {
// 1611       SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1612       return 4;
        MOVS     R0,#+4
        B.N      ??atc_2
// 1613     }
// 1614     if (irc_freq > 39062) // check frequency is below max spec.
??atc_5:
        MOVW     R1,#+39063
        CMP      R5,R1
        BLT.N    ??atc_6
// 1615     {
// 1616       SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1617       return 5;
        MOVS     R0,#+5
        B.N      ??atc_2
// 1618     }         
// 1619   }
// 1620   else
// 1621   {
// 1622     if (irc_freq < 3000000) // check frequency is above min spec.
??atc_4:
        LDR.W    R1,??DataTable26_11  ;; 0x2dc6c0
        CMP      R5,R1
        BGE.N    ??atc_7
// 1623     {
// 1624       SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1625       return 6;
        MOVS     R0,#+6
        B.N      ??atc_2
// 1626     }
// 1627     if (irc_freq > 5000000) // check frequency is below max spec.
??atc_7:
        LDR.N    R1,??DataTable23_3  ;; 0x4c4b41
        CMP      R5,R1
        BLT.N    ??atc_6
// 1628     {
// 1629       SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1630       return 7;
        MOVS     R0,#+7
        B.N      ??atc_2
// 1631     }            
// 1632   } // if
// 1633         
// 1634 // Set up autocal registers, must use floating point calculation
// 1635   if (irc_select) 
??atc_6:
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BEQ.N    ??atc_8
// 1636     atcv = (unsigned short)(128.0f * (21.0f * (bus_clock_freq / (float)irc_freq)));
        BL       __aeabi_i2f
        MOVS     R7,R0
        MOVS     R0,R5
        BL       __aeabi_i2f
        MOVS     R1,R0
        MOVS     R0,R7
        BL       __aeabi_fdiv
        LDR.W    R1,??DataTable26_12  ;; 0x41a80000
        BL       __aeabi_fmul
        MOVS     R1,#+1124073472
        BL       __aeabi_fmul
        BL       __aeabi_f2iz
        B.N      ??atc_9
// 1637   else
// 1638     atcv = (unsigned short)(21.0f * (bus_clock_freq / (float)irc_freq));
??atc_8:
        BL       __aeabi_i2f
        MOVS     R7,R0
        MOVS     R0,R5
        BL       __aeabi_i2f
        MOVS     R1,R0
        MOVS     R0,R7
        BL       __aeabi_fdiv
        LDR.W    R1,??DataTable26_12  ;; 0x41a80000
        BL       __aeabi_fmul
        BL       __aeabi_f2iz
// 1639         
// 1640   MCG_ATCVL = (atcv & 0xFF); //Set ATCVL to lower 8 bits of count value
??atc_9:
        LDR.W    R1,??DataTable26_13  ;; 0x4006400b
        STRB     R0,[R1, #+0]
// 1641   MCG_ATCVH = ((atcv & 0xFF00) >> 8); // Set ATCVH to upper 8 bits of count value
        UXTH     R0,R0            ;; ZeroExt  R0,R0,#+16,#+16
        LSRS     R0,R0,#+8
        LDR.W    R1,??DataTable26_14  ;; 0x4006400a
        STRB     R0,[R1, #+0]
// 1642 
// 1643 // Enable autocal
// 1644   MCG_SC &= ~(MCG_SC_ATME_MASK | MCG_SC_ATMS_MASK |MCG_SC_ATMF_MASK); // clear auto trim settings
        LDR.N    R0,??DataTable23  ;; 0x40064008
        LDRB     R0,[R0, #+0]
        ANDS     R0,R0,#0x1F
        LDR.N    R1,??DataTable23  ;; 0x40064008
        STRB     R0,[R1, #+0]
// 1645   temp_reg = (MCG_SC_ATME_MASK | (irc_select << MCG_SC_ATMS_SHIFT)); //Select IRC to trim and enable trim machine
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        LSLS     R0,R4,#+6
        ORRS     R1,R0,#0x80
// 1646   MCG_SC |= temp_reg;
        LDR.N    R0,??DataTable23  ;; 0x40064008
        LDRB     R0,[R0, #+0]
        ORRS     R0,R1,R0
        LDR.N    R1,??DataTable23  ;; 0x40064008
        STRB     R0,[R1, #+0]
// 1647         
// 1648   while (MCG_SC & MCG_SC_ATME_MASK) {}; //poll for ATME bit to clear
??atc_10:
        LDR.N    R0,??DataTable23  ;; 0x40064008
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+24
        BMI.N    ??atc_10
// 1649         
// 1650   if (MCG_SC & MCG_SC_ATMF_MASK) // check if error flag set
        LDR.N    R0,??DataTable23  ;; 0x40064008
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BPL.N    ??atc_11
// 1651   {
// 1652     SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1653     return 8;
        MOVS     R0,#+8
        B.N      ??atc_2
// 1654   } 
// 1655   else 
// 1656   {      
// 1657     if (!irc_select)
??atc_11:
        UXTB     R4,R4            ;; ZeroExt  R4,R4,#+24,#+24
        CMP      R4,#+0
        BNE.N    ??atc_12
// 1658     {
// 1659       if ((MCG_C3 == 0xFF) || (MCG_C3 == 0))
        LDR.W    R0,??DataTable26_15  ;; 0x40064002
        LDRB     R0,[R0, #+0]
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+255
        BEQ.N    ??atc_13
        LDR.W    R0,??DataTable26_15  ;; 0x40064002
        LDRB     R0,[R0, #+0]
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+0
        BNE.N    ??atc_14
// 1660       {
// 1661         SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
??atc_13:
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1662         return 9;
        MOVS     R0,#+9
        B.N      ??atc_2
// 1663       }
// 1664     }
// 1665     else
// 1666     {
// 1667       if ((((MCG_C4 & MCG_C4_FCTRIM_MASK) >> MCG_C4_FCTRIM_SHIFT) == 0xF) ||
// 1668           (((MCG_C4 & MCG_C4_FCTRIM_MASK) >> MCG_C4_FCTRIM_SHIFT) == 0))
??atc_12:
        LDR.W    R0,??DataTable26_16  ;; 0x40064003
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+1,#+4
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+15
        BEQ.N    ??atc_15
        LDR.W    R0,??DataTable26_16  ;; 0x40064003
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+1,#+4
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+0
        BNE.N    ??atc_14
// 1669       {
// 1670         SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
??atc_15:
        LDR.W    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1671         return 10;
        MOVS     R0,#+10
        B.N      ??atc_2
// 1672       }
// 1673     }
// 1674   }
// 1675   SIM_CLKDIV1 = orig_div; // set SIM_CLKDIV1 back to original value
??atc_14:
        LDR.N    R0,??DataTable26_7  ;; 0x40048044
        STR      R6,[R0, #+0]
// 1676   return 0;
        MOVS     R0,#+0
??atc_2:
        POP      {R1,R4-R7,PC}    ;; return
// 1677 }// atc

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23:
        DC32     0x40064008

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_1:
        DC32     0x1312d1

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_2:
        DC32     0x2625a1

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_3:
        DC32     0x4c4b41

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_4:
        DC32     0x989681

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_5:
        DC32     0x1312d01

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable23_6:
        DC32     0x40064000
// 1678 
// 1679 
// 1680 
// 1681 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1682 int fll_freq(int fll_ref)
// 1683 {
fll_freq:
        MOVS     R1,R0
// 1684   int fll_freq_hz;
// 1685   
// 1686   if (MCG_C4 & MCG_C4_DMX32_MASK) // if DMX32 set
        LDR.N    R2,??DataTable26_16  ;; 0x40064003
        LDRB     R2,[R2, #+0]
        LSLS     R2,R2,#+24
        BPL.N    ??fll_freq_0
// 1687   {
// 1688     switch ((MCG_C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT) // determine multiplier based on DRS
        LDR.N    R2,??DataTable26_16  ;; 0x40064003
        LDRB     R2,[R2, #+0]
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSRS     R2,R2,#+5
        ANDS     R2,R2,#0x3
        CMP      R2,#+0
        BEQ.N    ??fll_freq_1
        CMP      R2,#+2
        BEQ.N    ??fll_freq_2
        BCC.N    ??fll_freq_3
        CMP      R2,#+3
        BEQ.N    ??fll_freq_4
        B.N      ??fll_freq_5
// 1689     {
// 1690     case 0:
// 1691       fll_freq_hz = (fll_ref * 732);
??fll_freq_1:
        MOV      R0,#+732
        MUL      R0,R0,R1
// 1692       if (fll_freq_hz < 20000000) {return 0x33;}
        LDR.N    R1,??DataTable26_6  ;; 0x1312d00
        CMP      R0,R1
        BGE.N    ??fll_freq_6
        MOVS     R0,#+51
        B.N      ??fll_freq_7
// 1693       else if (fll_freq_hz > 25000000) {return 0x34;}
??fll_freq_6:
        LDR.N    R1,??DataTable26_17  ;; 0x17d7841
        CMP      R0,R1
        BLT.N    ??fll_freq_8
        MOVS     R0,#+52
        B.N      ??fll_freq_7
// 1694       break;
??fll_freq_8:
        B.N      ??fll_freq_5
// 1695     case 1:
// 1696       fll_freq_hz = (fll_ref * 1464);
??fll_freq_3:
        MOV      R0,#+1464
        MUL      R0,R0,R1
// 1697       if (fll_freq_hz < 40000000) {return 0x35;}
        LDR.N    R1,??DataTable26_18  ;; 0x2625a00
        CMP      R0,R1
        BGE.N    ??fll_freq_9
        MOVS     R0,#+53
        B.N      ??fll_freq_7
// 1698       else if (fll_freq_hz > 50000000) {return 0x36;}
??fll_freq_9:
        LDR.N    R1,??DataTable26_19  ;; 0x2faf081
        CMP      R0,R1
        BLT.N    ??fll_freq_10
        MOVS     R0,#+54
        B.N      ??fll_freq_7
// 1699       break;
??fll_freq_10:
        B.N      ??fll_freq_5
// 1700     case 2:
// 1701       fll_freq_hz = (fll_ref * 2197);
??fll_freq_2:
        MOVW     R0,#+2197
        MUL      R0,R0,R1
// 1702       if (fll_freq_hz < 60000000) {return 0x37;}
        LDR.N    R1,??DataTable26_20  ;; 0x3938700
        CMP      R0,R1
        BGE.N    ??fll_freq_11
        MOVS     R0,#+55
        B.N      ??fll_freq_7
// 1703       else if (fll_freq_hz > 75000000) {return 0x38;}
??fll_freq_11:
        LDR.N    R1,??DataTable26_21  ;; 0x47868c1
        CMP      R0,R1
        BLT.N    ??fll_freq_12
        MOVS     R0,#+56
        B.N      ??fll_freq_7
// 1704       break;
??fll_freq_12:
        B.N      ??fll_freq_5
// 1705     case 3:
// 1706       fll_freq_hz = (fll_ref * 2929);
??fll_freq_4:
        MOVW     R0,#+2929
        MUL      R0,R0,R1
// 1707       if (fll_freq_hz < 80000000) {return 0x39;}
        LDR.N    R1,??DataTable26_22  ;; 0x4c4b400
        CMP      R0,R1
        BGE.N    ??fll_freq_13
        MOVS     R0,#+57
        B.N      ??fll_freq_7
// 1708       else if (fll_freq_hz > 100000000) {return 0x3A;}
??fll_freq_13:
        LDR.N    R1,??DataTable26_23  ;; 0x5f5e101
        CMP      R0,R1
        BLT.N    ??fll_freq_14
        MOVS     R0,#+58
        B.N      ??fll_freq_7
// 1709       break;
??fll_freq_14:
        B.N      ??fll_freq_5
// 1710     }
// 1711   }
// 1712   else // if DMX32 = 0
// 1713   {
// 1714     switch ((MCG_C4 & MCG_C4_DRST_DRS_MASK) >> MCG_C4_DRST_DRS_SHIFT) // determine multiplier based on DRS
??fll_freq_0:
        LDR.N    R2,??DataTable26_16  ;; 0x40064003
        LDRB     R2,[R2, #+0]
        UXTB     R2,R2            ;; ZeroExt  R2,R2,#+24,#+24
        LSRS     R2,R2,#+5
        ANDS     R2,R2,#0x3
        CMP      R2,#+0
        BEQ.N    ??fll_freq_15
        CMP      R2,#+2
        BEQ.N    ??fll_freq_16
        BCC.N    ??fll_freq_17
        CMP      R2,#+3
        BEQ.N    ??fll_freq_18
        B.N      ??fll_freq_5
// 1715     {
// 1716     case 0:
// 1717       fll_freq_hz = (fll_ref * 640);
??fll_freq_15:
        MOV      R0,#+640
        MUL      R0,R0,R1
// 1718       if (fll_freq_hz < 20000000) {return 0x33;}
        LDR.N    R1,??DataTable26_6  ;; 0x1312d00
        CMP      R0,R1
        BGE.N    ??fll_freq_19
        MOVS     R0,#+51
        B.N      ??fll_freq_7
// 1719       else if (fll_freq_hz > 25000000) {return 0x34;}
??fll_freq_19:
        LDR.N    R1,??DataTable26_17  ;; 0x17d7841
        CMP      R0,R1
        BLT.N    ??fll_freq_20
        MOVS     R0,#+52
        B.N      ??fll_freq_7
// 1720       break;
??fll_freq_20:
        B.N      ??fll_freq_5
// 1721     case 1:
// 1722       fll_freq_hz = (fll_ref * 1280);
??fll_freq_17:
        MOV      R0,#+1280
        MUL      R0,R0,R1
// 1723       if (fll_freq_hz < 40000000) {return 0x35;}
        LDR.N    R1,??DataTable26_18  ;; 0x2625a00
        CMP      R0,R1
        BGE.N    ??fll_freq_21
        MOVS     R0,#+53
        B.N      ??fll_freq_7
// 1724       else if (fll_freq_hz > 50000000) {return 0x36;}
??fll_freq_21:
        LDR.N    R1,??DataTable26_19  ;; 0x2faf081
        CMP      R0,R1
        BLT.N    ??fll_freq_22
        MOVS     R0,#+54
        B.N      ??fll_freq_7
// 1725       break;
??fll_freq_22:
        B.N      ??fll_freq_5
// 1726     case 2:
// 1727       fll_freq_hz = (fll_ref * 1920);
??fll_freq_16:
        MOV      R0,#+1920
        MUL      R0,R0,R1
// 1728       if (fll_freq_hz < 60000000) {return 0x37;}
        LDR.N    R1,??DataTable26_20  ;; 0x3938700
        CMP      R0,R1
        BGE.N    ??fll_freq_23
        MOVS     R0,#+55
        B.N      ??fll_freq_7
// 1729       else if (fll_freq_hz > 75000000) {return 0x38;}
??fll_freq_23:
        LDR.N    R1,??DataTable26_21  ;; 0x47868c1
        CMP      R0,R1
        BLT.N    ??fll_freq_24
        MOVS     R0,#+56
        B.N      ??fll_freq_7
// 1730       break;
??fll_freq_24:
        B.N      ??fll_freq_5
// 1731     case 3:
// 1732       fll_freq_hz = (fll_ref * 2560);
??fll_freq_18:
        MOV      R0,#+2560
        MUL      R0,R0,R1
// 1733       if (fll_freq_hz < 80000000) {return 0x39;}
        LDR.N    R1,??DataTable26_22  ;; 0x4c4b400
        CMP      R0,R1
        BGE.N    ??fll_freq_25
        MOVS     R0,#+57
        B.N      ??fll_freq_7
// 1734       else if (fll_freq_hz > 100000000) {return 0x3A;}
??fll_freq_25:
        LDR.N    R1,??DataTable26_23  ;; 0x5f5e101
        CMP      R0,R1
        BLT.N    ??fll_freq_26
        MOVS     R0,#+58
        B.N      ??fll_freq_7
// 1735       break;
// 1736     }
// 1737   }    
// 1738   return fll_freq_hz;
??fll_freq_26:
??fll_freq_5:
??fll_freq_7:
        BX       LR               ;; return
// 1739 } // fll_freq

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable24:
        DC32     0x40064005

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable24_1:
        DC32     0x40064006
// 1740 
// 1741 

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1742 unsigned char what_mcg_mode(void)
// 1743 {
// 1744   // check if in FEI mode
// 1745   if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) &&      // check CLKS mux has selcted FLL output
// 1746       (MCG_S & MCG_S_IREFST_MASK) &&                                     // check FLL ref is internal ref clk
// 1747       (!(MCG_S & MCG_S_PLLST_MASK)))                                     // check PLLS mux has selected FLL
what_mcg_mode:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+0
        BNE.N    ??what_mcg_mode_0
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BPL.N    ??what_mcg_mode_0
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BMI.N    ??what_mcg_mode_0
// 1748   {
// 1749     return FEI;                                                          // return FEI code
        MOVS     R0,#+3
        B.N      ??what_mcg_mode_1
// 1750   }
// 1751   // Check MCG is in PEE mode
// 1752   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x3) && // check CLKS mux has selcted PLL output
// 1753           (!(MCG_S & MCG_S_IREFST_MASK)) &&                              // check FLL ref is external ref clk
// 1754           (MCG_S & MCG_S_PLLST_MASK))                                    // check PLLS mux has selected PLL 
??what_mcg_mode_0:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+3
        BNE.N    ??what_mcg_mode_2
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BMI.N    ??what_mcg_mode_2
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BPL.N    ??what_mcg_mode_2
// 1755   {
// 1756     return PEE;                                                          // return PEE code
        MOVS     R0,#+8
        B.N      ??what_mcg_mode_1
// 1757   }
// 1758   // Check MCG is in PBE mode
// 1759   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
// 1760           (!(MCG_S & MCG_S_IREFST_MASK)) &&                              // check FLL ref is external ref clk
// 1761           (MCG_S & MCG_S_PLLST_MASK) &&                                  // check PLLS mux has selected PLL
// 1762           (!(MCG_C2 & MCG_C2_LP_MASK)))                                  // check MCG_C2[LP] bit is not set
??what_mcg_mode_2:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+2
        BNE.N    ??what_mcg_mode_3
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BMI.N    ??what_mcg_mode_3
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BPL.N    ??what_mcg_mode_3
        LDR.N    R0,??DataTable26_25  ;; 0x40064001
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+30
        BMI.N    ??what_mcg_mode_3
// 1763   {
// 1764     return PBE;                                                          // return PBE code
        MOVS     R0,#+7
        B.N      ??what_mcg_mode_1
// 1765   }
// 1766   // Check MCG is in FBE mode
// 1767   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
// 1768           (!(MCG_S & MCG_S_IREFST_MASK)) &&                              // check FLL ref is external ref clk
// 1769           (!(MCG_S & MCG_S_PLLST_MASK)) &&                               // check PLLS mux has selected FLL
// 1770           (!(MCG_C2 & MCG_C2_LP_MASK)))                                  // check MCG_C2[LP] bit is not set   
??what_mcg_mode_3:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+2
        BNE.N    ??what_mcg_mode_4
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BMI.N    ??what_mcg_mode_4
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BMI.N    ??what_mcg_mode_4
        LDR.N    R0,??DataTable26_25  ;; 0x40064001
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+30
        BMI.N    ??what_mcg_mode_4
// 1771   {
// 1772     return FBE;                                                          // return FBE code
        MOVS     R0,#+5
        B.N      ??what_mcg_mode_1
// 1773   }
// 1774   // Check MCG is in BLPE mode
// 1775   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) && // check CLKS mux has selcted external reference
// 1776           (!(MCG_S & MCG_S_IREFST_MASK)) &&                              // check FLL ref is external ref clk
// 1777           (MCG_C2 & MCG_C2_LP_MASK))                                     // check MCG_C2[LP] bit is set   
??what_mcg_mode_4:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+2
        BNE.N    ??what_mcg_mode_5
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BMI.N    ??what_mcg_mode_5
        LDR.N    R0,??DataTable26_25  ;; 0x40064001
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+30
        BPL.N    ??what_mcg_mode_5
// 1778   {
// 1779     return BLPE;                                                         // return BLPE code
        MOVS     R0,#+6
        B.N      ??what_mcg_mode_1
// 1780   }
// 1781   // check if in BLPI mode
// 1782   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1783           (MCG_S & MCG_S_IREFST_MASK) &&                                 // check FLL ref is internal ref clk
// 1784           (!(MCG_S & MCG_S_PLLST_MASK)) &&                               // check PLLS mux has selected FLL
// 1785           (MCG_C2 & MCG_C2_LP_MASK))                                     // check LP bit is set
??what_mcg_mode_5:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+1
        BNE.N    ??what_mcg_mode_6
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BPL.N    ??what_mcg_mode_6
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BMI.N    ??what_mcg_mode_6
        LDR.N    R0,??DataTable26_25  ;; 0x40064001
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+30
        BPL.N    ??what_mcg_mode_6
// 1786   {
// 1787     return BLPI;                                                         // return BLPI code
        MOVS     R0,#+1
        B.N      ??what_mcg_mode_1
// 1788   }
// 1789   // check if in FBI mode
// 1790   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x1) && // check CLKS mux has selcted int ref clk
// 1791           (MCG_S & MCG_S_IREFST_MASK) &&                                 // check FLL ref is internal ref clk
// 1792           (!(MCG_S & MCG_S_PLLST_MASK)) &&                               // check PLLS mux has selected FLL
// 1793           (!(MCG_C2 & MCG_C2_LP_MASK)))                                  // check LP bit is clear
??what_mcg_mode_6:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+1
        BNE.N    ??what_mcg_mode_7
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BPL.N    ??what_mcg_mode_7
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BMI.N    ??what_mcg_mode_7
        LDR.N    R0,??DataTable26_25  ;; 0x40064001
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+30
        BMI.N    ??what_mcg_mode_7
// 1794   {  
// 1795     return FBI;                                                          // return FBI code 
        MOVS     R0,#+2
        B.N      ??what_mcg_mode_1
// 1796   }
// 1797   // Check MCG is in FEE mode
// 1798   else if ((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL
// 1799           (!(MCG_S & MCG_S_IREFST_MASK)) &&                              // check FLL ref is external ref clk
// 1800           (!(MCG_S & MCG_S_PLLST_MASK)))                                 // check PLLS mux has selected FLL
??what_mcg_mode_7:
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        UBFX     R0,R0,#+2,#+2
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+0
        BNE.N    ??what_mcg_mode_8
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+27
        BMI.N    ??what_mcg_mode_8
        LDR.N    R0,??DataTable26_24  ;; 0x40064006
        LDRB     R0,[R0, #+0]
        LSLS     R0,R0,#+26
        BMI.N    ??what_mcg_mode_8
// 1801   {
// 1802     return FEE;                                                          // return FEE code
        MOVS     R0,#+4
        B.N      ??what_mcg_mode_1
// 1803   }
// 1804   else
// 1805   {
// 1806     return 0;                                                            // error condition
??what_mcg_mode_8:
        MOVS     R0,#+0
??what_mcg_mode_1:
        BX       LR               ;; return
// 1807   }
// 1808 } // what_mcg_mode
// 1809 
// 1810 
// 1811 /********************************************************************/
// 1812 /* Functon name : clk_monitor_0
// 1813  *
// 1814  * This function simply enables or disables the OSC 0 clock monitor. This is
// 1815  * achieved by setting or clearing the MCG_C6[CME] bit. It is recommended to  
// 1816  * enable this monitor in external clock modes (FEE, FBE, BLPE, PBE and PEE.
// 1817  * It MUST be disabled in all other modes or a reset may be generated. It must
// 1818  * also be disabled if it is desired to enter VLPR from BLPE mode.
// 1819  *
// 1820  * Parameters: en_dis - enables (= 1) or disables (= 0) the OSC 0 clock monitor
// 1821  *
// 1822  * Return value : none
// 1823  */

        SECTION `.text`:CODE:NOROOT(1)
        THUMB
// 1824 void clk_monitor_0(unsigned char en_dis)
// 1825 {         
// 1826   if (en_dis)
clk_monitor_0:
        UXTB     R0,R0            ;; ZeroExt  R0,R0,#+24,#+24
        CMP      R0,#+0
        BEQ.N    ??clk_monitor_0_0
// 1827   {
// 1828     MCG_C6 |= MCG_C6_CME_MASK;   
        LDR.N    R0,??DataTable26_1  ;; 0x40064005
        LDRB     R0,[R0, #+0]
        ORRS     R0,R0,#0x20
        LDR.N    R1,??DataTable26_1  ;; 0x40064005
        STRB     R0,[R1, #+0]
        B.N      ??clk_monitor_0_1
// 1829   }
// 1830   else
// 1831   {
// 1832     MCG_C6 &= ~MCG_C6_CME_MASK;
??clk_monitor_0_0:
        LDR.N    R0,??DataTable26_1  ;; 0x40064005
        LDRB     R0,[R0, #+0]
        ANDS     R0,R0,#0xDF
        LDR.N    R1,??DataTable26_1  ;; 0x40064005
        STRB     R0,[R1, #+0]
// 1833   }
// 1834 }    // end clk_monitor_0
??clk_monitor_0_1:
        BX       LR               ;; return

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26:
        DC32     0x40064008

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_1:
        DC32     0x40064005

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_2:
        DC32     0x3938701

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_3:
        DC32     0x2d2a7f

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_4:
        DC32     0x1e84801

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_5:
        DC32     0x7a1201

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_6:
        DC32     0x1312d00

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_7:
        DC32     0x40048044

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_8:
        DC32     0xf42400

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_9:
        DC32     0xf0f0ffff

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_10:
        DC32     0x7a1200

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_11:
        DC32     0x2dc6c0

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_12:
        DC32     0x41a80000

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_13:
        DC32     0x4006400b

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_14:
        DC32     0x4006400a

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_15:
        DC32     0x40064002

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_16:
        DC32     0x40064003

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_17:
        DC32     0x17d7841

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_18:
        DC32     0x2625a00

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_19:
        DC32     0x2faf081

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_20:
        DC32     0x3938700

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_21:
        DC32     0x47868c1

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_22:
        DC32     0x4c4b400

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_23:
        DC32     0x5f5e101

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_24:
        DC32     0x40064006

        SECTION `.text`:CODE:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
??DataTable26_25:
        DC32     0x40064001

        SECTION `.iar_vfe_header`:DATA:REORDER:NOALLOC:NOROOT(2)
        SECTION_TYPE SHT_PROGBITS, 0
        DATA
        DC32 0

        SECTION __DLIB_PERTHREAD:DATA:REORDER:NOROOT(0)
        SECTION_TYPE SHT_PROGBITS, 0

        SECTION __DLIB_PERTHREAD_init:DATA:REORDER:NOROOT(0)
        SECTION_TYPE SHT_PROGBITS, 0

        END
// 1835 
// 1836 /*
// 1837 int fei_pee(int crystal_val, unsigned char hgo_val, unsigned char erefs_val, signed char prdiv_val, signed char vdiv_val)
// 1838 {
// 1839   unsigned char frdiv_val;
// 1840   unsigned char temp_reg;
// 1841   unsigned char prdiv, vdiv;
// 1842   short i;
// 1843   int ref_freq;
// 1844   int pll_freq;
// 1845 
// 1846 // check if in FEI mode
// 1847   if (!((((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x0) && // check CLKS mux has selcted FLL output
// 1848       (MCG_S & MCG_S_IREFST_MASK) &&                                  // check FLL ref is internal ref clk
// 1849       (!(MCG_S & MCG_S_PLLST_MASK))))                                 // check PLLS mux has selected FLL
// 1850   {
// 1851     return 0x1;                                                     // return error code
// 1852   }
// 1853 
// 1854 // check external frequency is less than the maximum frequency
// 1855   if  (crystal_val > 50000000) {return 0x21;}
// 1856 
// 1857 // check crystal frequency is within spec. if crystal osc is being used as PLL ref
// 1858   if (erefs_val)
// 1859   {
// 1860     if ((crystal_val < 8000000) || (crystal_val > 32000000)) {return 0x22;} // return 1 if one of the available crystal options is not available
// 1861   }
// 1862 
// 1863 // make sure HGO will never be greater than 1. Could return an error instead if desired.
// 1864   if (hgo_val > 0)
// 1865   {
// 1866     hgo_val = 1; // force hgo_val to 1 if > 0
// 1867   }
// 1868 
// 1869 // Check PLL divider settings are within spec.
// 1870   if ((prdiv_val < 1) || (prdiv_val > 8)) {return 0x41;}
// 1871   if ((vdiv_val < 16) || (vdiv_val > 47)) {return 0x42;}
// 1872 
// 1873 // Check PLL reference clock frequency is within spec.
// 1874   ref_freq = crystal_val / prdiv_val;
// 1875   if ((ref_freq < 8000000) || (ref_freq > 32000000)) {return 0x43;}
// 1876 
// 1877 // Check PLL output frequency is within spec.
// 1878   pll_freq = (crystal_val / prdiv_val) * vdiv_val;
// 1879   if ((pll_freq < 180000000) || (pll_freq > 360000000)) {return 0x45;}
// 1880 
// 1881 // configure the MCG_C2 register
// 1882 // the RANGE value is determined by the external frequency. Since the RANGE parameter affects the FRDIV divide value
// 1883 // it still needs to be set correctly even if the oscillator is not being used
// 1884   if (crystal_val <= 40000)
// 1885   {
// 1886     MCG_C2 = MCG_C2_RANGE(0) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT);
// 1887   }
// 1888   else if (crystal_val <= 8000000)
// 1889   {
// 1890     MCG_C2 = MCG_C2_RANGE(1) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT);
// 1891   }
// 1892   else
// 1893   {
// 1894     MCG_C2 = MCG_C2_RANGE(2) | (hgo_val << MCG_C2_HGO_SHIFT) | (erefs_val << MCG_C2_EREFS_SHIFT);
// 1895   }
// 1896 
// 1897 // determine FRDIV based on reference clock frequency
// 1898 // since the external frequency has already been checked only the maximum frequency for each FRDIV value needs to be compared here.
// 1899   if (crystal_val <= 1250000) {frdiv_val = 0;}
// 1900   else if (crystal_val <= 2500000) {frdiv_val = 1;}
// 1901   else if (crystal_val <= 5000000) {frdiv_val = 2;}
// 1902   else if (crystal_val <= 10000000) {frdiv_val = 3;}
// 1903   else if (crystal_val <= 20000000) {frdiv_val = 4;}
// 1904   else {frdiv_val = 5;}
// 1905 
// 1906 // Select external oscillator and Reference Divider and clear IREFS to start ext osc
// 1907 // If IRCLK is required it must be enabled outside of this driver, existing state will be maintained
// 1908 // CLKS=2, FRDIV=frdiv_val, IREFS=0, IRCLKEN=0, IREFSTEN=0
// 1909   temp_reg = MCG_C1;
// 1910   temp_reg &= ~(MCG_C1_CLKS_MASK | MCG_C1_FRDIV_MASK | MCG_C1_IREFS_MASK); // Clear values in these fields
// 1911   temp_reg = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv_val); // Set the required CLKS and FRDIV values
// 1912   MCG_C1 = temp_reg;
// 1913 
// 1914 // if the external oscillator is used need to wait for OSCINIT to set
// 1915   if (erefs_val)
// 1916   {
// 1917     for (i = 0 ; i < 10000 ; i++)
// 1918     {
// 1919       if (MCG_S & MCG_S_OSCINIT_MASK) break; // jump out early if OSCINIT sets before loop finishes
// 1920     }
// 1921     if (!(MCG_S & MCG_S_OSCINIT_MASK)) return 0x23; // check bit is really set and return with error if not set
// 1922   }
// 1923 
// 1924 // wait for Reference clock Status bit to clear
// 1925   for (i = 0 ; i < 2000 ; i++)
// 1926   {
// 1927     if (!(MCG_S & MCG_S_IREFST_MASK)) break; // jump out early if IREFST clears before loop finishes
// 1928   }
// 1929   if (MCG_S & MCG_S_IREFST_MASK) return 0x11; // check bit is really clear and return with error if not set
// 1930 
// 1931 // Wait for clock status bits to show clock source is ext ref clk
// 1932   for (i = 0 ; i < 2000 ; i++)
// 1933   {
// 1934     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x2) break; // jump out early if CLKST shows EXT CLK slected before loop finishes
// 1935   }
// 1936   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x2) return 0x1A; // check EXT CLK is really selected and return with error if not
// 1937 
// 1938 // Now in FBE
// 1939 // It is recommended that the clock monitor is enabled when using an external clock as the clock source/reference.
// 1940 // It is enabled here but can be removed if this is not required.
// 1941   MCG_C6 |= MCG_C6_CME_MASK;
// 1942 
// 1943 // Configure MCG_C5
// 1944 // If the PLL is to run in STOP mode then the PLLSTEN bit needs to be OR'ed in here or in user code.
// 1945   temp_reg = MCG_C5;
// 1946   temp_reg &= ~MCG_C5_PRDIV_MASK;
// 1947   temp_reg |= MCG_C5_PRDIV(prdiv_val - 1);    //set PLL ref divider
// 1948   MCG_C5 = temp_reg;
// 1949 
// 1950 // Configure MCG_C6
// 1951 // The PLLS bit is set to enable the PLL, MCGOUT still sourced from ext ref clk
// 1952 // The loss of lock interrupt can be enabled by seperately OR'ing in the LOLIE bit in MCG_C6
// 1953   temp_reg = MCG_C6; // store present C6 value
// 1954   temp_reg &= ~MCG_C6_VDIV_MASK; // clear VDIV settings
// 1955   temp_reg |= MCG_C6_PLLS_MASK | MCG_C6_VDIV(vdiv_val - 24); // write new VDIV and enable PLL
// 1956   MCG_C6 = temp_reg; // update MCG_C6
// 1957 
// 1958 // wait for PLLST status bit to set
// 1959   for (i = 0 ; i < 2000 ; i++)
// 1960   {
// 1961     if (MCG_S & MCG_S_PLLST_MASK) break; // jump out early if PLLST sets before loop finishes
// 1962   }
// 1963   if (!(MCG_S & MCG_S_PLLST_MASK)) return 0x16; // check bit is really set and return with error if not set
// 1964 
// 1965 // Wait for LOCK bit to set
// 1966   for (i = 0 ; i < 2000 ; i++)
// 1967   {
// 1968     if (MCG_S & MCG_S_LOCK_MASK) break; // jump out early if LOCK sets before loop finishes
// 1969   }
// 1970   if (!(MCG_S & MCG_S_LOCK_MASK)) return 0x44; // check bit is really set and return with error if not set
// 1971 
// 1972 // now in PBE
// 1973 
// 1974   MCG_C1 &= ~MCG_C1_CLKS_MASK; // clear CLKS to switch CLKS mux to select PLL as MCG_OUT
// 1975 
// 1976 // Wait for clock status bits to update
// 1977   for (i = 0 ; i < 2000 ; i++)
// 1978   {
// 1979     if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) == 0x3) break; // jump out early if CLKST = 3 before loop finishes
// 1980   }
// 1981   if (((MCG_S & MCG_S_CLKST_MASK) >> MCG_S_CLKST_SHIFT) != 0x3) return 0x1B; // check CLKST is set correctly and return with error if not
// 1982 
// 1983 // Use actual PLL settings to calculate PLL frequency
// 1984   prdiv = ((MCG_C5 & MCG_C5_PRDIV_MASK) + 1);
// 1985   vdiv = ((MCG_C6 & MCG_C6_VDIV_MASK) + 24);
// 1986 
// 1987 // Now in PEE
// 1988   return (((crystal_val / prdiv) * vdiv) / 2); //MCGOUT equals PLL output frequency/2
// 1989 } // fei_pee
// 1990 */
// 1991 
// 1992 
// 
// 6 834 bytes in section .text
// 
// 6 834 bytes of CODE memory
//
//Errors: none
//Warnings: none
