/** * @brief Storage drives initialization * @param None * @retval None */ void k_StorageInit(void) { /* Link the USB Host disk I/O driver */ FATFS_LinkDriver(&USBH_Driver, USBDISK_Drive); /* Link the micro SD disk I/O driver */ FATFS_LinkDriver(&SD_Driver, mSDDISK_Drive); /* Create USB background task */ osThreadDef(STORAGE_Thread, StorageThread, osPriorityBelowNormal, 0, 2 * configMINIMAL_STACK_SIZE); osThreadCreate (osThread(STORAGE_Thread), NULL); /* Create Storage Message Queue */ osMessageQDef(osqueue, 10, uint16_t); StorageEvent = osMessageCreate (osMessageQ(osqueue), NULL); /* Init Host Library */ USBH_Init(&hUSB_Host, USBH_UserProcess, 0); /* Add Supported Class */ USBH_RegisterClass(&hUSB_Host, USBH_MSC_CLASS); /* Start Host Process */ USBH_Start(&hUSB_Host); /* Enable SD Interrupt mode */ BSP_SD_Init(); BSP_SD_ITConfig(); if(BSP_SD_IsDetected()) { osMessagePut ( StorageEvent, MSDDISK_CONNECTION_EVENT, 0); } }
/** * @brief Initializes the SD Storage. * @param None * @retval Status */ uint8_t SD_StorageInit(void) { /*Initializes the SD card device*/ BSP_SD_Init(); /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() == SD_PRESENT ) { /* Link the SD Card disk I/O driver */ if(FATFS_LinkDriver(&SD_Driver, SD_Path) == 0) { if((f_mount(&SD_FatFs, (TCHAR const*)SD_Path, 0) != FR_OK)) { /* FatFs Initialization Error */ LCD_ErrLog("Cannot Initialize FatFs! \n"); return 1; } else { LCD_DbgLog ("INFO : FatFs Initialized! \n"); } } } else { LCD_ErrLog("SD card NOT plugged \n"); return 1; } return 0; }
/** * @brief Starts Audio streaming. * @param idx: File index * @retval Audio error */ AUDIO_ErrorTypeDef AUDIO_Start(uint8_t idx) { uint32_t bytesread; if((FileList.ptr > idx) && (BSP_SD_IsDetected())) { f_close(&wav_file); AUDIO_GetFileInfo(idx, &wav_info); audio_state = AUDIO_STATE_CONFIG; /* Set Frequency */ USBH_AUDIO_SetFrequency(&hUSBHost, wav_info.SampleRate, wav_info.NbrChannels, wav_info.BitPerSample); /* Fill whole buffer at first time */ if(f_read(&wav_file, &buffer_ctl.buff[0], AUDIO_BLOCK_SIZE * AUDIO_BLOCK_NBR, (void *)&bytesread) == FR_OK) { if(bytesread != 0) { return AUDIO_ERROR_NONE; } } buffer_ctl.in_ptr = 0; } return AUDIO_ERROR_IO; }
/** * @brief EXTI line detection callbacks. * @param GPIO_Pin: Specifies the pins connected EXTI line * @retval None */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin==SD_DETECT_PIN) { /* Check SD card detect pin */ BSP_SD_IsDetected(); } }
/** * @brief Saves the picture in microSD. * @param None * @retval None */ void Save_Picture(void) { FRESULT res1, res2; /* FatFs function common result code */ uint32_t byteswritten = 0; /* File write count */ static uint32_t counter = 0; uint8_t str[30]; /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { Error_Handler(); } else { /* Format the string */ sprintf((char *)str, "image_%lu.bmp", counter); /*##-1- Prepare the image to be saved ####################################*/ Prepare_Picture(); /*##-2- Create and Open a new bmp file object with write access ##########*/ if(f_open(&MyFile, (const char*)str, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) { /* 'image.bmp' file Open for write Error */ Error_Handler(); } else { /*##-3- Write data to the BMP file #####################################*/ /* Write the BMP header */ res1 = f_write(&MyFile, (uint32_t *)aBMPHeader, 54, (void *)&byteswritten); /* Write the BMP file */ res2 = f_write(&MyFile, (uint32_t *)CONVERTED_FRAME_BUFFER, ((BSP_LCD_GetYSize() - 80)*(BSP_LCD_GetXSize() - 80)*2), (void *)&byteswritten); if((res1 != FR_OK) || (res2 != FR_OK) || (byteswritten == 0)) { /* 'image.bmp' file Write or EOF Error */ Error_Handler(); } else { /*##-4- Close the open BMP file ######################################*/ f_close(&MyFile); /* Success of the demo: no error occurrence */ BSP_LED_On(LED1); /* Wait for 2s */ HAL_Delay(2000); /* Select Layer 1 */ BSP_LED_Off(LED1); counter++; } } } }
/** * @brief Configures Interrupt mode for SD detection pin. * @retval Returns 0 */ uint8_t BSP_SD_ITConfig(void) { /* Configure Interrupt mode for SD detection pin */ /* Note: disabling exti mode can be done calling SD_DeInit() */ UseExtiModeDetection = 1; BSP_SD_IsDetected(); return 0; }
/** * @brief SD detect callback * @param None * @retval None */ void BSP_SD_DetectCallback(void) { if(BSP_SD_IsDetected()) { osMessagePut ( StorageEvent, MSDDISK_CONNECTION_EVENT, 0); } else { osMessagePut ( StorageEvent, MSDDISK_DISCONNECTION_EVENT, 0); } }
/** * @brief Writes data into the medium. * @param lun: Logical unit number * @param blk_addr: Logical block address * @param blk_len: Blocks number * @retval Status (0 : Ok / -1 : Error) */ int8_t STORAGE_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len) { int8_t ret = -1; if(BSP_SD_IsDetected() != SD_NOT_PRESENT) { BSP_SD_WriteBlocks_DMA((uint32_t *)buf, blk_addr * STORAGE_BLK_SIZ, STORAGE_BLK_SIZ, blk_len); ret = 0; } return ret; }
/** * @brief SD detect callback * @param None * @retval None */ void BSP_SD_DetectCallback(void) { if((BSP_SD_IsDetected())) { /* After sd disconnection, a SD Init is required */ BSP_SD_Init(); osMessagePut ( StorageEvent, MSDDISK_CONNECTION_EVENT, 0); } else { osMessagePut ( StorageEvent, MSDDISK_DISCONNECTION_EVENT, 0); } }
/** * @brief Initializes the SD card device. * @retval SD status */ uint8_t BSP_SD_Init(void) { uint8_t sd_state = MSD_OK; /* PLLSAI is dedicated to LCD periph. Do not use it to get 48MHz*/ /* uSD device interface configuration */ uSdHandle.Instance = SDIO; uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B; uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; /* Configure IO functionalities for SD detect pin */ BSP_IO_Init(); /* Check if the SD card is plugged in the slot */ BSP_IO_ConfigPin(SD_DETECT_PIN, IO_MODE_INPUT_PU); if(BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR_SD_NOT_PRESENT; } /* Msp SD initialization */ BSP_SD_MspInit(&uSdHandle, NULL); /* HAL SD initialization */ if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) { sd_state = MSD_ERROR; } /* Configure SD Bus width */ if(sd_state == MSD_OK) { /* Enable wide operation */ if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) { sd_state = MSD_ERROR; } else { sd_state = MSD_OK; } } return sd_state; }
/** * @brief Returns the medium capacity. * @param lun: Logical unit number * @param block_num: Number of total block number * @param block_size: Block size * @retval Status (0: Ok / -1: Error) */ int8_t STORAGE_GetCapacity(uint8_t lun, uint32_t *block_num, uint16_t *block_size) { HAL_SD_CardInfoTypedef info; int8_t ret = -1; if(BSP_SD_IsDetected() != SD_NOT_PRESENT) { BSP_SD_GetCardInfo(&info); *block_num = (info.CardCapacity)/STORAGE_BLK_SIZ - 1; *block_size = STORAGE_BLK_SIZ; ret = 0; } return ret; }
/** * @brief Initializes the SD card device. * @retval SD status */ uint8_t BSP_SD_Init(void) { uint8_t sd_state = MSD_OK; /* uSD device interface configuration */ uSdHandle.Instance = SDIO; uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B; uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_ENABLE; uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; /* Msp SD Detect pin initialization */ BSP_SD_Detect_MspInit(&uSdHandle, NULL); /* Check if SD card is present */ if(BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR_SD_NOT_PRESENT; } /* Msp SD initialization */ BSP_SD_MspInit(&uSdHandle, NULL); /* HAL SD initialization */ if(HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) { sd_state = MSD_ERROR; } /* Configure SD Bus width */ if(sd_state == MSD_OK) { /* Enable wide operation */ if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) { sd_state = MSD_ERROR; } else { sd_state = MSD_OK; } } return sd_state; }
/** * @brief Initializes the SD card device. * @param None * @retval SD status. */ uint8_t BSP_SD_Init(void) { uint8_t SD_state = MSD_OK; /* uSD device interface configuration */ uSdHandle.Instance = SDIO; uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B; uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; /* Configure IO functionalities for SD detect pin */ BSP_IO_Init(); /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR; } /* HAL SD initialization */ SD_MspInit(); if(HAL_SD_Init(&uSdHandle, &SD_CardInfo) != SD_OK) { SD_state = MSD_ERROR; } /* Configure SD Bus width */ if(SD_state == MSD_OK) { /* Enable wide operation */ if(HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) { SD_state = MSD_ERROR; } else { SD_state = MSD_OK; } } return SD_state; }
/** * @brief EXTI line detection callbacks. * @param GPIO_Pin: Specifies the pins connected EXTI line * @retval None */ void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == MFX_IRQOUT_PIN) { if(BSP_SD_IsDetected()) { if(CAMERA_Configured == 0) { BSP_SD_Init(); } osMessagePut ( StorageEvent, MSDDISK_CONNECTION_EVENT, 0); } else { osMessagePut ( StorageEvent, MSDDISK_DISCONNECTION_EVENT, 0); } } }
/** * @brief Initializes the SD/SD communication. * @param None * @retval The SD Response: * - MSD_ERROR : Sequence failed * - MSD_OK : Sequence succeed */ uint8_t BSP_SD_Init(void) { /* Configure IO functionalities for SD pin */ SD_IO_Init(); /* Check SD card detect pin */ if(BSP_SD_IsDetected()==SD_NOT_PRESENT) { SdStatus = SD_NOT_PRESENT; return MSD_ERROR; } else { SdStatus = SD_PRESENT; } /* SD initialized and set to SPI mode properly */ return (SD_GoIdleState()); }
/** * @brief SD Demo exti detection * @param None * @retval None */ void SD_exti_demo (void) { uint32_t ITstatus = 0; SD_main_test(); if(BSP_SD_IsDetected() != SD_PRESENT) { BSP_SD_Init(); BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } else { BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); } BSP_SD_ITConfig(); while (1) { if (MfxExtiReceived == 1) { MfxExtiReceived = 0; ITstatus = BSP_IO_ITGetStatus(SD_DETECT_PIN); if (ITstatus) { SD_Detection(); } BSP_IO_ITClear(); } if(CheckForUserInput() > 0) { BSP_SD_DeInit(); return; } } }
/** * @brief SD_Detection checks detection and writes msg on display * @param None * @retval None */ void SD_Detection(void) { static uint8_t prev_status = 2; /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { if(prev_status != SD_NOT_PRESENT) { //BSP_SD_Init(); prev_status = SD_NOT_PRESENT; BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } } else if (prev_status != SD_PRESENT) { prev_status = SD_PRESENT; BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); } }
/** * @brief Shows audio file (*.wav) on the root * @param None * @retval None */ static uint8_t Audio_ShowWavFiles(void) { uint8_t i; uint8_t line_idx = 0; if((FileList.ptr > 0) && (BSP_SD_IsDetected())) { BSP_LCD_SetTextColor(LCD_COLOR_WHITE); LCD_UsrLog("audio file(s) [ROOT]:\n\n"); for( i = 0; i < FileList.ptr; i++) { line_idx++; if(line_idx > 9) { line_idx = 0; LCD_UsrLog("> Press [Key] To Continue.\n"); /* KEY Button in polling */ while(BSP_PB_GetState(BUTTON_KEY) != RESET) { /* Wait for User Input */ } } LCD_DbgLog(" |__"); LCD_DbgLog((char *)FileList.file[i].name); LCD_DbgLog("\n"); } BSP_LCD_SetTextColor(LCD_COLOR_WHITE); LCD_UsrLog("\nEnd of files list.\n"); return 0; } else { return 1; } }
/** * @brief Checks whether the medium is ready. * @param lun: Logical unit number * @retval Status (0: Ok / -1: Error) */ int8_t STORAGE_IsReady(uint8_t lun) { static int8_t prev_status = 0; int8_t ret = -1; if(BSP_SD_IsDetected() != SD_NOT_PRESENT) { if(prev_status < 0) { BSP_SD_Init(); prev_status = 0; } if(BSP_SD_GetStatus() == SD_TRANSFER_OK) { ret = 0; } } else if(prev_status == 0) { prev_status = -1; } return ret; }
/** * @brief Initializes the SD card device. * @param None * @retval SD status */ uint8_t BSP_SD_Init(void) { uint8_t SD_state = MSD_OK; /* Check if the SD card is plugged in the slot */ if (BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR; } SD_state = HAL_SD_Init(&hsd, &SDCardInfo); #ifdef BUS_4BITS if (SD_state == MSD_OK) { if (HAL_SD_WideBusOperation_Config(&hsd, SDIO_BUS_WIDE_4B) != SD_OK) { SD_state = MSD_ERROR; } else { SD_state = MSD_OK; } } #endif return SD_state; }
/** * @brief Main program * @param None * @retval None */ int main(void) { uint32_t counter = 0, transparency = 0; uint8_t str[30]; uwInternelBuffer = (uint8_t *)0xC0260000; /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 200 MHz */ SystemClock_Config(); /* Configure LED3 */ BSP_LED_Init(LED3); /*##-1- Configure LCD ######################################################*/ LCD_Config(); /* Configure TAMPER Button */ BSP_PB_Init(BUTTON_TAMPER, BUTTON_MODE_GPIO); BSP_SD_Init(); while(BSP_SD_IsDetected() != SD_PRESENT) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" Please insert SD Card "); } BSP_LCD_Clear(LCD_COLOR_BLACK); /*##-2- Link the SD Card disk I/O driver ###################################*/ if(FATFS_LinkDriver(&SD_Driver, SD_Path) == 0) { /*##-3- Initialize the Directory Files pointers (heap) ###################*/ for (counter = 0; counter < MAX_BMP_FILES; counter++) { pDirectoryFiles[counter] = malloc(MAX_BMP_FILE_NAME); if(pDirectoryFiles[counter] == NULL) { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" Cannot allocate memory "); while(1) { } } } /* Get the BMP file names on root directory */ ubNumberOfFiles = Storage_GetDirectoryBitmapFiles("/Media", pDirectoryFiles); if (ubNumberOfFiles == 0) { for (counter = 0; counter < MAX_BMP_FILES; counter++) { free(pDirectoryFiles[counter]); } BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" No Bitmap files... "); while(1) { } } } else { /* FatFs Initialization Error */ Error_Handler(); } while(1) { counter = 0; while ((counter) < ubNumberOfFiles) { /* Step1 : Display on Foreground layer -------------------------------*/ /* Format the string */ sprintf ((char*)str, "Media/%-11.11s", pDirectoryFiles[counter]); if (Storage_CheckBitmapFile((const char*)str, &uwBmplen) == 0) { /* Format the string */ sprintf ((char*)str, "Media/%-11.11s", pDirectoryFiles[counter]); /* Set LCD foreground Layer */ BSP_LCD_SelectLayer(1); /* Open a file and copy its content to an internal buffer */ Storage_OpenReadFile(uwInternelBuffer, (const char*)str); /* Write bmp file on LCD frame buffer */ BSP_LCD_DrawBitmap(0, 0, uwInternelBuffer); /* Configure the transparency for background layer : Increase the transparency */ for (transparency = 0; transparency < 255; (transparency++)) { BSP_LCD_SetTransparency(1, transparency); /* Insert a delay of display */ HAL_Delay(2); } /* Wait for tamper button pressed */ while (BSP_PB_GetState(BUTTON_TAMPER) == RESET) { } /* Configure the transparency for foreground layer : decrease the transparency */ for (transparency = 255; transparency > 0; transparency--) { BSP_LCD_SetTransparency(1, transparency); /* Insert a delay of display */ HAL_Delay(2); } /* Clear the Foreground Layer */ BSP_LCD_Clear(LCD_COLOR_BLACK); /* Jump to the next image */ counter++; /* Step2 : Display on Background layer -----------------------------*/ /* Format the string */ sprintf ((char*)str, "Media/%-11.11s", pDirectoryFiles[counter]); if ((Storage_CheckBitmapFile((const char*)str, &uwBmplen) == 0) || (counter < (ubNumberOfFiles))) { /* Connect the Output Buffer to LCD Background Layer */ BSP_LCD_SelectLayer(0); /* Format the string */ sprintf ((char*)str, "Media/%-11.11s", pDirectoryFiles[counter]); /* Open a file and copy its content to an internal buffer */ Storage_OpenReadFile(uwInternelBuffer, (const char*)str); /* Write bmp file on LCD frame buffer */ BSP_LCD_DrawBitmap(0, 0, uwInternelBuffer); /* Configure the transparency for background layer : decrease the transparency */ for (transparency = 0; transparency < 255; (transparency++)) { BSP_LCD_SetTransparency(0, transparency); /* Insert a delay of display */ HAL_Delay(2); } /* wait for tamper button pressed */ while (BSP_PB_GetState(BUTTON_TAMPER) == RESET) { } /* Step3 : -------------------------------------------------------*/ /* Configure the transparency for background layer : Increase the transparency */ for (transparency = 255; transparency > 0; transparency--) { BSP_LCD_SetTransparency(0, transparency); /* Insert a delay of display */ HAL_Delay(2); } /* Clear the Background Layer */ BSP_LCD_Clear(LCD_COLOR_BLACK); counter++; } else if (Storage_CheckBitmapFile((const char*)str, &uwBmplen) == 0) { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(7, (uint8_t *) str); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" File type not supported. "); while(1) { } } } } } }
/** * @brief SD Demo * @param None * @retval None */ void SD_demo (void) { uint8_t SD_state = SD_RESPONSE_NO_ERROR; __IO uint8_t prev_status = 0; SD_SetHint(); SD_state = BSP_SD_Init(); /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() == SD_PRESENT) { BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); } else { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } BSP_LCD_SetTextColor(LCD_COLOR_BLACK); if(SD_state != SD_RESPONSE_NO_ERROR) { BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD INITIALIZATION : FAIL.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD INITIALIZATION : OK.", LEFT_MODE); SD_state = BSP_SD_GetCardInfo(&CardInfo); if(SD_state != SD_RESPONSE_NO_ERROR) { BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD GET CARD INFO : FAIL.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD GET CARD INFO : OK.", LEFT_MODE); SD_state = BSP_SD_Erase(BLOCK_START_ADDR, (BLOCKSIZE * NUM_OF_BLOCKS)); /* Verify that SD card is ready to use after the Erase */ SD_state |= BSP_SD_GetStatus(); if(SD_state != SD_RESPONSE_NO_ERROR) { BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD ERASE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD ERASE : OK.", LEFT_MODE); /* Fill the buffer to write */ Fill_Buffer(aTxBuffer, BUFFER_WORDS_SIZE, 0x22FF); SD_state = BSP_SD_WriteBlocks((uint32_t *)aTxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS); if(SD_state != SD_RESPONSE_NO_ERROR) { BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD WRITE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD WRITE : OK.", LEFT_MODE); SD_state = BSP_SD_ReadBlocks((uint32_t *)aRxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS); if(SD_state != SD_RESPONSE_NO_ERROR) { BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD READ : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 175, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD READ : OK.", LEFT_MODE); if(Buffercmp(aTxBuffer, aRxBuffer, BUFFER_WORDS_SIZE) > 0) { BSP_LCD_DisplayStringAt(20, 175, (uint8_t *)"SD COMPARE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 190, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 175, (uint8_t *)"SD TEST : OK.", LEFT_MODE); } } } } } } while (1) { /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { if(prev_status == 0) { prev_status = 1; BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } } else if (prev_status == 1) { BSP_SD_Init(); BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); prev_status = 0; } if(CheckForUserInput() > 0) { return; } } }
/** * @brief SD Demo * @param None * @retval None */ void SD_demo(void) { uint8_t SD_state = SD_OK; static uint8_t prev_status = 0; SD_SetHint(); SD_state = BSP_SD_Init(); if(SD_state != SD_OK) { BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD Initialization : FAIL.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 100, (uint8_t *)"SD Initialization : OK.", LEFT_MODE); SD_state = BSP_SD_Erase(BLOCK_START_ADDR, (BLOCKSIZE * NUM_OF_BLOCKS)); if(SD_state != SD_OK) { BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD ERASE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 115, (uint8_t *)"SD ERASE : OK.", LEFT_MODE); /* Fill the buffer to write */ Fill_Buffer(aTxBuffer, BUFFER_WORDS_SIZE, 0x22FF); SD_state = BSP_SD_WriteBlocks(aTxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS); if(SD_state != SD_OK) { BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD WRITE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 130, (uint8_t *)"SD WRITE : OK.", LEFT_MODE); SD_state = BSP_SD_ReadBlocks(aRxBuffer, BLOCK_START_ADDR, BLOCKSIZE, NUM_OF_BLOCKS); if(SD_state != SD_OK) { BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD READ : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 145, (uint8_t *)"SD READ : OK.", LEFT_MODE); if(Buffercmp(aTxBuffer, aRxBuffer, BUFFER_WORDS_SIZE) > 0) { BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD COMPARE : FAILED.", LEFT_MODE); BSP_LCD_DisplayStringAt(20, 175, (uint8_t *)"SD Test Aborted.", LEFT_MODE); } else { BSP_LCD_DisplayStringAt(20, 160, (uint8_t *)"SD Test : OK.", LEFT_MODE); } } } } } /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() == SD_PRESENT) { BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); } else { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } while (1) { /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { if(prev_status == 0) { BSP_SD_Init(); prev_status = 1; BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Not Connected", LEFT_MODE); } } else if (prev_status == 1) { BSP_LCD_SetTextColor(LCD_COLOR_GREEN); BSP_LCD_DisplayStringAt(20, BSP_LCD_GetYSize()-30, (uint8_t *)"SD Connected ", LEFT_MODE); prev_status = 0; } if(CheckForUserInput() > 0) { return; } } }
/** * @brief Initializes the SD card device. * @param None * @retval SD status */ uint8_t BSP_SD_Init(void) { uint8_t SD_state = MSD_OK; /* uSD device interface configuration */ #if defined(SDIO) uSdHandle.Instance = SDIO; uSdHandle.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING; uSdHandle.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE; uSdHandle.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.BusWide = SDIO_BUS_WIDE_1B; uSdHandle.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE; uSdHandle.Init.ClockDiv = SDIO_TRANSFER_CLK_DIV; #elif defined(SDMMC1) uSdHandle.Instance = SDMMC1; uSdHandle.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; uSdHandle.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; uSdHandle.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; uSdHandle.Init.BusWide = SDMMC_BUS_WIDE_1B; uSdHandle.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; uSdHandle.Init.ClockDiv = SDMMC_TRANSFER_CLK_DIV; #else #error "NOT SUPPORTED!" #endif /* Init GPIO, DMA and NVIC */ SD_MspInit(); /* Check if the SD card is plugged in the slot */ if (BSP_SD_IsDetected() != SD_PRESENT) { return MSD_ERROR; } /* HAL SD initialization */ if (HAL_SD_Init(&uSdHandle, &uSdCardInfo) != SD_OK) { SD_state = MSD_ERROR; } /* Configure SD Bus width */ if (SD_state == MSD_OK) { /* Enable wide operation */ #if defined(SDIO_BUS_WIDE_4B) #if FATFS_SDIO_4BIT == 1 if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_4B) != SD_OK) { #else if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDIO_BUS_WIDE_1B) != SD_OK) { #endif #else #if FATFS_SDIO_4BIT == 1 if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_4B) != SD_OK) { #else if (HAL_SD_WideBusOperation_Config(&uSdHandle, SDMMC_BUS_WIDE_1B) != SD_OK) { #endif #endif SD_state = MSD_ERROR; } else { SD_state = MSD_OK; } } return SD_state; } /** * @brief Detects if SD card is correctly plugged in the memory slot or not. * @param None * @retval Returns if SD is detected or not */ uint8_t BSP_SD_IsDetected(void) { return SDCARD_IsDetected(); } /** * @brief Detects if SD card is write protected * @param None * @retval Returns if SD is write protected or not. */ uint8_t BSP_SD_IsWriteProtected(void) { return !SDCARD_IsWriteEnabled(); } /** * @brief Reads block(s) from a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read * @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) { if (HAL_SD_ReadBlocks(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) { return MSD_ERROR; } return MSD_OK; } /** * @brief Writes block(s) to a specified address in an SD card, in polling mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to write * @retval SD status */ uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) { if (HAL_SD_WriteBlocks(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) { return MSD_ERROR; } return MSD_OK; } /** * @brief Reads block(s) from a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param ReadAddr: Address from where data is to be read * @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to read * @retval SD status */ uint8_t BSP_SD_ReadBlocks_DMA(uint32_t *pData, uint64_t ReadAddr, uint32_t BlockSize, uint32_t NumOfBlocks) { uint8_t SD_state = MSD_OK; /* Read block(s) in DMA transfer mode */ if (HAL_SD_ReadBlocks_DMA(&uSdHandle, pData, ReadAddr, BlockSize, NumOfBlocks) != SD_OK) { SD_state = MSD_ERROR; } /* Wait until transfer is complete */ if (SD_state == MSD_OK) { if (HAL_SD_CheckReadOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) { SD_state = MSD_ERROR; } else { SD_state = MSD_OK; } } return SD_state; } /** * @brief Writes block(s) to a specified address in an SD card, in DMA mode. * @param pData: Pointer to the buffer that will contain the data to transmit * @param WriteAddr: Address from where data is to be written * @param BlockSize: SD card data block size, that should be 512 * @param NumOfBlocks: Number of SD blocks to write * @retval SD status */ uint8_t BSP_SD_WriteBlocks_DMA(uint32_t *pData, uint64_t WriteAddr, uint32_t BlockSize, uint32_t NumOfBlocks) { uint8_t SD_state = MSD_OK; /* Write block(s) in DMA transfer mode */ if (HAL_SD_WriteBlocks_DMA(&uSdHandle, pData, WriteAddr, BlockSize, NumOfBlocks) != SD_OK) { SD_state = MSD_ERROR; } /* Wait until transfer is complete */ if (SD_state == MSD_OK) { if(HAL_SD_CheckWriteOperation(&uSdHandle, (uint32_t)SD_DATATIMEOUT) != SD_OK) { SD_state = MSD_ERROR; } else { SD_state = MSD_OK; } } return SD_state; } /** * @brief Erases the specified memory area of the given SD card. * @param StartAddr: Start byte address * @param EndAddr: End byte address * @retval SD status */ uint8_t BSP_SD_Erase(uint64_t StartAddr, uint64_t EndAddr) { if (HAL_SD_Erase(&uSdHandle, StartAddr, EndAddr) != SD_OK) { return MSD_ERROR; } return MSD_OK; } /** * @brief Initializes the SD MSP. * @param None * @retval None */ static void SD_MspInit(void) { static DMA_HandleTypeDef dmaRxHandle; static DMA_HandleTypeDef dmaTxHandle; SD_HandleTypeDef *hsd = &uSdHandle; uint16_t gpio_af; /* Get GPIO alternate function */ #if defined(GPIO_AF12_SDIO) gpio_af = GPIO_AF12_SDIO; #endif #if defined(GPIO_AF12_SDMMC1) gpio_af = GPIO_AF12_SDMMC1; #endif /* Enable SDIO clock */ __HAL_RCC_SDIO_CLK_ENABLE(); /* Enable DMA2 clocks */ __DMAx_TxRx_CLK_ENABLE(); /* Detect pin, write protect pin */ #if FATFS_USE_DETECT_PIN > 0 TM_GPIO_Init(FATFS_DETECT_PORT, FATFS_DETECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low); #endif #if FATFS_USE_WRITEPROTECT_PIN > 0 TM_GPIO_Init(FATFS_WRITEPROTECT_PORT, FATFS_WRITEPROTECT_PIN, TM_GPIO_Mode_IN, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Low); #endif /* SDIO/SDMMC pins */ #if FATFS_SDIO_4BIT == 1 TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af); #else TM_GPIO_InitAlternate(GPIOC, GPIO_PIN_8 | GPIO_PIN_12, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af); #endif TM_GPIO_InitAlternate(GPIOD, GPIO_PIN_2, TM_GPIO_OType_PP, TM_GPIO_PuPd_UP, TM_GPIO_Speed_Fast, gpio_af); /* NVIC configuration for SDIO interrupts */ HAL_NVIC_SetPriority(SDIO_IRQn, 5, 0); HAL_NVIC_EnableIRQ(SDIO_IRQn); /* Configure DMA Rx parameters */ dmaRxHandle.Init.Channel = SD_DMAx_Rx_CHANNEL; dmaRxHandle.Init.Direction = DMA_PERIPH_TO_MEMORY; dmaRxHandle.Init.PeriphInc = DMA_PINC_DISABLE; dmaRxHandle.Init.MemInc = DMA_MINC_ENABLE; dmaRxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; dmaRxHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; dmaRxHandle.Init.Mode = DMA_PFCTRL; dmaRxHandle.Init.Priority = DMA_PRIORITY_VERY_HIGH; dmaRxHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; dmaRxHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; dmaRxHandle.Init.MemBurst = DMA_MBURST_INC4; dmaRxHandle.Init.PeriphBurst = DMA_PBURST_INC4; dmaRxHandle.Instance = SD_DMAx_Rx_STREAM; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmarx, dmaRxHandle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dmaRxHandle); /* Configure the DMA stream */ HAL_DMA_Init(&dmaRxHandle); /* Configure DMA Tx parameters */ dmaTxHandle.Init.Channel = SD_DMAx_Tx_CHANNEL; dmaTxHandle.Init.Direction = DMA_MEMORY_TO_PERIPH; dmaTxHandle.Init.PeriphInc = DMA_PINC_DISABLE; dmaTxHandle.Init.MemInc = DMA_MINC_ENABLE; dmaTxHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; dmaTxHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; dmaTxHandle.Init.Mode = DMA_PFCTRL; dmaTxHandle.Init.Priority = DMA_PRIORITY_VERY_HIGH; dmaTxHandle.Init.FIFOMode = DMA_FIFOMODE_ENABLE; dmaTxHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; dmaTxHandle.Init.MemBurst = DMA_MBURST_INC4; dmaTxHandle.Init.PeriphBurst = DMA_PBURST_INC4; dmaTxHandle.Instance = SD_DMAx_Tx_STREAM; /* Associate the DMA handle */ __HAL_LINKDMA(hsd, hdmatx, dmaTxHandle); /* Deinitialize the stream for new transfer */ HAL_DMA_DeInit(&dmaTxHandle); /* Configure the DMA stream */ HAL_DMA_Init(&dmaTxHandle); /* NVIC configuration for DMA transfer complete interrupt */ HAL_NVIC_SetPriority(SD_DMAx_Rx_IRQn, 6, 0); HAL_NVIC_EnableIRQ(SD_DMAx_Rx_IRQn); /* NVIC configuration for DMA transfer complete interrupt */ HAL_NVIC_SetPriority(SD_DMAx_Tx_IRQn, 6, 0); HAL_NVIC_EnableIRQ(SD_DMAx_Tx_IRQn); } /** * @brief Get SD information about specific SD card. * @param CardInfo: Pointer to HAL_SD_CardInfoTypedef structure * @retval None */ void BSP_SD_GetCardInfo(HAL_SD_CardInfoTypedef *CardInfo) { /* Get SD card Information */ HAL_SD_Get_CardInfo(&uSdHandle, CardInfo); }
/** * @brief Saves the picture in microSD. * @param None * @retval None */ void Save_Picture(void) { FRESULT res1, res2; /* FatFs function common result code */ uint32_t byteswritten = 0; /* File write count */ static uint32_t counter = 0; uint8_t str[30]; BSP_LCD_SetLayerVisible(1, ENABLE); BSP_LCD_SetColorKeying(1, LCD_COLOR_WHITE); /* Set foreground Layer */ BSP_LCD_SelectLayer(1); BSP_LCD_SetTextColor(LCD_COLOR_DARKRED); BSP_LCD_SetFont(&Font24); /* Initialize IOE */ BSP_IO_Init(); /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize()-125), (uint8_t *)"SD Not Connected", RIGHT_MODE); BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize()-100), (uint8_t *)"Please inser SDCard", RIGHT_MODE); } else { BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize()-100), (uint8_t *)"Saving ..", RIGHT_MODE); /* Format the string */ sprintf((char *)str,"image_%d.bmp", (int)counter); /*##-1- Prepare the image to be saved ######################################*/ Prepare_Picture(); /*##-2- Create and Open a new bmp file object with write access ##########*/ if(f_open(&MyFile, (const char*)str, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) { /* 'image.bmp' file Open for write Error */ Error_Handler(); } else { /*##-3- Write data to the BMP file #####################################*/ /* Write the BMP header */ if (BSP_LCD_GetXSize() == 640) { /* if ampire 640x480 LCD is used */ res1 = f_write(&MyFile, (uint32_t *)aBMPHeader1, 54, (void *)&byteswritten); } else { /* if ampire 480x272 LCD is used */ res1 = f_write(&MyFile, (uint32_t *)aBMPHeader2, 54, (void *)&byteswritten); } /* Write the bmp file */ res2 = f_write(&MyFile, (uint32_t *)CONVERTED_FRAME_BUFFER, ((BSP_LCD_GetYSize()-60)*(BSP_LCD_GetXSize()-60)*3), (void *)&byteswritten); if((res1 != FR_OK) || (res2 != FR_OK) || (byteswritten == 0)) { /* 'image' file Write or EOF Error */ Error_Handler(); } else { /*##-4- Close the open bmp file ######################################*/ f_close(&MyFile); /* Success of the demo: no error occurrence */ BSP_LED_On(LED1); BSP_LCD_SetTextColor(LCD_COLOR_DARKGREEN); BSP_LCD_DisplayStringAt(20, (BSP_LCD_GetYSize()-100), (uint8_t *)" Saved ", RIGHT_MODE); /* Select Layer 1 */ BSP_LED_Off(LED1); counter++; } } } /* Wait for 2s */ HAL_Delay(2000); /* Disable the Layer 2 */ BSP_LCD_SetLayerVisible(1, DISABLE); /* Clear the LCD Foreground layer */ BSP_LCD_Clear(LCD_COLOR_WHITE); BSP_LCD_SelectLayer(0); }
/** * @brief Saves the picture in microSD. * @param None * @retval None */ static void Save_Picture(void) { FRESULT res1 = FR_OK; FRESULT res2 = FR_OK; FRESULT res3 = FR_OK; /* FatFs function common result code */ uint32_t byteswritten = 0; /* File write count */ uint32_t bmpHeaderByteCnt = 0; uint32_t bmpFileInfoHeaderByteCnt = 0; uint32_t bmpFilePixelBytesCnt = 0; static uint32_t counter = 0; uint8_t str[30]; uint16_t tmp_size; /* Check if the SD card is plugged in the slot */ if(BSP_SD_IsDetected() != SD_PRESENT) { BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)"No SD card detected !!", RIGHT_MODE); Error_Handler(); } else { BSP_LCD_SetFont(&Font16); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)"Saving BMP to SD card", RIGHT_MODE); /* Format the string */ sprintf((char *)str, "image_%lu.bmp", counter); /* -- Prepare Bitmap file (BMP) header */ bmpFileHeader.bfType = 0x4D42; /* BMP file type */ /* Offset in bytes from start of file to first pixel data = size in bytes of complete BMP header */ /* careful the structure is padded on multiple of 32 bits by the compiler : the Padding should be removed */ bmpFileHeader.bOffBits = sizeof(BitMapFileHeader_Typedef) + sizeof(BitMapFileInfoHeader_Typedef) - sizeof(uint32_t) - sizeof(uint16_t); /* BMP complete file size is size of pad in RGB888 : 24bpp = 3 bytes per pixel + complete header size */ bmpFileHeader.bfSize = ((BSP_LCD_GetXSize() - 80) * (BSP_LCD_GetYSize() - 80) * RGB888_BYTE_PER_PIXEL); bmpFileHeader.bfSize += bmpFileHeader.bOffBits; bmpFileHeader.bfReserved1 = 0x0000; bmpFileHeader.bfReserved2 = 0x0000; bmpFileInfoHeader.biSize = 40; /* 40 bytes in bitmap info header */ bmpFileInfoHeader.biWidth = (BSP_LCD_GetXSize() - 80); bmpFileInfoHeader.biHeight = (BSP_LCD_GetYSize() - 80); bmpFileInfoHeader.biPlanes = 1; /* one single plane */ bmpFileInfoHeader.biBitCount = 24; /* RGB888 : 24 bits per pixel */ bmpFileInfoHeader.biCompression = 0; /* no compression */ /* This is number of pixel bytes in file : sizeX * sizeY * RGB888_BYTE_PER_PIXEL */ bmpFileInfoHeader.biSizeImage = ((BSP_LCD_GetXSize() - 80) * (BSP_LCD_GetYSize() - 80) * RGB888_BYTE_PER_PIXEL); bmpFileInfoHeader.biXPelsPerMeter = 0; /* not used */ bmpFileInfoHeader.biYPelsPerMeter = 0; /* not used */ bmpFileInfoHeader.biClrUsed = 0; /* not used */ bmpFileInfoHeader.biClrImportant = 0; /* not used */ /* -- End Prepare Bitmap file (BMP) header */ /*##-1- Prepare the image to be saved ####################################*/ Prepare_Picture(); /* Disable the LTDC to avoid charging the bandwidth for nothing while the BMP file is */ /* written to SD card */ LTDC_Operation(0); /*##-2- Create and Open a new bmp file object with write access ##########*/ if(f_open(&MyFile, (const char*)str, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) { /* 'image.bmp' file Open for write Error */ BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" BMP File Creation Error !!", RIGHT_MODE); Error_Handler(); } else { /*##-3- Write data to the BMP file #####################################*/ /* Write the BMP header step 1 : first write BMP header : all but padding is written to file */ res1 = f_write(&MyFile, (uint16_t *)&(bmpFileHeader.bfType), sizeof(uint16_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; /* LSB of size in bytes of BMP file */ tmp_size = (uint16_t)(bmpFileHeader.bfSize & 0x0000FFFF); res1 = f_write(&MyFile, (uint16_t *)&(tmp_size), sizeof(uint16_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; /* MSB of size in bytes of BMP file */ tmp_size = (uint16_t)((bmpFileHeader.bfSize & 0xFFFF0000) >> 16); res1 = f_write(&MyFile, (uint16_t *)&(tmp_size), sizeof(uint16_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; res1 = f_write(&MyFile, (uint16_t *)&(bmpFileHeader.bfReserved1), sizeof(uint16_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; res1 = f_write(&MyFile, (uint16_t *)&(bmpFileHeader.bfReserved2), sizeof(uint16_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; res1 = f_write(&MyFile, (uint32_t *)&(bmpFileHeader.bOffBits), sizeof(uint32_t), (void *)&bmpHeaderByteCnt); byteswritten += bmpHeaderByteCnt; if(res1 != FR_OK) { /* Reactivate LTDC */ LTDC_Operation(1); f_close(&MyFile); BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" BMP File Header Saving Error !!", RIGHT_MODE); Error_Handler(); } byteswritten += bmpHeaderByteCnt; if(res1 == FR_OK) { /* Write the BMP header step 2 : second write BMP file info header */ res2 = f_write(&MyFile, (BitMapFileInfoHeader_Typedef *)&bmpFileInfoHeader, sizeof(BitMapFileInfoHeader_Typedef), (void *)&bmpFileInfoHeaderByteCnt); if(res2 != FR_OK) { /* Reactivate LTDC */ LTDC_Operation(1); f_close(&MyFile); BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" BMP File Header Info Saving Error !!", RIGHT_MODE); Error_Handler(); } } byteswritten += bmpFileInfoHeaderByteCnt; if((res1 == FR_OK) && (res2 == FR_OK)) { /* Write pixel data in the the BMP file */ res3 = f_write(&MyFile, (uint8_t *)p_bmp_converted_pixel_data, bmpFileInfoHeader.biSizeImage, (void *)&bmpFilePixelBytesCnt); /* Reactivate LTDC */ LTDC_Operation(1); if(res3 != FR_OK) { if(res3 == FR_DISK_ERR) { f_close(&MyFile); BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" File Saving Error DISKERR !!", RIGHT_MODE); } Error_Handler(); } } byteswritten += bmpFilePixelBytesCnt; if((res1 != FR_OK) || (res2 != FR_OK) || (res3 != FR_OK) || (byteswritten == 0)) { /* 'image.bmp' file Write or EOF Error */ BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" BMP File Saving Error !!", RIGHT_MODE); Error_Handler(); } else { /*##-4- Close the open BMP file ######################################*/ f_close(&MyFile); /* Success of the demo: no error occurrence */ BSP_LED_On(LED1); BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); BSP_LCD_DisplayStringAt(0, BSP_LCD_GetYSize() - 20, (uint8_t*)" BMP File Saved.", RIGHT_MODE); /* Wait for 2s */ HAL_Delay(2000); BSP_LCD_ClearStringLine(BSP_LCD_GetYSize() - 20); /* Select Layer 1 */ BSP_LED_Off(LED1); counter++; } } } }
/** * @brief Main program * @param None * @retval None */ int main(void) { uint32_t counter = 0; uint8_t str[30]; uwInternelBuffer = (uint8_t *)0xC0260000; /* Enable the CPU Cache */ CPU_CACHE_Enable(); /* STM32F7xx HAL library initialization: - Configure the Flash ART accelerator on ITCM interface - Configure the Systick to generate an interrupt each 1 msec - Set NVIC Group Priority to 4 - Global MSP (MCU Support Package) initialization */ HAL_Init(); /* Configure the system clock to 200 MHz */ SystemClock_Config(); /* Configure LED3 */ BSP_LED_Init(LED3); /*##-1- Configure LCD ######################################################*/ LCD_Config(); BSP_SD_Init(); while(BSP_SD_IsDetected() != SD_PRESENT) { BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" Please insert SD Card "); } BSP_LCD_Clear(LCD_COLOR_BLACK); /*##-2- Link the SD Card disk I/O driver ###################################*/ if(FATFS_LinkDriver(&SD_Driver, SD_Path) != 0) { Error_Handler(); } else { /*##-3- Initialize the Directory Files pointers (heap) ###################*/ for (counter = 0; counter < MAX_BMP_FILES; counter++) { pDirectoryFiles[counter] = malloc(MAX_BMP_FILE_NAME); if(pDirectoryFiles[counter] == NULL) { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" Cannot allocate memory "); while(1) { } } } /*##-4- Display Background picture #######################################*/ /* Select Background Layer */ BSP_LCD_SelectLayer(0); /* Register the file system object to the FatFs module */ if(f_mount(&SD_FatFs, (TCHAR const*)SD_Path, 0) != FR_OK) { /* FatFs Initialization Error */ /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" FatFs Initialization Error "); } else { /* Open directory */ if (f_opendir(&directory, (TCHAR const*)"/BACK") != FR_OK) { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" Open directory.. fails "); while(1) { } } } if (Storage_CheckBitmapFile("BACK/image.bmp", &uwBmplen) == 0) { /* Format the string */ Storage_OpenReadFile(uwInternelBuffer, "BACK/image.bmp"); /* Write bmp file on LCD frame buffer */ BSP_LCD_DrawBitmap(0, 0, uwInternelBuffer); } else { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" File type not supported. "); while(1) { } } /*##-5- Display Foreground picture #######################################*/ /* Select Foreground Layer */ BSP_LCD_SelectLayer(1); /* Decrease the foreground transparency */ BSP_LCD_SetTransparency(1, 200); /* Get the BMP file names on root directory */ ubNumberOfFiles = Storage_GetDirectoryBitmapFiles("/TOP", pDirectoryFiles); if (ubNumberOfFiles == 0) { for (counter = 0; counter < MAX_BMP_FILES; counter++) { free(pDirectoryFiles[counter]); } /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" No Bitmap files... "); while(1) { } } } /* Infinite loop */ while(1) { counter = 0; while (counter < ubNumberOfFiles) { /* Format the string */ sprintf ((char*)str, "TOP/%-11.11s", pDirectoryFiles[counter]); if (Storage_CheckBitmapFile((const char*)str, &uwBmplen) == 0) { /* Format the string */ sprintf ((char*)str, "TOP/%-11.11s", pDirectoryFiles[counter]); /* Open a file and copy its content to a buffer */ Storage_OpenReadFile(uwInternelBuffer, (const char*)str); HAL_Delay(100); /* Write bmp file on LCD frame buffer */ BSP_LCD_DrawBitmap(0, 0, uwInternelBuffer); /* Jump to next image */ counter++; } else { /* Set the Text Color */ BSP_LCD_SetTextColor(LCD_COLOR_RED); BSP_LCD_DisplayStringAtLine(7, (uint8_t *) str); BSP_LCD_DisplayStringAtLine(8, (uint8_t*)" File type not supported. "); while(1) { } } } } }