fix opendir bug for multiple FAT volumes
authorJim Morris <morris@wolfman.com>
Sun, 28 Sep 2014 08:12:17 +0000 (01:12 -0700)
committerJim Morris <morris@wolfman.com>
Sun, 28 Sep 2014 08:12:17 +0000 (01:12 -0700)
Add sd card insertion detection and mount exernal sd

src/libs/ChaNFS/CHAN_FS/ffconf.h
src/libs/ChaNFS/FATFileSystem.cpp
src/libs/USBDevice/USBMSD/SDCard.h
src/main.cpp
src/modules/utils/panel/panels/ST7565.cpp
src/modules/utils/panel/panels/ST7565.h

index 4daa303..844701f 100644 (file)
@@ -8,24 +8,24 @@
 /----------------------------------------------------------------------------*/
 #ifndef _FFCONF
 #define _FFCONF 8237    /* Revision ID */
-\r
-\r
+
+
 /*---------------------------------------------------------------------------/
 / Function and Buffer Configurations
 /----------------------------------------------------------------------------*/
-\r
+
 #define    _FS_TINY        0    /* 0:Normal or 1:Tiny */
 /* When _FS_TINY is set to 1, FatFs uses the sector buffer in the file system
 /  object instead of the sector buffer in the individual file object for file
 /  data transfer. This reduces memory consumption 512 bytes each file object. */
-\r
-\r
+
+
 #define _FS_READONLY    0    /* 0:Read/Write or 1:Read only */
 /* Setting _FS_READONLY to 1 defines read only configuration. This removes
 /  writing functions, f_write, f_sync, f_unlink, f_mkdir, f_chmod, f_rename,
 /  f_truncate and useless f_getfree. */
-\r
-\r
+
+
 #define _FS_MINIMIZE    0    /* 0 to 3 */
 /* The _FS_MINIMIZE option defines minimization level to remove some functions.
 /
 /      are removed.
 /   2: f_opendir and f_readdir are removed in addition to 1.
 /   3: f_lseek is removed in addition to 2. */
-\r
-\r
+
+
 #define    _USE_STRFUNC    1    /* 0:Disable or 1/2:Enable */
 /* To enable string functions, set _USE_STRFUNC to 1 or 2. */
-\r
-\r
+
+
 #define    _USE_MKFS        1    /* 0:Disable or 1:Enable */
 /* To enable f_mkfs function, set _USE_MKFS to 1 and set _FS_READONLY to 0 */
-\r
-\r
+
+
 #define    _USE_FORWARD    0    /* 0:Disable or 1:Enable */
 /* To enable f_forward function, set _USE_FORWARD to 1 and set _FS_TINY to 1. */
-\r
-\r
+
+
 #define    _USE_FASTSEEK    0    /* 0:Disable or 1:Enable */
 /* To enable fast seek feature, set _USE_FASTSEEK to 1. */
-\r
-\r
-\r
+
+
+
 /*---------------------------------------------------------------------------/
 / Locale and Namespace Configurations
 /----------------------------------------------------------------------------*/
-\r
+
 #define _CODE_PAGE    1252
 /* The _CODE_PAGE specifies the OEM code page to be used on the target system.
 /  Incorrect setting of the code page can cause a file open failure.
@@ -88,8 +88,8 @@
 /   874  - Thai (OEM, Windows)
 /    1    - ASCII only (Valid for non LFN cfg.)
 */
-\r
-\r
+
+
 #define    _USE_LFN    1        /* 0 to 3 */
 #define    _MAX_LFN    255        /* Maximum LFN length to handle (12 to 255) */
 /* The _USE_LFN option switches the LFN support.
 /  Unicode handling functions ff_convert() and ff_wtoupper() must be added
 /  to the project. When enable to use heap, memory control functions
 /  ff_memalloc() and ff_memfree() must be added to the project. */
-\r
-\r
+
+
 #define    _LFN_UNICODE    0    /* 0:ANSI/OEM or 1:Unicode */
 /* To switch the character code set on FatFs API to Unicode,
 /  enable LFN feature and set _LFN_UNICODE to 1. */
-\r
-\r
+
+
 #define _FS_RPATH        0    /* 0 to 2 */
 /* The _FS_RPATH option configures relative path feature.
 /
 /   2: f_getcwd() is available in addition to 1.
 /
 /  Note that output of the f_readdir fnction is affected by this option. */
-\r
-\r
-\r
+
+
+
 /*---------------------------------------------------------------------------/
 / Physical Drive Configurations
 /----------------------------------------------------------------------------*/
-\r
-#define _VOLUMES    1
+
+#define _VOLUMES    2
 /* Number of volumes (logical drives) to be used. */
-\r
-\r
+
+
 #define    _MAX_SS        512        /* 512, 1024, 2048 or 4096 */
 /* Maximum sector size to be handled.
 /  Always set 512 for memory card and hard disk but a larger value may be
 /  required for on-board flash memory, floppy disk and optical disk.
 /  When _MAX_SS is larger than 512, it configures FatFs to variable sector size
 /  and GET_SECTOR_SIZE command must be implememted to the disk_ioctl function. */
-\r
-\r
+
+
 #define    _MULTI_PARTITION    0    /* 0:Single partition or 1:Multiple partition */
 /* When set to 0, each volume is bound to the same physical drive number and
 / it can mount only first primaly partition. When it is set to 1, each volume
 / is tied to the partitions listed in VolToPart[]. */
-\r
-\r
+
+
 #define    _USE_ERASE    0    /* 0:Disable or 1:Enable */
 /* To enable sector erase feature, set _USE_ERASE to 1. CTRL_ERASE_SECTOR command
 /  should be added to the disk_ioctl functio. */
-\r
-\r
-\r
+
+
+
 /*---------------------------------------------------------------------------/
 / System Configurations
 /----------------------------------------------------------------------------*/
-\r
+
 #define _WORD_ACCESS    0    /* 0 or 1 */
 /* Set 0 first and it is always compatible with all platforms. The _WORD_ACCESS
 /  option defines which access method is used to the word data on the FAT volume.
 /  access results incorrect behavior, the _WORD_ACCESS must be set to 0.
 /  If it is not the case, the value can also be set to 1 to improve the
 /  performance and code size. */
-\r
-\r
+
+
 /* A header file that defines sync object types on the O/S, such as
 /  windows.h, ucos_ii.h and semphr.h, must be included prior to ff.h. */
-\r
+
 #define _FS_REENTRANT    0        /* 0:Disable or 1:Enable */
 #define _FS_TIMEOUT        1000    /* Timeout period in unit of time ticks */
 #define    _SYNC_t            HANDLE    /* O/S dependent type of sync object. e.g. HANDLE, OS_EVENT*, ID and etc.. */
-\r
+
 /* The _FS_REENTRANT option switches the reentrancy (thread safe) of the FatFs module.
 /
 /   0: Disable reentrancy. _SYNC_t and _FS_TIMEOUT have no effect.
 /   1: Enable reentrancy. Also user provided synchronization handlers,
 /      ff_req_grant, ff_rel_grant, ff_del_syncobj and ff_cre_syncobj
 /      function must be added to the project. */
-\r
-\r
+
+
 #define    _FS_SHARE    0    /* 0:Disable or >=1:Enable */
 /* To enable file shareing feature, set _FS_SHARE to 1 or greater. The value
    defines how many files can be opened simultaneously. */
-\r
-\r
+
+
 #endif /* _FFCONFIG */
index 8f06397..56f8088 100644 (file)
@@ -54,7 +54,7 @@ FATFileSystem::FATFileSystem(const char* n) : FileSystemLike(n) {
     }
     error("Couldn't create %s in FATFileSystem::FATFileSystem\n",n);
 }
-    
+
 FATFileSystem::~FATFileSystem() {
     for(int i=0; i<_DRIVES; i++) {
         if(_ffs[i] == this) {
@@ -63,7 +63,7 @@ FATFileSystem::~FATFileSystem() {
         }
     }
 }
-    
+
 FileHandle *FATFileSystem::open(const char* name, int flags) {
     FFSDEBUG("open(%s) on filesystem [%s], drv [%d]\n", name, _name, _fsid);
     char n[64];
@@ -97,7 +97,7 @@ FileHandle *FATFileSystem::open(const char* name, int flags) {
     }
     return new FATFileHandle(fh);
 }
-    
+
 int FATFileSystem::remove(const char *filename) {
     FRESULT res = f_unlink(filename);
     if(res) {
@@ -118,8 +118,10 @@ int FATFileSystem::format() {
 }
 
 DirHandle *FATFileSystem::opendir(const char *name) {
+    char n[64];
+    sprintf(n, "%d:/%s", _fsid, name);
     DIR_t dir;
-    FRESULT res = f_opendir(&dir, name);
+    FRESULT res = f_opendir(&dir, n);
     if(res != 0) {
         return NULL;
     }
index b8b3507..d80c3e3 100644 (file)
@@ -79,8 +79,6 @@ public:
 \r
     CARD_TYPE card_type(void);\r
 \r
-    void on_main_loop(void);\r
-\r
     bool busy();\r
 \r
 protected:\r
index 2854921..bf75f26 100644 (file)
@@ -61,6 +61,7 @@
 // USB Stuff
 SDCard sd  __attribute__ ((section ("AHBSRAM0"))) (P0_9, P0_8, P0_7, P0_6);      // this selects SPI1 as the sdcard as it is on Smoothieboard
 //SDCard sd(P0_18, P0_17, P0_15, P0_16);  // this selects SPI0 as the sdcard
+//SDCard sd(P0_18, P0_17, P0_15, P2_8);  // this selects SPI0 as the sdcard witrh a different sd select
 
 USB u __attribute__ ((section ("AHBSRAM0")));
 USBSerial usbserial __attribute__ ((section ("AHBSRAM0"))) (&u);
index 6fa1e56..48bdda1 100644 (file)
@@ -14,6 +14,9 @@
 #include "StreamOutputPool.h"
 #include "ConfigValue.h"
 
+#include "libs/USBDevice/USBMSD/SDCard.h"
+#include "libs/SDFAT.h"
+
 //definitions for lcd
 #define LCDWIDTH 128
 #define LCDHEIGHT 64
 #define reverse_checksum           CHECKSUM("reverse")
 #define rst_pin_checksum           CHECKSUM("rst_pin")
 #define a0_pin_checksum            CHECKSUM("a0_pin")
+#define sdcd_pin_checksum          CHECKSUM("sdcd_pin")
 #define red_led_checksum           CHECKSUM("red_led_pin")
 #define blue_led_checksum          CHECKSUM("blue_led_pin")
 
 #define CLAMP(x, low, high) { if ( (x) < (low) ) x = (low); if ( (x) > (high) ) x = (high); } while (0);
 #define swap(a, b) { uint8_t t = a; a = b; b = t; }
 
-ST7565::ST7565(uint8_t variant) {
+ST7565::ST7565(uint8_t variant)
+{
     // set the variant
     switch(variant) {
         case 1:
-            is_viki2= true;
-            is_mini_viki2= false;
-            this->reversed= true;
-            this->contrast= 9;
+            is_viki2 = true;
+            is_mini_viki2 = false;
+            this->reversed = true;
+            this->contrast = 9;
             break;
         case 2:
-            is_mini_viki2= true;
-            is_viki2= false;
-            this->reversed= true;
-            this->contrast= 18;
+            is_mini_viki2 = true;
+            is_viki2 = false;
+            this->reversed = true;
+            this->contrast = 18;
             break;
         default:
             // set default for sub variants
-            is_viki2= false; // defaults to Wulfnors panel
-            is_mini_viki2= false;
-            this->reversed= false;
-            this->contrast= 9;
+            is_viki2 = false; // defaults to Wulfnors panel
+            is_mini_viki2 = false;
+            this->reversed = false;
+            this->contrast = 9;
             break;
     }
 
@@ -73,15 +78,15 @@ ST7565::ST7565(uint8_t variant) {
     int spi_channel = THEKERNEL->config->value(panel_checksum, spi_channel_checksum)->by_default(0)->as_number();
     PinName mosi;
     PinName sclk;
-    if(spi_channel == 0){
-        mosi= P0_18; sclk= P0_15;
-    }else if(spi_channel == 1){
-        mosi= P0_9; sclk= P0_7;
-    }else{
-        mosi= P0_18; sclk= P0_15;
+    if(spi_channel == 0) {
+        mosi = P0_18; sclk = P0_15;
+    } else if(spi_channel == 1) {
+        mosi = P0_9; sclk = P0_7;
+    } else {
+        mosi = P0_18; sclk = P0_15;
     }
 
-    this->spi= new mbed::SPI(mosi,NC,sclk);
+    this->spi = new mbed::SPI(mosi, NC, sclk);
     this->spi->frequency(THEKERNEL->config->value(panel_checksum, spi_frequency_checksum)->by_default(1000000)->as_number()); //4Mhz freq, can try go a little lower
 
     //chip select
@@ -99,7 +104,7 @@ ST7565::ST7565(uint8_t variant) {
     if(!is_viki2 && !is_mini_viki2) {
         this->up_pin.from_string(THEKERNEL->config->value( panel_checksum, up_button_pin_checksum )->by_default("nc")->as_string())->as_input();
         this->down_pin.from_string(THEKERNEL->config->value( panel_checksum, down_button_pin_checksum )->by_default("nc")->as_string())->as_input();
-    }else{
+    } else {
         this->up_pin.from_string("nc");
         this->down_pin.from_string("nc");
     }
@@ -107,18 +112,18 @@ ST7565::ST7565(uint8_t variant) {
     this->aux_pin.from_string("nc");
     if(is_viki2) {
         // the aux pin can be pause or back on a viki2
-        string aux_but= THEKERNEL->config->value( panel_checksum, pause_button_pin_checksum )->by_default("nc")->as_string();
+        string aux_but = THEKERNEL->config->value( panel_checksum, pause_button_pin_checksum )->by_default("nc")->as_string();
         if(aux_but != "nc") {
             this->aux_pin.from_string(aux_but)->as_input();
-            this->use_pause= true;
-            this->use_back= false;
+            this->use_pause = true;
+            this->use_back = false;
 
-        }else{
-            aux_but= THEKERNEL->config->value( panel_checksum, back_button_pin_checksum )->by_default("nc")->as_string();
+        } else {
+            aux_but = THEKERNEL->config->value( panel_checksum, back_button_pin_checksum )->by_default("nc")->as_string();
             if(aux_but != "nc") {
                 this->aux_pin.from_string(aux_but)->as_input();
-                this->use_back= true;
-                this->use_pause= false;
+                this->use_back = true;
+                this->use_pause = false;
             }
         }
     }
@@ -136,65 +141,75 @@ ST7565::ST7565(uint8_t variant) {
         this->blue_led.set(true);
     }
 
+    // external sdcard detect
+    this->sdcd_pin.from_string(THEKERNEL->config->value( panel_checksum, sdcd_pin_checksum )->by_default("nc")->as_string())->as_input();
+
     // contrast override
-    this->contrast= THEKERNEL->config->value(panel_checksum, contrast_checksum)->by_default(this->contrast)->as_number();
+    this->contrast = THEKERNEL->config->value(panel_checksum, contrast_checksum)->by_default(this->contrast)->as_number();
 
     // reverse display
-    this->reversed= THEKERNEL->config->value(panel_checksum, reverse_checksum)->by_default(this->reversed)->as_bool();
+    this->reversed = THEKERNEL->config->value(panel_checksum, reverse_checksum)->by_default(this->reversed)->as_bool();
 
-    framebuffer= (uint8_t *)AHB0.alloc(FB_SIZE); // grab some memory from USB_RAM
+    framebuffer = (uint8_t *)AHB0.alloc(FB_SIZE); // grab some memory from USB_RAM
     if(framebuffer == NULL) {
         THEKERNEL->streams->printf("Not enough memory available for frame buffer");
     }
 
+    this->sd= nullptr;
+    this->extmounter= nullptr;
 }
 
-ST7565::~ST7565() {
-       delete this->spi;
+ST7565::~ST7565()
+{
+    delete this->spi;
     AHB0.dealloc(framebuffer);
+    delete this->extmounter;
 }
 
 //send commands to lcd
-void ST7565::send_commands(const unsigned char* buf, size_t size){
+void ST7565::send_commands(const unsigned char *buf, size_t size)
+{
     cs.set(0);
     a0.set(0);
-    while(size-- >0){
-       spi->write(*buf++);
+    while(size-- > 0) {
+        spi->write(*buf++);
     }
     cs.set(1);
 }
 
 //send data to lcd
-void ST7565::send_data(const unsigned char* buf, size_t size){
+void ST7565::send_data(const unsigned char *buf, size_t size)
+{
     cs.set(0);
     a0.set(1);
-    while(size-- >0){
-       spi->write(*buf++);
+    while(size-- > 0) {
+        spi->write(*buf++);
     }
     cs.set(1);
     a0.set(0);
 }
 
 //clearing screen
-void ST7565::clear(){
+void ST7565::clear()
+{
     memset(framebuffer, 0, FB_SIZE);
-    this->tx=0;
-    this->ty=0;
+    this->tx = 0;
+    this->ty = 0;
 }
 
-void ST7565::send_pic(const unsigned char* data){
-    for (int i=0; i<LCDPAGES; i++)
-    {
-       set_xy(0, i);
-        send_data(data + i*LCDWIDTH, LCDWIDTH);
+void ST7565::send_pic(const unsigned char *data)
+{
+    for (int i = 0; i < LCDPAGES; i++) {
+        set_xy(0, i);
+        send_data(data + i * LCDWIDTH, LCDWIDTH);
     }
 }
 
 // set column and page number
 void ST7565::set_xy(int x, int y)
 {
-    CLAMP(x, 0, LCDWIDTH-1);
-    CLAMP(y, 0, LCDPAGES-1);
+    CLAMP(x, 0, LCDWIDTH - 1);
+    CLAMP(y, 0, LCDPAGES - 1);
     unsigned char cmd[3];
     cmd[0] = 0xb0 | (y & 0x07);
     cmd[1] = 0x10 | (x >> 4);
@@ -202,109 +217,118 @@ void ST7565::set_xy(int x, int y)
     send_commands(cmd, 3);
 }
 
-void ST7565::setCursor(uint8_t col, uint8_t row){
-  this->tx=col*6;
-  this->ty=row*8;
+void ST7565::setCursor(uint8_t col, uint8_t row)
+{
+    this->tx = col * 6;
+    this->ty = row * 8;
 }
 
-void ST7565::home(){
-       this->tx=0;
-       this->ty=0;
+void ST7565::home()
+{
+    this->tx = 0;
+    this->ty = 0;
 }
 
-void ST7565::display(){
-       ///nothing
+void ST7565::display()
+{
+    ///nothing
 }
 
-void ST7565::init(){
+void ST7565::init()
+{
     const unsigned char init_seq[] = {
-      0x40,    //Display start line 0
-      (unsigned char)(reversed?0xa0:0xa1), // ADC
-      (unsigned char)(reversed?0xc8:0xc0), // COM select
-      0xa6,    //Display normal
-      0xa2,    //Set Bias 1/9 (Duty 1/65)
-      0x2f,    //Booster, Regulator and Follower On
-      0xf8,    //Set internal Booster to 4x
-      0x00,
-      0x27,    //Contrast set
-      0x81,
-      this->contrast,    //contrast value
-      0xac,    //No indicator
-      0x00,
-      0xaf,    //Display on
-  };
-  //rst.set(0);
-  if(this->rst.connected()) rst.set(1);
-  send_commands(init_seq, sizeof(init_seq));
-  clear();
+        0x40,    //Display start line 0
+        (unsigned char)(reversed ? 0xa0 : 0xa1), // ADC
+        (unsigned char)(reversed ? 0xc8 : 0xc0), // COM select
+        0xa6,    //Display normal
+        0xa2,    //Set Bias 1/9 (Duty 1/65)
+        0x2f,    //Booster, Regulator and Follower On
+        0xf8,    //Set internal Booster to 4x
+        0x00,
+        0x27,    //Contrast set
+        0x81,
+        this->contrast,    //contrast value
+        0xac,    //No indicator
+        0x00,
+        0xaf,    //Display on
+    };
+    //rst.set(0);
+    if(this->rst.connected()) rst.set(1);
+    send_commands(init_seq, sizeof(init_seq));
+    clear();
 }
 
-void ST7565::setContrast(uint8_t c){
+void ST7565::setContrast(uint8_t c)
+{
     const unsigned char contrast_seq[] = {
-      0x27,    //Contrast set
-      0x81,
-      c    //contrast value
-  };
-  this->contrast= c;
-  send_commands(contrast_seq, sizeof(contrast_seq));
+        0x27,    //Contrast set
+        0x81,
+        c    //contrast value
+    };
+    this->contrast = c;
+    send_commands(contrast_seq, sizeof(contrast_seq));
 }
 
-int ST7565::drawChar(int x, int y, unsigned char c, int color){
-       int retVal=-1;
-         if(c=='\n'){
-           this->ty+=8;
-           retVal= -tx;
-         }
-         if(c=='\r'){
-                 retVal= -tx;
-         }
-         else{
-           for (uint8_t i =0; i<5; i++ ) {
-             if(color==0){
-               framebuffer[x + (y/8*128) ] = ~(glcd_font[(c*5)+i]<< y%8);
-               if(y+8<63){
-                 framebuffer[x + ((y+8)/8*128) ] = ~(glcd_font[(c*5)+i] >>(8-(y%8)));
-               }
-             }
-             if(color==1){
-               framebuffer[x + ((y)/8*128) ] = glcd_font[(c*5)+i] <<(y%8);
-               if(y+8<63){
-                       framebuffer[x + ((y+8)/8*128) ] = glcd_font[(c*5)+i] >>(8-(y%8));
-               }
-             }
-             x++;
-           }
-           retVal= 6;
-           this->tx+=6;
-         }
-
-       return retVal;
+int ST7565::drawChar(int x, int y, unsigned char c, int color)
+{
+    int retVal = -1;
+    if(c == '\n') {
+        this->ty += 8;
+        retVal = -tx;
+    }
+    if(c == '\r') {
+        retVal = -tx;
+    } else {
+        for (uint8_t i = 0; i < 5; i++ ) {
+            if(color == 0) {
+                framebuffer[x + (y / 8 * 128) ] = ~(glcd_font[(c * 5) + i] << y % 8);
+                if(y + 8 < 63) {
+                    framebuffer[x + ((y + 8) / 8 * 128) ] = ~(glcd_font[(c * 5) + i] >> (8 - (y % 8)));
+                }
+            }
+            if(color == 1) {
+                framebuffer[x + ((y) / 8 * 128) ] = glcd_font[(c * 5) + i] << (y % 8);
+                if(y + 8 < 63) {
+                    framebuffer[x + ((y + 8) / 8 * 128) ] = glcd_font[(c * 5) + i] >> (8 - (y % 8));
+                }
+            }
+            x++;
+        }
+        retVal = 6;
+        this->tx += 6;
+    }
+
+    return retVal;
 }
 
 //write single char to screen
-void ST7565::write_char(char value){
-       drawChar(this->tx, this->ty,value,1);
+void ST7565::write_char(char value)
+{
+    drawChar(this->tx, this->ty, value, 1);
 }
 
-void ST7565::write(const char* line, int len){
+void ST7565::write(const char *line, int len)
+{
     for (int i = 0; i < len; ++i) {
-       write_char(line[i]);
+        write_char(line[i]);
     }
 }
-//refreshing screen
 
-void ST7565::on_refresh(bool now){
+//refreshing screen
+void ST7565::on_refresh(bool now)
+{
     static int refresh_counts = 0;
     refresh_counts++;
     // 10Hz refresh rate
-    if(now || refresh_counts % 2 == 0 ){
-               send_pic(framebuffer);
-       }
+    if(now || refresh_counts % 2 == 0 ) {
+        send_pic(framebuffer);
+    }
 }
 
 //reading button state
-uint8_t ST7565::readButtons(void) {
-    uint8_t state= 0;
+uint8_t ST7565::readButtons(void)
+{
+    uint8_t state = 0;
     state |= (this->click_pin.get() ? BUTTON_SELECT : 0);
     if(this->up_pin.connected()) {
         state |= (this->up_pin.get() ? BUTTON_UP : 0);
@@ -314,63 +338,75 @@ uint8_t ST7565::readButtons(void) {
         if(this->use_pause) state |= BUTTON_PAUSE;
         else if(this->use_back) state |= BUTTON_LEFT;
     }
+
+    // sd insert detect, mount sdcard if inserted, unmount if removed
+    if(this->sdcd_pin.connected()) {
+        if(this->extmounter == nullptr && this->sdcd_pin.get()) {
+            mount_external_sd(true);
+        }else if(this->extmounter != nullptr && !this->sdcd_pin.get()){
+            mount_external_sd(false);
+        }
+    }
     return state;
 }
 
-int ST7565::readEncoderDelta() {
-    static int8_t enc_states[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0};
+int ST7565::readEncoderDelta()
+{
+    static int8_t enc_states[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
     static uint8_t old_AB = 0;
     if(this->encoder_a_pin.connected()) {
         // mviki
         old_AB <<= 2;                   //remember previous state
         old_AB |= ( this->encoder_a_pin.get() + ( this->encoder_b_pin.get() * 2 ) );  //add current state
-        return  enc_states[(old_AB&0x0f)];
+        return  enc_states[(old_AB & 0x0f)];
 
-    }else{
+    } else {
         return 0;
     }
 }
 
-void ST7565::bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span, int x_offset, int y_offset) {
+void ST7565::bltGlyph(int x, int y, int w, int h, const uint8_t *glyph, int span, int x_offset, int y_offset)
+{
     if(x_offset == 0 && y_offset == 0 && span == 0) {
         // blt the whole thing
         renderGlyph(x, y, glyph, w, h);
 
-    }else{
+    } else {
         // copy portion of glyph into g where x_offset is left byte aligned
         // Note currently the x_offset must be byte aligned
-        int n= w/8; // bytes per line to copy
-        if(w%8 != 0) n++; // round up to next byte
-        uint8_t g[n*h];
-        uint8_t *dst= g;
-        const uint8_t *src= &glyph[y_offset*span + x_offset/8];
+        int n = w / 8; // bytes per line to copy
+        if(w % 8 != 0) n++; // round up to next byte
+        uint8_t g[n * h];
+        uint8_t *dst = g;
+        const uint8_t *src = &glyph[y_offset * span + x_offset / 8];
         for (int i = 0; i < h; ++i) {
             memcpy(dst, src, n);
-            dst+=n;
-            src+= span;
+            dst += n;
+            src += span;
         }
         renderGlyph(x, y, g, w, h);
     }
 }
 
-void ST7565::renderGlyph(int x, int y, const uint8_t *g, int w, int h) {
-    CLAMP(x, 0, LCDWIDTH-1);
-    CLAMP(y, 0, LCDHEIGHT-1);
+void ST7565::renderGlyph(int x, int y, const uint8_t *g, int w, int h)
+{
+    CLAMP(x, 0, LCDWIDTH - 1);
+    CLAMP(y, 0, LCDHEIGHT - 1);
     CLAMP(w, 0, LCDWIDTH - x);
     CLAMP(h, 0, LCDHEIGHT - y);
 
-    for(int i=0; i<w; i++){
-       for(int j=0; j<h; j++){
-        pixel(x+i,y+j,g[(i/8)+ j*((w-1)/8 +1)] & (1<<(7-i%8)));
-       }
+    for(int i = 0; i < w; i++) {
+        for(int j = 0; j < h; j++) {
+            pixel(x + i, y + j, g[(i / 8) + j * ((w - 1) / 8 + 1)] & (1 << (7 - i % 8)));
+        }
     }
 }
 
 void ST7565::pixel(int x, int y, int colour)
 {
     int page = y / 8;
-    unsigned char mask = 1<<(y%8);
-    unsigned char *byte = &framebuffer[page*LCDWIDTH + x];
+    unsigned char mask = 1 << (y % 8);
+    unsigned char *byte = &framebuffer[page * LCDWIDTH + x];
     if ( colour == 0 )
         *byte &= ~mask; // clear pixel
     else
@@ -378,10 +414,11 @@ void ST7565::pixel(int x, int y, int colour)
 }
 
 // cycle the buzzer pin at a certain frequency (hz) for a certain duration (ms)
-void ST7565::buzz(long duration, uint16_t freq) {
+void ST7565::buzz(long duration, uint16_t freq)
+{
     if(!this->buzz_pin.connected()) return;
 
-    duration *=1000; //convert from ms to us
+    duration *= 1000; //convert from ms to us
     long period = 1000000 / freq; // period in us
     long elapsed_time = 0;
     while (elapsed_time < duration) {
@@ -393,16 +430,41 @@ void ST7565::buzz(long duration, uint16_t freq) {
     }
 }
 
-void ST7565::setLed(int led, bool onoff) {
+void ST7565::setLed(int led, bool onoff)
+{
     if(!is_viki2) return;
 
-    if(led == LED_HOT){
+    if(led == LED_HOT) {
         if(onoff)  {
             red_led.set(true);
             blue_led.set(false);
-        }else{
+        } else {
             red_led.set(false);
             blue_led.set(true);
         }
     }
 }
+
+bool ST7565::mount_external_sd(bool on)
+{
+    // now setup the external sdcard if we have one and mount it
+    if(on) {
+        if(this->sd == nullptr) {
+            size_t n= sizeof(SDCard);
+            void *v = AHB0.alloc(n);
+            memset(v, 0, n); // clear the allocated memory
+            this->sd= new(v) SDCard(P0_18, P0_17, P0_15, P2_8); // allocate object using zeroed memory
+        }
+        delete this->extmounter; // if it was not unmounted before
+        size_t n= sizeof(SDFAT);
+        void *v = AHB0.alloc(n);
+        memset(v, 0, n); // clear the allocated memory
+        this->extmounter= new(v) SDFAT("ext", this->sd);
+        THEKERNEL->streams->printf("External SDcard mounted as /ext, size %d\n", n);
+    }else{
+        delete this->extmounter;
+        this->extmounter= nullptr;
+        THEKERNEL->streams->printf("External SDcard unmounted\n");
+    }
+    return true;
+}
index 4c29e0a..c935485 100644 (file)
@@ -12,6 +12,9 @@
 #include "mbed.h"
 #include "libs/Pin.h"
 
+class SDCard;
+class SDFAT;
+
 class ST7565: public LcdBase {
 public:
        ST7565(uint8_t v= 0);
@@ -55,6 +58,8 @@ public:
     void setLed(int led, bool onoff);
 
 private:
+    bool mount_external_sd(bool on);
+
     //buffer
        unsigned char *framebuffer;
        mbed::SPI* spi;
@@ -70,6 +75,10 @@ private:
     Pin encoder_b_pin;
     Pin red_led;
     Pin blue_led;
+    Pin sdcd_pin;
+
+    SDCard *sd;
+    SDFAT *extmounter;
 
        // text cursor position
        uint8_t tx, ty;