/ * Redistributions of source code must retain the above copyright notice.
/
/----------------------------------------------------------------------------*/
-\r
+
#ifndef _FATFS
#define _FATFS 8237 /* Revision ID */
-\r
+
#ifdef __cplusplus
extern "C" {
#endif
-\r
+
#include "integer.h" /* Basic integer types */
#include "ffconf.h" /* FatFs configuration options */
-\r
+
#if _FATFS != _FFCONF
#error Wrong configuration file (ffconf.h).
#endif
-\r
-\r
-\r
+
+
+
#define _DRIVES 4
/* Number of logical drives to be used. This affects the size of internal table. */
/* Definitions of volume management */
-\r
+
#if _MULTI_PARTITION /* Multiple partition configuration */
#define LD2PD(vol) (VolToPart[vol].pd) /* Get physical drive# */
#define LD2PT(vol) (VolToPart[vol].pt) /* Get partition# */
BYTE pt; /* Partition # (0-3) */
} PARTITION;
extern const PARTITION VolToPart[]; /* Volume - Physical location resolution table */
-\r
+
#else /* Single partition configuration */
#define LD2PD(vol) (vol) /* Logical drive# is bound to the same physical drive# */
#define LD2PT(vol) 0 /* Always mounts the 1st partition */
-\r
+
#endif
-\r
-\r
-\r
+
+
+
/* Type of path name strings on FatFs API */
-\r
+
#if _LFN_UNICODE /* Unicode string */
#if !_USE_LFN
#error _LFN_UNICODE must be 0 in non-LFN cfg.
#define _T(x) L ## x
#define _TEXT(x) L ## x
#endif
-\r
+
#else /* ANSI/OEM string */
#ifndef _INC_TCHAR
typedef char TCHAR;
#define _T(x) x
#define _TEXT(x) x
#endif
-\r
+
#endif
-\r
-\r
-\r
+
+
+
/* File system object structure (FATFS) */
-\r
+
typedef struct {
BYTE fs_type; /* FAT sub-type (0:Not mounted) */
BYTE drv; /* Physical drive number */
DWORD winsect; /* Current sector appearing in the win[] */
BYTE win[_MAX_SS]; /* Disk access window for Directory, FAT (and Data on tiny cfg) */
} FATFS;
-\r
-\r
-\r
+
+
+
/* File object structure (FIL) */
-\r
+
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
BYTE buf[_MAX_SS]; /* File data read/write buffer */
#endif
} FIL_t;
-\r
-\r
-\r
+
+
+
/* Directory object structure (DIR) */
-\r
+
typedef struct {
FATFS* fs; /* Pointer to the owner file system object */
WORD id; /* Owner file system mount ID */
WORD lfn_idx; /* Last matched LFN index number (0xFFFF:No LFN) */
#endif
} DIR_t;
-\r
-\r
-\r
+
+
+
/* File status structure (FILINFO) */
-\r
+
typedef struct {
DWORD fsize; /* File size */
WORD fdate; /* Last modified date */
UINT lfsize; /* Size of LFN buffer in TCHAR */
#endif
} FILINFO;
-\r
-\r
-\r
+
+
+
/* File function return code (FRESULT) */
-\r
+
typedef enum {
FR_OK = 0, /* (0) Succeeded */
FR_DISK_ERR, /* (1) A hard error occured in the low level disk I/O layer */
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
FR_TOO_MANY_OPEN_FILES /* (18) Number of open files > _FS_SHARE */
} FRESULT;
-\r
-\r
-\r
+
+
+
/*--------------------------------------------------------------*/
/* FatFs module application interface */
-\r
+
FRESULT f_mount (BYTE, FATFS*); /* Mount/Unmount a logical drive */
FRESULT f_open (FIL_t*, const TCHAR*, BYTE); /* Open or create a file */
FRESULT f_read (FIL_t*, void*, UINT, UINT*); /* Read data from a file */
int f_puts (const TCHAR*, FIL_t*); /* Put a string to the file */
int f_printf (FIL_t*, const TCHAR*, ...); /* Put a formatted string to the file */
TCHAR* f_gets (TCHAR*, int, FIL_t*); /* Get a string from the file */
-\r
+
#ifndef EOF
#define EOF (-1)
#endif
-\r
+
#define f_eof(fp) (((fp)->fptr == (fp)->fsize) ? 1 : 0)
#define f_error(fp) (((fp)->flag & FA__ERROR) ? 1 : 0)
#define f_tell(fp) ((fp)->fptr)
#define f_size(fp) ((fp)->fsize)
-\r
-\r
-\r
-\r
+
+
+
+
/*--------------------------------------------------------------*/
/* Additional user defined functions */
-\r
+
/* RTC function */
#if !_FS_READONLY
DWORD get_fattime (void);
#endif
-\r
+
/* Unicode support functions */
#if _USE_LFN /* Unicode - OEM code conversion */
WCHAR ff_convert (WCHAR, UINT); /* OEM-Unicode bidirectional conversion */
void ff_memfree (void*); /* Free memory block */
#endif
#endif
-\r
+
/* Sync functions */
#if _FS_REENTRANT
int ff_cre_syncobj (BYTE, _SYNC_t*);/* Create a sync object */
void ff_rel_grant (_SYNC_t); /* Unlock sync object */
int ff_del_syncobj (_SYNC_t); /* Delete a sync object */
#endif
-\r
-\r
-\r
-\r
+
+
+
+
/*--------------------------------------------------------------*/
/* Flags and offset address */
-\r
-\r
+
+
/* File access control and file status flags (FIL.flag) */
-\r
+
#define FA_READ 0x01
#define FA_OPEN_EXISTING 0x00
#define FA__ERROR 0x80
-\r
+
#if !_FS_READONLY
#define FA_WRITE 0x02
#define FA_CREATE_NEW 0x04
#define FA__WRITTEN 0x20
#define FA__DIRTY 0x40
#endif
-\r
-\r
+
+
/* FAT sub type (FATFS.fs_type) */
-\r
+
#define FS_FAT12 1
#define FS_FAT16 2
#define FS_FAT32 3
-\r
-\r
+
+
/* File attribute bits for directory entry */
-\r
+
#define AM_RDO 0x01 /* Read only */
#define AM_HID 0x02 /* Hidden */
#define AM_SYS 0x04 /* System */
#define AM_DIR 0x10 /* Directory */
#define AM_ARC 0x20 /* Archive */
#define AM_MASK 0x3F /* Mask of defined bits */
-\r
-\r
+
+
/* Fast seek function */
#define CREATE_LINKMAP 0xFFFFFFFF
-\r
-\r
-\r
+
+
+
/*--------------------------------*/
/* Multi-byte word access macros */
-\r
+
#if _WORD_ACCESS == 1 /* Enable word access to the FAT structure */
#define LD_WORD(ptr) (WORD)(*(WORD*)(BYTE*)(ptr))
#define LD_DWORD(ptr) (DWORD)(*(DWORD*)(BYTE*)(ptr))
#define ST_WORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8)
#define ST_DWORD(ptr,val) *(BYTE*)(ptr)=(BYTE)(val); *((BYTE*)(ptr)+1)=(BYTE)((WORD)(val)>>8); *((BYTE*)(ptr)+2)=(BYTE)((DWORD)(val)>>16); *((BYTE*)(ptr)+3)=(BYTE)((DWORD)(val)>>24)
#endif
-\r
+
#ifdef __cplusplus
}
#endif
-\r
+
#endif /* _FATFS */
int stringSize = 0;
#if _USE_LFN
fn = *finfo.lfname ? finfo.lfname : finfo.fname;
- stringSize = finfo.lfsize;
+ stringSize = *finfo.lfname ? finfo.lfsize : sizeof(finfo.fname);
#else
fn = fno.fname;
stringSize = sizeof(finfo.fname);
#include "gpio.h"\r
\r
#include "disk.h"\r
+#include "mbed.h"\r
\r
// #include "DMA.h"\r
\r
* @param name The name used to access the virtual filesystem\r
*/\r
SDCard(PinName, PinName, PinName, PinName);\r
+ virtual ~SDCard() {};\r
\r
typedef enum {\r
SDCARD_FAIL,\r
uint32_t _sd_sectors();\r
uint32_t _sectors;\r
\r
- ::SPI _spi;\r
+ mbed::SPI _spi;\r
GPIO _cs;\r
\r
volatile bool busyflag;\r
#include "libs/nuts_bolts.h"
#include "libs/utils.h"
#include "Button.h"
+#include "libs/USBDevice/USBMSD/SDCard.h"
+#include "libs/SDFAT.h"
#include "modules/utils/player/PlayerPublicAccess.h"
#include "screens/CustomScreen.h"
#include "ModifyValuesScreen.h"
#include "PublicDataRequest.h"
#include "PublicData.h"
+#include "StreamOutputPool.h"
+#include "platform_memory.h"
#include "panels/ReprapDiscountGLCD.h"
#include "panels/ST7565.h"
#include "ConfigValue.h"
#include "Config.h"
+// for parse_pins in mbed
+#include "pinmap.h"
+
#define panel_checksum CHECKSUM("panel")
#define enable_checksum CHECKSUM("enable")
#define lcd_checksum CHECKSUM("lcd")
#define jog_z_feedrate_checksum CHECKSUM("gamma_jog_feedrate")
#define longpress_delay_checksum CHECKSUM("longpress_delay")
+#define ext_sd_checksum CHECKSUM("external_sd")
+#define sdcd_pin_checksum CHECKSUM("sdcd_pin")
+#define spi_channel_checksum CHECKSUM("spi_channel")
+#define spi_cs_pin_checksum CHECKSUM("spi_cs_pin")
+
#define hotend_temp_checksum CHECKSUM("hotend_temperature")
#define bed_temp_checksum CHECKSUM("bed_temperature")
this->idle_time = 0;
this->start_up = true;
this->current_screen = NULL;
+ this->sd= nullptr;
+ this->extmounter= nullptr;
+ this->external_sd_enable= false;
strcpy(this->playing_file, "Playing file");
}
Panel::~Panel()
{
delete this->lcd;
+ delete this->extmounter;
+ delete this->sd;
}
void Panel::on_module_loaded()
return;
}
+ // external sd
+ if(THEKERNEL->config->value( panel_checksum, ext_sd_checksum )->by_default(false)->as_bool()) {
+ this->external_sd_enable= true;
+ // external sdcard detect
+ this->sdcd_pin.from_string(THEKERNEL->config->value( panel_checksum, ext_sd_checksum, sdcd_pin_checksum )->by_default("nc")->as_string())->as_input();
+ this->extsd_spi_channel = THEKERNEL->config->value(panel_checksum, ext_sd_checksum, spi_channel_checksum)->by_default(0)->as_number();
+ string s= THEKERNEL->config->value( panel_checksum, ext_sd_checksum, spi_cs_pin_checksum)->by_default("2.8")->as_string();
+ s= "P" + s; // Pinnames need to be Px_x
+ this->extsd_spi_cs= parse_pins(s.c_str());
+ this->register_for_event(ON_SECOND_TICK);
+ }
+
// these need to be called here as they need the config cache loaded as they enumerate modules
this->custom_screen= new CustomScreen();
setup_temperature_screen();
this->temperature_screen= nullptr;
}
}
+
+bool Panel::mount_external_sd(bool on)
+{
+ // now setup the external sdcard if we have one and mount it
+ if(on) {
+ if(this->sd == nullptr) {
+ PinName mosi, miso, sclk, cs= this->extsd_spi_cs;
+ if(extsd_spi_channel == 0) {
+ mosi = P0_18; miso = P0_17; sclk = P0_15;
+ } else if(extsd_spi_channel == 1) {
+ mosi = P0_9; miso = P0_8; sclk = P0_7;
+ } else{
+ this->external_sd_enable= false;
+ THEKERNEL->streams->printf("Bad SPI channel for external SDCard\n");
+ return false;
+ }
+ size_t n= sizeof(SDCard);
+ void *v = AHB0.alloc(n);
+ memset(v, 0, n); // clear the allocated memory
+ this->sd= new(v) SDCard(mosi, miso, sclk, cs); // 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); // use cleared allocated memory
+ this->sd->disk_initialize(); // first one seems to fail, but works next time
+ THEKERNEL->streams->printf("External SDcard mounted as /ext\n");
+ }else{
+ delete this->extmounter;
+ this->extmounter= nullptr;
+ THEKERNEL->streams->printf("External SDcard unmounted\n");
+ }
+ return true;
+}
+
+void Panel::on_second_tick(void *arg)
+{
+ if(!this->external_sd_enable) return;
+
+ // 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);
+ // go to the play screen and the /ext directory
+ THEKERNEL->current_path= "/ext";
+ MainMenuScreen *mms= static_cast<MainMenuScreen*>(this->top_screen);
+ THEPANEL->enter_screen(mms->file_screen);
+
+ }else if(this->extmounter != nullptr && !this->sdcd_pin.get()){
+ mount_external_sd(false);
+ }
+ }else{
+ // TODO for panels with no sd card detect we need to poll to see if card is inserted - or not
+ }
+}
#define PANEL_H
#include "Button.h"
+#include "Pin.h"
+#include "mbed.h"
#include <string>
using std::string;
class LcdBase;
class PanelScreen;
+class SDCard;
+class SDFAT;
class Panel : public Module {
public:
void on_idle(void* argument);
void on_main_loop(void* argument);
void on_gcode_received(void* argument);
+ void on_second_tick(void* argument);
void enter_screen(PanelScreen* screen);
void reset_counter();
private:
void setup_temperature_screen();
+ // external SD card
+ bool mount_external_sd(bool on);
+ Pin sdcd_pin;
+ uint8_t extsd_spi_channel;
+ PinName extsd_spi_cs;
+ SDCard *sd;
+ SDFAT *extmounter;
+
// Menu
int menu_selected_line;
int menu_start_line;
bool start_up:1;
bool menu_changed:1;
bool control_value_changed:1;
+ bool external_sd_enable:1;
volatile bool counter_changed:1;
volatile bool click_changed:1;
volatile bool refresh_flag:1;
// select which SPI channel to use
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;
- }
-
- this->glcd= new RrdGlcd(mosi, sclk, this->spi_cs_pin);
+ this->glcd= new RrdGlcd(spi_channel, this->spi_cs_pin);
int spi_frequency = THEKERNEL->config->value(panel_checksum, spi_frequency_checksum)->by_default(1000000)->as_number();
this->glcd->setFrequency(spi_frequency);
#include "StreamOutputPool.h"
#include "ConfigValue.h"
-#include "libs/USBDevice/USBMSD/SDCard.h"
-#include "libs/SDFAT.h"
+
//definitions for lcd
#define LCDWIDTH 128
#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")
//SPI com
// select which SPI channel to use
int spi_channel = THEKERNEL->config->value(panel_checksum, spi_channel_checksum)->by_default(0)->as_number();
- PinName mosi;
- PinName sclk;
+ PinName mosi, miso, sclk;
if(spi_channel == 0) {
- mosi = P0_18; sclk = P0_15;
+ mosi = P0_18; miso = P0_17; sclk = P0_15;
} else if(spi_channel == 1) {
- mosi = P0_9; sclk = P0_7;
+ mosi = P0_9; miso = P0_8; sclk = P0_7;
} else {
- mosi = P0_18; sclk = P0_15;
+ mosi = P0_18; miso = P0_17; sclk = P0_15;
}
- this->spi = new mbed::SPI(mosi, NC, sclk);
+ this->spi = new mbed::SPI(mosi, miso, 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
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();
THEKERNEL->streams->printf("Not enough memory available for frame buffer");
}
- this->sd= nullptr;
- this->extmounter= nullptr;
}
ST7565::~ST7565()
{
delete this->spi;
AHB0.dealloc(framebuffer);
- delete this->extmounter;
}
//send commands to lcd
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;
}
}
}
-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;
-}
#include "mbed.h"
#include "libs/Pin.h"
-class SDCard;
-class SDFAT;
-
class ST7565: public LcdBase {
public:
ST7565(uint8_t v= 0);
void setLed(int led, bool onoff);
private:
- bool mount_external_sd(bool on);
//buffer
unsigned char *framebuffer;
Pin encoder_b_pin;
Pin red_led;
Pin blue_led;
- Pin sdcd_pin;
-
- SDCard *sd;
- SDFAT *extmounter;
// text cursor position
uint8_t tx, ty;
// select which SPI channel to use
int spi_channel = THEKERNEL->config->value(panel_checksum, spi_channel_checksum)->by_default(0)->as_number();
- PinName mosi;
- PinName miso;
- PinName sclk;
+ PinName mosi, miso, sclk;
if(spi_channel == 0) {
mosi = P0_18; miso = P0_17; sclk = P0_15;
} else if(spi_channel == 1) {
#define HEIGHT 64
#define FB_SIZE WIDTH*HEIGHT/8
-RrdGlcd::RrdGlcd(PinName mosi, PinName sclk, Pin cs) {
- this->spi= new mbed::SPI(mosi, NC, sclk);
- //chip select
+RrdGlcd::RrdGlcd(int spi_channel, Pin cs) {
+ PinName mosi, miso, sclk;
+ if(spi_channel == 0) {
+ mosi = P0_18; miso = P0_17; sclk = P0_15;
+ } else if(spi_channel == 1) {
+ mosi = P0_9; miso = P0_8; sclk = P0_7;
+ } else {
+ mosi = P0_18; miso = P0_17; sclk = P0_15;
+ }
+
+ this->spi = new mbed::SPI(mosi, miso, sclk);
+
+ //chip select
this->cs= cs;
this->cs.set(0);
fb= (uint8_t *)AHB0.alloc(FB_SIZE); // grab some memoery from USB_RAM
*@param cd Smoothie Pin for cs
*@return none
*/
- RrdGlcd (PinName mosi, PinName sclk, Pin cs);
+ RrdGlcd (int spi_channel, Pin cs);
virtual ~RrdGlcd();
THEPANEL->lcd->clear();
// Default folder to enter
- this->enter_folder("/");
+ this->enter_folder(THEKERNEL->current_path.c_str());
}
void FileScreen::on_exit()
{
- // reset to root directory, I'd prefer not to do this but it crashes on entry next time if it doesn't start at root
+ // reset to root directory, I think this is less confusing
THEKERNEL->current_path= "/";
}