cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4Discovery Distorted Image when writing to bmp on fatfs

glenn
Associate II
Posted on January 20, 2015 at 02:55

Hi I have the camera demo for STM32F4Discovery working which can display the image from camera (OV9655) to the LCD (DM-LCD35RT). I also have fatfs for SDIO working. I am writing the image data to a .bmp file on the SD card. This works except the image is distorted (see the different between the LCD image and the created PICBMP image. It looks like the width is incorrect some how.

https://drive.google.com/folderview?id=0B2tRJoqjaZmxSnJzYWdXYVVGQUE&usp=sharing

Flow is DCMI (SnapShot)->DMA->FSMC (on LCD) <- This works correctly then I simply read the data from the LCD and write it to a write, adding a bmp header at the start. Any suggestions as to why the bmp image does not align with the LCD image? Offending code below, in the for loop I suspect:

int32_t Capture_Image_TO_Bmp(
void
)
{
int32_t ret = -1;
int32_t i = 0;
int32_t j = 0;
int16_t data_temp = 0;
uint32_t bw = 0;
char
file_str[30] = 
''picbmp''
;
FIL file; 
/* File object */
/* mount the filesys */
if
(f_mount(&filesys, 
''''
, 1) != FR_OK) {
return
-1;
}
Delayms(10);
//sprintf(file_str, ''pic%d.bmp'',pic_counter);
file_str[4] = (
char
)((pic_counter % 10)+48);
file_str[3] = (
char
)(((pic_counter/10) % 10)+48);;
ret = f_open(&file, file_str, FA_WRITE | FA_CREATE_ALWAYS);
if
(ret) {
return
ret;
}
/* write the bmp header */
ret = f_write(&file, bmp_header, 70, &bw);
LCD_SetCursor(0,0);
LCD_WriteRAM_Prepare();
LCD_ReadRAM();
for
(j = 0; j < 240; j++) {
for
(i=0;i<320;i++) { 
data_temp = LCD_ReadRAM();
image_buf[i*2+1] = (data_temp&0xff00) >> 8;
image_buf[i*2+0] = data_temp & 0x00ff;
}
ret = f_write(&file, image_buf, 640, &bw);
}
ret = f_close(&file);
f_mount(0, 
''''
, 1);
/* statistics the take pictures count */
pic_counter++;
set_pic_count();
return
ret;
}

#fatfs #sdio #sd #dma #stm32f4 #stm32 #discovery
6 REPLIES 6
Posted on January 20, 2015 at 15:00

Does the display have the same concept of X and Y ?

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
glenn
Associate II
Posted on January 21, 2015 at 07:09

Thanks for the response Clive.

The LCD is a 320(x) x 240(y) display, but I don't believe it is directly addressed like that. The LCD is setup via FSMC (STM32F4DIS-LCD) and it appears that a a memory range corresponds to the LCD pixels. Unfortunately my understanding how the LCD_ReadRAM() function is lacking. It looks like it just reads the SRAM directly using a pointer. I'm unsure how this is incrementing automatically. This process 'seems' correct because I can read the bmp file from microSD and display it on the LCD using the same/opposite method i.eLCD_WriteRAM is a similar loop. - stm32f4_discovery_lcd.c

/* Note: LCD /CS is NE1 - Bank 1 of NOR/SRAM Bank 1~4 */
#define LCD_BASE_Data ((u32)(0x60000000|0x00100000))
#define LCD_BASE_Addr ((u32)(0x60000000|0x00000000))
#define LCD_CMD (*(vu16 *)LCD_BASE_Addr)
#define LCD_Data (*(vu16 *)LCD_BASE_Data)
...
uint16_t LCD_ReadRAM(
void
)
{
/* Read 16-bit Reg */
return
LCD_Data;
}
void
LCD_WriteRAM_Prepare(
void
)
{
LCD_CMD = SSD2119_RAM_DATA_REG;
}
void
LCD_WriteRAM_Prepare(
void
)
{
LCD_CMD = SSD2119_RAM_DATA_REG;
}

- bmp.c (write from BMP to LCD)

LCD_SetCursor(0,0);
LCD_WriteRAM_Prepare();
for
(j = 0; j < 240; j++) {
ret = f_read(&file, image_buf, 640, &bw);
if
(ret || !bw)
fault_err(ret);
else
{
for
(i=0;i<320;i++) { 
data_temp = image_buf[i*2+1] << 8;
data_temp |= image_buf[i*2+0];
LCD_WriteRAM(data_temp);
}
}
}

Posted on January 21, 2015 at 13:58

This process 'seems' correct because I can read the bmp file from microSD and display it on the LCD using the same/opposite method i.e LCD_WriteRAM is a similar loop.

I guess that means it has an internally consistent view of it's world.

Like I said try swapping the X and Y dimensions in your BMP header. It doesn't much matter how the sequential 76800 words get copied.
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
glenn
Associate II
Posted on January 21, 2015 at 15:33

Thanks for the suggestion. I swapped X & Y around in the bmp header and no luck.

I think my explanation about it works bmp on SD card -> LCD was misleading. What I mean is if I write the bmp file to the LCD it displays incorrect. I.e the same as it would when I view the image in Windows (as in the example I gave above). So it seems to load SD -> LCD correctly, but not the other way.

Potentially due to the header still. Although this seems unlikely as I wrote the bmp file without a header and then view using 7yuv which allows you to select data type etc. and the image shows the same (distorted).

Maybe corrupt data being written to SDIO. Potentially losing data etc.

Posted on January 21, 2015 at 16:20

It is relatively unusual to read out data from display's RAM, it is more common to keep a ''local copy'' in the system RAM of mcu. Thus, readout functions are often buggy, both in the display controller hardware, and driver software.

From SSD2119 datasheet:

''The address counter is not automatically updated when data are read out from the GDDRAM.''

''When the data is read to the microcomputer, the first-word read

immediately after the GDDRAM address setting is latched from the GDDRAM to the internal read-data latch. The data

on the data bus (DB17–0) becomes invalid and the second-word read is normal. ''

JW

glenn
Associate II
Posted on January 26, 2015 at 01:23

Thanks for the suggestions guys.

I was basically using the LCD as external RAM as I was short on the MCU RAM.

Indeed the issue I was facing is internal to the SSD2119 driver I believe. As this storing data in LCD RAM was only temporary I haven't spent alot of time debugging the issue I was facing. I have moved onto using double buffer DMA and MCU RAM to achieve what I want and the image stored to SD does not have this same distortion.

When I have time I will look back into this issue to learn what was causing it.