From: arighi Date: Fri, 9 Apr 2010 14:27:34 +0000 (+0000) Subject: LCD: generic OLED-RIT-128x96 (P14201) graphic display driver implementation. X-Git-Tag: 2.5.0~501 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=3b1451f6e3161b0f1b16e9be49dd46649b03a9d9;p=bertos.git LCD: generic OLED-RIT-128x96 (P14201) graphic display driver implementation. git-svn-id: https://src.develer.com/svnoss/bertos/trunk@3407 38d2e660-2303-0410-9eaa-f027e97ec537 --- diff --git a/bertos/cpu/cortex-m3/drv/lcd_lm3s.c b/bertos/cpu/cortex-m3/drv/lcd_lm3s.c deleted file mode 100644 index 2c98486f..00000000 --- a/bertos/cpu/cortex-m3/drv/lcd_lm3s.c +++ /dev/null @@ -1,228 +0,0 @@ -/** - * \file - * - * - * \brief LM3S1968 OLED display driver. - * - * \author Andrea Righi - */ - -#include -#include -#include "io/lm3s.h" -#include "clock_lm3s.h" -#include "ssi_lm3s.h" -#include "gpio_lm3s.h" -#include "lcd_lm3s.h" - -#define GPIO_OLEDDC_BASE GPIO_PORTH_BASE -#define GPIO_OLEDDC_PIN BV(2) -#define GPIO_OLEDEN_PIN BV(3) - -/* - * Hard-coded command initialization sequence. - * - * NOTE: the first byte is the size of the command. - */ -static const uint8_t init_cmd[] = -{ - /* Unlock commands */ - 3, 0xfd, 0x12, 0xe3, - /* Display off */ - 2, 0xae, 0xe3, - /* Icon off */ - 3, 0x94, 0, 0xe3, - /* Multiplex ratio */ - 3, 0xa8, 95, 0xe3, - /* Contrast */ - 3, 0x81, 0xb7, 0xe3, - /* Pre-charge current */ - 3, 0x82, 0x3f, 0xe3, - /* Display Re-map */ - 3, 0xa0, 0x52, 0xe3, - /* Display Start Line */ - 3, 0xa1, 0, 0xe3, - /* Display Offset */ - 3, 0xa2, 0x00, 0xe3, - /* Display Mode Normal */ - 2, 0xa4, 0xe3, - /* Phase Length */ - 3, 0xb1, 0x11, 0xe3, - /* Frame frequency */ - 3, 0xb2, 0x23, 0xe3, - /* Front Clock Divider */ - 3, 0xb3, 0xe2, 0xe3, - /* Set gray scale table */ - 17, 0xb8, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 19, 22, 26, 30, 0xe3, - /* Second pre-charge period */ - 3, 0xbb, 0x01, 0xe3, - /* Pre-charge voltage */ - 3, 0xbc, 0x3f, 0xe3, - /* Display ON */ - 2, 0xaf, 0xe3, -}; - -/* - * Hard-coded command shutdown sequence. - */ -static const uint8_t exit_cmd[] = -{ - /* Display OFF */ - 0xae, 0xe3 -}; - -/* - * Hard-coded horizontal increment command. - */ -static const uint8_t horizontal_inc[] = -{ - 0xa0, 0x52 -}; - -/** - * Write a sequence of data bytes to the LCD SSD1329 controller - */ -static void lcd_writeData(const uint8_t *buf, size_t count) -{ - while (count--) - lm3s_ssi_write_frame(SSI0_BASE, *buf++); -} - -/* Turn on the OLED display */ -void lm3s_lcd_on(void) -{ - unsigned int i; - - /* Loop through the SSD1329 controller initialization sequence */ - for (i = 0; i < sizeof(init_cmd); i += init_cmd[i] + 1) - { - lm3s_gpio_pin_write(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN, 0); - lcd_writeData(init_cmd + i + 1, init_cmd[i] - 1); - } -} - -/* Turn off the OLED display */ -void lm3s_lcd_off(void) -{ - lm3s_gpio_pin_write(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN, 0); - lcd_writeData(exit_cmd, sizeof(exit_cmd)); -} - -/* Refresh a bitmap on screen */ -void lm3s_lcd_blitBitmap(const Bitmap *bm) -{ - uint8_t lcd_row[bm->width / 2]; - uint8_t buffer[8]; - uint8_t mask; - int i, l; - - ASSERT(bm->width == LCD_WIDTH && bm->height == LCD_HEIGHT); - - /* Enter command mode */ - lm3s_gpio_pin_write(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN, 0); - - buffer[0] = 0x15; - buffer[1] = 0; - buffer[2] = (bm->width - 2) / 2; - lcd_writeData(buffer, 3); - - buffer[0] = 0x75; - buffer[1] = 0; - buffer[2] = bm->height - 1; - lcd_writeData(buffer, 3); - lcd_writeData((const uint8_t *)&horizontal_inc, sizeof(horizontal_inc)); - - /* - * Enter data mode and send the encoded image data to the OLED display, - * over the SSI bus. - */ - lm3s_gpio_pin_write(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN, GPIO_OLEDDC_PIN); - for (l = 0; l < bm->height / 8; l++) - { - for (mask = 1; mask; mask <<= 1) - { - for (i = 0; i < bm->width; i++) - { - if (bm->raster[l * bm->width + i] & mask) - lcd_row[i / 2] |= i & 1 ? 0x0f : 0xf0; - else - lcd_row[i / 2] &= i & 1 ? 0xf0 : 0x0f; - } - /* Write an entire row at once */ - lcd_writeData(lcd_row, sizeof(lcd_row)); - } - } -} - -/** - * Initialize the OLED display - * - * \param freq The SSI Clock Frequency - */ -void lm3s_lcd_init(unsigned long freq) -{ - uint32_t dummy; - - /* Enable the peripheral clock */ - SYSCTL_RCGC1_R |= SYSCTL_RCGC1_SSI0; - SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOA; - SYSCTL_RCGC2_R |= SYSCTL_RCGC2_GPIOH; - __delay(512); - - /* Configure the SSI0CLK and SSIOTX pins for SSI operation. */ - lm3s_gpio_pin_config(GPIO_PORTA_BASE, BV(2) | BV(3) | BV(5), - GPIO_DIR_MODE_HW, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU); - /* - * Configure the GPIO port pin used as a D/Cn signal for OLED device, - * and the port pin used to enable power to the OLED panel. - */ - lm3s_gpio_pin_config(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN, - GPIO_DIR_MODE_OUT, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD); - lm3s_gpio_pin_write(GPIO_OLEDDC_BASE, GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN, - GPIO_OLEDDC_PIN | GPIO_OLEDEN_PIN); - - /* Configure the SSI0 port for master mode */ - lm3s_ssi_init(SSI0_BASE, SSI_FRF_MOTO_MODE_2, SSI_MODE_MASTER, freq, 8); - /* - * Configure the GPIO port pin used as a D/Cn signal for OLED device, - * and the port pin used to enable power to the OLED panel. - */ - lm3s_gpio_pin_config(GPIO_PORTA_BASE, GPIO_OLEDEN_PIN, - GPIO_DIR_MODE_HW, GPIO_STRENGTH_8MA, GPIO_PIN_TYPE_STD_WPU); - /* Enable the SSI port */ - lm3s_ssi_enable(SSI0_BASE); - - /* Drain the RX fifo */ - while (lm3s_ssi_read_frame_nonblocking(SSI0_BASE, &dummy)); - - /* Turn on the OLED display */ - lm3s_lcd_on(); -} diff --git a/bertos/cpu/cortex-m3/drv/lcd_lm3s.h b/bertos/cpu/cortex-m3/drv/lcd_lm3s.h deleted file mode 100644 index 72048615..00000000 --- a/bertos/cpu/cortex-m3/drv/lcd_lm3s.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * \file - * - * - * \brief LM3S1968 OLED display driver. - */ - -#ifndef LCD_LM3S_H -#define LCD_LM3S_H - -#include /* Bitmap */ - -#define LCD_WIDTH 128 -#define LCD_HEIGHT 96 - -void lm3s_lcd_blitBitmap(const Bitmap *bm); -void lm3s_lcd_on(void); -void lm3s_lcd_off(void); -void lm3s_lcd_init(unsigned long freq); - -#endif /* LCD_LM3S_H */ diff --git a/bertos/drv/lcd_rit128x96.c b/bertos/drv/lcd_rit128x96.c new file mode 100644 index 00000000..216237d8 --- /dev/null +++ b/bertos/drv/lcd_rit128x96.c @@ -0,0 +1,188 @@ +/** + * \file + * + * + * \brief OLED-RIT-128x96 (P14201) graphic display driver + * + * \author Andrea Righi + */ + +#include +#include + +#include "lcd_rit128x96.h" + +/* + * Hard-coded command initialization sequence. + * + * NOTE: the first byte is the size of the command. + */ +static const uint8_t init_cmd[] = +{ + /* Unlock commands */ + 3, 0xfd, 0x12, 0xe3, + /* Display off */ + 2, 0xae, 0xe3, + /* Icon off */ + 3, 0x94, 0, 0xe3, + /* Multiplex ratio */ + 3, 0xa8, 95, 0xe3, + /* Contrast */ + 3, 0x81, 0xb7, 0xe3, + /* Pre-charge current */ + 3, 0x82, 0x3f, 0xe3, + /* Display Re-map */ + 3, 0xa0, 0x52, 0xe3, + /* Display Start Line */ + 3, 0xa1, 0, 0xe3, + /* Display Offset */ + 3, 0xa2, 0x00, 0xe3, + /* Display Mode Normal */ + 2, 0xa4, 0xe3, + /* Phase Length */ + 3, 0xb1, 0x11, 0xe3, + /* Frame frequency */ + 3, 0xb2, 0x23, 0xe3, + /* Front Clock Divider */ + 3, 0xb3, 0xe2, 0xe3, + /* Set gray scale table */ + 17, 0xb8, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 19, 22, 26, 30, 0xe3, + /* Second pre-charge period */ + 3, 0xbb, 0x01, 0xe3, + /* Pre-charge voltage */ + 3, 0xbc, 0x3f, 0xe3, + /* Display ON */ + 2, 0xaf, 0xe3, +}; + +/* + * Hard-coded command shutdown sequence. + */ +static const uint8_t exit_cmd[] = +{ + /* Display OFF */ + 0xae, 0xe3 +}; + +/* + * Hard-coded horizontal increment command. + */ +static const uint8_t horizontal_inc[] = +{ + 0xa0, 0x52 +}; + +/** + * Write a sequence of data bytes to the LCD controller + */ +static void lcd_dataWrite(const uint8_t *buf, size_t count) +{ + while (count--) + { + LCD_WRITE(*buf++); + /* Dummy read to drain the FIFO */ + (void)LCD_READ(); + } +} + +/* Turn on the OLED display */ +void rit128x96_lcd_on(void) +{ + unsigned int i; + + /* Loop through the SSD1329 controller initialization sequence */ + LCD_SET_COMMAND(); + for (i = 0; i < sizeof(init_cmd); i += init_cmd[i] + 1) + lcd_dataWrite(init_cmd + i + 1, init_cmd[i] - 1); +} + +/* Turn off the OLED display */ +void rit128x96_lcd_off(void) +{ + LCD_SET_COMMAND(); + lcd_dataWrite(exit_cmd, sizeof(exit_cmd)); +} + +/* Refresh a bitmap on screen */ +void rit128x96_lcd_blitBitmap(const Bitmap *bm) +{ + uint8_t lcd_row[bm->width / 2]; + uint8_t buffer[8]; + uint8_t mask; + int i, l; + + ASSERT(bm->width == LCD_WIDTH && bm->height == LCD_HEIGHT); + + /* Enter command mode */ + LCD_SET_COMMAND(); + + buffer[0] = 0x15; + buffer[1] = 0; + buffer[2] = (bm->width - 2) / 2; + lcd_dataWrite(buffer, 3); + + buffer[0] = 0x75; + buffer[1] = 0; + buffer[2] = bm->height - 1; + lcd_dataWrite(buffer, 3); + lcd_dataWrite((const uint8_t *)&horizontal_inc, sizeof(horizontal_inc)); + + /* + * Enter data mode and send the encoded image data to the OLED display, + * over the SSI bus. + */ + LCD_SET_DATA(); + for (l = 0; l < bm->height / 8; l++) + { + for (mask = 1; mask; mask <<= 1) + { + for (i = 0; i < bm->width; i++) + { + if (bm->raster[l * bm->width + i] & mask) + lcd_row[i / 2] |= i & 1 ? 0x0f : 0xf0; + else + lcd_row[i / 2] &= i & 1 ? 0xf0 : 0x0f; + } + /* Write an entire row at once */ + lcd_dataWrite(lcd_row, sizeof(lcd_row)); + } + } +} + +/* Initialize the OLED display */ +void rit128x96_lcd_init(void) +{ + /* Initialize the communication bus */ + lcd_bus_init(); + + /* Turn on the OLED display */ + rit128x96_lcd_on(); +} diff --git a/bertos/drv/lcd_rit128x96.h b/bertos/drv/lcd_rit128x96.h new file mode 100644 index 00000000..aaebd48a --- /dev/null +++ b/bertos/drv/lcd_rit128x96.h @@ -0,0 +1,53 @@ +/** + * \file + * + * + * \brief OLED-RIT-128x96 (P14201) graphic display driver + */ + +#ifndef LCD_LM3S_H +#define LCD_LM3S_H + +#include +#include +#include +#include /* Bitmap */ +#include + +#define LCD_WIDTH 128 +#define LCD_HEIGHT 96 + +void rit128x96_lcd_blitBitmap(const Bitmap *bm); +void rit128x96_lcd_on(void); +void rit128x96_lcd_off(void); +void rit128x96_lcd_init(void); + +#endif /* LCD_LM3S_H */