X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=uzumeapp%2Fkernel%2Fconfig%2Fblackfin%2Fbsp_bluetank%2Flcd.c;fp=uzumeapp%2Fkernel%2Fconfig%2Fblackfin%2Fbsp_bluetank%2Flcd.c;h=c3019fb6b357e238a63ac38b28de9b0146991fc4;hb=e8dd934e273c97055d844a1ec2f28e7d834ce042;hp=0000000000000000000000000000000000000000;hpb=51d3b1e112bb303f092dcdcb8f19df7259253e04;p=uzume%2Fuzume_bfin.git diff --git a/uzumeapp/kernel/config/blackfin/bsp_bluetank/lcd.c b/uzumeapp/kernel/config/blackfin/bsp_bluetank/lcd.c new file mode 100644 index 0000000..c3019fb --- /dev/null +++ b/uzumeapp/kernel/config/blackfin/bsp_bluetank/lcd.c @@ -0,0 +1,339 @@ +/** + * @file lcd.c + * @author Shinichiro Nakamura + * @brief BlueTank ACB-BF592 Application Sample Codes. + */ + +/* + * =============================================================== + * BlueTank + * =============================================================== + * Copyright (c) 2012-2013 Shinichiro Nakamura + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * =============================================================== + */ + +#include +#include +#include "lcd.h" +#include "bfin_util.h" + +#define PORT_INIT() \ + do { \ + *pPORTFIO_DIR |= (PF0 | PF1 | PF2 | PF3 | PF4 | PF5); \ + } while (0) + +#define DATA(N) \ + do { \ + if ((N) & 0x01) { \ + *pPORTFIO_SET = PF2; \ + } else { \ + *pPORTFIO_CLEAR = PF2; \ + } \ + if ((N) & 0x02) { \ + *pPORTFIO_SET = PF3; \ + } else { \ + *pPORTFIO_CLEAR = PF3; \ + } \ + if ((N) & 0x04) { \ + *pPORTFIO_SET = PF4; \ + } else { \ + *pPORTFIO_CLEAR = PF4; \ + } \ + if ((N) & 0x08) { \ + *pPORTFIO_SET = PF5; \ + } else { \ + *pPORTFIO_CLEAR = PF5; \ + } \ + } while (0) + +#define RS_ON() (*pPORTFIO_SET = PF0) +#define RS_OFF() (*pPORTFIO_CLEAR = PF0) +#define E_ON() (*pPORTFIO_SET = PF1) +#define E_OFF() (*pPORTFIO_CLEAR = PF1) + +#define DELAY_US(N) bfin_util_usleep(N) + +static void write_command(unsigned char c) +{ + DATA((c >> 4) & 0x0f); + DELAY_US(1); + E_ON(); + DELAY_US(1); + E_OFF(); + DELAY_US(1); + + DATA((c >> 0) & 0x0f); + DELAY_US(1); + E_ON(); + DELAY_US(1); + E_OFF(); + DELAY_US(1); +} + +/** + * @brief LCDを初期化する。 + */ +void lcd_init(void) +{ + DELAY_US(30000); + PORT_INIT(); + + E_ON(); + RS_OFF(); + + /* + * Function set (Interface is 8bits long.) + */ + DATA(0x03); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(20000); + DATA(0x03); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(5000); + DATA(0x03); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(100); + + /* + * Function set + */ + DATA(0x02); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DATA(0x02); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DATA(0x08); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DELAY_US(50); + + /* + * Display ON/OFF Control + */ + DATA(0x00); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DATA(0x0C); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DELAY_US(50); + + /* + * Display Clear + */ + DATA(0x00); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DATA(0x01); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DELAY_US(2000); + + /* + * Entry Mode Set + */ + DATA(0x00); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DATA(0x06); DELAY_US(1); E_ON(); DELAY_US(1); E_OFF(); DELAY_US(1000); + DELAY_US(50); +} + +void lcd_clear(void) +{ + RS_OFF(); + write_command(0x01); + DELAY_US(1640); +} + +void lcd_cursor_at_home(void) +{ + RS_OFF(); + write_command(0x02); + DELAY_US(1640); +} + +void lcd_entry_mode_set(bool increment, bool shifted) +{ + RS_OFF(); + write_command(0x04 + | (increment ? (1 << 1) : (0 << 1)) + | (shifted ? (1 << 0) : (0 << 0))); + DELAY_US(50); +} + +void lcd_display(bool display, bool cursor, bool blink) +{ + RS_OFF(); + write_command(0x08 + | (display ? (1 << 2) : (0 << 2)) + | (cursor ? (1 << 1) : (0 << 1)) + | (blink ? (1 << 0) : (0 << 0))); + DELAY_US(50); +} + +void lcd_cursor_shift(Direction dir) +{ + RS_OFF(); + write_command(0x10 + | (0 << 3) + | ((Right == dir) ? (1 << 2) : (0 << 2))); + DELAY_US(50); +} + +void lcd_display_shift(Direction dir) +{ + RS_OFF(); + write_command(0x10 + | (1 << 3) + | ((Right == dir) ? (1 << 2) : (0 << 2))); + DELAY_US(50); +} + +void lcd_goto(uint8_t x, uint8_t y) +{ + uint8_t addr = (y * 0xc0) + x; + RS_OFF(); + write_command(0x80 + | (addr & 0x7f)); + DELAY_US(50); +} + +void lcd_putc(char c) +{ + RS_ON(); + write_command(c); + DELAY_US(50); +} + +void lcd_puts(char *str) +{ + while (*str) { + lcd_putc(*str); + str++; + } +} + +void lcd_font_init(FontSet *fs) +{ + int i, j; + for (i = 0; i < LCD_FONT_CHARS; i++) { + for (j = 0; j < LCD_FONT_HEIGHT; j++) { + fs->fontlist[i].data[j] = 0x00; + } + } +} + +void lcd_font_init_single(FontSet *fs, UserFont index) +{ + int i = (int)index , j; + for (j = 0; j < LCD_FONT_HEIGHT; j++) { + fs->fontlist[i].data[j] = 0x00; + } +} + +void lcd_font_set_pixel( + FontSet *fs, UserFont index, + const int x, const int y, const int on) +{ + if (LCD_FONT_WIDTH <= x) { + return; + } + if (LCD_FONT_HEIGHT <= y) { + return; + } + if (on) { + fs->fontlist[(int)index].data[y] |= + (1 << (LCD_FONT_WIDTH - x - 1)); + } else { + fs->fontlist[(int)index].data[y] &= + ~(1 << (LCD_FONT_WIDTH - x - 1)); + } +} + +#define swap(A,B) \ + do { \ + int C = A; \ + A = B; \ + B = C; \ + } while (0) + +void lcd_font_draw_line( + FontSet *fs, UserFont index, + int x1, int y1, + int x2, int y2, + int on) +{ + int x; + /* + * Bresenham's line algorithm + */ + bool steep = abs(y2 - y1) > abs(x2 - x1); + if (steep) { + swap(x1, y1); + swap(x2, y2); + } + if (x1 > x2) { + swap(x1, x2); + swap(y1, y2); + } + int deltax = x2 - x1; + int deltay = abs(y2 - y1); + int error = deltax / 2; + int ystep; + int y = y1; + if (y1 < y2) { + ystep = 1; + } else { + ystep = -1; + } + for (x = x1; x <= x2; x++) { + if (steep) { + lcd_font_set_pixel(fs, index, y, x, on); + } else { + lcd_font_set_pixel(fs, index, x, y, on); + } + error = error - deltay; + if (error < 0) { + y = y + ystep; + error = error + deltax; + } + } +} + +void lcd_font_setup_single(FontSet *fs, UserFont index) +{ + uint8_t addr = 8 * (int)index; + int i = (int)index, j; + for (j = 0; j < LCD_FONT_HEIGHT; j++) { + RS_OFF(); + write_command(0x40 | (addr & 0x3f)); + DELAY_US(50); + + RS_ON(); + write_command(fs->fontlist[i].data[j]); + DELAY_US(50); + + addr++; + } +} + +void lcd_font_setup_all(FontSet *fs) +{ + uint8_t addr = 0; + int i, j; + for (i = 0; i < LCD_FONT_CHARS; i++) { + for (j = 0; j < LCD_FONT_HEIGHT; j++) { + RS_OFF(); + write_command(0x40 | (addr & 0x3f)); + DELAY_US(50); + + RS_ON(); + write_command(fs->fontlist[i].data[j]); + DELAY_US(50); + + addr++; + } + } +} +