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
This commit is contained in:
patacongo 2011-08-19 16:51:04 +00:00
parent d4fd560ea0
commit ad0721c9d7
3 changed files with 125 additions and 27 deletions

View File

@ -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 */
/* We could wait for ISR here ... */
while( !(getreg16(STM32_RCC_BDCR) & RCC_BDCR_LSERDY) ) up_waste();
modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_LSEON);
/* 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

View File

@ -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)

View File

@ -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.