Mercurial > ecos
changeset 2511:1f18f909a18e
* src/lpc2xxx_misc.c: Added hal_lpc_can_init() to initialize CAN
channels
* cdl/hal_arm_lpc24xx.cdl: Added a number of CYGHWR_HAL_ARM_LPC2XXX_xxx
options for device driver compatibility reasons. Some LPC2xxx device
drivers rely on these definitions. Moved some configuration options
to make configuration more intuitive in configuration tool. Added
CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK option for configuration of CAN
peripheral clock.
* include/var_io.h: Added macro CYGARC_HAL_LPC24XX_SET_PIN_FUN()
* src/lpc2xxx_misc.c: Added function hal_lpc_set_pclk() to set
peripheral clocks easily. Initialize peripheral clocks in
hal_hardware_init() according to configuration.
| author | asl |
|---|---|
| date | Fri, 25 Jul 2008 11:14:39 +0000 |
| parents | 0c2a776fc7f4 |
| children | be7755f32fd0 |
| files | packages/hal/arm/lpc24xx/var/current/ChangeLog packages/hal/arm/lpc24xx/var/current/cdl/hal_arm_lpc24xx.cdl packages/hal/arm/lpc24xx/var/current/include/var_arch.h packages/hal/arm/lpc24xx/var/current/include/var_io.h packages/hal/arm/lpc24xx/var/current/src/hal_diag.c packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c |
| diffstat | 6 files changed, 184 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/packages/hal/arm/lpc24xx/var/current/ChangeLog +++ b/packages/hal/arm/lpc24xx/var/current/ChangeLog @@ -1,3 +1,18 @@ +2008-07-21 Uwe Kindler <uwe_kindler@web.de> + + * src/lpc2xxx_misc.c: Added hal_lpc_can_init() to initialize CAN + channels + * cdl/hal_arm_lpc24xx.cdl: Added a number of CYGHWR_HAL_ARM_LPC2XXX_xxx + options for device driver compatibility reasons. Some LPC2xxx device + drivers rely on these definitions. Moved some configuration options + to make configuration more intuitive in configuration tool. Added + CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK option for configuration of CAN + peripheral clock. + * include/var_io.h: Added macro CYGARC_HAL_LPC24XX_SET_PIN_FUN() + * src/lpc2xxx_misc.c: Added function hal_lpc_set_pclk() to set + peripheral clocks easily. Initialize peripheral clocks in + hal_hardware_init() according to configuration. + 2008-07-06 Uwe Kindler <uwe_kindler@web.de> * Initial release of LPC24xx variant support (based on LPX2xxx variant)
--- a/packages/hal/arm/lpc24xx/var/current/cdl/hal_arm_lpc24xx.cdl +++ b/packages/hal/arm/lpc24xx/var/current/cdl/hal_arm_lpc24xx.cdl @@ -99,6 +99,48 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { available in the HAL." } } + + # This is going to get really messy before long as the number of parts + # explodes. Its useful to know the actual part in use, but its just as + # useful to know which family it belongs to. LPC210x shouldn't really + # be in the list of devices, but will probably break something if removed. + cdl_component CYGHWR_HAL_ARM_LPC2XXX { + display "LPC2XXX variant used" + flavor data + calculated CYGHWR_HAL_ARM_LPC24XX + description " + This option is only here for compatibility reasons because some of + the LPC2XXX device drivers rely on these definitions. If this + is defined here, the LPC24XX variant can use the LPC2XXX device + drivers for on-chip peripherals." + + cdl_option CYGHWR_HAL_ARM_LPC2XXX_FAMILY { + display "LPC2XXX variant family" + flavor data + calculated CYGHWR_HAL_ARM_LPC24XX_FAMILY + description " + This option is only here for compatibility reasons + because some of the LPC2XXX device drivers rely on + these definitions. If this is defined here, the + LPC24XX variant can use the LPC2XXX device drivers + for on-chip peripherals." + } + + cdl_option CYGHWR_HAL_ARM_LPC2XXX_VARIANT_VERSION { + display "LPC2XXX variant version" + flavor data + calculated { + is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC21") ? 1 : + is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC22") ? 2 : + is_substr(CYGHWR_HAL_ARM_LPC2XXX, "LPC24") ? 4 : 0 + } + description " + This specifies the variant version that the processor + belongs to. Some common characteristics may be + different in newer LPC2xxx versions. I.e. the LPC24xx variants + are significant different from former LPC2xxx variants." + } + } # Important! Be very careful changing this value. That will always # enter the LPC24XX bootloader after reset and consequently will @@ -142,54 +184,14 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { legal_values 275000000 to 290000000 calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * CYGNUM_HAL_ARM_LPC24XX_XTAL_FREQ / - CYGNUM_HAL_ARM_LPC24XX_PLL_DIV } - description " - Normally the PLL output must be in the range of 275 - MHz to 550 MHz. Because of a chip errata the maximum - output of the CCO within the PLL block is limited to - 290 MHz." - - } - - cdl_option CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV { - display "CPU clock divider" - flavor data - legal_values 6 to 256 - default_value { 6 } + CYGNUM_HAL_ARM_LPC24XX_PLL_DIV} description " - The CPU clock divider controls the division of the PLL - output before it is used by the CPU. When the PLL is - bypassed, the division may be by 1. When the PLL is - running, the output must be divided in order to bring - the CPU clock frequency (CCLK) within operating - limits. An 8 bit divider allows a range of options, - including slowing CPU operation to a low rate for - temporary power savings without turning off the - PLL. Only even values (2, 4, 6, ..., 256) are - supported and can be used. Warning: Using an odd value - (1, 3, 5, ..., 255) when setting this option may - result in incorrect operation of the device." - } - - cdl_option CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV { - display "USB clock divider" - flavor data - legal_values 1 to 8 - default_value { 6 } - description " - This divider controls the division of the PLL output - before it is used by the USB block. If the PLL is - bypassed, the division may be by 1. In that case, the - PLL input frequency must be 48 MHz, with a 500 ppm - tolerance. When the PLL is running, the output must be - divided in order to bring the USB clock frequency to - 48 MHz with a 50% duty cycle. A 4-bit divider allows - obtaining the correct USB clock from any even multiple - of 48 MHz (i.e. any multiple of 96 MHz) within the PLL - operating range." + Normally the PLL output must be in the range of 275 MHz to + 550 MHz Because of a chip errata the maximum output of the CCO + within the PLL block is limited to 290 MHz." } - - cdl_option CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED { + + cdl_component CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED { display "CPU clock speed" flavor data calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * @@ -198,10 +200,31 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV} description " The core CPU clock speed is the PLL output divided by the - CPU clock divider" + CPU clock divider" + + cdl_option CYGNUM_HAL_ARM_LPC24XX_CPU_CLK_DIV { + display "CPU clock divider" + flavor data + legal_values 6 to 256 + default_value { 6 } + description " + The CPU clock divider controls the division of the PLL + output before it is used by the CPU. When the PLL is + bypassed, the division may be by 1. When the PLL is + running, the output must be divided in order to bring the + CPU clock frequency (CCLK) within operating limits. An 8 + bit divider allows a range of options, including slowing + CPU operation to a low rate for temporary power savings + without turning off the PLL. Only even values + (2, 4, 6, ..., 256) are supported and can be used. + Warning: Using an odd value (1, 3, 5, ..., 255) when + setting this option may result in incorrect operation of + the device." + } } - cdl_option CYGNUM_HAL_ARM_LPC24XX_USB_CLOCK_SPEED { + + cdl_component CYGNUM_HAL_ARM_LPC24XX_USB_CLOCK_SPEED { display "USB clock speed" flavor data calculated { 2 * CYGNUM_HAL_ARM_LPC24XX_PLL_MUL * @@ -211,9 +234,47 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { description " The USB clock speed is the PLL output divided by the USB clock divider" + + cdl_option CYGNUM_HAL_ARM_LPC24XX_USB_CLK_DIV { + display "USB clock divider" + flavor data + legal_values 1 to 8 + default_value { 6 } + description " + This divider controls the division of the PLL output before + it is used by the USB block. If the PLL is bypassed, the + division may be by 1. In that case, the PLL input frequency + must be 48 MHz, with a 500 ppm tolerance. When the PLL is + running, the output must be divided in order to bring the + USB clock frequency to 48 MHz with a 50% duty cycle. A + 4-bit divider allows obtaining the correct USB clock from + any even multiple of 48 MHz (i.e. any mutliple of 96 MHz) + within the PLL operating range." + } } + + cdl_component CYGNUM_HAL_ARM_LPC2XXX_CAN_CLK { + display "CAN clock speed" + flavor data + calculated { CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / + CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV} + description " + The CAN clock speed is the CPU clock output divided by the + CAN clock divider" + + cdl_option CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV { + display "CAN clock divider" + flavor data + legal_values { 1 2 4 6 } + default_value { 1 } + description " + This divider selects the peripheral clock for both CAN + channels. The divider divides the CPU clock to get the + clock for the CAN peripherals." + } + } } - + cdl_component CYGNUM_HAL_RTC_CONSTANTS { display "Real-time clock constants" flavor none @@ -261,4 +322,5 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { lowest priority, allowing a single write to elevate the priority of an individual interrupt." } + }
--- a/packages/hal/arm/lpc24xx/var/current/include/var_arch.h +++ b/packages/hal/arm/lpc24xx/var/current/include/var_arch.h @@ -53,6 +53,8 @@ #include <pkgconf/hal.h> #include <cyg/hal/hal_io.h> +#include <cyg/infra/cyg_type.h> + //-------------------------------------------------------------------------- // Idle thread code. // This macro is called in the idle thread loop, and gives the HAL the
--- a/packages/hal/arm/lpc24xx/var/current/include/var_io.h +++ b/packages/hal/arm/lpc24xx/var/current/include/var_io.h @@ -463,6 +463,8 @@ #define CYGARC_HAL_LPC24XX_REG_PINMODE8 0x060 #define CYGARC_HAL_LPC24XX_REG_PINMODE9 0x064 +#define CYGARC_HAL_LPC24XX_SET_PIN_FUN(_regval_, _pin_, _func_) \ + (_regval_) = ((_regval_) & ~(0x3 << ((_pin_) << 1))) | ((_func_) << ((_pin_) << 1)) //=============================================================================
--- a/packages/hal/arm/lpc24xx/var/current/src/hal_diag.c +++ b/packages/hal/arm/lpc24xx/var/current/src/hal_diag.c @@ -303,24 +303,24 @@ static int cyg_hal_plf_serial_isr(void * cyg_uint8 iir; CYGARC_HAL_SAVE_GP(); - + *__ctrlc = 0; - + HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxIIR, iir); if((iir & (CYGARC_HAL_LPC24XX_REG_UxIIR_IIR0 | CYGARC_HAL_LPC24XX_REG_UxIIR_IIR1 | CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2)) == CYGARC_HAL_LPC24XX_REG_UxIIR_IIR2) - { + { // Rx data available or character timeout // Read data in order to clear interrupt HAL_READ_UINT32(chan->base + CYGARC_HAL_LPC24XX_REG_UxRBR, c); if( cyg_hal_is_break( &c , 1 ) ) *__ctrlc = 1; - + res = CYG_ISR_HANDLED; } - + HAL_INTERRUPT_ACKNOWLEDGE(chan->isr_vector); CYGARC_HAL_RESTORE_GP();
--- a/packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c +++ b/packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c @@ -92,8 +92,8 @@ cyg_uint32 hal_lpc_get_pclk(cyg_uint32 p // decide if we need PCLKSEL0 or PCLKSEL1 // pclkselreg = ((peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ? - CYGARC_HAL_LPC24XX_REG_PCLKSEL0 : - CYGARC_HAL_LPC24XX_REG_PCLKSEL1); + CYGARC_HAL_LPC24XX_REG_PCLKSEL0 : + CYGARC_HAL_LPC24XX_REG_PCLKSEL1); HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); regval = (regval >> ((peripheral_id & 0xF) << 1)) & 0x03; divider = divider_tbl[regval]; @@ -107,7 +107,35 @@ cyg_uint32 hal_lpc_get_pclk(cyg_uint32 p //=========================================================================== -// initialize timer 0 as eCos real time clock source +// Set peripheral clock +//=========================================================================== +void hal_lpc_set_pclk(cyg_uint32 peripheral_id, cyg_uint8 divider) +{ + static const cyg_uint8 clock_tbl[4] = + { + 0x01, 0x02, 0x00, 0x03 + }; + cyg_uint32 clock; + cyg_uint32 pclkselreg; + cyg_uint32 regval; + + CYG_ASSERT(divider <= 8, "Wrong peripheral clock divider value"); + // + // decide if we need PCLKSEL0 or PCLKSEL1 + // + pclkselreg = (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ? + CYGARC_HAL_LPC24XX_REG_PCLKSEL0 : + CYGARC_HAL_LPC24XX_REG_PCLKSEL1; + HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); + divider = (6 == divider) ? 8 : divider; + clock = clock_tbl[divider >> 1]; + regval |= (clock << ((peripheral_id & 0xF) << 1)); + HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); +} + + +//=========================================================================== +// initialize timer 0 as eCos realtime clock source //=========================================================================== void hal_clock_initialize(cyg_uint32 period) { @@ -179,8 +207,8 @@ void hal_delay_us(cyg_int32 usecs) // microseconds equate to. We do this calculation in 64 bit // arithmetic to avoid overflow. ticks = (((cyg_uint64)usecs) * - ((cyg_uint64)hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER1))) - / 1000000LL; + ((cyg_uint64)hal_lpc_get_pclk(CYNUM_HAL_LPC24XX_PCLK_TIMER1))) / + 1000000LL; // Disable and reset counter HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 2); @@ -192,7 +220,7 @@ void hal_delay_us(cyg_int32 usecs) CYGARC_HAL_LPC24XX_REG_TxMCR_MR0_RESET); //set prescale register to 0 - HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxPR, 0); + HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxPR, 0); // Enable counter HAL_WRITE_UINT32(timer+CYGARC_HAL_LPC24XX_REG_TxTCR, 1); @@ -210,14 +238,22 @@ void hal_delay_us(cyg_int32 usecs) //=========================================================================== void hal_hardware_init(void) { - cyg_uint32 i; + cyg_uint32 i; + + // + // Setup peripheral clocks here according to configuration + // + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN1, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV); + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_CAN2, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV); + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_ACF, CYGNUM_HAL_ARM_LPC24XX_CAN_CLK_DIV); + // // Fill vector address registers with interrupt number. If an interrupt // occurs we can simply read the interrupt number from the vector // address register later // - cyg_uint32 addr = (CYGARC_HAL_LPC24XX_REG_VIC_BASE + - CYGARC_HAL_LPC24XX_REG_VICVECTADDR0); + cyg_uint32 addr = CYGARC_HAL_LPC24XX_REG_VIC_BASE + + CYGARC_HAL_LPC24XX_REG_VICVECTADDR0; for (i = 0; i < 32; ++i) { HAL_WRITE_UINT32(addr, i); @@ -249,7 +285,7 @@ int hal_IRQ_handler(void) //=========================================================================== -// Block the the interrupt associated with the vector +// Block the interrupt associated with the vector //=========================================================================== void hal_interrupt_mask(int vector) { @@ -312,7 +348,7 @@ void hal_interrupt_configure(int vector, { cyg_uint32 regval; - // Only external interrupts are configurable + // Only external interrupts are configurable CYG_ASSERT(vector <= CYGNUM_HAL_INTERRUPT_EINT3 && vector >= CYGNUM_HAL_INTERRUPT_EINT0 , "Invalid vector"); @@ -390,7 +426,7 @@ void hal_lpc_watchdog_reset(void) // feed WD with the two magic values HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + CYGARC_HAL_LPC24XX_REG_WDFEED, - CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1); + CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC1); HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_WD_BASE + CYGARC_HAL_LPC24XX_REG_WDFEED, CYGARC_HAL_LPC24XX_REG_WDFEED_MAGIC2); @@ -399,5 +435,6 @@ void hal_lpc_watchdog_reset(void) continue; } + //-------------------------------------------------------------------------- // EOF lpc24xx_misc.c
