diff --git a/Marlin/src/HAL/HAL_LCD_defines.h b/Marlin/src/HAL/HAL_LCD_defines.h new file mode 100644 index 000000000..6b2a53d23 --- /dev/null +++ b/Marlin/src/HAL/HAL_LCD_defines.h @@ -0,0 +1,43 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +#ifndef HAL_LCD_DEFINES_H_ +#define HAL_LCD_DEFINES_H_ + +#ifdef ARDUINO_ARCH_SAM +// #include "HAL_DUE/HAL_DUE_LCD_defines.h" + +#elif defined(IS_32BIT_TEENSY) +// #include "HAL_TEENSY35_36/HAL_TEENSY_LCD_defines.h" + +#elif defined(ARDUINO_ARCH_AVR) +// #include "HAL_AVR/HAL_ARDUINO_LCD_defines.h" + +#elif defined(TARGET_LPC1768) + #include "HAL_LPC1768/HAL_LPC1768_LCD_defines.h" + +#else + #error "Unsupported Platform!" +#endif + +#endif // HAL_LCD_DEFINES_H_ diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.c b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.c new file mode 100644 index 000000000..e43032b09 --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.c @@ -0,0 +1,183 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// adapted from I2C/master/master.c example +// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html + + + +#if defined(TARGET_LPC1768) + + #ifdef __cplusplus + extern "C" { + #endif + + #include + #include + #include + + ////////////////////////////////////////////////////////////////////////////////////// + + // These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to + // to the lpc17xx_i2c.c routines so had to copy them into this file & rename them. + + static uint32_t _I2C_Start (LPC_I2C_TypeDef *I2Cx) + { + // Reset STA, STO, SI + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC; + + // Enter to Master Transmitter mode + I2Cx->I2CONSET = I2C_I2CONSET_STA; + + // Wait for complete + while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI)); + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK); + } + + static void _I2C_Stop (LPC_I2C_TypeDef *I2Cx) + { + + /* Make sure start bit is not active */ + if (I2Cx->I2CONSET & I2C_I2CONSET_STA) + { + I2Cx->I2CONCLR = I2C_I2CONCLR_STAC; + } + + I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA; + + I2Cx->I2CONCLR = I2C_I2CONCLR_SIC; + } + + + ////////////////////////////////////////////////////////////////////////////////////// + + #define U8G_I2C_OPT_FAST 16 // from u8g.h + + #define USEDI2CDEV_M 1 + + #define I2CDEV_S_ADDR 0x78 // from SSD1306 //actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write + + #define BUFFER_SIZE 0x1 // only do single byte transfers with LCDs + + #if (USEDI2CDEV_M == 0) + #define I2CDEV_M LPC_I2C0 + #elif (USEDI2CDEV_M == 1) + #define I2CDEV_M LPC_I2C1 + #elif (USEDI2CDEV_M == 2) + #define I2CDEV_M LPC_I2C2 + #else + #error "Master I2C device not defined!" + #endif + + + PINSEL_CFG_Type PinCfg; + I2C_M_SETUP_Type transferMCfg; + + #define I2C_status (LPC_I2C1->I2STAT & I2C_STAT_CODE_BITMASK) + + + uint8_t u8g_i2c_start(uint8_t sla) { // send slave address and write bit + // Sometimes TX data ACK or NAK status is returned. That mean the start state didn't + // happen which means only the value of the slave address was send. Keep looping until + // the slave address and write bit are actually sent. + do{ + _I2C_Stop(I2CDEV_M); // output stop state on I2C bus + _I2C_Start(I2CDEV_M); // output start state on I2C bus + while ((I2C_status != I2C_I2STAT_M_TX_START) + && (I2C_status != I2C_I2STAT_M_TX_RESTART) + && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted + + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address + LPC_I2C1->I2DAT = I2CDEV_S_ADDR & I2C_I2DAT_BITMASK; // transmit slave address & write bit + LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; + while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK) + && (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_ACK) + && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for slaw to finish + }while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK)); + return 1; + } + + + void u8g_i2c_init(uint8_t clock_option) { + + /* + * Init I2C pin connect + */ + PinCfg.OpenDrain = 0; + PinCfg.Pinmode = 0; + #if ((USEDI2CDEV_M == 0)) + PinCfg.Funcnum = 1; + PinCfg.Pinnum = 27; + PinCfg.Portnum = 0; + PINSEL_ConfigPin(&PinCfg); // SDA0 / D57 AUX-1 + PinCfg.Pinnum = 28; + PINSEL_ConfigPin(&PinCfg); // SCL0 / D58 AUX-1 + #endif + #if ((USEDI2CDEV_M == 1)) + PinCfg.Funcnum = 3; + PinCfg.Pinnum = 0; + PinCfg.Portnum = 0; + PINSEL_ConfigPin(&PinCfg); // SDA1 / D20 SCA + PinCfg.Pinnum = 1; + PINSEL_ConfigPin(&PinCfg); // SCL1 / D21 SCL + #endif + #if ((USEDI2CDEV_M == 2)) + PinCfg.Funcnum = 2; + PinCfg.Pinnum = 10; + PinCfg.Portnum = 0; + PINSEL_ConfigPin(&PinCfg); // SDA2 / D38 X_ENABLE_PIN + PinCfg.Pinnum = 11; + PINSEL_ConfigPin(&PinCfg); // SCL2 / D55 X_DIR_PIN + #endif + // Initialize I2C peripheral + I2C_Init(I2CDEV_M, (clock_option & U8G_I2C_OPT_FAST) ? 400000: 100000); // LCD data rates + + /* Enable Master I2C operation */ + I2C_Cmd(I2CDEV_M, I2C_MASTER_MODE, ENABLE); + + u8g_i2c_start(0); // send slave address and write bit + } + + volatile extern uint32_t _millis; + uint8_t u8g_i2c_send_byte(uint8_t data) { + #define I2C_TIMEOUT 3 + LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data + LPC_I2C1->I2CONSET = I2C_I2CONSET_AA; + LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC; + uint32_t timeout = _millis + I2C_TIMEOUT; + while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && (timeout > _millis)); // wait for xmit to finish + // had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens + return 1; + } + + void u8g_i2c_stop(void) { + } + + + #ifdef __cplusplus + } + #endif +#endif diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.h b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.h new file mode 100644 index 000000000..f53161f6d --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_I2C_routines.h @@ -0,0 +1,35 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +#if defined(TARGET_LPC1768) + + void u8g_i2c_init(uint8_t options); + + uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos); + + uint8_t u8g_i2c_start(uint8_t sla); + + uint8_t u8g_i2c_send_byte(uint8_t data); + + void u8g_i2c_stop(void); + +#endif diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_delay.h b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_delay.h new file mode 100644 index 000000000..3a7b3a483 --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_delay.h @@ -0,0 +1,46 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * LCD delay routines - used by all the drivers. + * + * These are based on the LPC1768 routines. + * + * Couldn't just call exact copies because the overhead resulted in the + * one microsecond delay being about 4uS. + */ + + + +#ifdef __cplusplus + extern "C" { +#endif + +void U8g_delay(int msec); + +void u8g_MicroDelay(void); + +void u8g_10MicroDelay(void); + +#ifdef __cplusplus + } +#endif \ No newline at end of file diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.c b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.c new file mode 100644 index 000000000..35c02ffec --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.c @@ -0,0 +1,116 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Low level pin manipulation routines - used by all the drivers. + * + * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. + * + * Couldn't just call exact copies because the overhead killed the LCD update speed + * With an intermediate level the softspi was running in the 10-20kHz range which + * resulted in using about about 25% of the CPU's time. + */ + +#if defined(TARGET_LPC1768) + + #include + #include + #include "src/core/macros.h" +// #include "pinmapping.h" + + #define LPC_PORT_OFFSET (0x0020) + #define LPC_PIN(pin) (1UL << pin) + #define LPC_GPIO(port) ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port)) + + #define INPUT 0 + #define OUTPUT 1 + #define INPUT_PULLUP 2 + + +uint8_t LPC1768_PIN_PORT(const uint8_t pin); +uint8_t LPC1768_PIN_PIN(const uint8_t pin); + + #ifdef __cplusplus + extern "C" { + #endif + +// IO functions +// As defined by Arduino INPUT(0x0), OUPUT(0x1), INPUT_PULLUP(0x2) +void pinMode_LCD(uint8_t pin, uint8_t mode) { +#define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) +#define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + PINSEL_CFG_Type config = { LPC1768_PIN_PORT(pin), + LPC1768_PIN_PIN(pin), + PINSEL_FUNC_0, + PINSEL_PINMODE_TRISTATE, + PINSEL_PINMODE_NORMAL }; + switch(mode) { + case INPUT: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); + PINSEL_ConfigPin(&config); + break; + case OUTPUT: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR |= LPC_PIN(LPC1768_PIN_PIN(pin)); + PINSEL_ConfigPin(&config); + break; + case INPUT_PULLUP: + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIODIR &= ~LPC_PIN(LPC1768_PIN_PIN(pin)); + config.Pinmode = PINSEL_PINMODE_PULLUP; + PINSEL_ConfigPin(&config); + break; + default: + break; + } +} + + + void u8g_SetPinOutput(uint8_t internal_pin_number) { + pinMode_LCD(internal_pin_number, 1); // OUTPUT + } + + void u8g_SetPinInput(uint8_t internal_pin_number) { + pinMode_LCD(internal_pin_number, 0); // INPUT + } + + + + void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) { +#define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) +#define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + if (pin_status) + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOSET = LPC_PIN(LPC1768_PIN_PIN(pin)); + else + LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOCLR = LPC_PIN(LPC1768_PIN_PIN(pin)); + } + + uint8_t u8g_GetPinLevel(uint8_t pin) { +#define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) +#define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + return (uint32_t)LPC_GPIO(LPC1768_PIN_PORT(pin))->FIOPIN & LPC_PIN(LPC1768_PIN_PIN(pin)) ? 1 : 0; + } + + + #ifdef __cplusplus + } + #endif + +#endif diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.h b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.h new file mode 100644 index 000000000..eb4cb2e5e --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LCD_pin_routines.h @@ -0,0 +1,47 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** + * Low level pin manipulation routines - used by all the drivers. + * + * These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines. + * + * Couldn't just call exact copies because the overhead killed the LCD update speed + * With an intermediate level the softspi was running in the 10-20kHz range which + * resulted in using about about 25% of the CPU's time. + */ + + + + + +void u8g_SetPinOutput(uint8_t internal_pin_number); + +void u8g_SetPinInput(uint8_t internal_pin_number); + +void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status); + +uint8_t u8g_GetPinLevel(uint8_t pin); + + + + diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_LPC1768_LCD_defines.h b/Marlin/src/HAL/HAL_LPC1768/HAL_LPC1768_LCD_defines.h new file mode 100644 index 000000000..ddc0c6bf4 --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_LPC1768_LCD_defines.h @@ -0,0 +1,58 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/** +* LPC1768 LCD specific defines +*/ + +#if defined(TARGET_LPC1768) + + // pointers to low level routines - must always supply these +// #define U8G_HAL_LINKS + #define HAL_LCD_pin_routines "HAL_LPC1768/HAL_LCD_pin_routines.h" + #define HAL_LCD_I2C_routines "HAL_LPC1768/HAL_LCD_I2C_routines.h" + #define HAL_LCD_delay "HAL_LPC1768/HAL_LCD_delay.h" + + // The following are optional depending on the platform. + + // definitions of HAL specific com and device drivers. + uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + + + // connect U8g com generic com names to the desired driver + #define U8G_COM_HW_SPI u8g_com_HAL_LPC1768_hw_spi_fn // use LPC1768 specific hardware SPI routine + #define U8G_COM_SW_SPI u8g_com_HAL_LPC1768_sw_spi_fn // use LPC1768 specific software SPI routine + #define U8G_COM_ST7920_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn + #define U8G_COM_ST7920_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn + #define U8G_COM_SSD_I2C u8g_com_HAL_LPC1768_ssd_hw_i2c_fn + + // let these default for now + #define U8G_COM_PARALLEL u8g_com_null_fn + #define U8G_COM_T6963 u8g_com_null_fn + #define U8G_COM_FAST_PARALLEL u8g_com_null_fn + #define U8G_COM_UC_I2C u8g_com_null_fn + +#endif diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp index 1d65a9203..1e2814534 100644 --- a/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_spi.cpp @@ -104,14 +104,14 @@ else if (SPI_speed == 1) { // medium - about 1 MHz for (int bits = 0; bits < 8; bits++) { if (b & 0x80) { - for (uint8_t i = 0; i < 8; i++) WRITE(MOSI_PIN, HIGH); + for (uint8_t i = 0; i < 9; i++) WRITE(MOSI_PIN, HIGH); } else { - for (uint8_t i = 0; i < 8; i++) WRITE(MOSI_PIN, LOW); + for (uint8_t i = 0; i < 9; i++) WRITE(MOSI_PIN, LOW); } b <<= 1; - for (uint8_t i = 0; i < 6; i++) WRITE(SCK_PIN, HIGH); + for (uint8_t i = 0; i < 7; i++) WRITE(SCK_PIN, HIGH); if (READ(MISO_PIN)) { b |= 1; diff --git a/Marlin/src/HAL/HAL_LPC1768/HAL_temp.h b/Marlin/src/HAL/HAL_LPC1768/HAL_temp.h new file mode 100644 index 000000000..20d2cf8d0 --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/HAL_temp.h @@ -0,0 +1 @@ +// blank file needed until I get platformio to update it's copy of U8Glib-HAL \ No newline at end of file diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_hw_spi.cpp new file mode 100644 index 000000000..93974ac9c --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_hw_spi.cpp @@ -0,0 +1,146 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +/* + + based on u8g_com_msp430_hw_spi.c + + Universal 8bit Graphics Library + + Copyright (c) 2012, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + +#ifdef TARGET_LPC1768 + +// #include + +// #include "src/core/macros.h" +// #include "Configuration.h" + + #include + + #define SPI_FULL_SPEED 0 + #define SPI_HALF_SPEED 1 + #define SPI_QUARTER_SPEED 2 + #define SPI_EIGHTH_SPEED 3 + #define SPI_SIXTEENTH_SPEED 4 + #define SPI_SPEED_5 5 + #define SPI_SPEED_6 6 + + void spiBegin(); + void spiInit(uint8_t spiRate); + void spiSend(uint8_t b); + void spiSend(const uint8_t* buf, size_t n); + + + uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) + { + switch(msg) + { + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_INIT: + u8g_SetPILevel(u8g, U8G_PI_CS, 1); + u8g_SetPILevel(u8g, U8G_PI_A0, 1); + u8g_SetPILevel(u8g, U8G_PI_RESET, 1); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPIOutput(u8g, U8G_PI_A0); + u8g_SetPIOutput(u8g, U8G_PI_RESET); + u8g_Delay(5); + spiBegin(); + #ifndef SPI_SPEED + #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card + #endif + spiInit(SPI_SPEED); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g_SetPILevel(u8g, U8G_PI_A0, arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g_SetPILevel(u8g, U8G_PI_CS, (arg_val ? 0 : 1)); + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + spiSend((uint8_t)arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + spiSend(*ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + spiSend(*ptr++); + arg_val--; + } + } + break; + } + return 1; + } + +#endif //TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp new file mode 100644 index 000000000..ce5ac199f --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp @@ -0,0 +1,204 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +/* + + based on u8g_com_arduino_ssd_i2c.c + + com interface for arduino (AND atmega) and the SSDxxxx chip (SOLOMON) variant + I2C protocol + + ToDo: Rename this to u8g_com_avr_ssd_i2c.c + + Universal 8bit Graphics Library + + Copyright (c) 2012, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Special pin usage: + U8G_PI_I2C_OPTION additional options + U8G_PI_A0_STATE used to store the last value of the command/data register selection + U8G_PI_SET_A0 1: Signal request to update I2C device with new A0_STATE, 0: Do nothing, A0_STATE matches I2C device + U8G_PI_SCL clock line (NOT USED) + U8G_PI_SDA data line (NOT USED) + + U8G_PI_RESET reset line (currently disabled, see below) + + Protocol: + SLA, Cmd/Data Selection, Arguments + The command/data register is selected by a special instruction byte, which is sent after SLA + + The continue bit is always 0 so that a (re)start is equired for the change from cmd to/data mode +*/ + +#ifdef TARGET_LPC1768 + + #include + + #define I2C_SLA (0x3c*2) + //#define I2C_CMD_MODE 0x080 + #define I2C_CMD_MODE 0x000 + #define I2C_DATA_MODE 0x040 + +// #define U8G_I2C_OPT_FAST 16 + + uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) + { + /* are we requested to set the a0 state? */ + if ( u8g->pin_list[U8G_PI_SET_A0] == 0 ) + return 1; + + /* setup bus, might be a repeated start */ + if ( u8g_i2c_start(I2C_SLA) == 0 ) + return 0; + if ( u8g->pin_list[U8G_PI_A0_STATE] == 0 ) + { + if ( u8g_i2c_send_byte(I2C_CMD_MODE) == 0 ) + return 0; + } + else + { + if ( u8g_i2c_send_byte(I2C_DATA_MODE) == 0 ) + return 0; + } + + u8g->pin_list[U8G_PI_SET_A0] = 0; + return 1; + } + + uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) + { + switch(msg) + { + case U8G_COM_MSG_INIT: + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH); + //u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH); + //u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: unknown mode */ + + u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]); + u8g_com_ssd_I2C_start_sequence(u8g); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + /* Currently disabled, but it could be enable. Previous restrictions have been removed */ + /* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */ + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g->pin_list[U8G_PI_A0_STATE] = 0; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */ + if ( arg_val == 0 ) + { + /* disable chip, send stop condition */ + u8g_i2c_stop(); + } + else + { + /* enable, do nothing: any byte writing will trigger the i2c start */ + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + //u8g->pin_list[U8G_PI_SET_A0] = 1; +// if ( u8g_com_arduino_ssd_start_sequence(u8g) == 0 ) +// return u8g_i2c_stop(), 0; + if ( u8g_i2c_send_byte(arg_val) == 0 ) + return u8g_i2c_stop(), 0; + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_ssd_I2C_start_sequence(u8g) == 0 ) + return u8g_i2c_stop(), 0; + { + register uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte(*ptr++) == 0 ) + return u8g_i2c_stop(), 0; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_ssd_I2C_start_sequence(u8g) == 0 ) + return u8g_i2c_stop(), 0; + { + register uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte(u8g_pgm_read(ptr)) == 0 ) + return 0; + ptr++; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */ + + u8g_i2c_start(0); // send slave address and write bit + if (arg_val) + u8g_i2c_send_byte(0x40); // write to graphics DRAM mode + else + u8g_i2c_send_byte(0x80); //command mode + break; + } + return 1; + } + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_sw_i2c.cpp under construction b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_sw_i2c.cpp under construction new file mode 100644 index 000000000..11fd77f7c --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_ssd_sw_i2c.cpp under construction @@ -0,0 +1,283 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* based on U8G2 code + + u8x8_byte.c + + Universal 8bit Graphics Library (https://github.com/olikraus/u8g2/) + + Copyright (c) 2016, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +*/ + +/* + software i2c, + ignores ACK response (which is anyway not provided by some displays) + also does not allow reading from the device +*/ + +#ifdef TARGET_LPC1768 + + #include + +void delayMicroseconds(uint32_t us); +//void pinMode(int16_t pin, uint8_t mode); +//void digitalWrite(int16_t pin, uint8_t pin_status); + + + #define I2C_SLA (0x3c*2) + //#define I2C_CMD_MODE 0x080 + #define I2C_CMD_MODE 0x000 + #define I2C_DATA_MODE 0x040 + +//static uint8_t I2C_speed; // 3 - 400KHz, 13 - 100KHz +//#define SPEED_400KHz 3 +//#define SPEED_100KHz 13 + + +// #define U8G_I2C_OPT_FAST 16 + + + +uint8_t SCL_pin_HAL_LPC1768_sw_I2C, SCL_port_HAL_LPC1768_sw_I2C, SDA_pin_HAL_LPC1768_sw_I2C, SDA_port_HAL_LPC1768_sw_I2C; + +#define SPI_SPEED 2 //20: 200KHz 5:750KHz 2:3-4MHz + +uint8_t u8g_i2c_send_byte_sw(uint8_t data) { +{ + for (uint8_t i = 0; i < 9; i++) { // 1 extra bit for the ack/nak + + if (val & 0x80) + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + } + else + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + } + val = val << 1; + } + return 1; +} + + +uint8_t u8g_i2c_start_sw(uint8_t sla) { // assert start condition and then send slave address with write bit +{ + /* send the start condition, both lines go from 1 to 0 */ + + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + delayMicroseconds(2); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + delayMicroseconds(2); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOSET = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + delayMicroseconds(2); + LPC_GPIO(SDA_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SDA_pin_HAL_LPC1768_sw_I2C); + delayMicroseconds(2); + LPC_GPIO(SCL_port_HAL_LPC1768_sw_I2C)->FIOCLR = LPC_PIN(SCL_pin_HAL_LPC1768_sw_I2C); + + u8g_i2c_send_byte_sw(I2C_SLA); // send slave address with write bit +} + + +void u8g_i2c_stop_sw(void) { +} + +void u8g_i2c_init_sw(uint8_t clock_option) { + u8g_i2c_start(0); // send slave address and write bit +} + + + + uint8_t u8g_com_ssd_I2C_start_sequence_sw(u8g_t *u8g) + { + /* are we requested to set the a0 state? */ + if ( u8g->pin_list[U8G_PI_SET_A0] == 0 ) + return 1; + + /* setup bus, might be a repeated start */ + if ( u8g_i2c_start(I2C_SLA) == 0 ) + return 0; + if ( u8g->pin_list[U8G_PI_A0_STATE] == 0 ) + { + if ( u8g_i2c_send_byte(I2C_CMD_MODE) == 0 ) + return 0; + } + else + { + if ( u8g_i2c_send_byte(I2C_DATA_MODE) == 0 ) + return 0; + } + + u8g->pin_list[U8G_PI_SET_A0] = 0; + return 1; + } + + uint8_t u8g_com_HAL_LPC1768_ssd_sw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) + { + switch(msg) + { + case U8G_COM_MSG_INIT: + + #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) + #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + SCL_pin_HAL_LPC1768_sw_I2C = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SCL]); + SCL_port_HAL_LPC1768_sw_I2C = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SCL]); + SDA_pin_HAL_LPC1768_sw_I2C = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SDA]); + SDA_port_HAL_LPC1768_sw_I2C = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SDA]); + // As defined by Arduino INPUT(0x0), OUPUT(0x1), INPUT_PULLUP(0x2) + #define OUPUT 0x1 + u8g_SetPIOutput(u8g, U8G_PI_SCL); + u8g_SetPIOutput(u8g, U8G_PI_SDA); + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPIOutput(u8g, U8G_PI_CS); + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_A0]) u8g_SetPIOutput(u8g, U8G_PI_A0); + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET); + + //u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH); + //u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH); + //u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: unknown mode */ + + u8g_i2c_init_sw(u8g->pin_list[U8G_PI_I2C_OPTION]); + u8g_com_ssd_I2C_start_sequence_sw((u8g); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g->pin_list[U8G_PI_A0_STATE] = 0; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */ + if ( arg_val == 0 ) + { + /* disable chip, send stop condition */ + u8g_i2c_stop_sw(); + } + else + { + /* enable, do nothing: any byte writing will trigger the i2c start */ + } + break; + + case U8G_COM_MSG_WRITE_BYTE: + //u8g->pin_list[U8G_PI_SET_A0] = 1; +// if ( u8g_com_arduino_ssd_start_sequence(u8g) == 0 ) +// return u8g_i2c_stop(), 0; + if ( u8g_i2c_send_byte_sw(arg_val) == 0 ) + return u8g_i2c_stop_sw(), 0; + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_ssd_I2C_start_sequence_sw(u8g) == 0 ) + return u8g_i2c_stop_sw(), 0; + { + register uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte_sw(*ptr++) == 0 ) + return u8g_i2c_stop_sw(), 0; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + //u8g->pin_list[U8G_PI_SET_A0] = 1; + if ( u8g_com_ssd_I2C_start_sequence_sw(u8g) == 0 ) + return u8g_i2c_stop_sw(), 0; + { + register uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + if ( u8g_i2c_send_byte_sw(u8g_pgm_read(ptr)) == 0 ) + return 0; + ptr++; + arg_val--; + } + } + // u8g_i2c_stop(); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */ + + u8g_i2c_start_sw(0); // send slave address and write bit + if (arg_val) + u8g_i2c_send_byte_sw(0x40); // write to graphics DRAM mode + else + u8g_i2c_send_byte_sw(0x80); //command mode + break; + } + return 1; + } + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp new file mode 100644 index 000000000..f9b0890f7 --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp @@ -0,0 +1,164 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + + based on u8g_com_LPC1768_st7920_hw_spi.c + + Universal 8bit Graphics Library + + Copyright (c) 2011, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef TARGET_LPC1768 + +// #include + +// #include "src/core/macros.h" +// #include "Configuration.h" + + #include + + #define SPI_FULL_SPEED 0 + #define SPI_HALF_SPEED 1 + #define SPI_QUARTER_SPEED 2 + #define SPI_EIGHTH_SPEED 3 + #define SPI_SIXTEENTH_SPEED 4 + #define SPI_SPEED_5 5 + #define SPI_SPEED_6 6 + + + void spiBegin(); + void spiInit(uint8_t spiRate); + void spiSend(uint8_t b); + void spiSend(const uint8_t* buf, size_t n); + + + static uint8_t rs_last_state = 255; + + static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) + { + uint8_t i; + + if ( rs != rs_last_state) { // time to send a command/data byte + rs_last_state = rs; + + if ( rs == 0 ) + /* command */ + spiSend(0x0f8); + else + /* data */ + spiSend(0x0fa); + + for( i = 0; i < 4; i++ ) // give the controller some time to process the data + u8g_10MicroDelay(); // 2 is bad, 3 is OK, 4 is safe + } + + spiSend(val & 0x0f0); + spiSend(val << 4); + } + + + uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) + { + switch(msg) + { + case U8G_COM_MSG_INIT: + u8g_SetPILevel(u8g, U8G_PI_CS, 0); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_Delay(5); + spiBegin(); + spiInit(SPI_EIGHTH_SPEED); // ST7920 max speed is about 1.1 MHz + u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: command mode */ + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + + case U8G_COM_MSG_CHIP_SELECT: + u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + } + return 1; + } + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp new file mode 100644 index 000000000..47a4f443f --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp @@ -0,0 +1,198 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + + based on u8g_com_st7920_hw_spi.c + + Universal 8bit Graphics Library + + Copyright (c) 2011, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + +#ifdef TARGET_LPC1768 + + #include + + #include + + #define LPC_PORT_OFFSET (0x0020) + #define LPC_PIN(pin) (1UL << pin) + #define LPC_GPIO(port) ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port)) + + + uint8_t SCK_pin_ST7920_HAL, SCK_port_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL, MOSI_port_ST7920_HAL; + + + #define SPI_SPEED 4 //20: 200KHz 5:750KHz 4:1MHz 3:1.5MHz 2:3-4MHz + + static void spiSend_sw(uint8_t val) + { + for (uint8_t i = 0; i < 8; i++) { + + if (val & 0x80) + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOSET = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + } + else + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + LPC_GPIO(MOSI_port_ST7920_HAL)->FIOCLR = LPC_PIN(MOSI_pin_ST7920_HAL_HAL); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL); + LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL); + LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL); + LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL); + LPC_GPIO(SCK_port_ST7920_HAL)->FIOSET = LPC_PIN(SCK_pin_ST7920_HAL); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCK_port_ST7920_HAL)->FIOCLR = LPC_PIN(SCK_pin_ST7920_HAL); + LPC_GPIO(SCK_port_ST7920_HAL)->FIOCLR = LPC_PIN(SCK_pin_ST7920_HAL); + } + val = val << 1; + } + } + + static uint8_t rs_last_state = 255; + + static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) + { + uint8_t i; + + if ( rs != rs_last_state) { // time to send a command/data byte + rs_last_state = rs; + + if ( rs == 0 ) + /* command */ + spiSend_sw(0x0f8); + else + /* data */ + spiSend_sw(0x0fa); + + for( i = 0; i < 4; i++ ) // give the controller some time to process the data + u8g_10MicroDelay(); // 2 is bad, 3 is OK, 4 is safe + } + + spiSend_sw(val & 0x0f0); + spiSend_sw(val << 4); + } + + + uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) + { + switch(msg) + { + case U8G_COM_MSG_INIT: + #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) + #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + SCK_pin_ST7920_HAL = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SCK]); + SCK_port_ST7920_HAL = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SCK]); + MOSI_pin_ST7920_HAL_HAL = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_MOSI]); + MOSI_port_ST7920_HAL = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_MOSI]); + + u8g_SetPILevel(u8g, U8G_PI_CS, 0); + u8g_SetPIOutput(u8g, U8G_PI_CS); + u8g_SetPILevel(u8g, U8G_PI_SCK, 0); + u8g_SetPIOutput(u8g, U8G_PI_SCK); + u8g_SetPILevel(u8g, U8G_PI_MOSI, 0); + u8g_SetPIOutput(u8g, U8G_PI_MOSI); + u8g_Delay(5); + u8g->pin_list[U8G_PI_A0_STATE] = 0; /* inital RS state: command mode */ + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val); + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + u8g->pin_list[U8G_PI_A0_STATE] = arg_val; + break; + + case U8G_COM_MSG_CHIP_SELECT: + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + uint8_t *ptr = (uint8_t*) arg_ptr; + while( arg_val > 0 ) + { + u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++); + arg_val--; + } + } + break; + } + return 1; + } + +#endif //TARGET_LPC1768 diff --git a/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_sw_spi.cpp new file mode 100644 index 000000000..eca12685a --- /dev/null +++ b/Marlin/src/HAL/HAL_LPC1768/u8g_com_HAL_LPC1768_sw_spi.cpp @@ -0,0 +1,184 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + + adapted from u8g_com_std_sw_spi.c + + Universal 8bit Graphics Library + + Copyright (c) 2015, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*/ + + + +#if defined (TARGET_LPC1768) + + +#include +#include + +#include + +#define LPC_PORT_OFFSET (0x0020) +#define LPC_PIN(pin) (1UL << pin) +#define LPC_GPIO(port) ((volatile LPC_GPIO_TypeDef *)(LPC_GPIO0_BASE + LPC_PORT_OFFSET * port)) + +void delayMicroseconds(uint32_t us); +void pinMode(int16_t pin, uint8_t mode); +void digitalWrite(int16_t pin, uint8_t pin_status); + + +uint8_t SCK_pin, SCK_port, MOSI_pin, MOSI_port; + +#define SPI_SPEED 2 //20: 200KHz 5:750KHz 2:3-4MHz + +static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) +{ + for (uint8_t i = 0; i < 8; i++) { + + if (val & 0x80) + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin); + LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin); + LPC_GPIO(MOSI_port)->FIOSET = LPC_PIN(MOSI_pin); + } + else + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin); + LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin); + LPC_GPIO(MOSI_port)->FIOCLR = LPC_PIN(MOSI_pin); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin); + LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin); + LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin); + LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin); + LPC_GPIO(SCK_port)->FIOSET = LPC_PIN(SCK_pin); + } + + for (uint8_t j = 0; j < SPI_SPEED; j++) { + LPC_GPIO(SCK_port)->FIOCLR = LPC_PIN(SCK_pin); + LPC_GPIO(SCK_port)->FIOCLR = LPC_PIN(SCK_pin); + } + val = val << 1; + } +} + + +uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) +{ + + + switch(msg) + { + case U8G_COM_MSG_INIT: + #define LPC1768_PIN_PORT(pin) ((uint8_t)((pin >> 5) & 0b111)) + #define LPC1768_PIN_PIN(pin) ((uint8_t)(pin & 0b11111)) + SCK_pin = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_SCK]); + SCK_port = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_SCK]); + MOSI_pin = LPC1768_PIN_PIN(u8g->pin_list[U8G_PI_MOSI]); + MOSI_port = LPC1768_PIN_PORT(u8g->pin_list[U8G_PI_MOSI]); + // As defined by Arduino INPUT(0x0), OUPUT(0x1), INPUT_PULLUP(0x2) + #define OUPUT 0x1 + pinMode(u8g->pin_list[U8G_PI_SCK], OUPUT); + pinMode(u8g->pin_list[U8G_PI_MOSI], OUPUT); + pinMode(u8g->pin_list[U8G_PI_CS], OUPUT); + pinMode(u8g->pin_list[U8G_PI_A0], OUPUT); + if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) pinMode(u8g->pin_list[U8G_PI_RESET], OUPUT); + digitalWrite(u8g->pin_list[U8G_PI_SCK], 0); + digitalWrite(u8g->pin_list[U8G_PI_MOSI], 0); + break; + + case U8G_COM_MSG_STOP: + break; + + case U8G_COM_MSG_RESET: + digitalWrite(u8g->pin_list[U8G_PI_RESET], arg_val); + break; + + case U8G_COM_MSG_CHIP_SELECT: + digitalWrite(u8g->pin_list[U8G_PI_CS], !arg_val); + break; + + case U8G_COM_MSG_WRITE_BYTE: + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val); + break; + + case U8G_COM_MSG_WRITE_SEQ: + { + uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++); + arg_val--; + } + } + break; + + case U8G_COM_MSG_WRITE_SEQ_P: + { + uint8_t *ptr = (uint8_t *)arg_ptr; + while( arg_val > 0 ) + { + u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr)); + ptr++; + arg_val--; + } + } + break; + + case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */ + digitalWrite(u8g->pin_list[U8G_PI_A0], arg_val); + break; + } + return 1; +} + +#endif // TARGET_LPC1768 diff --git a/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h new file mode 100644 index 000000000..98c061cac --- /dev/null +++ b/Marlin/src/lcd/dogm/HAL_LCD_class_defines.h @@ -0,0 +1,82 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +// use this file to create the public interface for device drivers that are NOT in the U8G library + +extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi; +extern u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi; +class U8GLIB_64128N_2X_HAL : public U8GLIB +{ + public: + U8GLIB_64128N_2X_HAL(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_sw_spi, sck, mosi, cs, a0, reset) + { } + U8GLIB_64128N_2X_HAL(uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7565_64128n_HAL_2x_hw_spi, cs, a0, reset) + { } +}; + + +extern u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_sw_spi; +extern u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_hw_spi; +class U8GLIB_ST7920_128X64_4X_HAL : public U8GLIB +{ + public: + U8GLIB_ST7920_128X64_4X_HAL(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_sw_spi, sck, mosi, cs, U8G_PIN_NONE, reset) // a0 = U8G_PIN_NONE + { } + U8GLIB_ST7920_128X64_4X_HAL(uint8_t cs, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_HAL_4x_hw_spi, cs, U8G_PIN_NONE, reset) // a0 = U8G_PIN_NONE + { } +}; + + + +extern u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi; +class U8GLIB_ST7920_128X64_RRD : public U8GLIB +{ + public: + U8GLIB_ST7920_128X64_RRD(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t reset = U8G_PIN_NONE) + : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi, sck, mosi, cs, U8G_PIN_NONE, reset) // a0 = U8G_PIN_NONE + { } +}; + + + +extern u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire; +class U8GLIB_SH1106_128X64_2X_I2C_2_WIRE : public U8GLIB { + public: + U8GLIB_SH1106_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) + : U8GLIB(&u8g_dev_sh1106_128x64_2x_i2c_2_wire, options) + { } +}; + + + +extern u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire; +class U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE : public U8GLIB { + public: + U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE(uint8_t options = U8G_I2C_OPT_NONE) + : U8GLIB(&u8g_dev_ssd1306_128x64_2x_i2c_2_wire, options) + { } +}; diff --git a/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h new file mode 100644 index 000000000..5175c5d43 --- /dev/null +++ b/Marlin/src/lcd/dogm/HAL_LCD_com_defines.h @@ -0,0 +1,66 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +// use this file to select the com driver for device drivers that are NOT in the U8G library + + +#ifndef U8G_HAL_LINKS + + uint8_t u8g_com_arduino_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_SW_SPI_FN u8g_com_arduino_sw_spi_fn + + uint8_t u8g_com_arduino_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_HW_SPI_FN u8g_com_arduino_hw_spi_fn + + uint8_t u8g_com_arduino_st7920_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_arduino_st7920_spi_fn + + uint8_t u8g_com_arduino_st7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_arduino_st7920_hw_spi_fn + + uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn + +#elif TARGET_LPC1768 + uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_LPC1768_sw_spi_fn + + uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_HW_SPI_FN u8g_com_HAL_LPC1768_hw_spi_fn + + uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn + + uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn + + uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_SSD_I2C_HAL u8g_com_HAL_LPC1768_ssd_hw_i2c_fn + +#else // need to give them some definition or else get compiler errors + uint8_t u8g_com_null_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr); + #define U8G_COM_HAL_SW_SPI_FN u8g_com_null_fn + #define U8G_COM_HAL_HW_SPI_FN u8g_com_null_fn + #define U8G_COM_ST7920_HAL_SW_SPI u8g_com_null_fn + #define U8G_COM_ST7920_HAL_HW_SPI u8g_com_null_fn + #define U8G_COM_SSD_I2C_HAL u8g_com_null_fn +#endif \ No newline at end of file diff --git a/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp new file mode 100644 index 000000000..8d0221fc8 --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g_dev_ssd1306_sh1106_128x64_I2C.cpp @@ -0,0 +1,320 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +/* + + u8g_dev_ssd1306_128x64.c + + Universal 8bit Graphics Library + + Copyright (c) 2011, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +*/ + +/** + * These routines are meant for two wire I2C interfaces. + * + * Three and four wire I2C interfaces have an A0 line. That line is + * used to switch between command and data modes. + * + * The two wire LCDs use an instruction byte to signal if data or + * command info is to follow. The command stream needs the instruction + * byte between eack command byte. The data stream needs one at the + * beginning. + */ + +#include +#include + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq); + +// The sh1106 is compatible to the ssd1306, but is 132x64. 128x64 display area is centered within +// the 132x64. + + +static const uint8_t u8g_dev_sh1106_128x64_data_start_2_wire[] PROGMEM = { + 0x010, // set upper 4 bit of the col adr to 0 + 0x002, // set lower 4 bit of the col adr to 2 (centered display with ssd1306) + U8G_ESC_END // end of sequence +}; + + +static const uint8_t u8g_dev_sh1106_128x64_init_seq_2_wire[] PROGMEM = { + U8G_ESC_ADR(0), // initiate command mode + 0x0ae, /* display off, sleep mode */ + 0x0a8, 0x03f, /* mux ratio */ + 0x0d3, 0x00, /* display offset */ + 0x040, /* start line */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x0cf, /* [2] set contrast control */ + 0x020, 0x002, /* 2012-05-27: page addressing mode */ + 0x21, 2, 0x81, // set column range from 0 through 131 + 0x22, 0, 7, // set page range from 0 through 7 + 0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ + 0x0db, 0x040, /* vcomh deselect level */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ + 0x02e, /* 2012-05-27: Deactivate scroll */ + 0x0af, /* display on */ + U8G_ESC_END /* end of sequence */ +}; + + +uint8_t u8g_dev_sh1106_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_init_seq_2_wire); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2)); // select current page + u8g_SetAddress(u8g, dev, 1); // data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_sh1106_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2+1)); // select current page + u8g_SetAddress(u8g, dev, 1); // data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + + +uint8_t u8g_dev_sh1106_128x64_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_sh1106_128x64_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_sh1106_128x64_2x_buf}; +u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c = { u8g_dev_sh1106_128x64_2x_2_wire_fn, &u8g_dev_sh1106_128x64_2x_pb, U8G_COM_SSD_I2C_HAL }; + + +uint8_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_sh1106_128x64_2x_i2c_2_wire_buf}; +u8g_dev_t u8g_dev_sh1106_128x64_2x_i2c_2_wire = { u8g_dev_sh1106_128x64_2x_2_wire_fn, &u8g_dev_sh1106_128x64_2x_i2c_2_wire_pb, U8G_COM_SSD_I2C_HAL }; + +///////////////////////////////////////////////////////////////////////////////////////////// + +static const uint8_t u8g_dev_ssd1306_128x64_data_start_2_wire[] PROGMEM = { + 0x010, // set upper 4 bit of the col adr to 0 + 0x000, // set lower 4 bit of the col adr to 0 + U8G_ESC_END // end of sequence +}; + + +static const uint8_t u8g_dev_ssd1306_128x64_init_seq_2_wire[] PROGMEM = { + U8G_ESC_ADR(0), // initiate command mode + 0x0ae, /* display off, sleep mode */ + 0x0a8, 0x03f, /* mux ratio */ + 0x0d3, 0x00, /* display offset */ + 0x040, /* start line */ + 0x0a1, /* segment remap a0/a1*/ + 0x0c8, /* c0: scan dir normal, c8: reverse */ + 0x0da, 0x012, /* com pin HW config, sequential com pin config (bit 4), disable left/right remap (bit 5) */ + 0x081, 0x0cf, /* [2] set contrast control */ + 0x020, 0x002, /* 2012-05-27: page addressing mode */ + 0x21, 0, 0x7f, // set column range from 0 through 127 + 0x22, 0, 7, // set page range from 0 through 7 + 0x0d9, 0x0f1, /* [2] pre-charge period 0x022/f1*/ + 0x0db, 0x040, /* vcomh deselect level */ + 0x0a4, /* output ram to display */ + 0x0a6, /* none inverted normal display mode */ + 0x0d5, 0x080, /* clock divide ratio (0x00=1) and oscillator frequency (0x8) */ + 0x08d, 0x014, /* [2] charge pump setting (p62): 0x014 enable, 0x010 disable */ + 0x02e, /* 2012-05-27: Deactivate scroll */ + 0x0af, /* display on */ + U8G_ESC_END /* end of sequence */ +}; + + +uint8_t u8g_dev_ssd1306_128x64_2x_2_wire_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_300NS); + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_init_seq_2_wire); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_SetAddress(u8g, dev, 0); // instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2)); // select current page + u8g_SetAddress(u8g, dev, 1); // data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *) pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + u8g_SetAddress(u8g, dev, 0); // instruction mode + u8g_WriteEscSeqP_2_wire(u8g, dev, u8g_dev_ssd1306_128x64_data_start_2_wire); + u8g_WriteByte(u8g, dev, 0x0b0 | (pb->p.page*2+1)); // select current page + u8g_SetAddress(u8g, dev, 1); // data mode + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_SLEEP_ON: + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + + +uint8_t u8g_dev_ssd1306_128x64_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_ssd1306_128x64_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_ssd1306_128x64_2x_buf}; +u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c = { u8g_dev_ssd1306_128x64_2x_2_wire_fn, &u8g_dev_ssd1306_128x64_2x_pb, U8G_COM_SSD_I2C_HAL }; + + +uint8_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_ssd1306_128x64_2x_i2c_2_wire_buf}; +u8g_dev_t u8g_dev_ssd1306_128x64_2x_i2c_2_wire = { u8g_dev_ssd1306_128x64_2x_2_wire_fn, &u8g_dev_ssd1306_128x64_2x_i2c_2_wire_pb, U8G_COM_SSD_I2C_HAL }; + + +///////////////////////////////////////////////////////////////////////////////////////////// + +// This routine adds the instruction byte in between the command bytes. This makes the init +// sequences a lot easier to read. + +#define I2C_CMD_MODE 0x080 + +uint8_t u8g_WriteEscSeqP_2_wire(u8g_t *u8g, u8g_dev_t *dev, const uint8_t *esc_seq) +{ + uint8_t is_escape = 0; + uint8_t value; + for(;;) + { + value = u8g_pgm_read(esc_seq); + if ( is_escape == 0 ) + { + if ( value != 255 ) + { + if ( u8g_WriteByte(u8g, dev, value) == 0 ) + return 0; + if ( u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) + return 0; + } + else + { + is_escape = 1; + } + } + else + { + if ( value == 255 ) + { + if ( u8g_WriteByte(u8g, dev, value) == 0 ) + return 0; + if ( u8g_WriteByte(u8g, dev, I2C_CMD_MODE) == 0 ) + return 0; + } + else if ( value == 254 ) + { + break; + } + else if ( value >= 0x0f0 ) + { + /* not yet used, do nothing */ + } + else if ( value >= 0xe0 ) + { + u8g_SetAddress(u8g, dev, value & 0x0f); + } + else if ( value >= 0xd0 ) + { + u8g_SetChipSelect(u8g, dev, value & 0x0f); + } + else if ( value >= 0xc0 ) + { + u8g_SetResetLow(u8g, dev); + value &= 0x0f; + value <<= 4; + value+=2; + u8g_Delay(value); + u8g_SetResetHigh(u8g, dev); + u8g_Delay(value); + } + else if ( value >= 0xbe ) + { + /* not yet implemented */ + /* u8g_SetVCC(u8g, dev, value & 0x01); */ + } + else if ( value <= 127 ) + { + u8g_Delay(value); + } + is_escape = 0; + } + esc_seq++; + } + return 1; +} + diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp new file mode 100644 index 000000000..6019b8228 --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g_dev_st7565_64128n_HAL.cpp @@ -0,0 +1,229 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + + +/* + + u8g_dev_st7565_64128n_HAL.c (Displaytech) + + Universal 8bit Graphics Library + + Copyright (c) 2011, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +*/ + +#include + +#include + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + +/* init sequence from https://github.com/adafruit/ST7565-LCD/blob/master/ST7565/ST7565.cpp */ +static const uint8_t u8g_dev_st7565_64128n_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + U8G_ESC_RST(15), /* do reset low pulse with (15*16)+2 milliseconds (=maximum delay)*/ + + 0x0A2, /* 0x0a2: LCD bias 1/9 (according to Displaytech 64128N datasheet) */ + 0x0A0, /* Normal ADC Select (according to Displaytech 64128N datasheet) */ + + 0x0c8, /* common output mode: set scan direction normal operation/SHL Select, 0x0c0 --> SHL = 0, normal, 0x0c8 --> SHL = 1 */ + 0x040, /* Display start line for Displaytech 64128N */ + + 0x028 | 0x04, /* power control: turn on voltage converter */ + U8G_ESC_DLY(50), /* delay 50 ms */ + + 0x028 | 0x06, /* power control: turn on voltage regulator */ + U8G_ESC_DLY(50), /* delay 50 ms */ + + 0x028 | 0x07, /* power control: turn on voltage follower */ + U8G_ESC_DLY(50), /* delay 50 ms */ + + 0x010, /* Set V0 voltage resistor ratio. Setting for controlling brightness of Displaytech 64128N */ + + 0x0a6, /* display normal, bit val 0: LCD pixel off. */ + + 0x081, /* set contrast */ + 0x01e, /* Contrast value. Setting for controlling brightness of Displaytech 64128N */ + + + 0x0af, /* display on */ + + U8G_ESC_DLY(100), /* delay 100 ms */ + 0x0a5, /* display all points, ST7565 */ + U8G_ESC_DLY(100), /* delay 100 ms */ + U8G_ESC_DLY(100), /* delay 100 ms */ + 0x0a4, /* normal display */ + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_st7565_64128n_HAL_data_start[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x010, /* set upper 4 bit of the col adr to 0x10 */ + 0x000, /* set lower 4 bit of the col adr to 0x00. Changed for DisplayTech 64128N */ + U8G_ESC_END /* end of sequence */ +}; + +static const uint8_t u8g_dev_st7565_64128n_HAL_sleep_on[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0ac, /* static indicator off */ + 0x000, /* indicator register set (not sure if this is required) */ + 0x0ae, /* display off */ + 0x0a5, /* all points on */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ + }; + +static const uint8_t u8g_dev_st7565_64128n_HAL_sleep_off[] PROGMEM = { + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_CS(1), /* enable chip */ + 0x0a4, /* all points off */ + 0x0af, /* display on */ + U8G_ESC_DLY(50), /* delay 50 ms */ + U8G_ESC_CS(0), /* disable chip, bugfix 12 nov 2014 */ + U8G_ESC_END /* end of sequence */ +}; + +uint8_t u8g_dev_st7565_64128n_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | pb->p.page); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + if ( u8g_pb_WriteBuffer(pb, u8g, dev) == 0 ) + return 0; + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); /* instruction mode */ + u8g_WriteByte(u8g, dev, 0x081); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 2); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_sleep_off); + return 1; + } + return u8g_dev_pb8v1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_st7565_64128n_HAL_2x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (2*pb->p.page)); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)pb->buf); + u8g_SetChipSelect(u8g, dev, 0); + + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_data_start); + u8g_WriteByte(u8g, dev, 0x0b0 | (2*pb->p.page+1)); /* select current page (ST7565R) */ + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, pb->width, (uint8_t *)(pb->buf)+pb->width); + u8g_SetChipSelect(u8g, dev, 0); + } + break; + case U8G_DEV_MSG_CONTRAST: + u8g_SetChipSelect(u8g, dev, 1); + u8g_SetAddress(u8g, dev, 0); /* instruction mode */ + u8g_WriteByte(u8g, dev, 0x081); + u8g_WriteByte(u8g, dev, (*(uint8_t *)arg) >> 2); + u8g_SetChipSelect(u8g, dev, 0); + return 1; + case U8G_DEV_MSG_SLEEP_ON: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_sleep_on); + return 1; + case U8G_DEV_MSG_SLEEP_OFF: + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7565_64128n_HAL_sleep_off); + return 1; + } + return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); +} + + +U8G_PB_DEV(u8g_dev_st7565_64128n_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_64128n_HAL_fn, U8G_COM_HAL_SW_SPI_FN); + +uint8_t u8g_dev_st7565_64128n_HAL_2x_buf[WIDTH*2] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_st7565_64128n_HAL_2x_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7565_64128n_HAL_2x_buf}; +u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_sw_spi = { u8g_dev_st7565_64128n_HAL_2x_fn, &u8g_dev_st7565_64128n_HAL_2x_pb, U8G_COM_HAL_SW_SPI_FN }; + + +U8G_PB_DEV(u8g_dev_st7565_64128n_HAL_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7565_64128n_HAL_fn, U8G_COM_HAL_HW_SPI_FN); +u8g_dev_t u8g_dev_st7565_64128n_HAL_2x_hw_spi = { u8g_dev_st7565_64128n_HAL_2x_fn, &u8g_dev_st7565_64128n_HAL_2x_pb, U8G_COM_HAL_HW_SPI_FN }; \ No newline at end of file diff --git a/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp new file mode 100644 index 000000000..d3f7f66ee --- /dev/null +++ b/Marlin/src/lcd/dogm/u8g_dev_st7920_128x64_HAL.cpp @@ -0,0 +1,202 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ + +/* + + u8g_dev_st7920_128x64_HAL.c + + Universal 8bit Graphics Library + + Copyright (c) 2011, olikraus@gmail.com + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list + of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, this + list of conditions and the following disclaimer in the documentation and/or other + materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +*/ + +#include + +#include + +#define WIDTH 128 +#define HEIGHT 64 +#define PAGE_HEIGHT 8 + + +/* init sequence from https://github.com/adafruit/ST7565-LCD/blob/master/ST7565/ST7565.cpp */ +static const uint8_t u8g_dev_st7920_128x64_HAL_init_seq[] PROGMEM = { + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_ADR(0), /* instruction mode */ + U8G_ESC_RST(15), /* do reset low pulse with (15*16)+2 milliseconds (=maximum delay)*/ + U8G_ESC_DLY(100), /* 8 Dez 2012: additional delay 100 ms because of reset*/ + U8G_ESC_CS(1), /* enable chip */ + U8G_ESC_DLY(50), /* delay 50 ms */ + + 0x038, /* 8 Bit interface (DL=1), basic instruction set (RE=0) */ + 0x00c, /* display on, cursor & blink off; 0x08: all off */ + 0x006, /* Entry mode: Cursor move to right ,DDRAM address counter (AC) plus 1, no shift */ + 0x002, /* disable scroll, enable CGRAM adress */ + 0x001, /* clear RAM, needs 1.6 ms */ + U8G_ESC_DLY(100), /* delay 100 ms */ + + U8G_ESC_CS(0), /* disable chip */ + U8G_ESC_END /* end of sequence */ +}; + +uint8_t u8g_dev_st7920_128x64_HAL_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_HAL_init_seq); + break; + case U8G_DEV_MSG_STOP: + break; + case U8G_DEV_MSG_PAGE_NEXT: + { + uint8_t y, i; + uint8_t *ptr; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_SetChipSelect(u8g, dev, 1); + y = pb->p.page_y0; + ptr = (uint8_t *)pb->buf; + for( i = 0; i < 8; i ++ ) + { + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_WriteByte(u8g, dev, 0x03e ); /* enable extended mode */ + + if ( y < 32 ) + { + u8g_WriteByte(u8g, dev, 0x080 | y ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 ); /* set x pos to 0*/ + } + else + { + u8g_WriteByte(u8g, dev, 0x080 | (y-32) ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 | 8); /* set x pos to 64*/ + } + + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, WIDTH/8, ptr); + ptr += WIDTH/8; + y++; + } + u8g_SetChipSelect(u8g, dev, 0); + } + break; + } + return u8g_dev_pb8h1_base_fn(u8g, dev, msg, arg); +} + +uint8_t u8g_dev_st7920_128x64_HAL_4x_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) +{ + switch(msg) + { + case U8G_DEV_MSG_INIT: + u8g_InitCom(u8g, dev, U8G_SPI_CLK_CYCLE_400NS); + u8g_WriteEscSeqP(u8g, dev, u8g_dev_st7920_128x64_HAL_init_seq); + break; + + case U8G_DEV_MSG_STOP: + break; + + case U8G_DEV_MSG_PAGE_NEXT: + { + uint8_t y, i; + uint8_t *ptr; + u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); + + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_SetChipSelect(u8g, dev, 1); + y = pb->p.page_y0; + ptr = (uint8_t *)pb->buf; + for( i = 0; i < 32; i ++ ) + { + u8g_SetAddress(u8g, dev, 0); /* cmd mode */ + u8g_WriteByte(u8g, dev, 0x03e ); /* enable extended mode */ + + if ( y < 32 ) + { + u8g_WriteByte(u8g, dev, 0x080 | y ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 ); /* set x pos to 0*/ + } + else + { + u8g_WriteByte(u8g, dev, 0x080 | (y-32) ); /* y pos */ + u8g_WriteByte(u8g, dev, 0x080 | 8); /* set x pos to 64*/ + } + + u8g_SetAddress(u8g, dev, 1); /* data mode */ + u8g_WriteSequence(u8g, dev, WIDTH/8, ptr); + ptr += WIDTH/8; + y++; + } + u8g_SetChipSelect(u8g, dev, 0); + } + break; + } + return u8g_dev_pb32h1_base_fn(u8g, dev, msg, arg); +} + +U8G_PB_DEV(u8g_dev_st7920_128x64_HAL_sw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_HAL_fn, U8G_COM_ST7920_HAL_SW_SPI); + +#define QWIDTH (WIDTH*4) +uint8_t u8g_dev_st7920_128x64_HAL_4x_buf[QWIDTH] U8G_NOCOMMON ; +u8g_pb_t u8g_dev_st7920_128x64_HAL_4x_pb = { {32, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7920_128x64_HAL_4x_buf}; +u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_SW_SPI }; + + +U8G_PB_DEV(u8g_dev_st7920_128x64_HAL_hw_spi, WIDTH, HEIGHT, PAGE_HEIGHT, u8g_dev_st7920_128x64_HAL_fn, U8G_COM_ST7920_HAL_HW_SPI); +u8g_dev_t u8g_dev_st7920_128x64_HAL_4x_hw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_HW_SPI }; + + +#ifdef U8G_HAL_LINKS + // Also use this device for HAL version of rrd class. This results in the same device being used + // for the ST7920 for HAL systems no matter what is selected in ultralcd_impl_DOGM.h. + u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = { u8g_dev_st7920_128x64_HAL_4x_fn, &u8g_dev_st7920_128x64_HAL_4x_pb, U8G_COM_ST7920_HAL_SW_SPI }; +#endif diff --git a/Marlin/src/lcd/dogm/ultralcd_st7565_u8glib_VIKI.h b/Marlin/src/lcd/dogm/ultralcd_st7565_u8glib_VIKI.h deleted file mode 100644 index f36dec806..000000000 --- a/Marlin/src/lcd/dogm/ultralcd_st7565_u8glib_VIKI.h +++ /dev/null @@ -1,259 +0,0 @@ -/** - * Marlin 3D Printer Firmware - * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] - * - * Based on Sprinter and grbl. - * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -#ifndef ULCDST7565_H -#define ULCDST7565_H - -#include "../../Marlin.h" - -#if ENABLED(U8GLIB_ST7565_64128N) - -#define ST7565_CLK_PIN DOGLCD_SCK -#define ST7565_DAT_PIN DOGLCD_MOSI -#define ST7565_CS_PIN DOGLCD_CS -#define ST7565_A0_PIN DOGLCD_A0 - -#include - -#define WIDTH 128 -#define HEIGHT 64 -#define PAGE_HEIGHT 8 - -//set optimization so ARDUINO optimizes this file -#pragma GCC optimize (3) - -// If you want you can define your own set of delays in Configuration.h -//#define ST7565_DELAY_1 DELAY_0_NOP -//#define ST7565_DELAY_2 DELAY_0_NOP -//#define ST7565_DELAY_3 DELAY_0_NOP - -/* -#define ST7565_DELAY_1 u8g_10MicroDelay() -#define ST7565_DELAY_2 u8g_10MicroDelay() -#define ST7565_DELAY_3 u8g_10MicroDelay() -*/ - -#if F_CPU >= 20000000 - #define CPU_ST7565_DELAY_1 DELAY_0_NOP - #define CPU_ST7565_DELAY_2 DELAY_0_NOP - #define CPU_ST7565_DELAY_3 DELAY_1_NOP -#elif MB(3DRAG) || MB(K8200) || MB(K8400) - #define CPU_ST7565_DELAY_1 DELAY_0_NOP - #define CPU_ST7565_DELAY_2 DELAY_3_NOP - #define CPU_ST7565_DELAY_3 DELAY_0_NOP -#elif MB(MINIRAMBO) - #define CPU_ST7565_DELAY_1 DELAY_0_NOP - #define CPU_ST7565_DELAY_2 DELAY_4_NOP - #define CPU_ST7565_DELAY_3 DELAY_0_NOP -#elif MB(RAMBO) - #define CPU_ST7565_DELAY_1 DELAY_0_NOP - #define CPU_ST7565_DELAY_2 DELAY_0_NOP - #define CPU_ST7565_DELAY_3 DELAY_0_NOP -#elif F_CPU == 16000000 - #define CPU_ST7565_DELAY_1 DELAY_0_NOP - #define CPU_ST7565_DELAY_2 DELAY_0_NOP - #define CPU_ST7565_DELAY_3 DELAY_1_NOP -#else - #error "No valid condition for delays in 'ultralcd_st7565_u8glib_VIKI.h'" -#endif - -#ifndef ST7565_DELAY_1 - #define ST7565_DELAY_1 CPU_ST7565_DELAY_1 -#endif -#ifndef ST7565_DELAY_2 - #define ST7565_DELAY_2 CPU_ST7565_DELAY_2 -#endif -#ifndef ST7565_DELAY_3 - #define ST7565_DELAY_3 CPU_ST7565_DELAY_3 -#endif - -#if ENABLED(SHARED_SPI) // Re-ARM requires that the LCD and the SD card share a single SPI - - #define ST7565_WRITE_BYTE(a) { spiSend((uint8_t)a); U8G_DELAY; } - #define ST7560_WriteSequence(count, pointer) { uint8_t *ptr = pointer; for (uint8_t i = 0; i < count; i++) {spiSend( *ptr++);} DELAY_10US; } - -#else - #define ST7565_SND_BIT \ - WRITE(ST7565_CLK_PIN, LOW); ST7565_DELAY_1; \ - WRITE(ST7565_DAT_PIN, val & 0x80); ST7565_DELAY_2; \ - WRITE(ST7565_CLK_PIN, HIGH); ST7565_DELAY_3; \ - WRITE(ST7565_CLK_PIN, LOW);\ - val <<= 1 - - static void ST7565_SWSPI_SND_8BIT(uint8_t val) { - ST7565_SND_BIT; // 1 - ST7565_SND_BIT; // 2 - ST7565_SND_BIT; // 3 - ST7565_SND_BIT; // 4 - ST7565_SND_BIT; // 5 - ST7565_SND_BIT; // 6 - ST7565_SND_BIT; // 7 - ST7565_SND_BIT; // 8 - } - - #define ST7565_WRITE_BYTE(a) { ST7565_SWSPI_SND_8BIT((uint8_t)a); U8G_DELAY; } - #define ST7560_WriteSequence(count, pointer) { uint8_t *ptr = pointer; for (uint8_t i = 0; i < count; i++) {ST7565_SWSPI_SND_8BIT( *ptr++);} DELAY_10US; } -#endif - -#if defined(DOGM_SPI_DELAY_US) && DOGM_SPI_DELAY_US > 0 - #define U8G_DELAY delayMicroseconds(DOGM_SPI_DELAY_US) -#else - #define U8G_DELAY u8g_10MicroDelay() -#endif - -#define ST7565_CS() { WRITE(ST7565_CS_PIN,1); U8G_DELAY; } -#define ST7565_NCS() { WRITE(ST7565_CS_PIN,0); } -#define ST7565_A0() { WRITE(ST7565_A0_PIN,1); U8G_DELAY; } -#define ST7565_NA0() { WRITE(ST7565_A0_PIN,0); } - - -uint8_t u8g_dev_st7565_64128n_2x_VIKI_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, void *arg) { - switch (msg) { - case U8G_DEV_MSG_INIT: { - OUT_WRITE(ST7565_CS_PIN, LOW); - #if ENABLED(SHARED_SPI) - u8g_Delay(250); - spiBegin(); - #ifndef SPI_SPEED - #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card - #endif - spiInit(SPI_SPEED); - #else - OUT_WRITE(ST7565_DAT_PIN, LOW); - OUT_WRITE(ST7565_CLK_PIN, LOW); - #endif - OUT_WRITE(ST7565_A0_PIN, LOW); - - ST7565_CS(); /* disable chip */ - ST7565_NA0(); /* instruction mode */ - ST7565_NCS(); /* enable chip */ - - ST7565_WRITE_BYTE(0x0A2); /* 0x0A2: LCD bias 1/9 (according to Displaytech 64128N datasheet) */ - ST7565_WRITE_BYTE(0x0A0); /* Normal ADC Select (according to Displaytech 64128N datasheet) */ - - ST7565_WRITE_BYTE(0x0C8); /* common output mode: set scan direction normal operation/SHL Select; 0x0C0 --> SHL = 0; normal; 0x0C8 --> SHL = 1 */ - ST7565_WRITE_BYTE(0x040); /* Display start line for Displaytech 64128N */ - - ST7565_WRITE_BYTE(0x028 | 0x04); /* power control: turn on voltage converter */ - //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ - - ST7565_WRITE_BYTE(0x028 | 0x06); /* power control: turn on voltage regulator */ - //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ - - ST7565_WRITE_BYTE(0x028 | 0x07); /* power control: turn on voltage follower */ - //U8G_ESC_DLY(50); /* delay 50 ms - hangs after a reset if used */ - - ST7565_WRITE_BYTE(0x010); /* Set V0 voltage resistor ratio. Setting for controlling brightness of Displaytech 64128N */ - - ST7565_WRITE_BYTE(0x0A6); /* display normal, bit val 0: LCD pixel off. */ - - ST7565_WRITE_BYTE(0x081); /* set contrast */ - ST7565_WRITE_BYTE(0x01E); /* Contrast value. Setting for controlling brightness of Displaytech 64128N */ - - ST7565_WRITE_BYTE(0x0AF); /* display on */ - - U8G_ESC_DLY(100); /* delay 100 ms */ - ST7565_WRITE_BYTE(0x0A5); /* display all points; ST7565 */ - U8G_ESC_DLY(100); /* delay 100 ms */ - U8G_ESC_DLY(100); /* delay 100 ms */ - ST7565_WRITE_BYTE(0x0A4); /* normal display */ - ST7565_CS(); /* disable chip */ - } /* end of sequence */ - break; - - case U8G_DEV_MSG_STOP: break; - - case U8G_DEV_MSG_PAGE_NEXT: { - u8g_pb_t *pb = (u8g_pb_t *)(dev->dev_mem); - ST7565_CS(); /* disable chip */ - ST7565_NA0(); /* instruction mode */ - ST7565_NCS(); /* enable chip */ - ST7565_WRITE_BYTE(0x010); /* set upper 4 bit of the col adr to 0x10 */ - ST7565_WRITE_BYTE(0x000); /* set lower 4 bit of the col adr to 0x00. Changed for DisplayTech 64128N */ - /* end of sequence */ - ST7565_WRITE_BYTE(0x0B0 | (2*pb->p.page));; /* select current page (ST7565R) */ - ST7565_A0(); /* data mode */ - ST7560_WriteSequence( (uint8_t) pb->width, (uint8_t *)pb->buf); - ST7565_CS(); /* disable chip */ - ST7565_NA0(); /* instruction mode */ - ST7565_NCS(); /* enable chip */ - ST7565_WRITE_BYTE(0x010); /* set upper 4 bit of the col adr to 0x10 */ - ST7565_WRITE_BYTE(0x000); /* set lower 4 bit of the col adr to 0x00. Changed for DisplayTech 64128N */ - /* end of sequence */ - ST7565_WRITE_BYTE(0x0B0 | (2*pb->p.page+1)); /* select current page (ST7565R) */ - ST7565_A0(); /* data mode */ - ST7560_WriteSequence( (uint8_t) pb->width, (uint8_t *)(pb->buf)+pb->width); - ST7565_CS(); /* disable chip */ - } - break; - - case U8G_DEV_MSG_CONTRAST: - ST7565_NCS(); - ST7565_NA0(); /* instruction mode */ - ST7565_WRITE_BYTE(0x081); - ST7565_WRITE_BYTE((*(uint8_t *)arg) >> 2); - ST7565_CS(); /* disable chip */ - return 1; - - case U8G_DEV_MSG_SLEEP_ON: - ST7565_NA0(); /* instruction mode */ - ST7565_NCS(); /* enable chip */ - ST7565_WRITE_BYTE(0x0AC); /* static indicator off */ - ST7565_WRITE_BYTE(0x000); /* indicator register set (not sure if this is required) */ - ST7565_WRITE_BYTE(0x0AE); /* display off */ - ST7565_WRITE_BYTE(0x0A5); /* all points on */ - ST7565_CS(); /* disable chip , bugfix 12 nov 2014 */ - /* end of sequence */ - return 1; - - case U8G_DEV_MSG_SLEEP_OFF: - ST7565_NA0(); /* instruction mode */ - ST7565_NCS(); /* enable chip */ - ST7565_WRITE_BYTE(0x0A4); /* all points off */ - ST7565_WRITE_BYTE(0x0AF); /* display on */ - U8G_ESC_DLY(50); /* delay 50 ms */ - ST7565_CS(); /* disable chip , bugfix 12 nov 2014 */ - /* end of sequence */ - return 1; - } - return u8g_dev_pb16v1_base_fn(u8g, dev, msg, arg); -} - -uint8_t u8g_dev_st7565_64128n_2x_VIKI_buf[WIDTH*2] U8G_NOCOMMON ; -u8g_pb_t u8g_dev_st7565_64128n_2x_VIKI_pb = { {16, HEIGHT, 0, 0, 0}, WIDTH, u8g_dev_st7565_64128n_2x_VIKI_buf}; -u8g_dev_t u8g_dev_st7565_64128n_2x_VIKI_sw_spi = { u8g_dev_st7565_64128n_2x_VIKI_fn, &u8g_dev_st7565_64128n_2x_VIKI_pb, &u8g_com_null_fn}; - - -class U8GLIB_ST7565_64128n_2x_VIKI : public U8GLIB { - public: - U8GLIB_ST7565_64128n_2x_VIKI(uint8_t dummy) - : U8GLIB(&u8g_dev_st7565_64128n_2x_VIKI_sw_spi) - { } - U8GLIB_ST7565_64128n_2x_VIKI(uint8_t sck, uint8_t mosi, uint8_t cs, uint8_t a0, uint8_t reset = U8G_PIN_NONE) - : U8GLIB(&u8g_dev_st7565_64128n_2x_VIKI_sw_spi) - { } -}; - -#pragma GCC reset_options - -#endif // U8GLIB_ST7565 -#endif // ULCDST7565_H diff --git a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd.h b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp similarity index 57% rename from Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd.h rename to Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp index ff0057b54..261b72607 100644 --- a/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd.h +++ b/Marlin/src/lcd/dogm/ultralcd_st7920_u8glib_rrd_AVR.cpp @@ -1,6 +1,6 @@ /** * Marlin 3D Printer Firmware - * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] * * Based on Sprinter and grbl. * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm @@ -20,16 +20,25 @@ * */ -#ifndef ULCDST7920_H -#define ULCDST7920_H +// NOTE - the HAL version of the rrd device uses a generic ST7920 device. See the +// file u8g_dev_st7920_128x64_HAL.cpp for the HAL version. -#include "../../Marlin.h" +#ifndef U8G_HAL_LINKS -#if ENABLED(U8GLIB_ST7920) +#include +//#if ENABLED(U8GLIB_ST7920) +//#if ( ENABLED(SHARED_SPI) || !ENABLED(SHARED_SPI) && (defined(LCD_PINS_D4) && LCD_PINS_D4 >= 0) && (defined(LCD_PINS_ENABLE) && LCD_PINS_ENABLE >= 0)) + +#define ST7920_CLK_PIN 23 +#define ST7920_DAT_PIN 17 +#define ST7920_CS_PIN 16 + +/* #define ST7920_CLK_PIN LCD_PINS_D4 #define ST7920_DAT_PIN LCD_PINS_ENABLE #define ST7920_CS_PIN LCD_PINS_RS +*/ //#define PAGE_HEIGHT 8 //128 byte framebuffer #define PAGE_HEIGHT 16 //256 byte framebuffer @@ -52,15 +61,15 @@ #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_0_NOP #define CPU_ST7920_DELAY_3 DELAY_1_NOP -#elif MB(3DRAG) || MB(K8200) || MB(K8400) || MB(SILVER_GATE) +#elif (MOTHERBOARD == BOARD_3DRAG) || (MOTHERBOARD == BOARD_K8200) || (MOTHERBOARD == BOARD_K8400) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_3_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP -#elif MB(MINIRAMBO) +#elif (MOTHERBOARD == BOARD_MINIRAMBO) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_4_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP -#elif MB(RAMBO) +#elif (MOTHERBOARD == BOARD_RAMBO) #define CPU_ST7920_DELAY_1 DELAY_0_NOP #define CPU_ST7920_DELAY_2 DELAY_0_NOP #define CPU_ST7920_DELAY_3 DELAY_0_NOP @@ -88,37 +97,23 @@ #define U8G_DELAY() u8g_10MicroDelay() #endif -#if ENABLED(SHARED_SPI) // Re-ARM requires that the LCD and the SD card share a single SPI - #define ST7920_SET_CMD() { spiSend(0xF8); U8G_DELAY(); } - #define ST7920_SET_DAT() { spiSend(0xFA); U8G_DELAY(); } - #define ST7920_WRITE_BYTE(a) { spiSend((uint8_t)((a)&0xF0u)); U8G_DELAY(); spiSend((uint8_t)((a)<<4u)); U8G_DELAY(); } - #define ST7920_WRITE_BYTES(p,l) { for (uint8_t i = l + 1; --i;) { spiSend(*p&0xF0); spiSend(*p<<4); p++; } U8G_DELAY(); } - -#else - #define ST7920_SND_BIT \ - WRITE(ST7920_CLK_PIN, LOW); ST7920_DELAY_1; \ - WRITE(ST7920_DAT_PIN, val & 0x80); ST7920_DELAY_2; \ - WRITE(ST7920_CLK_PIN, HIGH); ST7920_DELAY_3; \ - val <<= 1 - - static void ST7920_SWSPI_SND_8BIT(uint8_t val) { - ST7920_SND_BIT; // 1 - ST7920_SND_BIT; // 2 - ST7920_SND_BIT; // 3 - ST7920_SND_BIT; // 4 - ST7920_SND_BIT; // 5 - ST7920_SND_BIT; // 6 - ST7920_SND_BIT; // 7 - ST7920_SND_BIT; // 8 +static void ST7920_WRITE_BYTE(uint8_t val) { + for (uint8_t i = 0; i < 8; i++) { + WRITE(ST7920_DAT_PIN, val & 0x80); + WRITE(ST7920_CLK_PIN, HIGH); + WRITE(ST7920_CLK_PIN, LOW); + val = val << 1; } +} + + +#define ST7920_SET_CMD() { ST7920_WRITE_BYTE(0xF8); U8G_DELAY(); } +#define ST7920_SET_DAT() { ST7920_WRITE_BYTE(0xFA); U8G_DELAY(); } +#define ST7920_WRITE_NIBBLES(a) { ST7920_WRITE_BYTE((uint8_t)((a)&0xF0u)); ST7920_WRITE_BYTE((uint8_t)((a)<<4u)); U8G_DELAY(); } +#define ST7920_WRITE_NIBBLES_P(p,l) { for (uint8_t i = l + 1; --i;) { ST7920_WRITE_BYTE(*p&0xF0); ST7920_WRITE_BYTE(*p<<4); p++; } U8G_DELAY(); } - #define ST7920_SET_CMD() { ST7920_SWSPI_SND_8BIT(0xF8); U8G_DELAY(); } - #define ST7920_SET_DAT() { ST7920_SWSPI_SND_8BIT(0xFA); U8G_DELAY(); } - #define ST7920_WRITE_BYTE(a) { ST7920_SWSPI_SND_8BIT((uint8_t)((a)&0xF0u)); ST7920_SWSPI_SND_8BIT((uint8_t)((a)<<4u)); U8G_DELAY(); } - #define ST7920_WRITE_BYTES(p,l) { for (uint8_t i = l + 1; --i;) { ST7920_SWSPI_SND_8BIT(*p&0xF0); ST7920_SWSPI_SND_8BIT(*p<<4); p++; } U8G_DELAY(); } -#endif #define ST7920_CS() { WRITE(ST7920_CS_PIN,1); U8G_DELAY(); } #define ST7920_NCS() { WRITE(ST7920_CS_PIN,0); } @@ -131,47 +126,35 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo case U8G_DEV_MSG_INIT: { OUT_WRITE(ST7920_CS_PIN, LOW); - #if ENABLED(SHARED_SPI) - u8g_Delay(250); - spiBegin(); - spiInit(SPI_EIGHTH_SPEED); // run LCD at 1 MHz - garbled display if run at 2 MHz - #else + OUT_WRITE(ST7920_DAT_PIN, LOW); - OUT_WRITE(ST7920_CLK_PIN, HIGH); - #endif + OUT_WRITE(ST7920_CLK_PIN, LOW); ST7920_CS(); u8g_Delay(120); //initial delay for boot up ST7920_SET_CMD(); - ST7920_WRITE_BYTE(0x08); //display off, cursor+blink off - ST7920_WRITE_BYTE(0x01); //clear CGRAM ram + ST7920_WRITE_NIBBLES(0x08); //display off, cursor+blink off + ST7920_WRITE_NIBBLES(0x01); //clear CGRAM ram u8g_Delay(15); //delay for CGRAM clear - ST7920_WRITE_BYTE(0x3E); //extended mode + GDRAM active + ST7920_WRITE_NIBBLES(0x3E); //extended mode + GDRAM active for (y = 0; y < (LCD_PIXEL_HEIGHT) / 2; y++) { //clear GDRAM - ST7920_WRITE_BYTE(0x80 | y); //set y - ST7920_WRITE_BYTE(0x80); //set x = 0 + ST7920_WRITE_NIBBLES(0x80 | y); //set y + ST7920_WRITE_NIBBLES(0x80); //set x = 0 ST7920_SET_DAT(); for (i = 0; i < 2 * (LCD_PIXEL_WIDTH) / 8; i++) //2x width clears both segments - ST7920_WRITE_BYTE(0); + ST7920_WRITE_NIBBLES(0); ST7920_SET_CMD(); } - ST7920_WRITE_BYTE(0x0C); //display on, cursor+blink off - #if ENABLED(SHARED_SPI) - #ifndef SPI_SPEED - #define SPI_SPEED SPI_FULL_SPEED // switch SPI speed back to SD card speed - #endif - spiInit(SPI_SPEED); - #endif + ST7920_WRITE_NIBBLES(0x0C); //display on, cursor+blink off + ST7920_NCS(); } break; case U8G_DEV_MSG_STOP: break; case U8G_DEV_MSG_PAGE_NEXT: { - #if ENABLED(SHARED_SPI) - spiInit(SPI_EIGHTH_SPEED); // run LCD at 1 MHz - garbled display if run at 2 MHz - #endif + uint8_t* ptr; u8g_pb_t* pb = (u8g_pb_t*)(dev->dev_mem); y = pb->p.page_y0; @@ -181,20 +164,18 @@ uint8_t u8g_dev_rrd_st7920_128x64_fn(u8g_t *u8g, u8g_dev_t *dev, uint8_t msg, vo for (i = 0; i < PAGE_HEIGHT; i ++) { ST7920_SET_CMD(); if (y < 32) { - ST7920_WRITE_BYTE(0x80 | y); //y - ST7920_WRITE_BYTE(0x80); //x=0 + ST7920_WRITE_NIBBLES(0x80 | y); //y + ST7920_WRITE_NIBBLES(0x80); //x=0 } else { - ST7920_WRITE_BYTE(0x80 | (y - 32)); //y - ST7920_WRITE_BYTE(0x80 | 8); //x=64 + ST7920_WRITE_NIBBLES(0x80 | (y - 32)); //y + ST7920_WRITE_NIBBLES(0x80 | 8); //x=64 } ST7920_SET_DAT(); - ST7920_WRITE_BYTES(ptr, (LCD_PIXEL_WIDTH) / 8); //ptr is incremented inside of macro + ST7920_WRITE_NIBBLES_P(ptr, (LCD_PIXEL_WIDTH) / 8); //ptr is incremented inside of macro y++; } - #if ENABLED(SHARED_SPI) - spiInit(SPI_SPEED); // switch SPI speed back to SD card speed - #endif + ST7920_NCS(); } break; @@ -212,12 +193,8 @@ uint8_t u8g_dev_st7920_128x64_rrd_buf[(LCD_PIXEL_WIDTH) * (PAGE_HEIGHT) / 8] U u8g_pb_t u8g_dev_st7920_128x64_rrd_pb = {{PAGE_HEIGHT, LCD_PIXEL_HEIGHT, 0, 0, 0}, LCD_PIXEL_WIDTH, u8g_dev_st7920_128x64_rrd_buf}; u8g_dev_t u8g_dev_st7920_128x64_rrd_sw_spi = {u8g_dev_rrd_st7920_128x64_fn, &u8g_dev_st7920_128x64_rrd_pb, &u8g_com_null_fn}; -class U8GLIB_ST7920_128X64_RRD : public U8GLIB { - public: - U8GLIB_ST7920_128X64_RRD(uint8_t dummy) : U8GLIB(&u8g_dev_st7920_128x64_rrd_sw_spi) { UNUSED(dummy); } -}; - #pragma GCC reset_options -#endif // U8GLIB_ST7920 -#endif // ULCDST7920_H +//#endif //( ENABLED(SHARED_SPI) || !ENABLED(SHARED_SPI) && (defined(LCD_PINS_D4) && LCD_PINS_D4 >= 0) && (defined(LCD_PINS_ENABLE) && LCD_PINS_ENABLE >= 0)) +//#endif // U8GLIB_ST7920 +#endif // AVR diff --git a/Marlin/src/lcd/ultralcd.cpp b/Marlin/src/lcd/ultralcd.cpp index 043380def..9a3f513ed 100644 --- a/Marlin/src/lcd/ultralcd.cpp +++ b/Marlin/src/lcd/ultralcd.cpp @@ -4758,6 +4758,11 @@ void lcd_update() { #if ENABLED(DOGLCD) // Changes due to different driver architecture of the DOGM display if (!drawing_screen) { +#if defined(TARGET_LPC1768) +digitalWrite(P1_4, !digitalRead(P1_4)); //re-arm (was 77 in the old system) +#else +digitalWrite(29, !digitalRead(29)); //2560 +#endif u8g.firstPage(); drawing_screen = 1; } diff --git a/Marlin/src/lcd/ultralcd_impl_DOGM.h b/Marlin/src/lcd/ultralcd_impl_DOGM.h index 5d3f15ab4..bb6fddfd8 100644 --- a/Marlin/src/lcd/ultralcd_impl_DOGM.h +++ b/Marlin/src/lcd/ultralcd_impl_DOGM.h @@ -44,11 +44,13 @@ */ #include "ultralcd.h" +/* #if ENABLED(U8GLIB_ST7565_64128N) #include "dogm/ultralcd_st7565_u8glib_VIKI.h" #elif ENABLED(U8GLIB_ST7920) #include "dogm/ultralcd_st7920_u8glib_rrd.h" #endif +*/ #include "dogm/dogm_bitmaps.h" @@ -57,6 +59,7 @@ #endif #include +#include #if ENABLED(AUTO_BED_LEVELING_UBL) #include "../feature/bedlevel/ubl/ubl.h" @@ -161,53 +164,52 @@ // LCD selection #if ENABLED(REPRAPWORLD_GRAPHICAL_LCD) - U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes - // U8GLIB_ST7920_128X64 u8g(LCD_PINS_RS); // 8 stripes -#elif ENABLED(U8GLIB_ST7920) - //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes - // No 4 stripe device available from u8glib. - //U8GLIB_ST7920_128X64_1X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 8 stripes - U8GLIB_ST7920_128X64_RRD u8g(0); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT + U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI + //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI +#elif ENABLED(U8GLIB_ST7920) + // RepRap Discount Full Graphics Smart Controller + //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_RS); // 2 stripes, HW SPI + //U8GLIB_ST7920_128X64_4X u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Original u8glib device. 2 stripes, SW SPI + U8GLIB_ST7920_128X64_RRD u8g(LCD_PINS_D4, LCD_PINS_ENABLE, LCD_PINS_RS); // Number of stripes can be adjusted in ultralcd_st7920_u8glib_rrd.h with PAGE_HEIGHT + // AVR version ignores these pin settings + // HAL version uses these pin settings #elif ENABLED(CARTESIO_UI) // The CartesioUI display - #if DOGLCD_MOSI != -1 && DOGLCD_SCK != -1 - // using SW-SPI - //U8GLIB_DOGM128 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes - U8GLIB_DOGM128_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes - #else - //U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + //U8GLIB_DOGM128_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes U8GLIB_DOGM128_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes - #endif + #elif ENABLED(U8GLIB_LM6059_AF) // Based on the Adafruit ST7565 (http://www.adafruit.com/products/250) - //U8GLIB_LM6059 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes - U8GLIB_LM6059_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes + //U8GLIB_LM6059 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_LM6059_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes #elif ENABLED(U8GLIB_ST7565_64128N) // The MaKrPanel, Mini Viki, and Viki 2.0, ST7565 controller - //U8GLIB_ST7565_64128n_2x_VIKI u8g(0); // using SW-SPI DOGLCD_MOSI != -1 && DOGLCD_SCK - U8GLIB_ST7565_64128n_2x_VIKI u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // using SW-SPI - //U8GLIB_NHD_C12864 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes - //U8GLIB_NHD_C12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes HWSPI + //U8GLIB_64128N_2X_HAL u8g(DOGLCD_CS, DOGLCD_A0); // using HW-SPI + U8GLIB_64128N_2X_HAL u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // using SW-SPI + #elif ENABLED(U8GLIB_SSD1306) // Generic support for SSD1306 OLED I2C LCDs - //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes - U8GLIB_SSD1306_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes + //U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes + U8GLIB_SSD1306_128X64_2X_I2C_2_WIRE u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes + //U8GLIB_SSD1306_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes + #elif ENABLED(MKS_12864OLED) // MKS 128x64 (SH1106) OLED I2C LCD - U8GLIB_SH1106_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes - //U8GLIB_SH1106_128X64_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes + U8GLIB_SH1106_128X64 u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 8 stripes + //U8GLIB_SH1106_128X64_2X u8g(DOGLCD_SCK, DOGLCD_MOSI, DOGLCD_CS, DOGLCD_A0); // 4 stripes #elif ENABLED(U8GLIB_SH1106) // Generic support for SH1106 OLED I2C LCDs - //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes - U8GLIB_SH1106_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes + //U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 8 stripes + U8GLIB_SH1106_128X64_2X_I2C_2_WIRE u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes + //U8GLIB_SH1106_128X64_2X u8g(U8G_I2C_OPT_NONE | U8G_I2C_OPT_FAST); // 4 stripes #elif ENABLED(MINIPANEL) // The MINIPanel display - //U8GLIB_MINI12864 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes - U8GLIB_MINI12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes + //U8GLIB_MINI12864 u8g(DOGLCD_CS, DOGLCD_A0); // 8 stripes + U8GLIB_MINI12864_2X u8g(DOGLCD_CS, DOGLCD_A0); // 4 stripes #else // for regular DOGM128 display with HW-SPI - //U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 8 stripes - U8GLIB_DOGM128_2X u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 4 stripes + //U8GLIB_DOGM128 u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 8 stripes + U8GLIB_DOGM128_2X u8g(DOGLCD_CS, DOGLCD_A0); // HW-SPI Com: CS, A0 // 4 stripes #endif #ifndef LCD_PIXEL_WIDTH @@ -311,6 +313,8 @@ void lcd_printPGM_utf(const char *str, uint8_t n=LCD_WIDTH) { const uint8_t offx = (u8g.getWidth() - (START_BMPWIDTH)) / 2, txt1X = (u8g.getWidth() - (sizeof(STRING_SPLASH_LINE1) - 1) * (DOG_CHAR_WIDTH)) / 2; + static bool show_bootscreen = true; + u8g.firstPage(); do { u8g.drawBitmapP(offx, offy, START_BMPBYTEWIDTH, START_BMPHEIGHT, start_bmp); @@ -354,6 +358,7 @@ static void lcd_implementation_init() { #elif ENABLED(LCD_SCREEN_ROT_270) u8g.setRot270(); // Rotate screen by 270° #endif + } // The kill screen is displayed for unrecoverable conditions diff --git a/platformio.ini b/platformio.ini index a918a94be..66b3dd134 100644 --- a/platformio.ini +++ b/platformio.ini @@ -19,13 +19,15 @@ env_default = megaatmega2560 [common] lib_deps = - U8glib@1.19.1 + LiquidCrystal_I2C@1.1.2 https://github.com/lincomatic/LiquidTWI2.git https://github.com/teemuatlut/TMC2130Stepper.git https://github.com/trinamic/TMC26XStepper.git https://github.com/adafruit/Adafruit_NeoPixel.git https://github.com/ameyer/Arduino-L6470.git + U8glib-HAL + default_src_filter = + - @@ -47,6 +49,7 @@ platform = atmelavr framework = arduino board = megaatmega2560 build_flags = -I $BUILDSRC_DIR + -fmax-errors=5 board_f_cpu = 16000000L lib_deps = ${common.lib_deps} src_filter = ${common.default_src_filter} @@ -145,11 +148,14 @@ src_filter = ${common.default_src_filter} platform = nxplpc board_f_cpu = 100000000L build_flags = !python Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py + -DU8G_HAL_LINKS src_build_flags = -Wall build_unflags = -Wall lib_ldf_mode = off lib_extra_dirs = frameworks -lib_deps = U8glib-ARM, CMSIS-LPC1768 +#lib_deps = U8glib-ARM, CMSIS-LPC1768 +lib_deps = CMSIS-LPC1768 + U8glib-HAL extra_scripts = Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py src_filter = ${common.default_src_filter} @@ -163,9 +169,11 @@ platform = nxplpc board = lpc1768 board_f_cpu = 100000000L build_flags = !python Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py + -DU8G_HAL_LINKS lib_ldf_mode = off lib_extra_dirs = frameworks -lib_deps = U8glib-ARM, CMSIS-LPC1768 +lib_deps = CMSIS-LPC1768 + U8glib-HAL src_filter = ${common.default_src_filter} extra_scripts = Marlin/src/HAL/HAL_LPC1768/debug_extra_script.py, Marlin/src/HAL/HAL_LPC1768/lpc1768_flag_script.py debug_tool = custom @@ -190,4 +198,3 @@ board = genericSTM32F103RE build_flags = !python Marlin/src/HAL/HAL_STM32F1/stm32f1_flag_script.py lib_deps = ${common.lib_deps} src_filter = ${common.default_src_filter} -