From aae0c1e888d173b7a850a3e0023b8c352f657f62 Mon Sep 17 00:00:00 2001 From: patacongo Date: Fri, 19 Aug 2011 16:51:04 +0000 Subject: Add support for multiplexed SDIO pins from Uros git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@3898 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/arch/arm/src/stm32/stm32_rcc.c | 94 ++++++++++++++++++++++++++++------- nuttx/arch/arm/src/stm32/stm32_rcc.h | 15 +++--- nuttx/arch/arm/src/stm32/stm32_sdio.c | 43 ++++++++++++++++ 3 files changed, 125 insertions(+), 27 deletions(-) (limited to 'nuttx/arch/arm/src/stm32') diff --git a/nuttx/arch/arm/src/stm32/stm32_rcc.c b/nuttx/arch/arm/src/stm32/stm32_rcc.c index f39aa0d42..a9155f1a2 100755 --- a/nuttx/arch/arm/src/stm32/stm32_rcc.c +++ b/nuttx/arch/arm/src/stm32/stm32_rcc.c @@ -59,6 +59,22 @@ #define HSERDY_TIMEOUT 256 +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Activity reference count, showing inactivity after start-up. + * Device drivers increment this count using rcclock() and rccunlock() + * + * If this value goes beyond the range [0, MAX_RCCs] indicates + * reference count leakage (asymetric number of locks vs. unlocks) and + * system enters permanent active state. + */ + +#ifdef CONFIG_STM32_RCCLOCK +static int stm32_rcclock_count = 0; +#endif + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -98,7 +114,6 @@ static inline void rcc_reset(void) putreg32(0, STM32_RCC_CIR); /* Disable all interrupts */ } - static inline void rcc_enableahb(void) { uint32_t regval; @@ -140,7 +155,6 @@ static inline void rcc_enableahb(void) putreg32(regval, STM32_RCC_AHBENR); /* Enable peripherals */ } - static inline void rcc_enableapb1(void) { uint32_t regval; @@ -292,7 +306,6 @@ static inline void rcc_enableapb1(void) putreg32(regval, STM32_RCC_APB1ENR); } - static inline void rcc_enableapb2(void) { uint32_t regval; @@ -374,14 +387,14 @@ static inline void rcc_enableapb2(void) putreg32(regval, STM32_RCC_APB2ENR); } - #if !defined(CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG) -/** Called to change to new clock based on settings in board.h +/* Called to change to new clock based on settings in board.h * - * NOTE: This logic would need to be extended if you need to select low- - * power clocking modes! - **/ + * NOTE: This logic would need to be extended if you need to select low- + * power clocking modes! + */ + static inline void stm32_stdclockconfig(void) { uint32_t regval; @@ -469,7 +482,6 @@ static inline void stm32_stdclockconfig(void) } #endif - /**************************************************************************** * Public Functions ****************************************************************************/ @@ -501,22 +513,66 @@ void stm32_clockconfig(void) rcc_enableapb1(); } - -/** +/* * \todo Check for LSE good timeout and return with -1, * possible ISR optimization? or at least ISR should be cough in case of failure */ + void stm32_rcc_enablelse(void) { - /* Enable LSE */ - modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_LSEON); + /* Enable LSE */ + + modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_LSEON); - /* We could wait for ISR here ... */ - while( !(getreg16(STM32_RCC_BDCR) & RCC_BDCR_LSERDY) ) up_waste(); + /* We could wait for ISR here ... */ + + while( !(getreg16(STM32_RCC_BDCR) & RCC_BDCR_LSERDY) ) up_waste(); - /* Select LSE as RTC Clock Source */ - modifyreg16(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE); + /* Select LSE as RTC Clock Source */ + + modifyreg16(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE); - /* Enable Clock */ - modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN); + /* Enable Clock */ + + modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN); +} + +#ifdef CONFIG_STM32_RCCLOCK +uint32_t stm32_rcclock(uint8_t domain_id) +{ + // THINK: + // maybe just shift domain_id into 32-bit or 64-bit register + // and if there value of this var != 0, we are active... + // increment some variable, so it is possible to test leakage + // multiple locks or multiple unlocks + + if (stm32_rcclock_count >= 0) + { + stm32_rcclock_count++; + if (stm32_rcclock_count > 64) + { + stm32_rcclock_count = -1; /* capture error */ + } + } + + return 0; } + +uint32_t stm32_rccunlock(uint8_t domain_id) +{ + if (stm32_rcclock_count > -1) + { + stm32_rcclock_count--; + } + return 0; +} + +uint32_t stm32_setrccoptions(uint8_t domain_id, uint32_t options) +{ +} + +int stm32_getrccactivity(void) +{ + return stm32_rcclock_count; +} +#endif diff --git a/nuttx/arch/arm/src/stm32/stm32_rcc.h b/nuttx/arch/arm/src/stm32/stm32_rcc.h index 1c0020a21..a224447a1 100755 --- a/nuttx/arch/arm/src/stm32/stm32_rcc.h +++ b/nuttx/arch/arm/src/stm32/stm32_rcc.h @@ -72,22 +72,21 @@ extern "C" { extern uint32_t stm32_vectors[]; /* See stm32_vectors.S */ - /************************************************************************************ * Public Function Prototypes ************************************************************************************/ -/** Called to change to new clock based on settings in board.h +/* Called to change to new clock based on settings in board.h * - * NOTE: This logic needs to be extended so that we can selected low-power - * clocking modes as well! - **/ + * NOTE: This logic needs to be extended so that we can selected low-power + * clocking modes as well! + */ + EXTERN void stm32_clockconfig(void); -/** Enable LSE Clock - **/ -EXTERN void stm32_rcc_enablelse(void); +/* Enable LSE Clock */ +EXTERN void stm32_rcc_enablelse(void); #undef EXTERN #if defined(__cplusplus) diff --git a/nuttx/arch/arm/src/stm32/stm32_sdio.c b/nuttx/arch/arm/src/stm32/stm32_sdio.c index 63930ef8b..1bd2b8c97 100644 --- a/nuttx/arch/arm/src/stm32/stm32_sdio.c +++ b/nuttx/arch/arm/src/stm32/stm32_sdio.c @@ -317,6 +317,12 @@ static int stm32_interrupt(int irq, void *context); /* SDIO interface methods ***************************************************/ +/* Mutual exclusion */ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock); +#endif + /* Initialization/setup */ static void stm32_reset(FAR struct sdio_dev_s *dev); @@ -380,6 +386,9 @@ struct stm32_dev_s g_sdiodev = { .dev = { +#ifdef CONFIG_SDIO_MUXBUS + .lock = stm32_lock, +#endif .reset = stm32_reset, .status = stm32_status, .widebus = stm32_widebus, @@ -1312,6 +1321,35 @@ static int stm32_interrupt(int irq, void *context) /**************************************************************************** * SDIO Interface Methods ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_lock + * + * Description: + * Locks the bus. Function calls low-level multiplexed bus routines to + * resolve bus requests and acknowledgment issues. + * + * Input Parameters: + * dev - An instance of the SDIO device interface + * lock - TRUE to lock, FALSE to unlock. + * + * Returned Value: + * OK on success; a negated errno on failure + * + ****************************************************************************/ + +#ifdef CONFIG_SDIO_MUXBUS +static int stm32_lock(FAR struct sdio_dev_s *dev, bool lock) +{ + /* Single SDIO instance so there is only one possibility. The multiplex + * bus is part of board support package. + */ + + stm32_muxbus_sdio_lock(lock); + return OK; +} +#endif + /**************************************************************************** * Name: stm32_reset * @@ -2574,8 +2612,12 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) /* Configure GPIOs for 4-bit, wide-bus operation (the chip is capable of * 8-bit wide bus operation but D4-D7 are not configured). + * + * If bus is multiplexed then there is a custom bus configuration utility + * in the scope of the board support package. */ +#ifndef CONFIG_SDIO_MUXBUS stm32_configgpio(GPIO_SDIO_D0); #ifndef CONFIG_SDIO_WIDTH_D1_ONLY stm32_configgpio(GPIO_SDIO_D1); @@ -2584,6 +2626,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno) #endif stm32_configgpio(GPIO_SDIO_CK); stm32_configgpio(GPIO_SDIO_CMD); +#endif /* Reset the card and assure that it is in the initial, unconfigured * state. -- cgit v1.2.3