F746NG fatfs and micro sd example

Dependencies:   BSP_DISCO_F746NG FatFS mbed

This is a quick and dirty example about how to use micro sd card module with FatFs on STM32746G Discovery board. I simply use the FatFs library downloaded with DFP for STM32F7. The project shows how to read PPM image file from sd card, display on LCD and writing image to sd card.

Committer:
buyukesmeli
Date:
Sun Feb 04 10:12:09 2018 +0000
Revision:
2:19c2835ce409
Parent:
1:28e2f24b11b3
Color and output image bugs are fixed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
buyukesmeli 0:020195991898 1 #include "mbed.h"
buyukesmeli 0:020195991898 2 #define USE_STM32746G_DISCOVERY
buyukesmeli 0:020195991898 3 #include "stm32f7xx_hal.h"
buyukesmeli 0:020195991898 4 #include "stm32746g_discovery.h"
buyukesmeli 0:020195991898 5 #include "stm32746g_discovery_sd.h"
buyukesmeli 0:020195991898 6 #include "string.h"
buyukesmeli 0:020195991898 7 #include "stm32746g_discovery_lcd.h"
buyukesmeli 0:020195991898 8 #include "ff_gen_drv.h"
buyukesmeli 0:020195991898 9 #include "sd_diskio.h"
buyukesmeli 0:020195991898 10
buyukesmeli 0:020195991898 11 #define FRAME_BUFFER 0xC0000000
buyukesmeli 0:020195991898 12 #define SD_IN_BUFFER 0xC0140000
buyukesmeli 0:020195991898 13 #define SD_OUT_BUFFER 0xC0280000
buyukesmeli 0:020195991898 14
buyukesmeli 2:19c2835ce409 15 FATFS SDFatFs;
buyukesmeli 2:19c2835ce409 16 FIL MyFile;
buyukesmeli 0:020195991898 17
buyukesmeli 0:020195991898 18
buyukesmeli 2:19c2835ce409 19
buyukesmeli 0:020195991898 20
buyukesmeli 0:020195991898 21 static void LCD_LL_ConvertFrameToARGB8888(void *pSrc, void *pDst);
buyukesmeli 0:020195991898 22 static void LCD_LL_ConvertFrameToRGB888(void *pSrc, void *pDst);
buyukesmeli 0:020195991898 23 extern SD_HandleTypeDef uSdHandle;
buyukesmeli 0:020195991898 24 DMA2D_HandleTypeDef hdma2d_disco;
buyukesmeli 0:020195991898 25
buyukesmeli 0:020195991898 26 Serial pc(USBTX, USBRX);
buyukesmeli 0:020195991898 27 uint32_t i = 0, image_width = 0, image_height = 0;
buyukesmeli 2:19c2835ce409 28 const char image_header[] = "P6\n# Generated by STM32\n480 272\n255\n";
buyukesmeli 0:020195991898 29
buyukesmeli 0:020195991898 30 char SDPath[4];
buyukesmeli 0:020195991898 31 char text [40];
buyukesmeli 0:020195991898 32 char c;
buyukesmeli 0:020195991898 33 int main(void)
buyukesmeli 0:020195991898 34 {
buyukesmeli 0:020195991898 35 FRESULT res;
buyukesmeli 0:020195991898 36 uint32_t bytesread;
buyukesmeli 0:020195991898 37 uint32_t line_cnt=0;
buyukesmeli 0:020195991898 38 pc.baud(115200);
buyukesmeli 0:020195991898 39
buyukesmeli 0:020195991898 40 BSP_LCD_Init();
buyukesmeli 0:020195991898 41 BSP_LCD_DisplayOff();
buyukesmeli 0:020195991898 42 BSP_LCD_LayerDefaultInit(0, FRAME_BUFFER);
buyukesmeli 0:020195991898 43 BSP_LCD_SelectLayer(0);
buyukesmeli 0:020195991898 44 BSP_LCD_DisplayOn();
buyukesmeli 0:020195991898 45
buyukesmeli 0:020195991898 46 FATFS_LinkDriver(&SD_Driver, SDPath);
buyukesmeli 2:19c2835ce409 47
buyukesmeli 0:020195991898 48 res = f_mount(&SDFatFs, (TCHAR const*)SDPath, 0);
buyukesmeli 0:020195991898 49 if(res!= FR_OK)
buyukesmeli 0:020195991898 50 pc.printf("Failed to mount SD\n");
buyukesmeli 2:19c2835ce409 51
buyukesmeli 0:020195991898 52 res = f_open(&MyFile, "image.ppm", FA_READ);
buyukesmeli 0:020195991898 53 if(res!= FR_OK)
buyukesmeli 0:020195991898 54 pc.printf("Failed to open file\n");
buyukesmeli 2:19c2835ce409 55
buyukesmeli 2:19c2835ce409 56 // Read image header and get image size
buyukesmeli 2:19c2835ce409 57 while(res==FR_OK) {
buyukesmeli 0:020195991898 58 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 59 if (c!='#')
buyukesmeli 0:020195991898 60 line_cnt++;
buyukesmeli 0:020195991898 61 if(line_cnt==2) {
buyukesmeli 0:020195991898 62 text[0] = c;
buyukesmeli 0:020195991898 63 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 64 i = 1;
buyukesmeli 0:020195991898 65 while(c!=' ') {
buyukesmeli 0:020195991898 66 text[i]=c;
buyukesmeli 0:020195991898 67 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 68 i++;
buyukesmeli 0:020195991898 69 }
buyukesmeli 0:020195991898 70 text[i]=0;
buyukesmeli 0:020195991898 71 image_width = atoi(text);
buyukesmeli 0:020195991898 72 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 73 i = 0;
buyukesmeli 0:020195991898 74 while(c!='\n') {
buyukesmeli 0:020195991898 75 text[i]=c;
buyukesmeli 0:020195991898 76 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 77 i++;
buyukesmeli 0:020195991898 78 }
buyukesmeli 0:020195991898 79 text[i]=0;
buyukesmeli 0:020195991898 80 image_height = atoi(text);
buyukesmeli 0:020195991898 81 } else {
buyukesmeli 0:020195991898 82 while(c!='\n')
buyukesmeli 0:020195991898 83 res = f_read(&MyFile, &c, 1, (UINT*)&bytesread);
buyukesmeli 0:020195991898 84 }
buyukesmeli 0:020195991898 85 if(line_cnt == 3)
buyukesmeli 0:020195991898 86 break;
buyukesmeli 0:020195991898 87
buyukesmeli 0:020195991898 88 }
buyukesmeli 2:19c2835ce409 89
buyukesmeli 0:020195991898 90 if(image_width != 480 || image_height != 272)
buyukesmeli 2:19c2835ce409 91 pc.printf("Image size should be 480x272");
buyukesmeli 2:19c2835ce409 92
buyukesmeli 2:19c2835ce409 93 // Read image as 512 byte blocks
buyukesmeli 2:19c2835ce409 94 for(i = 0; i < image_width*image_width*3; i = i + 512) {
buyukesmeli 2:19c2835ce409 95 res = f_read(&MyFile, (uint8_t *)(SD_IN_BUFFER+i) , 512, (UINT*)&bytesread);
buyukesmeli 2:19c2835ce409 96 }
buyukesmeli 0:020195991898 97
buyukesmeli 2:19c2835ce409 98 // Correct color order
buyukesmeli 2:19c2835ce409 99 for(i = 0; i < image_width*image_width*3; i = i + 3) {
buyukesmeli 2:19c2835ce409 100 c = *(char *)(SD_IN_BUFFER+i+2);
buyukesmeli 2:19c2835ce409 101 *(char *)(SD_IN_BUFFER+i+2)= *(char *)(SD_IN_BUFFER+i);
buyukesmeli 2:19c2835ce409 102 *(char *)(SD_IN_BUFFER+i) = c;
buyukesmeli 0:020195991898 103 }
buyukesmeli 0:020195991898 104 f_close(&MyFile);
buyukesmeli 0:020195991898 105
buyukesmeli 2:19c2835ce409 106 // Print image on LCD
buyukesmeli 0:020195991898 107 LCD_LL_ConvertFrameToARGB8888((uint32_t *)(SD_IN_BUFFER), (uint32_t *)(FRAME_BUFFER));
buyukesmeli 2:19c2835ce409 108
buyukesmeli 2:19c2835ce409 109
buyukesmeli 2:19c2835ce409 110 // Transfer image to a buffer
buyukesmeli 2:19c2835ce409 111 LCD_LL_ConvertFrameToRGB888((uint32_t *)(FRAME_BUFFER), (uint32_t *)(SD_OUT_BUFFER));
buyukesmeli 0:020195991898 112
buyukesmeli 2:19c2835ce409 113 // Correct color order
buyukesmeli 2:19c2835ce409 114 for(i = 0; i < image_width*image_width*3; i = i + 3) {
buyukesmeli 2:19c2835ce409 115 c = *(char *)(SD_OUT_BUFFER+i+2);
buyukesmeli 2:19c2835ce409 116 *(char *)(SD_OUT_BUFFER+i+2)= *(char *)(SD_OUT_BUFFER+i);
buyukesmeli 2:19c2835ce409 117 *(char *)(SD_OUT_BUFFER+i) = c;
buyukesmeli 2:19c2835ce409 118 }
buyukesmeli 0:020195991898 119
buyukesmeli 0:020195991898 120 res = f_open(&MyFile, "image_ou.ppm", FA_CREATE_ALWAYS | FA_WRITE);
buyukesmeli 0:020195991898 121 if(res!= FR_OK)
buyukesmeli 0:020195991898 122 pc.printf("Failed to open file\n");
buyukesmeli 0:020195991898 123
buyukesmeli 2:19c2835ce409 124 // Write image header
buyukesmeli 2:19c2835ce409 125 res = f_write(&MyFile, image_header, sizeof(image_header), &bytesread);
buyukesmeli 0:020195991898 126 if(res!= FR_OK)
buyukesmeli 0:020195991898 127 pc.printf("Failed to write file 1\n");
buyukesmeli 0:020195991898 128
buyukesmeli 2:19c2835ce409 129 // Write image as 512 byte blocks
buyukesmeli 0:020195991898 130 for(i = 0; i < 480*272*3; i = i + 512) {
buyukesmeli 0:020195991898 131 res = f_write(&MyFile, (uint8_t *)(SD_OUT_BUFFER+i), 512, &bytesread);
buyukesmeli 0:020195991898 132 if(res!= FR_OK)
buyukesmeli 0:020195991898 133 pc.printf("Failed to write file\n");
buyukesmeli 0:020195991898 134 }
buyukesmeli 2:19c2835ce409 135
buyukesmeli 1:28e2f24b11b3 136 pc.printf("Done!\n");
buyukesmeli 0:020195991898 137 f_close(&MyFile);
buyukesmeli 0:020195991898 138 FATFS_UnLinkDriver(SDPath);
buyukesmeli 0:020195991898 139
buyukesmeli 0:020195991898 140 while (1) {
buyukesmeli 0:020195991898 141 }
buyukesmeli 0:020195991898 142 }
buyukesmeli 0:020195991898 143 extern "C" {
buyukesmeli 0:020195991898 144 void BSP_SDMMC_IRQHandler(void)
buyukesmeli 0:020195991898 145 {
buyukesmeli 0:020195991898 146 HAL_SD_IRQHandler(&uSdHandle);
buyukesmeli 0:020195991898 147 }
buyukesmeli 0:020195991898 148 void BSP_SDMMC_DMA_Tx_IRQHandler(void)
buyukesmeli 0:020195991898 149 {
buyukesmeli 0:020195991898 150 HAL_DMA_IRQHandler(uSdHandle.hdmatx);
buyukesmeli 0:020195991898 151 }
buyukesmeli 0:020195991898 152 void BSP_SDMMC_DMA_Rx_IRQHandler(void)
buyukesmeli 0:020195991898 153 {
buyukesmeli 0:020195991898 154 HAL_DMA_IRQHandler(uSdHandle.hdmarx);
buyukesmeli 0:020195991898 155 }
buyukesmeli 0:020195991898 156 static void LCD_LL_ConvertFrameToARGB8888(void *pSrc, void *pDst)
buyukesmeli 0:020195991898 157 {
buyukesmeli 0:020195991898 158 /* Enable DMA2D clock */
buyukesmeli 0:020195991898 159 __HAL_RCC_DMA2D_CLK_ENABLE();
buyukesmeli 0:020195991898 160
buyukesmeli 0:020195991898 161 /* Configure the DMA2D Mode, Color Mode and output offset */
buyukesmeli 0:020195991898 162 hdma2d_disco.Init.Mode = DMA2D_M2M_PFC;
buyukesmeli 0:020195991898 163 hdma2d_disco.Init.ColorMode = DMA2D_ARGB8888;
buyukesmeli 0:020195991898 164 hdma2d_disco.Init.OutputOffset = 0;
buyukesmeli 0:020195991898 165
buyukesmeli 0:020195991898 166 /* Foreground Configuration */
buyukesmeli 0:020195991898 167 hdma2d_disco.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
buyukesmeli 0:020195991898 168 hdma2d_disco.LayerCfg[1].InputAlpha = 0xFF;
buyukesmeli 0:020195991898 169 hdma2d_disco.LayerCfg[1].InputColorMode = CM_RGB888;
buyukesmeli 0:020195991898 170 hdma2d_disco.LayerCfg[1].InputOffset = 0;
buyukesmeli 0:020195991898 171
buyukesmeli 0:020195991898 172 hdma2d_disco.Instance = DMA2D;
buyukesmeli 0:020195991898 173
buyukesmeli 0:020195991898 174 /* DMA2D Initialization */
buyukesmeli 0:020195991898 175 if(HAL_DMA2D_Init(&hdma2d_disco) == HAL_OK) {
buyukesmeli 0:020195991898 176 if(HAL_DMA2D_ConfigLayer(&hdma2d_disco, 1) == HAL_OK) {
buyukesmeli 0:020195991898 177 if (HAL_DMA2D_Start(&hdma2d_disco, (uint32_t)pSrc, (uint32_t)pDst, 480, 272) == HAL_OK) {
buyukesmeli 0:020195991898 178 /* Polling For DMA transfer */
buyukesmeli 0:020195991898 179 HAL_DMA2D_PollForTransfer(&hdma2d_disco, 10);
buyukesmeli 0:020195991898 180 }
buyukesmeli 0:020195991898 181 }
buyukesmeli 0:020195991898 182 } else {
buyukesmeli 0:020195991898 183
buyukesmeli 0:020195991898 184 }
buyukesmeli 0:020195991898 185 }
buyukesmeli 0:020195991898 186 static void LCD_LL_ConvertFrameToRGB888(void *pSrc, void *pDst)
buyukesmeli 0:020195991898 187 {
buyukesmeli 0:020195991898 188 /* Enable DMA2D clock */
buyukesmeli 0:020195991898 189 __HAL_RCC_DMA2D_CLK_ENABLE();
buyukesmeli 0:020195991898 190
buyukesmeli 0:020195991898 191 /* Configure the DMA2D Mode, Color Mode and output offset */
buyukesmeli 0:020195991898 192 hdma2d_disco.Init.Mode = DMA2D_M2M_PFC;
buyukesmeli 0:020195991898 193 hdma2d_disco.Init.ColorMode = DMA2D_RGB888;
buyukesmeli 0:020195991898 194 hdma2d_disco.Init.OutputOffset = 0;
buyukesmeli 0:020195991898 195
buyukesmeli 0:020195991898 196 /* Foreground Configuration */
buyukesmeli 0:020195991898 197 hdma2d_disco.LayerCfg[1].AlphaMode = DMA2D_NO_MODIF_ALPHA;
buyukesmeli 0:020195991898 198 hdma2d_disco.LayerCfg[1].InputAlpha = 0xFF;
buyukesmeli 0:020195991898 199 hdma2d_disco.LayerCfg[1].InputColorMode = CM_ARGB8888;
buyukesmeli 0:020195991898 200 hdma2d_disco.LayerCfg[1].InputOffset = 0;
buyukesmeli 0:020195991898 201
buyukesmeli 0:020195991898 202 hdma2d_disco.Instance = DMA2D;
buyukesmeli 0:020195991898 203
buyukesmeli 0:020195991898 204 /* DMA2D Initialization */
buyukesmeli 0:020195991898 205 if(HAL_DMA2D_Init(&hdma2d_disco) == HAL_OK) {
buyukesmeli 0:020195991898 206 if(HAL_DMA2D_ConfigLayer(&hdma2d_disco, 1) == HAL_OK) {
buyukesmeli 0:020195991898 207 if (HAL_DMA2D_Start(&hdma2d_disco, (uint32_t)pSrc, (uint32_t)pDst, 480, 272) == HAL_OK) {
buyukesmeli 0:020195991898 208 /* Polling For DMA transfer */
buyukesmeli 0:020195991898 209 HAL_DMA2D_PollForTransfer(&hdma2d_disco, 10);
buyukesmeli 0:020195991898 210 }
buyukesmeli 0:020195991898 211 }
buyukesmeli 0:020195991898 212 } else {
buyukesmeli 0:020195991898 213
buyukesmeli 0:020195991898 214 }
buyukesmeli 0:020195991898 215 }
buyukesmeli 0:020195991898 216
buyukesmeli 0:020195991898 217 }