|

楼主 |
发表于 2018-9-28 11:52:28
|
显示全部楼层
例子:SD_ReadWrite_DMA
实现了一个简单的状态机思想来调用函数HAL_SD_WriteBlocks_DMA和HAL_SD_ReadBlocks_DMA。

注意引脚的复用设置,有GPIO_AF7_SDIO1,GPIO_AF8_SDIO1和GPIO_AF12_SDIO1
- /**
- * @brief SD MSP Initialization
- * This function configures the hardware resources used in this example:
- * - Peripheral's clock enable
- * - Peripheral's GPIO Configuration
- * - DMA configuration for requests by peripheral
- * - NVIC configuration for DMA and SD interrupts
- * @param hsd: SD handle pointer
- * @retval None
- */
- void HAL_SD_MspInit(SD_HandleTypeDef *hsd)
- {
- GPIO_InitTypeDef gpio_init_structure;
-
- /* Enable SDIO clock */
- __HAL_RCC_SDMMC1_CLK_ENABLE();
-
- /* Enable GPIOs clock */
- __HAL_RCC_GPIOB_CLK_ENABLE();
- __HAL_RCC_GPIOC_CLK_ENABLE();
- __HAL_RCC_GPIOD_CLK_ENABLE();
- gpio_init_structure.Mode = GPIO_MODE_AF_PP;
- gpio_init_structure.Pull = GPIO_NOPULL;
- gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
-
- /* D0(PC8), D1(PC9), D2(PC10), D3(PC11), CK(PC12), CMD(PD2) */
- /* Common GPIO configuration */
- gpio_init_structure.Alternate = GPIO_AF12_SDIO1;
-
- /* GPIOC configuration */
- gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
- HAL_GPIO_Init(GPIOC, &gpio_init_structure);
- /* GPIOD configuration */
- gpio_init_structure.Pin = GPIO_PIN_2;
- HAL_GPIO_Init(GPIOD, &gpio_init_structure);
- /* D0DIR(PC6), D123DIR(PC7) */
- gpio_init_structure.Alternate = GPIO_AF8_SDIO1;
- /* GPIOC configuration */
- gpio_init_structure.Pin = GPIO_PIN_6 | GPIO_PIN_7;
- HAL_GPIO_Init(GPIOC, &gpio_init_structure);
- /* CKIN(PB8), CDIR(PB9) */
- gpio_init_structure.Alternate = GPIO_AF7_SDIO1;
- /* GPIOB configuration */
- gpio_init_structure.Pin = GPIO_PIN_8 | GPIO_PIN_9;
- HAL_GPIO_Init(GPIOB, &gpio_init_structure);
- __HAL_RCC_SDMMC1_FORCE_RESET();
- __HAL_RCC_SDMMC1_RELEASE_RESET();
- /* NVIC configuration for SDIO interrupts */
- HAL_NVIC_SetPriority(SDMMC1_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
- }
- /**
- * @brief SD MSP De-Initialization
- * This function frees the hardware resources used in this example:
- * - Disable the Peripheral's clock
- * - Revert GPIO, DMA and NVIC configuration to their default state
- * @param hsd: SD handle pointer
- * @retval None
- */
- void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd)
- {
-
- /* DeInit GPIO pins can be done in the application
- (by surcharging this __weak function) */
-
- /* Enable GPIOs clock */
- __HAL_RCC_GPIOB_CLK_DISABLE();
- __HAL_RCC_GPIOC_CLK_DISABLE();
- __HAL_RCC_GPIOD_CLK_DISABLE();
-
- /* Disable SDMMC1 clock */
- __HAL_RCC_SDMMC1_CLK_DISABLE();
- }
复制代码
主实现函数如下:- /* Private define ------------------------------------------------------------*/
- #define DATA_SIZE ((uint32_t)0x06400000U) /* Data Size 100Mo */
- /* ------ Buffer Size ------ */
- #define BUFFER_SIZE ((uint32_t)0x00040000U) /* 256Ko */
- #define NB_BUFFER DATA_SIZE / BUFFER_SIZE
- #define NB_BLOCK_BUFFER BUFFER_SIZE / BLOCKSIZE /* Number of Block (512o) by Buffer */
- #define BUFFER_WORD_SIZE (BUFFER_SIZE>>2) /* Buffer size in Word */
- #define SD_TIMEOUT ((uint32_t)0x00100000U)
- #define ADDRESS ((uint32_t)0x00000400U) /* SD Address to write/read data */
- #define DATA_PATTERN ((uint32_t)0xB5F3A5F3U) /* Data pattern to write */
- /* Private macro -------------------------------------------------------------*/
- /* Private variables ---------------------------------------------------------*/
- SD_HandleTypeDef SDHandle;
- __IO uint8_t RxCplt, TxCplt;
- /******** SD Transmission Buffer definition *******/
- #if defined ( __ICCARM__ )
- #pragma location = 0x24000000
- #elif defined ( __CC_ARM )
- __attribute__((section (".RAM_D1")))
- #elif defined ( __GNUC__ )
- __attribute__((section (".RAM_D1")))
- #endif
- uint8_t aTxBuffer[BUFFER_WORD_SIZE*4];
- /**************************************************/
- /******** SD Receive Buffer definition *******/
- #if defined ( __ICCARM__ )
- #pragma location = 0x24040000
- #elif defined ( __CC_ARM )
- __attribute__((section (".RAM_D1")))
- #elif defined ( __GNUC__ )
- __attribute__((section (".RAM_D1")))
- #endif
- uint8_t aRxBuffer[BUFFER_WORD_SIZE*4];
- /**************************************************/
- /* UART handler declaration, used for printf */
- UART_HandleTypeDef UartHandle;
- __IO uint8_t step = 0;
- uint32_t start_time = 0;
- uint32_t stop_time = 0;
- /* Private function prototypes -----------------------------------------------*/
- static void SystemClock_Config(void);
- static void Error_Handler(void);
- static void CPU_CACHE_Enable(void);
- static void UART_Config(void);
- static uint8_t Wait_SDCARD_Ready(void);
- #ifdef __GNUC__ /* __GNUC__ */
- #define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
- #else
- #define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
- #endif /* __GNUC__ */
- /* Private functions ---------------------------------------------------------*/
- void Fill_Buffer(uint32_t *pBuffer, uint16_t BufferLength, uint32_t Offset);
- /**
- * @brief Main program
- * @param None
- * @retval None
- */
- int main(void)
- {
- uint32_t index = 0;
- /* Enable the CPU Cache */
- CPU_CACHE_Enable();
- HAL_SD_CardCIDTypedef pCID;
- HAL_SD_CardCSDTypedef pCSD;
- /* STM32H7xx HAL library initialization:
- - Configure the Systick to generate an interrupt each 1 msec
- - Set NVIC Group Priority to 4
- - Low Level Initialization
- */
- HAL_Init();
- /* Configure the system clock to 400 MHz */
- SystemClock_Config();
- /*##-1- Initialize LEDs mounted on STM32H743I-EVAL board #####################*/
- BSP_LED_Init(LED_GREEN);
- BSP_LED_Init(LED_ORANGE);
- BSP_LED_Init(LED_RED);
-
- /*##-2- Configure USART for printf messages #####################*/
- UART_Config();
-
- /*##-2- Initialize IO functionalities (MFX) #####################*/
- BSP_IO_Init();
-
- /* Initialise Transciver MFXPIN to enable 1.8V Switch mode */
- BSP_IO_ConfigPin(SD_LDO_SEL_PIN, IO_MODE_OUTPUT_PP_PU);
-
- /*##-3- Initialize SD instance #####################*/
- SDHandle.Instance = SDMMC1;
- HAL_SD_DeInit(&SDHandle);
-
- /* SDMMC IP clock 200Mhz, SDCard clock 100Mhz */
- SDHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
- SDHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
- SDHandle.Init.BusWide = SDMMC_BUS_WIDE_4B;
- SDHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
- SDHandle.Init.ClockDiv = 1;
-
- if(HAL_SD_Init(&SDHandle) != HAL_OK)
- {
- Error_Handler();
- }
-
- if(HAL_SD_Erase(&SDHandle, ADDRESS, ADDRESS+BUFFERSIZE) != HAL_OK)
- {
- Error_Handler();
- }
- if(Wait_SDCARD_Ready() != HAL_OK)
- {
- Error_Handler();
- }
-
- HAL_SD_GetCardCID(&SDHandle, &pCID);
- HAL_SD_GetCardCSD(&SDHandle, &pCSD);
-
- while(1)
- {
- switch(step)
- {
- case 0:
- {
- /*##- 4 - Initialize Transmission buffer #####################*/
- for (index = 0; index < BUFFERSIZE; index++)
- {
- aTxBuffer[index] = DATA_PATTERN + index;
- }
- SCB_CleanDCache_by_Addr((uint32_t*)aTxBuffer, BUFFER_WORD_SIZE*4);
- printf(" ****************** Start Write test ******************* \n");
- printf(" - Buffer size to write: %lu MB \n", (DATA_SIZE>>20));
- index = 0;
- start_time = HAL_GetTick();
- step++;
- }
- break;
- case 1:
- {
- TxCplt = 0;
- /*##- 5 - Start Transmission buffer #####################*/
- if(HAL_SD_WriteBlocks_DMA(&SDHandle, aTxBuffer, ADDRESS, NB_BLOCK_BUFFER) != HAL_OK)
- {
- Error_Handler();
- }
- step++;
- }
- break;
- case 2:
- {
- if(TxCplt != 0)
- {
- /* Toogle Led Orange, Transfer of Buffer OK */
- BSP_LED_Toggle(LED_ORANGE);
-
- /* Transfer of Buffer completed */
- index++;
- if(index<NB_BUFFER)
- {
- /* More data need to be trasnfered */
- step--;
- }
- else
- {
- stop_time = HAL_GetTick();
- printf(" - Write Time(ms): %lu - Write Speed: %02.2f MB/s \n", stop_time - start_time, (float)((float)(DATA_SIZE>>10)/(float)(stop_time - start_time)));
- /* All data are transfered */
- step++;
- }
- }
- }
- break;
- case 3:
- {
- /*##- 6 - Initialize Reception buffer #####################*/
- for (index = 0; index < BUFFERSIZE; index++)
- {
- aRxBuffer[index] = 0;
- }
- SCB_CleanDCache_by_Addr((uint32_t*)aRxBuffer, BUFFER_WORD_SIZE*4);
- printf(" ******************* Start Read test ******************* \n");
- printf(" - Buffer size to read: %lu MB \n", (DATA_SIZE>>20));
- start_time = HAL_GetTick();
- index = 0;
- step++;
- }
- break;
- case 4:
- {
- /*##- 7 - Initialize Reception buffer #####################*/
- RxCplt = 0;
- if(HAL_SD_ReadBlocks_DMA(&SDHandle, aRxBuffer, ADDRESS, NB_BLOCK_BUFFER) != HAL_OK)
- {
- Error_Handler();
- }
- step++;
- }
- break;
- case 5:
- {
- if(RxCplt != 0)
- {
- /* Toogle Led Orange, Transfer of Buffer OK */
- BSP_LED_Toggle(LED_ORANGE);
- /* Transfer of Buffer completed */
- index++;
- if(index<NB_BUFFER)
- {
- /* More data need to be trasnfered */
- step--;
- }
- else
- {
- stop_time = HAL_GetTick();
- printf(" - Read Time(ms): %lu - Read Speed: %02.2f MB/s \n", stop_time - start_time, (float)((float)(DATA_SIZE>>10)/(float)(stop_time - start_time)));
- /* All data are transfered */
- step++;
- }
- }
- }
- break;
- case 6:
- {
- /*##- 8 - Check Reception buffer #####################*/
- index=0;
- printf(" ********************* Check data ********************** \n");
- while((index<BUFFERSIZE) && (aRxBuffer[index] == aTxBuffer[index]))
- {
- index++;
- }
-
- if(index != BUFFERSIZE)
- {
- printf(" - Check data Error !!!! \n");
- Error_Handler();
- }
- printf(" - Check data OK \n");
- /* Toogle Green LED, Check Transfer OK */
- BSP_LED_Toggle(LED_GREEN);
- step = 0;
- }
- break;
- default :
- Error_Handler();
- }
- }
- }
- /**
- * @brief System Clock Configuration
- * The system Clock is configured as follow :
- * System Clock source = PLL (HSE)
- * SYSCLK(Hz) = 400000000 (CPU Clock)
- * HCLK(Hz) = 200000000 (AXI and AHBs Clock)
- * AHB Prescaler = 2
- * D1 APB3 Prescaler = 2 (APB3 Clock 100MHz)
- * D2 APB1 Prescaler = 2 (APB1 Clock 100MHz)
- * D2 APB2 Prescaler = 2 (APB2 Clock 100MHz)
- * D3 APB4 Prescaler = 2 (APB4 Clock 100MHz)
- * HSE Frequency(Hz) = 25000000
- * PLL_M = 5
- * PLL_N = 160
- * PLL_P = 2
- * PLL_Q = 4
- * PLL_R = 2
- * VDD(V) = 3.3
- * Flash Latency(WS) = 4
- * @param None
- * @retval None
- */
- static void SystemClock_Config(void)
- {
- RCC_ClkInitTypeDef RCC_ClkInitStruct;
- RCC_OscInitTypeDef RCC_OscInitStruct;
- HAL_StatusTypeDef ret = HAL_OK;
- /*!< Supply configuration update enable */
- MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);
- /* The voltage scaling allows optimizing the power consumption when the device is
- clocked below the maximum system frequency, to update the voltage scaling value
- regarding system frequency refer to product datasheet. */
- __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
- while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
- /* Enable HSE Oscillator and activate PLL with HSE as source */
- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
- RCC_OscInitStruct.HSEState = RCC_HSE_ON;
- RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
- RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
- RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
- RCC_OscInitStruct.PLL.PLLM = 5;
- RCC_OscInitStruct.PLL.PLLN = 160;
- RCC_OscInitStruct.PLL.PLLP = 2;
- RCC_OscInitStruct.PLL.PLLR = 2;
- RCC_OscInitStruct.PLL.PLLQ = 4;
- RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
- RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
- ret = HAL_RCC_OscConfig(&RCC_OscInitStruct);
- if(ret != HAL_OK)
- {
- Error_Handler();
- }
-
- /* Select PLL as system clock source and configure bus clocks dividers */
- RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \
- RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1);
-
- RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
- RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
- RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
- RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
- RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
- RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
- RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
- ret = HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
- if(ret != HAL_OK)
- {
- Error_Handler();
- }
- /*activate CSI clock mondatory for I/O Compensation Cell*/
- __HAL_RCC_CSI_ENABLE() ;
-
- /* Enable SYSCFG clock mondatory for I/O Compensation Cell */
- __HAL_RCC_SYSCFG_CLK_ENABLE() ;
-
- /* Enables the I/O Compensation Cell */
- HAL_EnableCompensationCell();
-
- }
- /**
- * @brief Enable the SD Transciver 1.8V Mode Callback.
- * @param None
- * @retval None
- */
- void HAL_SD_DriveTransciver_1_8V_Callback(FlagStatus status)
- {
- if(status == SET)
- {
- BSP_IO_WritePin(IO_PIN_13, BSP_IO_PIN_SET);
- }
- else
- {
- BSP_IO_WritePin(IO_PIN_13, BSP_IO_PIN_RESET);
- }
- }
- /**
- * @brief Rx Transfer completed callbacks
- * @param hsd: SD handle
- * @retval None
- */
- void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
- {
- if(Wait_SDCARD_Ready() != HAL_OK)
- {
- Error_Handler();
- }
- SCB_InvalidateDCache_by_Addr((uint32_t*)aRxBuffer, BUFFER_WORD_SIZE*4);
- RxCplt=1;
- }
- /**
- * @brief Tx Transfer completed callbacks
- * @param hsd: SD handle
- * @retval None
- */
- void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
- {
- if(Wait_SDCARD_Ready() != HAL_OK)
- {
- Error_Handler();
- }
- TxCplt=1;
- }
复制代码
|
|