Wakeup Light with touch user interface, anti-aliased Font, SD card access and RTC usage on STM32F746NG-DISCO board

Dependencies:   BSP_DISCO_F746NG_patch_fixed LCD_DISCO_F746NG TS_DISCO_F746NG FATFileSystem TinyJpgDec_interwork mbed-src

SD.cpp

Committer:
the_sz
Date:
2016-02-21
Revision:
14:2044ad5cd3fe
Parent:
12:a89096944f20

File content as of revision 14:2044ad5cd3fe:

#include "WakeupLight.h"

class mySD:public FATFileSystem
{
    protected:
        HAL_SD_CardInfoTypedef CardInfo;

    public:
        mySD(const char* name):FATFileSystem(name)
        {
            uint8_t result=BSP_SD_Init();
            DPrintf_("BSP_SD_Init: %u.\r\n",result);
            BSP_SD_GetCardInfo(&CardInfo);
            DPrintf("BSP_SD_GetCardInfo: 0x%llX bytes / %u sector size.\r\n",CardInfo.CardCapacity,CardInfo.CardBlockSize);
        };
        virtual int disk_initialize() { return 0; }
        virtual int disk_status() { return 0; }
        virtual int disk_read(uint8_t * buffer, uint64_t sector, uint8_t count)
        {
            DPrintf_("disk_read: %llu / %u.\r\n",sector,count);
            return BSP_SD_ReadBlocks((uint32_t *)buffer,sector*CardInfo.CardBlockSize,CardInfo.CardBlockSize,count);
        };
        virtual int disk_write(const uint8_t * buffer, uint64_t sector, uint8_t count)
        {
            DPrintf_("disk_write: %llu / %u.\r\n",sector,count);
            return BSP_SD_WriteBlocks((uint32_t *)buffer,sector*CardInfo.CardBlockSize,CardInfo.CardBlockSize,count);
        };
        virtual int disk_sync() { return 0; }
        virtual uint64_t disk_sectors()
        {
            return CardInfo.CardCapacity/CardInfo.CardBlockSize;
        };
};

mySD                        sd("sd");
FileHandle                  *fileHandle;
uint8_t                     buffer[6000];
int16_t                     offsetX;
int16_t                     offsetY;

void SD_Init(void)
{
}

JPG_UINT jpeg_input_func(JDEC *jd, BYTE *buff, JPG_UINT ndata)
{
    if(buff)
    {
        size_t n = fileHandle->read(buff,ndata);
        return n == (size_t)-1 ? 0 : n;
    }
    else
    {
        off_t t = fileHandle->lseek( ndata, SEEK_CUR);
        return t == (off_t)-1 ? 0 : ndata;
    }
}
 
JPG_UINT jpeg_output_func(JDEC *jd, void *bitmap, JRECT *rect)
{
    int             x0=rect->left+offsetX;
    int             x1=rect->right+offsetX;
    int             y0=rect->top+offsetY;
    int             y1=rect->bottom+offsetY;
    int             w=x1-x0+1;

    DPrintf_("jpeg_output_func: %ux%u / %ux%u\r\n",x0,y0,x1,y1);

    if ((y0>=uiLcd.GetYSize()) || (x0>=uiLcd.GetXSize()))
        return 1;
 
    if (x1>uiLcd.GetXSize()-1)
        x1=uiLcd.GetXSize()-1;
    if (y1>uiLcd.GetYSize()-1)
        y1=uiLcd.GetYSize()-1;
 
    for (int y=y0;y<=y1;y++)
    {
        uint8_t *p=((uint8_t *)bitmap)+((w*(y-y0))*3);

        for (int x=x0;x<=x1;x++)
        {
            if ((x>=0) && (y>=0))
                uiLcd.DrawPixel(x,y,(0xFF000000 | p[0]<<16 | (p[1]<<8) | (p[2]) ));

            p+=3;
        }
    }

    return 1;
}

bool SD_ShowRandomPicture(void)
{
    uint32_t                count;
    DIR                     *dir;
    struct dirent           *dirEnt;
    char                    *extension;
    char                    file[100];
    JRESULT                 jResult;
    JDEC                    jdec;
    bool                    result;
    BYTE                    scale;
    JPG_UINT                pictureWidth;
    JPG_UINT                pictureHeight;

    //
    // count all jpegs
    //
    count=0;
    dir=opendir("/sd/");
    while ((dirEnt=readdir(dir))!=NULL)
    {
        extension=strrchr(dirEnt->d_name,'.');
        if ((extension==NULL) || (strcmp(extension,".jpg"))!=0)
            continue;        

        count++;

        DPrintf_("SD_ShowRandomPicture: Count %s.\r\n",dirEnt->d_name);
    }
    closedir(dir);

    DPrintf_("SD_ShowRandomPicture: Count %u.\r\n",count);

    //
    // get random number
    //
    count=(uint32_t)((uint64_t)TM_RNG_Get()*(uint64_t)count/0xFFFFFFFF);
    DPrintf_("SD_ShowRandomPicture: Take %u.\r\n",count);

    //
    // find random jpeg
    //
    file[0]='\0';
    dir=opendir("/sd/");
    while ((dirEnt=readdir(dir))!=NULL)
    {
        extension=strrchr(dirEnt->d_name,'.');
        if ((extension==NULL) || (strcmp(extension,".jpg"))!=0)
            continue;        

        if (count==0)
        {
            snprintf(file,sizeof(file),"%s",dirEnt->d_name);
            break;
        }

        count--;
    }
    closedir(dir);
    
    if (file[0]=='\0')
        return false;

    //
    // load random jpeg
    //
    DPrintf_("SD_ShowRandomPicture: Open %s.\r\n",file);
    if ((fileHandle=sd.open(file,O_RDONLY))==NULL)
        return false;

    result=false;

    jResult=jd_prepare(&jdec,jpeg_input_func,buffer,sizeof(buffer),NULL);
    if (jResult==JDR_OK)
    {
        pictureWidth=jdec.width;
        pictureHeight=jdec.height;
        scale=0;

        DPrintf("SD_ShowRandomPicture: Picture %ux%u, LCD: %ux%u.\r\n",pictureWidth,pictureHeight,uiLcd.GetXSize(),uiLcd.GetYSize());

        while ((pictureWidth>uiLcd.GetXSize()) || (pictureHeight>uiLcd.GetYSize()))
        {
            pictureWidth/=2;
            pictureHeight/=2;
            scale++;

            if (scale>=3)
                break;
        }
        offsetX=(uiLcd.GetXSize()-pictureWidth)/2;
        offsetY=(uiLcd.GetYSize()-pictureHeight)/2;

        DPrintf("SD_ShowRandomPicture: Scale %u.\r\n",scale);

        jResult=jd_decomp(&jdec,jpeg_output_func,scale);
        if (jResult==JDR_OK)
            result=true;
        else
            DPrintf("SD_ShowRandomPicture: jd_decomp: %u on %s\r\n",jResult,file);
    }
    else
        DPrintf("SD_ShowRandomPicture: jd_prepare %u on %s\r\n",jResult,file);

    fileHandle->close();

    return result;
}