Mercurial > ecos
changeset 2562:14c67833f954
* cdl/hal_arm_lpc24xx.cdl: Added I2C configuration options for
interrupt priority, peripheral clock divider and I2C bus
frequency
* include/lpc24xx_misc.h: Added function hal_lpc_set_power() and
peripheral identifiers for enabling peripheral modules in a
common way
* include/var_io.h: Removed CYGARC_HAL_LPC24XX_SET_PIN_FUN()
* src/lpc24xx_misc.c: Bugfix in hal_lpc_get_pclk(), Added function
hal_lpc_set_power(), Added hal_set_pin_function(), Added
peripheral clock divider configuration for I2C modules in
hal_hardware_init()
| author | asl |
|---|---|
| date | Mon, 22 Sep 2008 19:20:59 +0000 |
| parents | 55c015cde894 |
| children | 73921684f287 |
| 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/lpc24xx_misc.h packages/hal/arm/lpc24xx/var/current/include/var_io.h packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c |
| diffstat | 5 files changed, 220 insertions(+), 21 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,17 @@ +2008-09-18 Uwe Kindler <uwe_kindler@web.de> + + * cdl/hal_arm_lpc24xx.cdl: Added I2C configuration options for + interrupt priority, peripheral clock divider and I2C bus + frequency + * include/lpc24xx_misc.h: Added function hal_lpc_set_power() and + peripheral identifiers for enabling peripheral modules in a + common way + * include/var_io.h: Removed CYGARC_HAL_LPC24XX_SET_PIN_FUN() + * src/lpc24xx_misc.c: Bugfix in hal_lpc_get_pclk(), Added function + hal_lpc_set_power(), Added hal_set_pin_function(), Added + peripheral clock divider configuration for I2C modules in + hal_hardware_init() + 2008-09-11 Uwe Kindler <uwe_kindler@web.de> * include/var_io.h: Added CYGARC_HAL_LPC2XXX_REG_EMAC_BASE to support
--- a/packages/hal/arm/lpc24xx/var/current/cdl/hal_arm_lpc24xx.cdl +++ b/packages/hal/arm/lpc24xx/var/current/cdl/hal_arm_lpc24xx.cdl @@ -65,7 +65,7 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { implements CYGINT_HAL_VIRTUAL_VECTOR_COMM_BAUD_SUPPORT implements CYGINT_HAL_ARM_ARCH_ARM7 implements CYGINT_HAL_ARM_THUMB_ARCH - + # Let the architectural HAL see this variant's files define_proc { puts $::cdl_header "#define CYGBLD_HAL_VAR_INTS_H <cyg/hal/hal_var_ints.h>" @@ -272,9 +272,67 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { channels. The divider divides the CPU clock to get the clock for the CAN peripherals." } - } + } + + for { set ::channel 0 } { $::channel < 3 } { incr ::channel } { + cdl_component CYGNUM_HAL_ARM_LPC24XX_I2C[set ::channel]_CLK { + display "I2C channel [set ::channel] clock speed" + flavor data + calculated CYGNUM_HAL_ARM_LPC24XX_CLOCK_SPEED / \ + CYGNUM_HAL_ARM_LPC24XX_I2C[set ::channel]_CLK_DIV + description " + The I2C clock speed is the CPU clock output divided by the + I2C clock divider" + + cdl_option CYGNUM_HAL_ARM_LPC24XX_I2C[set ::channel]_CLK_DIV { + display "I2C channel [set ::channel] clock divider" + flavor data + legal_values { 1 2 4 8 } + default_value { 1 } + description " + This divider selects the peripheral clock for I2C + channel [set ::channel]. The divider divides the CPU + clock to get the clock for the I2C peripheral." + } + } + } } + for { set ::channel 0 } { $::channel < 3 } { incr ::channel } { + cdl_component CYGHWR_HAL_ARM_LPC24XX_I2C[set ::channel]_SUPP { + display "I2C channel [set ::channel] configuration" + parent CYGPKG_DEVS_I2C_ARM_LPC2XXX + flavor bool + default_value [set ::channel] == 0 + description " + I2C channel [set ::channel] configuration data." + + cdl_option CYGNUM_HAL_ARM_LPC24XX_I2C[set ::channel]_INT_PRIO { + display "I2C channel [set ::channel] interrupt priority" + flavor data + legal_values 0 to 15 + default_value 15 + description " + There are 16 priority levels, corresponding to the + values 0 through 15 decimal, of which 15 is the + lowest priority. The reset value of these + interrupt priority registers defaults all + interrupts to the lowest priority 15, allowing a + single write to elevate the priority of an + individual interrupt." + } + + cdl_option CYGNUM_HAL_ARM_LPC24XX_I2C[set ::channel]_BUS_FREQ { + display "I2C channel [set ::channel] bus frequency (Hz)" + flavor data + legal_values {100000 400000} + default_value 100000 + description " + This option selects the data rate for the I2C bus." + } + } + } + cdl_component CYGNUM_HAL_RTC_CONSTANTS { display "Real-time clock constants" flavor none @@ -316,7 +374,7 @@ cdl_package CYGPKG_HAL_ARM_LPC24XX { legal_values { 0 to 15 } default_value 15 description " - There are 16 priority levels, corresponding to the values 0 through + There are 16 priority levels, corresponding to the values 0 through 15 decimal, of which 15 is the lowest priority. The reset value of these interrupt priority registers defaults all interrupts to the lowest priority, allowing a single write to elevate the priority
--- a/packages/hal/arm/lpc24xx/var/current/include/lpc24xx_misc.h +++ b/packages/hal/arm/lpc24xx/var/current/include/lpc24xx_misc.h @@ -51,9 +51,10 @@ //============================================================================= //----------------------------------------------------------------------------- -// Functions to obtain the current processor clock settings -//----------------------------------------------------------------------------- -externC cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id); +// Function to obtain the current processor clock settings +// Use PCLK identifiers below +// +externC cyg_uint32 hal_lpc_get_pclk(cyg_uint32 pclk_id); // // Identifiers for peripheral clock. Use these identifiers with the function @@ -91,10 +92,55 @@ externC cyg_uint32 hal_lpc_get_pclk(cyg_ //----------------------------------------------------------------------------- +// Function to enable/disable power for certain peripheral +// Use PCONP identifiers from below +// +externC void hal_lpc_set_power(cyg_uint8 pconp_id, int on); + +// +// Identifiers for power control +// hal_get_pclk() +// +#define CYNUM_HAL_LPC24XX_PCONP_TIMER0 1 +#define CYNUM_HAL_LPC24XX_PCONP_TIMER1 2 +#define CYNUM_HAL_LPC24XX_PCONP_UART0 3 +#define CYNUM_HAL_LPC24XX_PCONP_UART1 4 +#define CYNUM_HAL_LPC24XX_PCONP_PWM0 5 +#define CYNUM_HAL_LPC24XX_PCONP_PWM1 6 +#define CYNUM_HAL_LPC24XX_PCONP_I2C0 7 +#define CYNUM_HAL_LPC24XX_PCONP_SPI 8 +#define CYNUM_HAL_LPC24XX_PCONP_RTC 9 +#define CYNUM_HAL_LPC24XX_PCONP_SSP1 10 +#define CYNUM_HAL_LPC24XX_PCONP_EMC 11 +#define CYNUM_HAL_LPC24XX_PCONP_ADC 12 +#define CYNUM_HAL_LPC24XX_PCONP_CAN1 13 +#define CYNUM_HAL_LPC24XX_PCONP_CAN2 14 +#define CYNUM_HAL_LPC24XX_PCONP_I2C1 19 +#define CYNUM_HAL_LPC24XX_PCONP_LCD 20 +#define CYNUM_HAL_LPC24XX_PCONP_SSP0 21 +#define CYNUM_HAL_LPC24XX_PCONP_TIMER2 22 +#define CYNUM_HAL_LPC24XX_PCONP_TIMER3 23 +#define CYNUM_HAL_LPC24XX_PCONP_UART2 24 +#define CYNUM_HAL_LPC24XX_PCONP_UART3 25 +#define CYNUM_HAL_LPC24XX_PCONP_I2C2 26 +#define CYNUM_HAL_LPC24XX_PCONP_I2S 27 +#define CYNUM_HAL_LPC24XX_PCONP_SDC 28 +#define CYNUM_HAL_LPC24XX_PCONP_GPDMA 29 +#define CYNUM_HAL_LPC24XX_PCONP_ENET 30 +#define CYNUM_HAL_LPC24XX_PCONP_USB 31 + + +//----------------------------------------------------------------------------- +// Configure pin function +// +void hal_set_pin_function(cyg_uint8 port, cyg_uint8 pin, cyg_uint8 function); + + +//----------------------------------------------------------------------------- // Macros to derive the baudrate divider values for the internal UARTs -// The LPC24xx family supports differents baudrate clocks for each single +// The LPC24xx family supports different baudrate clocks for each single // UART. So we need a way to calculate the baudrate for each single UART -// Now we rely on the fact that we use the same baurate clock for all +// Now we rely on the fact that we use the same baudrate clock for all // UARTs and we query only UART0 //----------------------------------------------------------------------------- #define CYG_HAL_ARM_LPC24XX_PCLK(_pclkid_) hal_lpc_get_pclk(_pclkid_)
--- a/packages/hal/arm/lpc24xx/var/current/include/var_io.h +++ b/packages/hal/arm/lpc24xx/var/current/include/var_io.h @@ -463,9 +463,6 @@ #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)) - //============================================================================= // SSP - Synchronous Serial Port
--- a/packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c +++ b/packages/hal/arm/lpc24xx/var/current/src/lpc24xx_misc.c @@ -78,7 +78,7 @@ //=========================================================================== // Get peripheral clock for a certain peripheral //=========================================================================== -cyg_uint32 hal_lpc_get_pclk(cyg_uint32 peripheral_id) +cyg_uint32 hal_lpc_get_pclk(cyg_uint32 pclk_id) { static const cyg_uint8 divider_tbl[4] = { @@ -87,18 +87,22 @@ cyg_uint32 hal_lpc_get_pclk(cyg_uint32 p cyg_uint32 pclkselreg; cyg_uint32 regval; cyg_uint8 divider; + + CYG_ASSERT(pclk_id >= CYNUM_HAL_LPC24XX_PCLK_WDT && + pclk_id <= CYNUM_HAL_LPC24XX_PCLK_SYSCON, + "Invalid peripheral clock ID"); // // decide if we need PCLKSEL0 or PCLKSEL1 // - pclkselreg = ((peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF) ? + pclkselreg = ((pclk_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); - regval = (regval >> ((peripheral_id & 0xF) << 1)) & 0x03; + regval = (regval >> ((pclk_id & 0xF) << 1)) & 0x03; divider = divider_tbl[regval]; - if ((8 == divider) && (peripheral_id >= CYNUM_HAL_LPC24XX_PCLK_CAN1) - && (peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_ACF)) + if ((8 == divider) && (pclk_id >= CYNUM_HAL_LPC24XX_PCLK_CAN1) + && (pclk_id <= CYNUM_HAL_LPC24XX_PCLK_ACF)) { divider = 6; } @@ -118,7 +122,10 @@ void hal_lpc_set_pclk(cyg_uint32 periphe cyg_uint32 clock; cyg_uint32 pclkselreg; cyg_uint32 regval; - + + CYG_ASSERT(peripheral_id >= CYNUM_HAL_LPC24XX_PCLK_WDT && + peripheral_id <= CYNUM_HAL_LPC24XX_PCLK_SYSCON, + "Invalid peripheral clock ID"); CYG_ASSERT(divider <= 8, "Wrong peripheral clock divider value"); // // decide if we need PCLKSEL0 or PCLKSEL1 @@ -129,8 +136,55 @@ void hal_lpc_set_pclk(cyg_uint32 periphe HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); divider = (6 == divider) ? 8 : divider; clock = clock_tbl[divider >> 1]; + regval &= ~(0x03 << ((peripheral_id & 0xF) << 1)); regval |= (clock << ((peripheral_id & 0xF) << 1)); - HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); + HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + pclkselreg, regval); +} + + +//=========================================================================== +// Enable/Disable power for certain peripheral +//=========================================================================== +void hal_lpc_set_power(cyg_uint8 pconp_id, int on) +{ + cyg_uint32 regval; + + CYG_ASSERT(pconp_id >= CYNUM_HAL_LPC24XX_PCONP_TIMER0 && + pconp_id <= CYNUM_HAL_LPC24XX_PCONP_USB, + "Invalid peripheral power ID"); + HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + + CYGARC_HAL_LPC24XX_REG_PCONP, regval); + if (on) + { + regval |= (0x01 << pconp_id); + } + else + { + regval &= ~(0x01 << pconp_id); + } + + HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_SCB_BASE + + CYGARC_HAL_LPC24XX_REG_PCONP, regval); +} + + +//=========================================================================== +// Set pin function +//=========================================================================== +void hal_set_pin_function(cyg_uint8 port, cyg_uint8 pin, cyg_uint8 function) +{ + CYG_ASSERT(port <= 4, "Port value out of bounds"); + CYG_ASSERT(pin <= 31, "Pin value out of bounds"); + CYG_ASSERT(function <= 3, "Invalid function value"); + + cyg_uint32 regval; + cyg_uint8 pinsel_reg = port << 1; + pinsel_reg += (pin > 15) ? 1 :0; + pinsel_reg <<= 2; + HAL_READ_UINT32(CYGARC_HAL_LPC24XX_REG_PIN_BASE + pinsel_reg, regval); + regval &= ~(0x03 << ((pin & 0xF) << 1)); + regval |= (function << ((pin & 0xF) << 1)); + HAL_WRITE_UINT32(CYGARC_HAL_LPC24XX_REG_PIN_BASE + pinsel_reg, regval); } @@ -243,9 +297,39 @@ void hal_hardware_init(void) // // 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); + 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); + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_I2C0, + CYGNUM_HAL_ARM_LPC24XX_I2C0_CLK_DIV); + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_I2C1, + CYGNUM_HAL_ARM_LPC24XX_I2C1_CLK_DIV); + hal_lpc_set_pclk(CYNUM_HAL_LPC24XX_PCLK_I2C2, + CYGNUM_HAL_ARM_LPC24XX_I2C2_CLK_DIV); + + // + // Enable power for all used on-chip peripherals + // +#ifdef CYGHWR_HAL_ARM_LPC24XX_I2C0_SUPP + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C0, 1); +#else + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C0, 0); +#endif // CYGHWR_HAL_ARM_LPC24XX_I2C0_SUPP + +#ifdef CYGHWR_HAL_ARM_LPC24XX_I2C1_SUPP + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C1, 1); +#else + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C1, 0); +#endif // CYGHWR_HAL_ARM_LPC24XX_I2C0_SUPP + +#ifdef CYGHWR_HAL_ARM_LPC24XX_I2C2_SUPP + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C2, 1); +#else + hal_lpc_set_power(CYNUM_HAL_LPC24XX_PCONP_I2C2, 0); +#endif // CYGHWR_HAL_ARM_LPC24XX_I2C0_SUPP // // Fill vector address registers with interrupt number. If an interrupt
