Skip to main content
Chuev.Vladimir
Associate III
October 26, 2015
Question

TJpgDec and FatFs

  • October 26, 2015
  • 8 replies
  • 1573 views
Posted on October 26, 2015 at 09:51

I checked the code, it works when picture is in memory. But I can't make it work with MicroCD.

I rewrote the code for work with FatFs, but STM32 freezes on f_lseek() function. There is my code, I purposely deleted all unnecessary for easy reading.

FATFS MicroSD_FAT;
char
MicroSD_Path[4];
BYTE
jdwork[3100];
typedef
struct
{
void
*pData;
} IODEV;
UINT
input_func(JDEC *jd, 
BYTE
*buff, 
UINT
ndata){
IODEV *dev = (IODEV *)jd->device;
UINT
rb;
FIL *fil;
if
(buff){
fil = (FIL *)dev->pData;
f_read(fil, buff, ndata, &rb);
return
rb;
}
return
(f_lseek(fil, f_tell(fil) + ndata) == FR_OK) ? ndata : 0; 
// Here freezes
}
// It works
UINT
output_func(JDEC *jd, 
void
*bitmap, JRECT *rect){
uint16_t *bmp = (uint16_t *)bitmap;
uint16_t x, y, i = 0;
for
(y = rect->top; y <= rect->bottom; y++) {
for
(x = rect->left; x <= rect->right; x++) {
*(__IO uint16_t *)(LCD_FRAME_BUFFER + (x * 2) + (y * IMAGE_WIDTH * 2)) = (uint16_t)(bmp[i++]);
} 
}
return
1;
}
int
main(
void
){
CPU_CACHE_Enable();
HAL_Init();
SystemClock_Config();
LCD_Config();
JDEC jd;
IODEV iodev; 
JRESULT rc; 
FIL JpegEncFile;
BSP_LCD_Clear(LCD_COLOR_WHITE); 
// Start
if
(FATFS_LinkDriver(&SD_Driver, MicroSD_Path) != 0){
while
(1);
}
if
(f_mount(&MicroSD_FAT, (
TCHAR
const
*)MicroSD_Path, 0) != FR_OK){
while
(1);
}
if
(f_open(&JpegEncFile, IMAGE_NAME, FA_READ) != FR_OK){
while
(1);
}
iodev.pData = (
void
*)&JpegEncFile;
rc = jd_prepare(&jd, input_func, jdwork, 
sizeof
(jdwork), &iodev); 
if
(rc){
BSP_LCD_Clear(LCD_COLOR_LIGHTBLUE); 
// jd_prepare() error
while
(1);
}
rc = jd_decomp(&jd, output_func, 2);
if
(rc){
BSP_LCD_Clear(LCD_COLOR_RED); 
// jd_decomp() error
while
(1);
}
while
(1);
}

    This topic has been closed for replies.

    8 replies

    Tesla DeLorean
    Guru
    October 26, 2015
    Posted on October 26, 2015 at 13:31

    Make sure you assign fil on both execution paths.

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Chuev.Vladimir
    Associate III
    October 26, 2015
    Posted on October 26, 2015 at 14:56

    You can

    explain it

    more in detail

    ?

    qwer.asdf
    Senior
    October 26, 2015
    Posted on October 26, 2015 at 15:04

    I think Clive suggests you to move the ''fil = (FIL *)dev->pData;'' line up, so it comes before the if statement (in ''input_func'' function).

    Tesla DeLorean
    Guru
    October 26, 2015
    Posted on October 26, 2015 at 15:44

    In

    input_func

    () Where buff == NULL, fil has no value assigned to it (random stack junk), and then you attempt to f_lseek() against garbage. Move the assignment up earlier as it's needed for both execution/exit paths.
    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Chuev.Vladimir
    Associate III
    October 27, 2015
    Posted on October 27, 2015 at 10:15

    I changed my

    code, but

    there is no result

    typedef
    struct
    {
    void
    *pData;
    uint32_t joffset;
    uint32_t jsize;
    } IODEV;
    UINT
    input_func(JDEC *jd, 
    BYTE
    *buff, 
    UINT
    ndata){
    IODEV *dev = (IODEV *)jd->device;
    UINT
    rb;
    FIL *fil;
    ndata = dev->jsize - dev->joffset > ndata ? ndata : dev->jsize - dev->joffset;
    if
    (buff){
    fil = (FIL *)dev->pData;
    f_read(fil, buff, ndata, &rb);
    f_lseek(fil, dev->joffset);
    }
    dev->joffset += ndata;
    return
    ndata;
    }
    int
    main(
    void
    ){
    // ...
    iodev.pData = (
    void
    *)&JpegEncFile;
    iodev.jsize = f_size(&JpegEncFile);
    iodev.joffset = 0;
    // ...
    }

    Chuev.Vladimir
    Associate III
    October 28, 2015
    Posted on October 28, 2015 at 09:17

    I rewrote

    the code from

    a working

    example.

    Here's the

    code:

    UINT
    input_func (JDEC * jd, 
    BYTE
    * buff, 
    UINT
    ndata) {
    IODEV * dev = (IODEV *) jd->device;
    ndata = dev->jsize - dev->joffset > ndata ? ndata : dev->jsize - dev->joffset;
    if
    (buff) 
    memcpy
    (buff, dev->jpic + dev->joffset, ndata);
    dev->joffset += ndata;
    return
    ndata;
    }

    Tesla DeLorean
    Guru
    October 28, 2015
    Posted on October 28, 2015 at 12:27

    Need to work on logic and sequence

    I'd expect these have a better chance of working

    UINT input_func(JDEC *jd, BYTE *buff, UINT ndata){
    IODEV *dev = (IODEV *)jd->device;
    UINT rb;
    FIL *fil = (FIL *)dev->pData;
    if(buff){
    f_read(fil, buff, ndata, &rb);
    return rb;
    }
    return (f_lseek(fil, f_tell(fil) + ndata) == FR_OK) ? ndata : 0; // Here freezes
    }
    or
    UINT input_func(JDEC *jd, BYTE *buff, UINT ndata){
    IODEV *dev = (IODEV *)jd->device;
    ndata = dev->jsize - dev->joffset > ndata ? ndata : dev->jsize - dev->joffset;
    if(buff){
    UINT rb;
    FIL *fil = (FIL *)dev->pData;
    f_lseek(fil, dev->joffset);
    f_read(fil, buff, ndata, &rb);
    }
    dev->joffset += ndata;
    return ndata;
    }

    Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
    Chuev.Vladimir
    Associate III
    October 29, 2015
    Posted on October 29, 2015 at 08:29

    Thank you!

    It works