diff --git a/examples/ssd1306_example/main.c b/examples/ssd1306_example/main.c index 0238408..58781c5 100644 --- a/examples/ssd1306_example/main.c +++ b/examples/ssd1306_example/main.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -45,6 +46,11 @@ static const ssd1306_t dev = { /* Local frame buffer */ static uint8_t buffer[DISPLAY_WIDTH * DISPLAY_HEIGHT / 8]; +TimerHandle_t scrol_timer_handle = NULL; // Timer handler + + +#define SECOND (1000 / portTICK_PERIOD_MS) + static void ssd1306_task(void *pvParameters) { @@ -58,7 +64,7 @@ static void ssd1306_task(void *pvParameters) ssd1306_set_whole_display_lighting(&dev, false); bool fwd = false; while (1) { - vTaskDelay(2000 / portTICK_PERIOD_MS); + vTaskDelay(2*SECOND); printf("%s: still alive, flipping!\n", __FUNCTION__); ssd1306_set_scan_direction_fwd(&dev, fwd); fwd = !fwd; @@ -67,11 +73,22 @@ static void ssd1306_task(void *pvParameters) error_loop: printf("%s: error while loading framebuffer into SSD1306\n", __func__); for(;;){ - vTaskDelay(2000 / portTICK_PERIOD_MS); + vTaskDelay(2*SECOND); printf("%s: error loop\n", __FUNCTION__); } } +void scrolling_timer(TimerHandle_t h) +{ + static bool scrol = true ; + if(scrol) + ssd1306_start_scroll_hori(&dev, false, 0, 7, FRAME_25); + else + ssd1306_stop_scroll(&dev); + printf("Scrolling status: %s\n", (scrol)? "On" : "Off"); + scrol=!scrol ; +} + void user_init(void) { // Setup HW @@ -86,11 +103,16 @@ void user_init(void) while (ssd1306_init(&dev) != 0) { printf("%s: failed to init SSD1306 lcd\n", __func__); - vTaskDelay(1000/portTICK_PERIOD_MS); + vTaskDelay(SECOND); } ssd1306_set_whole_display_lighting(&dev, true); - vTaskDelay(1000/portTICK_PERIOD_MS); + vTaskDelay(SECOND); // Create user interface task xTaskCreate(ssd1306_task, "ssd1306_task", 256, NULL, 2, NULL); + + //Scrolling timer + scrol_timer_handle = xTimerCreate("fps_timer", 10*SECOND, pdTRUE, NULL, scrolling_timer); + xTimerStart(scrol_timer_handle, 0); + } diff --git a/extras/ssd1306/ssd1306.c b/extras/ssd1306/ssd1306.c index 4bad19a..2d8dc18 100644 --- a/extras/ssd1306/ssd1306.c +++ b/extras/ssd1306/ssd1306.c @@ -63,6 +63,13 @@ #define SSD1306_CHARGE_PUMP_EN (0x14) #define SSD1306_CHARGE_PUMP_DIS (0x10) +#define SSD1306_SCROL_HOR_LEFT (0x27) +#define SSD1306_SCROL_HOR_RIGHT (0x26) +#define SSD1306_SCROL_HOR_VER_LEFT (0x2A) +#define SSD1306_SCROL_HOR_VER_RIGHT (0x29) +#define SSD1306_SCROL_ENABLE (0x2F) +#define SSD1306_SCROL_DISABLE (0x2E) + #ifdef SSD1306_DEBUG #define debug(fmt, ...) printf("%s: " fmt "\n", "SSD1306", ## __VA_ARGS__) #else @@ -935,3 +942,70 @@ uint8_t ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb, } return x - t; } + +int ssd1306_stop_scroll(const ssd1306_t *dev) +{ + return ssd1306_command(dev, SSD1306_SCROL_DISABLE); +} + +int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, ssd1306_scroll_t frame) +{ + int err ; + + if (way) + { + if ((err = ssd1306_command(dev, SSD1306_SCROL_HOR_LEFT))) + return err ; + } + else + { + if ((err = ssd1306_command(dev, SSD1306_SCROL_HOR_RIGHT))) + return err ; + } + if (!ssd1306_command(dev, 0x00) && //dummy + !ssd1306_command(dev, (start&0x07)) && + !ssd1306_command(dev, frame) && + !ssd1306_command(dev, (stop&0x07)) && + !ssd1306_command(dev, 0x00) && //dummy + !ssd1306_command(dev, 0xFF) && //dummy + !ssd1306_command(dev, SSD1306_SCROL_ENABLE)) { + return 0; + } + return -EIO; +} + +int ssd1306_set_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame) +{ + //this function dont work well if no vertical setting. + if ( (!dy) || (dy > 63)) + return -EINVAL; + int err ; + + //vertical scrolling selection (all screen) + if ((err = ssd1306_command(dev, 0xA3))) + return err ; + if ((err = ssd1306_command(dev, 0))) + return err ; + if ((err = ssd1306_command(dev, dev->height))) + return err ; + + if (way) + { + if ((err = ssd1306_command(dev, SSD1306_SCROL_HOR_VER_LEFT))) + return err ; + } + else + { + if ((err = ssd1306_command(dev, SSD1306_SCROL_HOR_VER_RIGHT))) + return err ; + } + if (!ssd1306_command(dev, 0x00) && //dummy + !ssd1306_command(dev, (start&0x07)) && + !ssd1306_command(dev, frame) && + !ssd1306_command(dev, (stop&0x07)) && + !ssd1306_command(dev, dy) && + !ssd1306_command(dev, SSD1306_SCROL_ENABLE)) { + return 0; + } + return -EIO; +} diff --git a/extras/ssd1306/ssd1306.h b/extras/ssd1306/ssd1306.h index ee1fc74..43df6fe 100644 --- a/extras/ssd1306/ssd1306.h +++ b/extras/ssd1306/ssd1306.h @@ -75,6 +75,23 @@ typedef enum OLED_COLOR_WHITE = 1, //!< White (or blue, yellow, pixel on) OLED_COLOR_INVERT = 2, //!< Invert pixel (XOR) } ssd1306_color_t; + +/** + * Scrolling time frame interval + */ +typedef enum +{ + FRAME_5 = 0, + FRAME_64, + FRAME_128, + FRAME_256, + FRAME_3, + FRAME_4, + FRAME_25, + FRAME_2 + +} ssd1306_scroll_t; + /** * Issue a single command on SSD1306. * @param dev Pointer to device descriptor @@ -443,6 +460,36 @@ uint8_t ssd1306_draw_char(const ssd1306_t *dev, uint8_t *fb, const font_info_t * */ uint8_t ssd1306_draw_string(const ssd1306_t *dev, uint8_t *fb, const font_info_t *font, uint8_t x, uint8_t y, char *str, ssd1306_color_t foreground, ssd1306_color_t background); +/** + * Stop scrolling (the ram data needs to be rewritten) + * @param dev Pointer to device descriptor + * @return Non-zero if error occured + */ +int ssd1306_stop_scroll(const ssd1306_t *dev); + +/** + * Start horizontal scrolling + * @param dev Pointer to device descriptor + * @param way Orientation ( true: left // false: right ) + * @param start Page address start + * @param stop Page address stop + * @param frame Time interval between each scroll + * @return Non-zero if error occured + */ +int ssd1306_start_scroll_hori(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, ssd1306_scroll_t frame); + +/** + * Start horizontal+vertical scrolling (cant vertical scrolling) + * @param dev Pointer to device descriptor + * @param way Orientation ( true: left // false: right ) + * @param start Page address start + * @param stop Page address stop + * @param dy vertical size shifting (min : 1 // max: 63 ) + * @param frame Time interval between each scroll + * @return Non-zero if error occured + */ +int ssd1306_set_scroll_hori_vert(const ssd1306_t *dev, bool way, uint8_t start, uint8_t stop, uint8_t dy, ssd1306_scroll_t frame); + #ifdef __cplusplus extern "C" }