/* * Set the IOCFG */ static void stm32f4xx_sdio_set_iocfg(struct rt_mmcsd_host *host, struct rt_mmcsd_io_cfg *io_cfg) { rt_uint32_t clkdiv; if (io_cfg->clock == 0) { SDIO_ClockCmd(DISABLE); clkdiv = 0; } else { clkdiv = SDIOCLK / io_cfg->clock; if (clkdiv < 2) { clkdiv = SDIO_TRANSFER_CLK_DIV; } else { clkdiv -= 2; } SDIO_InitStructure.SDIO_ClockDiv = clkdiv; SDIO_Init(&SDIO_InitStructure); SDIO_ClockCmd(ENABLE); } if (io_cfg->bus_width == MMCSD_BUS_WIDTH_4) { sdio_dbg("MMC: Setting controller bus width to 4\n"); SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_4b; } else { sdio_dbg("MMC: Setting controller bus width to 1\n"); SDIO_InitStructure.SDIO_BusWide = SDIO_BusWide_1b; } /* maybe switch power to the card */ switch (io_cfg->power_mode) { case MMCSD_POWER_OFF: SDIO_SetPowerState(SDIO_PowerState_OFF); break; case MMCSD_POWER_UP: break; case MMCSD_POWER_ON: SDIO_SetPowerState(SDIO_PowerState_ON); break; default: rt_kprintf("unknown power_mode %d\n", io_cfg->power_mode); break; } SDIO_Init(&SDIO_InitStructure); }
/** * @brief DeInitializes the SDIO interface. * @param None * @retval None */ void SD_LowLevel_DeInit(void) { GPIO_InitTypeDef GPIO_InitStructure; /*!< Disable SDIO Clock */ SDIO_ClockCmd(DISABLE); /*!< Set Power State to OFF */ SDIO_SetPowerState(SDIO_PowerState_OFF); /*!< DeInitializes the SDIO peripheral */ SDIO_DeInit(); /*!< Disable the SDIO AHB Clock */ RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, DISABLE); /*!< Configure PC.08, PC.09, PC.10, PC.11, PC.12 pin: D0, D1, D2, D3, CLK pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStructure); /*!< Configure PD.02 CMD line */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); }
void SD_LowLevel_DeInit(void){ GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&NVIC_InitStructure); // Disable SDIO Clock SDIO_ClockCmd(DISABLE); // Set Power State to OFF SDIO_SetPowerState(SDIO_PowerState_OFF); // DeInitializes the SDIO peripheral SDIO_DeInit(); // Disable the SDIO APB2 Clock RCC_AHBPeriphClockCmd(RCC_AHBPeriph_SDIO, DISABLE); // Configure PC.08, PC.09, PC.10, PC.11, PC.12 pins: D0, D1, D2, D3, CLK GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOC, &GPIO_InitStructure); // Configure PD.02 CMD line GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); }
/** * @brief DeInitializes the SDIO interface. * @param None * @retval None */ void SD_LowLevel_DeInit(void) { GPIO_InitTypeDef GPIO_InitStructure; /*!< Disable SDIO Clock */ SDIO_ClockCmd(DISABLE); /*!< Set Power State to OFF */ SDIO_SetPowerState(SDIO_PowerState_OFF); /*!< DeInitializes the SDIO peripheral */ SDIO_DeInit(); /* Disable the SDIO APB2 Clock */ RCC_APB2PeriphClockCmd(RCC_APB2Periph_SDIO, DISABLE); GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_MCO); /* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure PD.02 CMD line */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Configure PC.12 pin: CLK pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_Init(GPIOC, &GPIO_InitStructure); }
/************************************************************************* * Function Name: _SdPowerDown * Parameters: none * Return: none * * Description: Set power down state * *************************************************************************/ static void _SdPowerDown (void) { SDIO_SetPowerState(SDIO_PowerState_OFF); // Clock Freq. Identification Mode < 400kHz _SdSetClockFreq(IdentificationModeClock); }
/** * @brief DeInitializes the SDIO interface. * @param None * @retval None */ void SD_LowLevel_DeInit(void) { GPIO_InitTypeDef GPIO_InitStructure; /*!< Disable SDIO Clock */ SDIO_ClockCmd(DISABLE); /*!< Set Power State to OFF */ SDIO_SetPowerState(SDIO_PowerState_OFF); /*!< DeInitializes the SDIO peripheral */ SDIO_DeInit(); /* Disable the SDIO APB2 Clock */ CLEAR_BIT(RCC->APB2ENR,RCC_APB2ENR_SDIOEN); // Set GPIOC 8-12 alt funciton as MCO = 0 ie set to zero Alt Function (from 12) GPIO_PinAFConfig(GPIOC, GPIO_PinSource8, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource9, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource11, GPIO_AF_MCO); GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_MCO); // set GPIOD.2 as MCO GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_MCO); /* Configure PC.08, PC.09, PC.10, PC.11 pins: D0, D1, D2, D3 pins */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOC, &GPIO_InitStructure); /* Configure PD.02 CMD line */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_Init(GPIOD, &GPIO_InitStructure); /* Configure PC.12 pin: CLK pin */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_Init(GPIOC, &GPIO_InitStructure); }
void host_platform_enable_high_speed_sdio( void ) { SDIO_InitTypeDef sdio_init_structure; sdio_init_structure.SDIO_ClockDiv = (uint8_t) 0; /* 0 = 24MHz if SDIO clock = 48MHz */ sdio_init_structure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; sdio_init_structure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; sdio_init_structure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Disable; #ifndef SDIO_1_BIT sdio_init_structure.SDIO_BusWide = SDIO_BusWide_4b; #else sdio_init_structure.SDIO_BusWide = SDIO_BusWide_1b; #endif sdio_init_structure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_DeInit( ); SDIO_Init( &sdio_init_structure ); SDIO_SetPowerState( SDIO_PowerState_ON ); SDIO_ClockCmd( ENABLE ); sdio_enable_bus_irq( ); }
OSStatus host_platform_bus_deinit( void ) { OSStatus result; uint32_t a; result = mico_rtos_deinit_semaphore( &sdio_transfer_finished_semaphore ); platform_mcu_powersave_disable(); /* Disable SPI and SPI DMA */ sdio_disable_bus_irq( ); SDIO_ClockCmd( DISABLE ); SDIO_SetPowerState( SDIO_PowerState_OFF ); SDIO_DeInit( ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_SDIO, DISABLE ); #ifdef SDIO_1_BIT platform_gpio_deinit( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ] ); platform_gpio_irq_disable( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ] ); #endif for ( a = 0; a < WIFI_PIN_SDIO_MAX; a++ ) { platform_gpio_deinit( &wifi_sdio_pins[ a ] ); } #if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP ) platform_gpio_deinit( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] ); platform_gpio_deinit( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] ); #endif /* Turn off SDIO IRQ */ NVIC_DisableIRQ( SDIO_IRQ_CHANNEL ); NVIC_DisableIRQ( DMA2_3_IRQ_CHANNEL ); platform_mcu_powersave_enable(); return result; }
/************************************************************************* * Function Name: _SdInitMedia * Parameters: none * * Return: SdState_t * * Description: SD/MMC detect and initialize * *************************************************************************/ static SdState_t _SdInitMedia (void) { Int32U i,res; volatile Int32U Dly; Int8U MmcSdCid[16]; _Tnac = 1; if(!_SdPresent()) { if(SDIO_PowerState_OFF != SDIO_GetPowerState()) { // Set to power down state _SdPowerDown(); } return(SdNoPresent); } _SdPowerDown(); SdDly_1ms(100); // Set Power State to ON SDIO_SetPowerState(SDIO_PowerState_ON); SdDly_1ms(100); // Enable SDIO Clock SDIO_ClockCmd(ENABLE); if(_SdSendCmd(CMD0,NULL) != SdOk) { return(SdNoResponse); } // Determinate Card type SD or MMC _SdDskCtrlBlk.DiskType = DiskSD_Spec2_0; res = Cmd8Reg; if(SdOk == _SdSendCmd(CMD8,&res)) { _bHC = TRUE; } else { _SdDskCtrlBlk.DiskType = DiskSD_Spec1_x; } for(i=100; i; --i) { res = 0; if((_SdSendCmd(CMD55,&res) == SdOk) && (res & 0x100)) { res = _bHC?OcrReg | OcrReg_HC:OcrReg; if((_SdSendCmd(ACMD41,&res) == SdOk) && (res & 0x80000000)) { // SD card is find _bHC = 0 != (res & OcrReg_HC); break; } } else { _SdDskCtrlBlk.DiskType = DiskMMC; // CMD1 for MMC Init sequence // will be complete within 500ms res = OcrReg; if(_SdSendCmd(CMD1,&res) == SdOk && (res & 0x80000000)) { // MMC card is find _bHC = FALSE; break; } } SdDly_1ms(10); } if(i == 0) { return(SdNoResponse); } // Read CID if(_SdSendCmd(CMD2,(pInt32U)MmcSdCid) != SdOk) { return(SdNoResponse); } // Set address _CardRCA = (_SdDskCtrlBlk.DiskType == DiskMMC)?0x00010000:0x00000000; if(_SdSendCmd(CMD3,&_CardRCA) != SdOk) { return(SdNoResponse); } if(DiskMMC != _SdDskCtrlBlk.DiskType) { _CardRCA &= 0xFFFF0000; } else { _CardRCA = 0x00010000; } // Read CSD _MmcSdCsd[0] = 0; _MmcSdCsd[1] = 0; _MmcSdCsd[2] = _CardRCA >> 16; _MmcSdCsd[3] = _CardRCA >> 24; if(_SdSendCmd(CMD9,(pInt32U)_MmcSdCsd) != SdOk) { return(SdNoResponse); } // Implement CSD data _SdCsdImplemet(); // Enter in TRAN state res = _CardRCA; if(_SdSendCmd(CMD7,&res) != SdOk) { return(SdNoResponse); } res = _CardRCA; if(SdOk != _SdSendCmd(CMD13,&res)) { return(SdNoResponse); } else if(!(res & READY_FOR_DATA) || ((res & CURRENT_STATE) != CARD_TRAN)) { return(SdCardError); } // Set Block size res = _SdDskCtrlBlk.BlockSize; if(_SdSendCmd(CMD16,&res)) { return(SdNoResponse); } if(DiskMMC != _SdDskCtrlBlk.DiskType) { // Use wide bus for SD res = _CardRCA; if((_SdSendCmd(CMD55,&res) != SdOk) || !(res & 0x100)) { return(SdCardError); } // Set bus width 4bits res = 2; if(_SdSendCmd(ACMD6,&res) != SdOk) { return(SdCardError); } SDIO->CLKCR |= 1UL << 11; } return(SdOk); }
OSStatus host_platform_bus_init( void ) { SDIO_InitTypeDef sdio_init_structure; OSStatus result; uint8_t a; platform_mcu_powersave_disable(); result = mico_rtos_init_semaphore( &sdio_transfer_finished_semaphore, 1 ); if ( result != kNoErr ) { return result; } /* Turn on SDIO IRQ */ SDIO->ICR = (uint32_t) 0xffffffff; /* Must be lower priority than the value of configMAX_SYSCALL_INTERRUPT_PRIORITY */ /* otherwise FreeRTOS will not be able to mask the interrupt */ /* keep in mind that ARMCM3 interrupt priority logic is inverted, the highest value */ /* is the lowest priority */ NVIC_EnableIRQ( SDIO_IRQ_CHANNEL ); NVIC_EnableIRQ( DMA2_3_IRQ_CHANNEL ); /* Set GPIO_B[1:0] to 00 to put WLAN module into SDIO mode */ #if defined ( MICO_WIFI_USE_GPIO_FOR_BOOTSTRAP ) platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0], OUTPUT_PUSH_PULL ); platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_0] ); platform_gpio_init( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1], OUTPUT_PUSH_PULL ); platform_gpio_output_low( &wifi_control_pins[WIFI_PIN_BOOTSTRAP_1] ); #endif /* Setup GPIO pins for SDIO data & clock */ for ( a = WIFI_PIN_SDIO_CLK; a < WIFI_PIN_SDIO_MAX; a++ ) { platform_gpio_set_alternate_function( wifi_sdio_pins[ a ].port, wifi_sdio_pins[ a ].pin_number, GPIO_OType_PP, GPIO_PuPd_UP, GPIO_AF_SDIO ); } #ifdef SDIO_1_BIT platform_gpio_init( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], INPUT_PULL_UP ); platform_gpio_irq_enable( &wifi_sdio_pins[WIFI_PIN_SDIO_IRQ], IRQ_TRIGGER_FALLING_EDGE, sdio_int_pin_irq_handler, 0 ); #endif /*!< Enable the SDIO AHB Clock and the DMA2 Clock */ RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_DMA2, ENABLE ); RCC_APB2PeriphClockCmd( RCC_APB2Periph_SDIO, ENABLE ); SDIO_DeInit( ); sdio_init_structure.SDIO_ClockDiv = (uint8_t) 120; /* 0x78, clock is taken from the high speed APB bus ; */ /* About 400KHz */ sdio_init_structure.SDIO_ClockEdge = SDIO_ClockEdge_Rising; sdio_init_structure.SDIO_ClockBypass = SDIO_ClockBypass_Disable; sdio_init_structure.SDIO_ClockPowerSave = SDIO_ClockPowerSave_Enable; sdio_init_structure.SDIO_BusWide = SDIO_BusWide_1b; sdio_init_structure.SDIO_HardwareFlowControl = SDIO_HardwareFlowControl_Disable; SDIO_Init( &sdio_init_structure ); SDIO_SetPowerState( SDIO_PowerState_ON ); SDIO_SetSDIOReadWaitMode( SDIO_ReadWaitMode_CLK ); SDIO_ClockCmd( ENABLE ); platform_mcu_powersave_enable(); return kNoErr; }
bool SdCardSdioFeature::powerOn() { SD_Error errorstatus=SD_OK; uint32_t response=0,count=0,validvoltage=0; uint32_t SDType=SD_STD_CAPACITY; SDIO_InitTypeDef sdioInit; SDIO_CmdInitTypeDef cmdInit; /*!< Power ON Sequence -----------------------------------------------------*/ sdioInit.SDIO_ClockDiv=_initDivider; sdioInit.SDIO_ClockEdge=SDIO_ClockEdge_Rising; sdioInit.SDIO_ClockBypass=SDIO_ClockBypass_Disable; sdioInit.SDIO_ClockPowerSave=SDIO_ClockPowerSave_Disable; sdioInit.SDIO_BusWide=SDIO_BusWide_1b; sdioInit.SDIO_HardwareFlowControl=SDIO_HardwareFlowControl_Disable; SDIO_Init(&sdioInit); /*!< Set Power State to ON */ SDIO_SetPowerState(SDIO_PowerState_ON); /*!< Enable SDIO Clock */ SDIO_ClockCmd(ENABLE); /*!< CMD0: GO_IDLE_STATE ---------------------------------------------------*/ /*!< No CMD response required */ cmdInit.SDIO_Argument=0x0; cmdInit.SDIO_CmdIndex=SD_CMD_GO_IDLE_STATE; cmdInit.SDIO_Response=SDIO_Response_No; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdError(); if(errorstatus != SD_OK) return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus); /*!< CMD8: SEND_IF_COND ----------------------------------------------------*/ /*!< Send CMD8 to verify SD card interface operating condition */ /*!< Argument: - [31:12]: Reserved (shall be set to '0') - [11:8]: Supply Voltage (VHS) 0x1 (Range: 2.7-3.6 V) - [7:0]: Check Pattern (recommended 0xAA) */ /*!< CMD Response: R7 */ cmdInit.SDIO_Argument=SD_CHECK_PATTERN; cmdInit.SDIO_CmdIndex=SDIO_SEND_IF_COND; cmdInit.SDIO_Response=SDIO_Response_Short; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdResp7Error(); if(errorstatus == SD_OK) { _cardType=SDIO_STD_CAPACITY_SD_CARD_V2_0; /*!< SD Card 2.0 */ SDType=SD_HIGH_CAPACITY; } else { /*!< CMD55 */ cmdInit.SDIO_Argument=0x00; cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD; cmdInit.SDIO_Response=SDIO_Response_Short; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdResp1Error(SD_CMD_APP_CMD); } /*!< CMD55 */ cmdInit.SDIO_Argument=0x00; cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD; cmdInit.SDIO_Response=SDIO_Response_Short; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdResp1Error(SD_CMD_APP_CMD); /*!< If errorstatus is Command TimeOut, it is a MMC card */ /*!< If errorstatus is SD_OK it is a SD card: SD card 2.0 (voltage range mismatch) or SD card 1.x */ if(errorstatus == SD_OK) { /*!< SD CARD */ /*!< Send ACMD41 SD_APP_OP_COND with Argument 0x80100000 */ while((!validvoltage) && (count < SD_MAX_VOLT_TRIAL)) { /*!< SEND CMD55 APP_CMD with RCA as 0 */ cmdInit.SDIO_Argument=0x00; cmdInit.SDIO_CmdIndex=SD_CMD_APP_CMD; cmdInit.SDIO_Response=SDIO_Response_Short; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdResp1Error(SD_CMD_APP_CMD); if(errorstatus != SD_OK) return errorstatus; cmdInit.SDIO_Argument=SD_VOLTAGE_WINDOW_SD | SDType; cmdInit.SDIO_CmdIndex=SD_CMD_SD_APP_OP_COND; cmdInit.SDIO_Response=SDIO_Response_Short; cmdInit.SDIO_Wait=SDIO_Wait_No; cmdInit.SDIO_CPSM=SDIO_CPSM_Enable; SDIO_SendCommand(&cmdInit); errorstatus=cmdResp3Error(); if(errorstatus != SD_OK) return errorstatus; response=SDIO_GetResponse(SDIO_RESP1); validvoltage=(((response >> 31) == 1) ? 1 : 0); count++; } if(count >= SD_MAX_VOLT_TRIAL) { errorstatus=SD_INVALID_VOLTRANGE; return errorstatus; } if(response&=SD_HIGH_CAPACITY) _cardType=SDIO_HIGH_CAPACITY_SD_CARD; }/*!< else MMC Card */ if(errorstatus != SD_OK) return errorProvider.set(ErrorProvider::ERROR_PROVIDER_SD_SDIO,E_SDIO_ERROR,errorstatus); return true; }
void SdCardSdioFeature::powerOff() { SDIO_SetPowerState(SDIO_PowerState_OFF); }