/*==========================================================================
//
//      lpc1xxx_misc.c
//
//      Cortex-M LPC1XXX HAL functions
//
//==========================================================================
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
// -------------------------------------------                              
// This file is part of eCos, the Embedded Configurable Operating System.   
// Copyright (C) 2008, 2009 Free Software Foundation, Inc.                        
//
// eCos is free software; you can redistribute it and/or modify it under    
// the terms of the GNU General Public License as published by the Free     
// Software Foundation; either version 2 or (at your option) any later      
// version.                                                                 
//
// eCos is distributed in the hope that it will be useful, but WITHOUT      
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
// for more details.                                                        
//
// You should have received a copy of the GNU General Public License        
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
//
// As a special exception, if other files instantiate templates or use      
// macros or inline functions from this file, or you compile this file      
// and link it with other works to produce a work based on this file,       
// this file does not by itself cause the resulting work to be covered by   
// the GNU General Public License. However the source code for this file    
// must still be made available in accordance with section (3) of the GNU   
// General Public License v2.                                               
//
// This exception does not invalidate any other reasons why a work based    
// on this file might be covered by the GNU General Public License.         
// -------------------------------------------                              
// ####ECOSGPLCOPYRIGHTEND####                                              
//==========================================================================
//#####DESCRIPTIONBEGIN####
//
// Author(s):    nickg
// Date:         2009-11-20
// Description:  
//
//####DESCRIPTIONEND####
//
//========================================================================*/

#include <pkgconf/hal.h>
#include <pkgconf/hal_cortexm.h>
#include <pkgconf/hal_cortexm_lpc1xxx.h>
#ifdef CYGPKG_KERNEL
#include <pkgconf/kernel.h>
#endif

#include <cyg/infra/diag.h>
#include <cyg/infra/cyg_type.h>
#include <cyg/infra/cyg_trac.h>         // tracing macros
#include <cyg/infra/cyg_ass.h>          // assertion macros

#include <cyg/hal/hal_arch.h>           // HAL header
#include <cyg/hal/hal_intr.h>           // HAL header
#include <cyg/hal/hal_if.h>             // HAL header

//==========================================================================
// Clock frequencies
//
// These are set to the frequencies of the various system clocks.

cyg_uint32 hal_lpc1xxx_sysclk;
cyg_uint32 hal_lpc1xxx_pllclk;
cyg_uint32 hal_lpc1xxx_cclk;
cyg_uint32 hal_cortexm_systick_clock;

void hal_start_clocks( void );

cyg_uint8 const hal_lpc1xxx_pclock_divider[4] = { 4, 1, 2, 8 };

//==========================================================================

void hal_variant_init( void )
{
#if !defined(CYG_HAL_STARTUP_RAM)
    hal_start_clocks();
#endif

#ifdef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
    hal_if_init();
#endif
}

//==========================================================================
// Setup up system clocks
//
// Set up clocks from configuration. In the future this should be extended so
// that clock rates can be changed at runtime.

void hal_start_clocks( void )
{
    CYG_ADDRESS scb = CYGHWR_HAL_LPC1XXX_SCB;
    cyg_uint32 pllstat, pllcon, pllcfg;

    HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT, pllstat );
    if( pllstat & CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT_PLLC )
    {
        // Disconnect PLL, clear PLLC, keep PLLE set
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0CON,
                          CYGHWR_HAL_LPC1XXX_SCB_PLL0CON_PLLE );
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                          CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY0 );
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                          CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY1 );
    }

    // Disable PLL
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0CON, 0 );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY0 );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY1 );

#if defined(CYGHWR_HAL_CORTEXM_LPC1XXX_SYSCLK_SOURCE_OSC)
    {
        cyg_uint32 scs = CYGHWR_HAL_LPC1XXX_SCB_SCS_OSCEN;

        // Enable the external ocillator

        hal_lpc1xxx_sysclk = CYGHWR_HAL_LPC1XXX_INPUT_CLOCK;
        
        if( hal_lpc1xxx_sysclk >= 15000000 )
            scs |= CYGHWR_HAL_LPC1XXX_SCB_SCS_OSCRANGE;

        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_SCS, scs );

        // Wait for ocillator to settle
        do
        {
            HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_SCS, scs );
        } while( 0 == (scs & CYGHWR_HAL_LPC1XXX_SCB_SCS_OSCSTAT) );

        // Select main ocillator as SYSCLK
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL,
                          CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL_MAIN);
    }
#elif defined(CYGHWR_HAL_CORTEXM_LPC1XXX_SYSCLK_SOURCE_RTC)    

    hal_lpc1xxx_sysclk = 32000;
    
    // Select RTC ocillator as SYSCLK
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL,
                      CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL_RTC);

#elif defined(CYGHWR_HAL_CORTEXM_LPC1XXX_SYSCLK_SOURCE_IRC)    

    hal_lpc1xxx_sysclk = 4000000;
    
    // Select internal ocillator as SYSCLK
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL,
                      CYGHWR_HAL_LPC1XXX_SCB_CLKSRCSEL_IRC);
    
#endif

#ifdef CYGHWR_HAL_CORTEXM_LPC1XXX_CCLK_SOURCE_PLL

    // Set multiplier and divider
    pllcfg = CYGHWR_HAL_LPC1XXX_SCB_PLL0CFG_MSEL(CYGHWR_HAL_CORTEXM_LPC1XXX_PLL0_MUL-1) |
             CYGHWR_HAL_LPC1XXX_SCB_PLL0CFG_NSEL(CYGHWR_HAL_CORTEXM_LPC1XXX_PLL0_PREDIV-1);

    hal_lpc1xxx_pllclk =
    hal_lpc1xxx_cclk = (hal_lpc1xxx_sysclk * 2 * CYGHWR_HAL_CORTEXM_LPC1XXX_PLL0_MUL) /
                                                 CYGHWR_HAL_CORTEXM_LPC1XXX_PLL0_PREDIV;
    
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0CFG, pllcfg );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY0 );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY1 );

    // Enable the PLL and wait for it to lock

    pllcon = CYGHWR_HAL_LPC1XXX_SCB_PLL0CON_PLLE;
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0CON, pllcon );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY0 );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY1 );

    do
    {
        HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT, pllstat );
    } while( 0 == (pllstat & CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT_PLOCK) );

    // set CCLK divider

    hal_lpc1xxx_cclk /= CYGHWR_HAL_CORTEXM_LPC1XXX_CCLK_DIV;
    
    HAL_WRITE_UINT32(scb+CYGHWR_HAL_LPC1XXX_SCB_CCLKCFG,
                     CYGHWR_HAL_CORTEXM_LPC1XXX_CCLK_DIV-1 );
    
    // Connect the PLL and wait for it to connect

    pllcon |= CYGHWR_HAL_LPC1XXX_SCB_PLL0CON_PLLC;
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0CON, pllcon );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY0 );
    HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED,
                      CYGHWR_HAL_LPC1XXX_SCB_PLL0FEED_KEY1 );

    do
    {
        HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT, pllstat );
    } while( 0 == (pllstat & CYGHWR_HAL_LPC1XXX_SCB_PLL0STAT_PLLC) );
    
#else
#error Non-PLL CCLK source not yet supported
#endif
            
    hal_cortexm_systick_clock = hal_lpc1xxx_cclk;
}

//==========================================================================
// GPIO support
//
// These functions provide configuration and IO for GPIO pins.

__externC void hal_lpc1xxx_gpio_set( cyg_uint32 pin )
{
    cyg_uint32 pinsel = CYGHWR_HAL_LPC1XXX_PCB;
    cyg_uint32 gpio = CYGHWR_HAL_LPC1XXX_FGPIO;

    cyg_uint32 port = CYGHWR_HAL_LPC1XXX_GPIO_PORT(pin);
    int bit = CYGHWR_HAL_LPC1XXX_GPIO_BIT(pin);
    cyg_uint32 bitmask = 1<<bit;
    cyg_uint32 mode = CYGHWR_HAL_LPC1XXX_GPIO_MODE(pin);
    cyg_uint32 reg;
    
    if( pin == CYGHWR_HAL_LPC1XXX_GPIO_NONE )
        return;

    // Set PINSEL for this pin
    HAL_READ_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINSEL(port,bit), reg );
    reg &= ~CYGHWR_HAL_LPC1XXX_PCB_PINSEL_FIELD( bit, 3);
    reg |= CYGHWR_HAL_LPC1XXX_PCB_PINSEL_FIELD( bit, CYGHWR_HAL_LPC1XXX_GPIO_MODE_PINSEL(mode));
    HAL_WRITE_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINSEL(port,bit), reg );

    // Set PINMODE for this pin
    HAL_READ_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINMODE(port,bit), reg );
    reg &= ~CYGHWR_HAL_LPC1XXX_PCB_PINMODE_FIELD( bit, 3);
    reg |= CYGHWR_HAL_LPC1XXX_PCB_PINMODE_FIELD( bit, CYGHWR_HAL_LPC1XXX_GPIO_MODE_PINMODE(mode));
    HAL_WRITE_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINMODE(port,bit), reg );

    // Set PINMODE_OD for this pin
    HAL_READ_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINMODE_OD(port,bit), reg );
    reg &= ~bitmask;
    reg |= (mode & CYGHWR_HAL_LPC1XXX_GPIO_MODE_OPENDRAIN) ? bitmask : 0;
    HAL_WRITE_UINT32( pinsel+CYGHWR_HAL_LPC1XXX_PCB_PINMODE(port,bit), reg );

    if( CYGHWR_HAL_LPC1XXX_GPIO_MODE_PINSEL(mode) == CYGHWR_HAL_LPC1XXX_GPIO_MODE_GPIO )
    {
        // Set direction
        HAL_READ_UINT32( gpio+CYGHWR_HAL_LPC1XXX_GPIO_FIODIR(port), reg );
        reg &= ~bitmask;
        reg |= (mode & CYGHWR_HAL_LPC1XXX_GPIO_MODE_OUTPUT) ? bitmask : 0;
        HAL_WRITE_UINT32( gpio+CYGHWR_HAL_LPC1XXX_GPIO_FIODIR(port), reg );
    }
   
}
    
__externC void hal_lpc1xxx_gpio_out( cyg_uint32 pin, int val )
{
    cyg_uint32 gpio = CYGHWR_HAL_LPC1XXX_FGPIO;    
    cyg_uint32 port = CYGHWR_HAL_LPC1XXX_GPIO_PORT(pin);
    int bit = CYGHWR_HAL_LPC1XXX_GPIO_BIT(pin);

    if( val&1 )
        HAL_WRITE_UINT32( gpio+CYGHWR_HAL_LPC1XXX_GPIO_FIOSET(port), 1<<bit );
    else
        HAL_WRITE_UINT32( gpio+CYGHWR_HAL_LPC1XXX_GPIO_FIOCLR(port), 1<<bit );
}
    
__externC void hal_lpc1xxx_gpio_in ( cyg_uint32 pin, int *val )
{
    cyg_uint32 gpio = CYGHWR_HAL_LPC1XXX_FGPIO;    
    cyg_uint32 port = CYGHWR_HAL_LPC1XXX_GPIO_PORT(pin);
    int bit = CYGHWR_HAL_LPC1XXX_GPIO_BIT(pin);
    cyg_uint32 data;
    
    HAL_READ_UINT32( gpio+CYGHWR_HAL_LPC1XXX_GPIO_FIOPIN(port), data );

    *val = (data>>bit)&1;
}

//==========================================================================
// Clock support.
//
// These functions provide support for enabling and disabling clock
// and power control bits.

__externC void hal_lpc1xxx_clock_enable( cyg_uint32 desc )
{
    cyg_uint32 scb = CYGHWR_HAL_LPC1XXX_SCB;
    cyg_uint32 pclksel = CYGHWR_HAL_LPC1XXX_CLOCK_PCLK(desc);
    cyg_uint32 reg = CYGHWR_HAL_LPC1XXX_CLOCK_REG(desc);
    cyg_uint32 pconp = CYGHWR_HAL_LPC1XXX_CLOCK_PCONP(desc);
    cyg_uint32 div = CYGHWR_HAL_LPC1XXX_CLOCK_DIV(desc);
    cyg_uint32 r;

    if( pclksel < 32 )
    {
        reg = scb+CYGHWR_HAL_LPC1XXX_SCB_PCLKSEL0+reg*4;

        HAL_READ_UINT32( reg, r );
        r &= ~(3<<pclksel);
        r |= div<<pclksel;
        HAL_WRITE_UINT32( reg, r );
    }

    if( pconp < 32 )
    {
        HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PCONP, r );
        r &= ~(1<<pconp);
        r |= 1<<pconp;
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PCONP, r );
    }
}

__externC void hal_lpc1xxx_clock_disable( cyg_uint32 desc )
{
    cyg_uint32 scb = CYGHWR_HAL_LPC1XXX_SCB;
    cyg_uint32 pconp = CYGHWR_HAL_LPC1XXX_CLOCK_PCONP(desc);
    cyg_uint32 r;

    if( pconp < 32 )
    {
        HAL_READ_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PCONP, r );
        r &= ~(1<<pconp);
        r |= 1<<pconp;
        HAL_WRITE_UINT32( scb+CYGHWR_HAL_LPC1XXX_SCB_PCONP, r );
    }
}

//==========================================================================
// UART baud rate
//
// Set the baud rate divider of a UART based on the requested rate and
// the current SYSCLK clock settings.

void hal_lpc1xxx_uart_setbaud( cyg_uint32 base, cyg_uint32 baud )
{
//    cyg_uint32 div = ((( hal_lpc1xxx_sysclk * 8) / baud) + 1) / 2;

//    HAL_WRITE_UINT32( base+CYGHWR_HAL_LPC1XXX_UART_IBRD, div / 64 );
//    HAL_WRITE_UINT32( base+CYGHWR_HAL_LPC1XXX_UART_FBRD, div % 64 );
}

// start-sanitize-ecospro
//==========================================================================
// Profiling timer

#ifdef CYGPKG_PROFILE_GPROF

#include <cyg/profile/profile.h>
#include <cyg/hal/hal_arch.h>
#include <cyg/hal/hal_intr.h>
#include <cyg/hal/drv_api.h>

// -------------------------------------------------------------------------
// These defines select the timer to be used. By default we use
// Timer0.

#define CYGHWR_HAL_LPC1XXX_TIMER                CYGHWR_HAL_LPC1XXX_TIMER0
#define CYGNUM_HAL_INTERRUPT_TIMER              CYGNUM_HAL_INTERRUPT_TIMER0
#define CYGHWR_HAL_LPC1XXX_TIMER_CLOCK          CYGHWR_HAL_LPC1XXX_TIMER0_CLOCK

// -------------------------------------------------------------------------
// Interrupt object

static cyg_interrupt    profile_interrupt;
static cyg_handle_t     profile_handle;
static cyg_uint32       profile_period;

// -------------------------------------------------------------------------
// Saved state pointer.
//
// If break or Ctrl-C support is enabled, this is defined
// elsewhere. If not then we must define it ourself.

#if defined(CYGDBG_HAL_DEBUG_GDB_BREAK_SUPPORT) || \
    defined(CYGDBG_HAL_DEBUG_GDB_CTRLC_SUPPORT)

__externC HAL_SavedRegisters *hal_saved_interrupt_state;

#else

HAL_SavedRegisters *hal_saved_interrupt_state;

#endif

// -------------------------------------------------------------------------
// Profile DSR. This is not actually called.

static  void
profile_dsr(cyg_vector_t vector, cyg_ucount32 count, cyg_addrword_t data)
{
    CYG_UNUSED_PARAM(cyg_vector_t, vector);
    CYG_UNUSED_PARAM(cyg_ucount32, count);
    CYG_UNUSED_PARAM(cyg_addrword_t, data);
}

// -------------------------------------------------------------------------
// Profile ISR.

static cyg_uint32
profile_isr(cyg_vector_t vector, cyg_addrword_t data)
{
    CYG_ADDRESS base = CYGHWR_HAL_LPC1XXX_TIMER;    
    HAL_SavedRegisters *regs = hal_saved_interrupt_state;

    // Reset counters
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_TCR, CYGHWR_HAL_LPC1XXX_TIMER_TCR_CTR_RESET );

// Clear all pending interrupts
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_IR, 0xff );
    
    // Set period as PR
    HAL_WRITE_UINT32( base+CYGHWR_HAL_LPC1XXX_TIMER_PR, profile_period-1 );

    // Enable counters. Also clears reset state.
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_TCR, CYGHWR_HAL_LPC1XXX_TIMER_TCR_CTR_ENABLE );

    __profile_hit(regs->u.interrupt.pc);
    HAL_INTERRUPT_ACKNOWLEDGE(vector);
    return CYG_ISR_HANDLED;
}

// -------------------------------------------------------------------------
// Enable profile timer.
//

int
hal_enable_profile_timer(int resolution)
{
    CYG_ADDRESS base = CYGHWR_HAL_LPC1XXX_TIMER;
    cyg_uint32 period;

    // Enable clocking of profile timer

    CYGHWR_HAL_LPC1XXX_CLOCK_ENABLE( CYGHWR_HAL_LPC1XXX_TIMER_CLOCK );

    // The requested resolution is in microseconds. We divide PCLK by
    // 1000000 to give ticks per microsecond, then multiply that by
    // the resolution to give the period to be programmed into the PR
    // register.

    profile_period = hal_lpc1xxx_cclk;
    profile_period /= hal_lpc1xxx_pclock_divider[CYGHWR_HAL_LPC1XXX_CLOCK_DIV(CYGHWR_HAL_LPC1XXX_TIMER_CLOCK)];
    profile_period /= 1000000;
    profile_period *= resolution;
    
    // Recalculate resolution from period to account for any rounding or clock inaccuracy.
    resolution = (long long)profile_period * 1000000LL;
    resolution /= hal_lpc1xxx_pclock_divider[CYGHWR_HAL_LPC1XXX_CLOCK_DIV(CYGHWR_HAL_LPC1XXX_TIMER_CLOCK)];
    resolution /= hal_lpc1xxx_cclk;
//    resolution = (cyg_uint32)(((long long)profile_period * 1000000LL) / (long long)CYGNUM_HAL_ARM_LPC2XXX_PCLK_SPEED);
    
    // Reset counters. Reset must be blipped on and off, so clock stays reset until later.
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_TCR, CYGHWR_HAL_LPC1XXX_TIMER_TCR_CTR_RESET );

    // Clear all pending interrupts
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_IR, 0xff );

    // Set period in PR
    HAL_WRITE_UINT32( base+CYGHWR_HAL_LPC1XXX_TIMER_PR, profile_period-1 );
    
    // MR0 set to 1 so we interrupt every TC
    HAL_WRITE_UINT32( base+CYGHWR_HAL_LPC1XXX_TIMER_MR0, 1 );
    
    // Generate interrupt when TC matches MR0
    HAL_WRITE_UINT16( base+CYGHWR_HAL_LPC1XXX_TIMER_MCR, CYGHWR_HAL_LPC1XXX_TIMER_MCR_MR0_INT );

    // Ensure Capture control is disabled
    HAL_WRITE_UINT16( base+CYGHWR_HAL_LPC1XXX_TIMER_CCR, 0 );
    
    // Ensure External Match control is disabled
    HAL_WRITE_UINT16( base+CYGHWR_HAL_LPC1XXX_TIMER_EMR, 0 );

    // Create interrupt object.
    cyg_drv_interrupt_create( CYGNUM_HAL_INTERRUPT_TIMER, 0, 0, (cyg_ISR_t*) &profile_isr, &profile_dsr, &profile_handle, &profile_interrupt);
    cyg_drv_interrupt_attach(profile_handle);
    cyg_drv_interrupt_unmask(CYGNUM_HAL_INTERRUPT_TIMER);

    // Enable counters. Also clears reset state.
    HAL_WRITE_UINT8( base+CYGHWR_HAL_LPC1XXX_TIMER_TCR, CYGHWR_HAL_LPC1XXX_TIMER_TCR_CTR_ENABLE );
    
    return resolution;
}

#endif // CYGPKG_PROFILE_GPROF
// end-sanitize-ecospro

//==========================================================================
// EOF lpc1xxx_misc.c
