More improvements to the LCD screen.

master
Marcio Teixeira 7 years ago
parent ea78124172
commit ec3f4b5e56

@ -628,6 +628,69 @@ namespace FTDI {
const uint32_t CMD_LOGO = 0xFFFFFF31; const uint32_t CMD_LOGO = 0xFFFFFF31;
} }
namespace FTDI {
enum effect_t {
SILENCE = 0x00,
SQUARE_WAVE = 0x01,
SINE_WAVE = 0x02,
SAWTOOTH_WAVE = 0x03,
TRIANGLE_WAVE = 0x04,
BEEPING = 0x05,
ALARM = 0x06,
WARBLE = 0x07,
CAROUSEL = 0x08,
SHORT_PIPS_1 = 0x10,
SHORT_PIPS_2 = 0x11,
SHORT_PIPS_3 = 0x12,
SHORT_PIPS_4 = 0x13,
SHORT_PIPS_5 = 0x14,
SHORT_PIPS_6 = 0x15,
SHORT_PIPS_7 = 0x16,
SHORT_PIPS_8 = 0x17,
SHORT_PIPS_9 = 0x18,
SHORT_PIPS_10 = 0x19,
SHORT_PIPS_11 = 0x1A,
SHORT_PIPS_12 = 0x1B,
SHORT_PIPS_13 = 0x1C,
SHORT_PIPS_14 = 0x1D,
SHORT_PIPS_15 = 0x1E,
SHORT_PIPS_16 = 0x1F,
DTMF_POUND = 0x23,
DTMF_STAR = 0x2C,
DTMF_0 = 0x30,
DTMF_1 = 0x31,
DTMF_2 = 0x32,
DTMF_3 = 0x33,
DTMF_4 = 0x34,
DTMF_5 = 0x35,
DTMF_6 = 0x36,
DTMF_7 = 0x37,
DTMF_8 = 0x38,
DTMF_9 = 0x39,
HARP = 0x40,
XYLOPHONE = 0x41,
TUBA = 0x42,
GLOCKENSPIEL = 0x43,
ORGAN = 0x44,
TRUMPET = 0x45,
PIANO = 0x46,
CHIMES = 0x47,
MUSIC_BOX = 0x48,
BELL = 0x49,
CLICK = 0x50,
SWITCH = 0x51,
COWBELL = 0x52,
NOTCH = 0x53,
HIHAT = 0x54,
KICKDRUM = 0x55,
POP = 0x56,
CLACK = 0x57,
CHACK = 0x58,
MUTE = 0x60,
UNMUTE = 0x61
};
}
// If LCD_IS_FT800 is defined, then copy the FT800 namespace into the FTDI namespace // If LCD_IS_FT800 is defined, then copy the FT800 namespace into the FTDI namespace
// If LCD_IS_FT810 is defined, then copy the FT810 namespace into the FTDI namespace // If LCD_IS_FT810 is defined, then copy the FT810 namespace into the FTDI namespace

@ -160,96 +160,9 @@ class CLCD {
const uint16_t height; const uint16_t height;
} bitmap_info_t; } bitmap_info_t;
class CommandFifo { class CommandFifo;
protected: class SoundPlayer;
static uint32_t getRegCmdWrite(); class DLCache;
static uint32_t getRegCmdRead();
#if defined(LCD_IS_FT800)
static uint32_t command_write_ptr;
template <class T> void _write_unaligned(T data, uint16_t len);
#else
uint32_t getRegCmdBSpace();
#endif
void Cmd_Start(void);
public:
template <class T> void write(T data, uint16_t len);
public:
CommandFifo() {Cmd_Start();}
static void Cmd_Reset (void);
static bool Cmd_Is_Idle();
static void Cmd_Wait_Until_Idle();
void Cmd_Execute(void);
void Cmd (uint32_t cmd32);
void Cmd (void* data, uint16_t len);
void Cmd_Str (char* data);
void Cmd_Str (progmem_str data);
void Cmd_Clear_Color (uint32_t rgb);
void Cmd_Clear (bool Clr, bool Stl, bool Tag);
void Cmd_Color (uint32_t rgb);
void Cmd_Set_Foreground_Color (uint32_t rgb);
void Cmd_Set_Background_Color (uint32_t rgb);
void Cmd_Set_Tag (uint8_t Tag);
void Cmd_Bitmap_Source (uint32_t RAM_G_Addr);
// The following functions *must* be inlined since we are relying on the compiler to do
// substitution of the constants from the data structure rather than actually storing
// it in PROGMEM (which would fail, since we are not using pgm_read_near to read them).
// Plus, by inlining, all the equations are evaluated at compile-time as everything
// should be a constant.
FORCEDINLINE void Cmd_Bitmap_Source (const bitmap_info_t& info) {Cmd_Bitmap_Source (info.RAMG_addr);};
FORCEDINLINE void Cmd_Bitmap_Layout (const bitmap_info_t& info) {Cmd_Bitmap_Layout (info.format, info.linestride, info.height);};
FORCEDINLINE void Cmd_Bitmap_Size(const bitmap_info_t& info) {Cmd_Bitmap_Size (info.filter, info.wrapx, info.wrapy, info.width, info.height);}
FORCEDINLINE void Cmd_Draw_Button_Icon(int16_t x, int16_t y, int16_t w, int16_t h, const bitmap_info_t& info, const float scale = 1) {
Cmd_Begin(BEGIN_BITMAPS);
if(scale != 1) {
Cmd(BITMAP_TRANSFORM_A | uint32_t(float(256)/scale) & 0xFFFF);
Cmd(BITMAP_TRANSFORM_E | uint32_t(float(256)/scale) & 0xFFFF);
}
Cmd_Bitmap_Size(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale);
Cmd_Vertex_2F((x + w/2 - info.width*scale/2)*16, (y + h/2 - info.height*scale/2)*16);
if(scale != 1) {
Cmd(BITMAP_TRANSFORM_A | 256);
Cmd(BITMAP_TRANSFORM_E | 256);
}
}
template<typename T> FORCEDINLINE void Cmd_Draw_Button_Text(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font) {
Cmd_Draw_Text(x + w/2, y + h/2, text, font, OPT_CENTER);
}
void Cmd_Bitmap_Layout (uint8_t format, uint16_t linestride, uint16_t height);
void Cmd_Bitmap_Size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height);
void Cmd_Bitmap_Handle (uint16_t Handle);
void Cmd_Begin (uint32_t Primitive);
void Cmd_Vertex_2F (uint16_t X_Coord, uint16_t Y_Coord);
void Cmd_Vertex_2II (uint16_t X_Coord, uint16_t Y_Coord, uint8_t B_Handle, uint8_t Cell);
template<typename T> void Cmd_Draw_Button(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font, uint16_t option);
template<typename T> void Cmd_Draw_Text(int16_t x, int16_t y, T text, int16_t font, uint16_t options);
void Cmd_Draw_Clock (int16_t x, int16_t y, int16_t r, uint16_t option, int16_t h, int16_t m, int16_t s, int16_t ms);
void Cmd_Draw_Progress_Bar (int16_t x, int16_t y, int16_t w, int16_t h, int16_t val, int16_t range);
void Cmd_Draw_Slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
void Cmd_Mem_Cpy (uint32_t dst, uint32_t src, uint32_t size);
void Cmd_Append (uint32_t ptr, uint32_t size);
};
class DLCache {
private:
static uint16_t dl_free;
uint16_t dl_addr = 0;
uint16_t dl_size = 0;
public:
bool hasData();
void store();
void append();
};
public: public:
static void Init (void); static void Init (void);
@ -330,122 +243,87 @@ void CLCD::Flash_Write_RGB332_Bitmap(uint32_t Mem_Address, const unsigned char*
} }
} }
uint8_t Device_ID; /******************* FT800/810 Graphic Commands *********************************/
void CLCD::Init (void) {
spiInit(); // Set Up I/O Lines for SPI and FT800/810 Control
delay(50);
Reset(); // Power Down the FT800/810 for 50 ms
delay(50);
/*
* If driving the 4D Systems 4DLCD-FT843 Board, the following Init sequence is needed for its FT800 Driver
*/
#ifdef LCD_IS_FT800 // Use External Crystal and 48 MHz System Clock
Host_Cmd(CLKEXT, 0);
delay(20);
Host_Cmd(CLK48M, 0);
#else
Host_Cmd(CLKINT, 0);
delay(20);
Host_Cmd(CLKSEL, Clksel); // Use Internal RC Oscillator and 48 MHz System Clock
#endif
delay(20);
Host_Cmd(ACTIVE, 0); // Activate the System Clock class CLCD::CommandFifo {
delay(50); protected:
static uint32_t getRegCmdWrite();
static uint32_t getRegCmdRead();
delay(400); #if defined(LCD_IS_FT800)
Device_ID = Mem_Read8(REG_ID); // Read Device ID, Should Be 0x7C; static uint32_t command_write_ptr;
#if defined(UI_FRAMEWORK_DEBUG) template <class T> void _write_unaligned(T data, uint16_t len);
if(Device_ID != 0x7C) {
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Incorrect device ID, should be 7C, got ", Device_ID);
#else
Serial.print(F("Incorrect device ID, should be 7C, got "));
Serial.println(Device_ID, HEX);
#endif
} else {
#if defined (SERIAL_PROTOCOLLNPGM)
SERIAL_PROTOCOLLNPGM("Device is correct ");
#else #else
Serial.println(F("Device is correct ")); uint32_t getRegCmdBSpace();
#endif
}
#endif #endif
delay(400); void Cmd_Start(void);
Mem_Write8(REG_GPIO, 0x00); // Turn OFF Display Enable (GPIO Bit 7);
Mem_Write8(REG_PCLK, 0x00); // Turn OFF LCD PCLK
Set_Backlight(0x00FA, 0);
/* public:
* Configure the FT800/810 Registers template <class T> void write(T data, uint16_t len);
*/
Mem_Write16(REG_HCYCLE, Hcycle); public:
Mem_Write16(REG_HOFFSET, Hoffset); CommandFifo() {Cmd_Start();}
Mem_Write16(REG_HSYNC0, Hsync0);
Mem_Write16(REG_HSYNC1, Hsync1);
Mem_Write16(REG_VCYCLE, Vcycle);
Mem_Write16(REG_VOFFSET, Voffset);
Mem_Write16(REG_VSYNC0, Vsync0);
Mem_Write16(REG_VSYNC1, Vsync1);
Mem_Write16(REG_HSIZE, Hsize);
Mem_Write16(REG_VSIZE, Vsize);
Mem_Write8(REG_SWIZZLE, Swizzle);
Mem_Write8(REG_PCLK_POL, Pclkpol);
Mem_Write8(REG_CSPREAD, 1);
#if defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN) static void Cmd_Reset (void);
Mem_Write8(REG_ROTATE, 3); static bool Cmd_Is_Idle();
#elif defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN) static void Cmd_Wait_Until_Idle();
Mem_Write8(REG_ROTATE, 2);
#elif !defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 1);
#else !defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 0);
#endif
Mem_Write8(REG_TOUCH_MODE, 0x03); // Configure the Touch Screen void Cmd_Execute(void);
Mem_Write8(REG_TOUCH_ADC_MODE, 0x01);
Mem_Write8(REG_TOUCH_OVERSAMPLE, 0x0F);
Mem_Write16(REG_TOUCH_RZTHRESH, 5000);
Mem_Write8(REG_VOL_SOUND, 0x00); // Turn Synthesizer Volume Off
Mem_Write8(REG_DLSWAP, 0x02); // Swap on New Frame
/* void Cmd (uint32_t cmd32);
* Turn On the Display void Cmd (void* data, uint16_t len);
*/ void Cmd_Str (char* data);
#if defined(LCD_IS_FT800) void Cmd_Str (progmem_str data);
Mem_Write8(REG_GPIO_DIR, 0x80); // Turn ON Display Enable void Cmd_Clear_Color (uint32_t rgb);
Mem_Write8(REG_GPIO, 0x80); void Cmd_Clear (bool Clr, bool Stl, bool Tag);
#else void Cmd_Color (uint32_t rgb);
Mem_Write16(REG_GPIOX_DIR, 1 << 15); // Turn ON Display Enable void Cmd_Set_Foreground_Color (uint32_t rgb);
Mem_Write16(REG_GPIOX, 1 << 15); void Cmd_Set_Background_Color (uint32_t rgb);
#endif void Cmd_Set_Tag (uint8_t Tag);
void Cmd_Bitmap_Source (uint32_t RAM_G_Addr);
Enable(); // Turns on Clock by setting PCLK Register to 5 // The following functions *must* be inlined since we are relying on the compiler to do
delay(50); // substitution of the constants from the data structure rather than actually storing
// it in PROGMEM (which would fail, since we are not using pgm_read_near to read them).
// Plus, by inlining, all the equations are evaluated at compile-time as everything
// should be a constant.
CommandFifo::Cmd_Reset(); FORCEDINLINE void Cmd_Bitmap_Source (const bitmap_info_t& info) {Cmd_Bitmap_Source (info.RAMG_addr);};
delay(50); FORCEDINLINE void Cmd_Bitmap_Layout (const bitmap_info_t& info) {Cmd_Bitmap_Layout (info.format, info.linestride, info.height);};
FORCEDINLINE void Cmd_Bitmap_Size(const bitmap_info_t& info) {Cmd_Bitmap_Size (info.filter, info.wrapx, info.wrapy, info.width, info.height);}
FORCEDINLINE void Cmd_Draw_Button_Icon(int16_t x, int16_t y, int16_t w, int16_t h, const bitmap_info_t& info, const float scale = 1) {
Cmd_Begin(BEGIN_BITMAPS);
if(scale != 1) {
Cmd(BITMAP_TRANSFORM_A | uint32_t(float(256)/scale) & 0xFFFF);
Cmd(BITMAP_TRANSFORM_E | uint32_t(float(256)/scale) & 0xFFFF);
}
Cmd_Bitmap_Size(info.filter, info.wrapx, info.wrapy, info.width*scale, info.height*scale);
Cmd_Vertex_2F((x + w/2 - info.width*scale/2)*16, (y + h/2 - info.height*scale/2)*16);
if(scale != 1) {
Cmd(BITMAP_TRANSFORM_A | 256);
Cmd(BITMAP_TRANSFORM_E | 256);
}
}
template<typename T> FORCEDINLINE void Cmd_Draw_Button_Text(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font) {
Cmd_Draw_Text(x + w/2, y + h/2, text, font, OPT_CENTER);
}
// Set Initial Values for Touch Transform Registers void Cmd_Bitmap_Layout (uint8_t format, uint16_t linestride, uint16_t height);
void Cmd_Bitmap_Size(uint8_t filter, uint8_t wrapx, uint8_t wrapy, uint16_t width, uint16_t height);
void Cmd_Bitmap_Handle (uint16_t Handle);
void Cmd_Begin (uint32_t Primitive);
void Cmd_Vertex_2F (uint16_t X_Coord, uint16_t Y_Coord);
void Cmd_Vertex_2II (uint16_t X_Coord, uint16_t Y_Coord, uint8_t B_Handle, uint8_t Cell);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_A, default_transform_a); template<typename T> void Cmd_Draw_Button(int16_t x, int16_t y, int16_t w, int16_t h, T text, int16_t font, uint16_t option);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_B, default_transform_b); template<typename T> void Cmd_Draw_Text(int16_t x, int16_t y, T text, int16_t font, uint16_t options);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_C, default_transform_c);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_D, default_transform_d);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_E, default_transform_e);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_F, default_transform_f);
}
/******************* FT800/810 Graphic Commands *********************************/ void Cmd_Draw_Clock (int16_t x, int16_t y, int16_t r, uint16_t option, int16_t h, int16_t m, int16_t s, int16_t ms);
void Cmd_Draw_Progress_Bar (int16_t x, int16_t y, int16_t w, int16_t h, int16_t val, int16_t range);
void Cmd_Draw_Slider (int16_t x, int16_t y, int16_t w, int16_t h, uint16_t options, uint16_t val, uint16_t range);
void Cmd_Mem_Cpy (uint32_t dst, uint32_t src, uint32_t size);
void Cmd_Append (uint32_t ptr, uint32_t size);
};
#if defined(LCD_IS_FT800) #if defined(LCD_IS_FT800)
uint32_t CLCD::CommandFifo::command_write_ptr = 0xFFFFFFFFul; uint32_t CLCD::CommandFifo::command_write_ptr = 0xFFFFFFFFul;
@ -709,6 +587,17 @@ void CLCD::CommandFifo::Cmd_Append (uint32_t ptr, uint32_t size)
* } * }
*/ */
class CLCD::DLCache {
private:
static uint16_t dl_free;
uint16_t dl_addr = 0;
uint16_t dl_size = 0;
public:
bool hasData();
void store();
void append();
};
uint16_t CLCD::DLCache::dl_free = 0; uint16_t CLCD::DLCache::dl_free = 0;
bool CLCD::DLCache::hasData() { bool CLCD::DLCache::hasData() {
@ -780,6 +669,192 @@ void CLCD::DLCache::append() {
#endif #endif
} }
/******************* LCD INITIALIZATION ************************/
void CLCD::Init (void) {
spiInit(); // Set Up I/O Lines for SPI and FT800/810 Control
delay(50);
Reset(); // Power Down the FT800/810 for 50 ms
delay(50);
/*
* If driving the 4D Systems 4DLCD-FT843 Board, the following Init sequence is needed for its FT800 Driver
*/
#ifdef LCD_IS_FT800 // Use External Crystal and 48 MHz System Clock
Host_Cmd(CLKEXT, 0);
delay(20);
Host_Cmd(CLK48M, 0);
#else
Host_Cmd(CLKINT, 0);
delay(20);
Host_Cmd(CLKSEL, Clksel); // Use Internal RC Oscillator and 48 MHz System Clock
#endif
delay(20);
Host_Cmd(ACTIVE, 0); // Activate the System Clock
delay(50);
delay(400);
uint8_t Device_ID = Mem_Read8(REG_ID); // Read Device ID, Should Be 0x7C;
#if defined(UI_FRAMEWORK_DEBUG)
if(Device_ID != 0x7C) {
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Incorrect device ID, should be 7C, got ", Device_ID);
#else
Serial.print(F("Incorrect device ID, should be 7C, got "));
Serial.println(Device_ID, HEX);
#endif
} else {
#if defined (SERIAL_PROTOCOLLNPGM)
SERIAL_PROTOCOLLNPGM("Device is correct ");
#else
Serial.println(F("Device is correct "));
#endif
}
#endif
delay(400);
Mem_Write8(REG_GPIO, 0x00); // Turn OFF Display Enable (GPIO Bit 7);
Mem_Write8(REG_PCLK, 0x00); // Turn OFF LCD PCLK
Set_Backlight(0x00FA, 0);
/*
* Configure the FT800/810 Registers
*/
Mem_Write16(REG_HCYCLE, Hcycle);
Mem_Write16(REG_HOFFSET, Hoffset);
Mem_Write16(REG_HSYNC0, Hsync0);
Mem_Write16(REG_HSYNC1, Hsync1);
Mem_Write16(REG_VCYCLE, Vcycle);
Mem_Write16(REG_VOFFSET, Voffset);
Mem_Write16(REG_VSYNC0, Vsync0);
Mem_Write16(REG_VSYNC1, Vsync1);
Mem_Write16(REG_HSIZE, Hsize);
Mem_Write16(REG_VSIZE, Vsize);
Mem_Write8(REG_SWIZZLE, Swizzle);
Mem_Write8(REG_PCLK_POL, Pclkpol);
Mem_Write8(REG_CSPREAD, 1);
#if defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 3);
#elif defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 2);
#elif !defined(LCD_PORTRAIT) && defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 1);
#else !defined(LCD_PORTRAIT) && !defined(LCD_UPSIDE_DOWN)
Mem_Write8(REG_ROTATE, 0);
#endif
Mem_Write8(REG_TOUCH_MODE, 0x03); // Configure the Touch Screen
Mem_Write8(REG_TOUCH_ADC_MODE, 0x01);
Mem_Write8(REG_TOUCH_OVERSAMPLE, 0x0F);
Mem_Write16(REG_TOUCH_RZTHRESH, 5000);
Mem_Write8(REG_VOL_SOUND, 0x00); // Turn Synthesizer Volume Off
Mem_Write8(REG_DLSWAP, 0x02); // Swap on New Frame
/*
* Turn On the Display
*/
#if defined(LCD_IS_FT800)
Mem_Write8(REG_GPIO_DIR, 0x80); // Turn ON Display Enable
Mem_Write8(REG_GPIO, 0x80);
#else
Mem_Write16(REG_GPIOX_DIR, 1 << 15); // Turn ON Display Enable
Mem_Write16(REG_GPIOX, 1 << 15);
#endif
Enable(); // Turns on Clock by setting PCLK Register to 5
delay(50);
CommandFifo::Cmd_Reset();
delay(50);
// Set Initial Values for Touch Transform Registers
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_A, default_transform_a);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_B, default_transform_b);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_C, default_transform_c);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_D, default_transform_d);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_E, default_transform_e);
CLCD::Mem_Write32(REG_TOUCH_TRANSFORM_F, default_transform_f);
}
/******************* SOUND HELPER CLASS ************************/
class CLCD::SoundPlayer {
public:
struct sound_t {
effect_t effect; // The sound effect number
uint8_t note; // The MIDI note value
uint8_t sixteenths; // Duration of note, in sixteeths of a second, or zero to play to completion
};
private:
const sound_t *sequence;
uint32_t next;
public:
static const uint8_t MIDDLE_C = 60; // C4
static void setVolume(uint8_t volume);
static void play(effect_t effect, uint8_t note = MIDDLE_C);
static bool soundPlaying();
void play(const sound_t* seq);
void onIdle();
};
void CLCD::SoundPlayer::setVolume(uint8_t vol) {
CLCD::Mem_Write8(REG_VOL_SOUND, vol);
}
void CLCD::SoundPlayer::play(effect_t effect, uint8_t note) {
CLCD::Mem_Write16(REG_SOUND, (note << 8) | effect);
CLCD::Mem_Write8( REG_PLAY, 1);
#if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLPAIR("Playing note ", note);
SERIAL_PROTOCOLLNPAIR(", instrument ", effect);
#endif
#endif
}
void CLCD::SoundPlayer::play(const sound_t* seq) {
sequence = seq;
next = 0;
}
bool CLCD::SoundPlayer::soundPlaying() {
return CLCD::Mem_Read8( REG_PLAY ) & 0x1;
}
void CLCD::SoundPlayer::onIdle() {
if(!sequence) return;
const bool readyForNextNote = next != 0 ? (millis() > next) : !soundPlaying();
if(readyForNextNote) {
const effect_t fx = effect_t(pgm_read_byte_near(&sequence->effect));
const uint8_t nt = pgm_read_byte_near(&sequence->note);
const uint16_t ms = uint32_t(pgm_read_byte_near(&sequence->sixteenths)) * 1000 / 16;
if(ms == 0 && fx == SILENCE && nt == 0) {
sequence = 0;
} else {
next = ms ? (millis() + ms) : 0;
play(fx, nt != 0 ? nt : MIDDLE_C);
sequence++;
}
}
}
#endif // _AO_FT810_FUNC_H #endif // _AO_FT810_FUNC_H

@ -67,7 +67,7 @@ void CLCD::spiDeselect (void) { // CLC
void CLCD::Reset (void) { void CLCD::Reset (void) {
WRITE(CLCD_MOD_RESET, 0); WRITE(CLCD_MOD_RESET, 0);
delay(50); delay(100);
WRITE(CLCD_MOD_RESET, 1); WRITE(CLCD_MOD_RESET, 1);
} }

@ -107,13 +107,11 @@ class BootScreen : public UIScreen {
}; };
class AboutScreen : public UIScreen { class AboutScreen : public UIScreen {
private:
static void playChime();
static void draw(bool);
public: public:
static void onEntry(); static void onEntry();
static void onRefresh(); static void onRefresh();
static void onTouchStart(uint8_t tag); static void onTouchStart(uint8_t tag);
static void onIdle();
}; };
class StatusScreen : public UIScreen { class StatusScreen : public UIScreen {
@ -301,6 +299,10 @@ namespace Theme {
const float icon_scale = 0.6; const float icon_scale = 0.6;
#endif #endif
#endif #endif
const effect_t press_sound = CHACK;
const effect_t repeat_sound = CHACK;
const effect_t unpress_sound = POP;
}; };
/******************************** BOOT SCREEN ****************************/ /******************************** BOOT SCREEN ****************************/
@ -316,6 +318,7 @@ void BootScreen::onRefresh() {
cmd.Cmd_Wait_Until_Idle(); cmd.Cmd_Wait_Until_Idle();
CLCD::Turn_On_Backlight(); CLCD::Turn_On_Backlight();
CLCD::SoundPlayer::setVolume(255);
} }
void BootScreen::onIdle() { void BootScreen::onIdle() {
@ -324,32 +327,61 @@ void BootScreen::onIdle() {
/******************************** ABOUT SCREEN ****************************/ /******************************** ABOUT SCREEN ****************************/
CLCD::SoundPlayer sound;
const PROGMEM CLCD::SoundPlayer::sound_t chimes[] = {
{CHIMES, 55, 13},
{CHIMES, 64, 13},
{CHIMES, 60, 19}
};
const PROGMEM CLCD::SoundPlayer::sound_t samples[] = {
{HARP},
{XYLOPHONE},
{TUBA},
{GLOCKENSPIEL},
{ORGAN},
{TRUMPET},
{PIANO},
{CHIMES},
{MUSIC_BOX},
{BELL},
{CLICK},
{SWITCH},
{COWBELL},
{NOTCH},
{HIHAT},
{KICKDRUM},
{SWITCH},
{POP},
{CLACK},
{CHACK},
{SILENCE}
};
void AboutScreen::onEntry() { void AboutScreen::onEntry() {
draw(false); UIScreen::onEntry();
playChime();
draw(true);
}
void AboutScreen::onRefresh() { CLCD::Mem_Write8(REG_VOL_SOUND, 0xFF);
draw(true); sound.play(chimes);
} }
void AboutScreen::draw(bool showOkay) { void AboutScreen::onRefresh() {
CLCD::CommandFifo cmd; CLCD::CommandFifo cmd;
cmd.Cmd(CMD_DLSTART); cmd.Cmd(CMD_DLSTART);
cmd.Cmd_Clear_Color(Theme::about_bg); cmd.Cmd_Clear_Color(Theme::about_bg);
cmd.Cmd_Clear(1,1,1); cmd.Cmd_Clear(1,1,1);
#define GRID_COLS 4 #define GRID_COLS 4
#define GRID_ROWS 6 #define GRID_ROWS 8
BTX( BTN_POS(1,2), BTN_SIZE(4,1), F("Color LCD Interface"), FONT_LRG); BTX( BTN_POS(1,2), BTN_SIZE(4,1), F("Color LCD Interface"), FONT_LRG);
BTN_TAG(2) BTN_TAG(2)
BTX( BTN_POS(1,3), BTN_SIZE(4,1), F("(c) 2018 Aleph Objects, Inc."), FONT_LRG); BTX( BTN_POS(1,3), BTN_SIZE(4,1), F("(c) 2018 Aleph Objects, Inc."), FONT_LRG);
if(showOkay) { BTX( BTN_POS(1,5), BTN_SIZE(4,1), Marlin_LCD_API::getFirmwareName(), FONT_LRG);
BTN_TAG(1) THEME(about_btn) BTN( BTN_POS(2,5), BTN_SIZE(2,1), F("Okay"), MENU_BTN_STYLE);
} BTN_TAG(1) THEME(about_btn) BTN( BTN_POS(2,7), BTN_SIZE(2,1), F("Okay"), MENU_BTN_STYLE);
cmd.Cmd(DL_DISPLAY); cmd.Cmd(DL_DISPLAY);
cmd.Cmd(CMD_SWAP); cmd.Cmd(CMD_SWAP);
@ -363,25 +395,8 @@ void AboutScreen::onTouchStart(uint8_t tag) {
} }
} }
void AboutScreen::playChime() { void AboutScreen::onIdle() {
CLCD::Mem_Write8(REG_VOL_SOUND, 0xFF); sound.onIdle();
CLCD::Mem_Write16(REG_SOUND, (0x37<< 8) | 0x47); // C8 MIDI note on xylophone 37
CLCD::Mem_Write8(REG_PLAY, 1);
delay(800);
CLCD::Mem_Write16(REG_SOUND, (0x40<< 8) | 0x47); // C8 MIDI note on xylophone 40
CLCD::Mem_Write8(REG_PLAY, 1);
delay(800);
CLCD::Mem_Write16(REG_SOUND, (0x3C<< 8) | 0x47); // C8 MIDI note on xylophone 3C
CLCD::Mem_Write8(REG_PLAY, 1);
delay(1200);
CLCD::Mem_Write16(REG_SOUND, 0);
CLCD::Mem_Write8(REG_PLAY, 1);
} }
/*********************************** STATUS SCREEN ******************************/ /*********************************** STATUS SCREEN ******************************/
@ -1255,8 +1270,11 @@ void lcd_update() {
// except when pressed is IGNORE. // except when pressed is IGNORE.
if(pressed == IGNORE) { if(pressed == IGNORE) {
pressed = NONE; pressed = NONE;
sound.play(Theme::unpress_sound);
} }
else if(pressed != NONE) { else if(pressed != NONE) {
sound.play(Theme::unpress_sound);
current_screen.onTouchEnd(pressed); current_screen.onTouchEnd(pressed);
pressed = NONE; pressed = NONE;
#if defined(UI_FRAMEWORK_DEBUG) #if defined(UI_FRAMEWORK_DEBUG)
@ -1275,6 +1293,8 @@ void lcd_update() {
current_screen.onTouchStart(tag); current_screen.onTouchStart(tag);
last_repeat = millis(); last_repeat = millis();
sound.play(Theme::press_sound);
#if defined(UI_FRAMEWORK_DEBUG) #if defined(UI_FRAMEWORK_DEBUG)
#if defined (SERIAL_PROTOCOLLNPAIR) #if defined (SERIAL_PROTOCOLLNPAIR)
SERIAL_PROTOCOLLNPAIR("Touch start: ", tag); SERIAL_PROTOCOLLNPAIR("Touch start: ", tag);
@ -1296,6 +1316,7 @@ void lcd_update() {
// The user is holding down a button. // The user is holding down a button.
if((millis() - last_repeat) > 250) { if((millis() - last_repeat) > 250) {
current_screen.onTouchHeld(tag); current_screen.onTouchHeld(tag);
sound.play(Theme::repeat_sound);
last_repeat = millis(); last_repeat = millis();
} }
} }

@ -41,6 +41,8 @@ class Marlin_LCD_API {
static const uint8_t getFeedRate_percent(); static const uint8_t getFeedRate_percent();
static const float getZOffset_mm(); static const float getZOffset_mm();
static const bool isAxisPositionKnown(const axis_t axis); static const bool isAxisPositionKnown(const axis_t axis);
static const progmem_str getFirmwareName();
}; };
#if defined(MSG_MARLIN) #if defined(MSG_MARLIN)
@ -103,4 +105,8 @@ const bool Marlin_LCD_API::isAxisPositionKnown(const axis_t axis) {
case Z: return axis_known_position[Z_AXIS]; break; case Z: return axis_known_position[Z_AXIS]; break;
} }
} }
const Marlin_LCD_API::progmem_str Marlin_LCD_API::getFirmwareName() {
return F("Marlin " SHORT_BUILD_VERSION LULZBOT_FW_VERSION);
}
#endif #endif
Loading…
Cancel
Save