Subversion Repositories Projects

Rev

Blame | Last modification | View Log | RSS feed


/****************************************************************/
/*                                                                                                                                                                                                                                                      */
/*                                                                       NG-Video 5,8GHz                                                                                                                */
/*                                                                                                                                                                                                                                                      */
/*                                                              Copyright (C) 2011 - gebad                                                                              */
/*                                                                                                                                                                                                                                                      */
/*      This code is distributed under the GNU Public License                           */
/*      which can be found at http://www.gnu.org/licenses/gpl.txt               */
/*                                                                                                                                                                                                                                                      */
/*              using DOGM-Library 1.0.                                                                                                                                         */
/*              Copyright (C) 2010-averyfarwaydate Luca Bertoncello                             */
/*              Hartigstrasse, 12 - 01127 Dresden Deutschland                                                   */
/*              E-Mail: lucabert@lucabert.de, lucabert@lucabert.com                             */
/*              http://www.lucabert.de/ http://www.lucabert.com/                                        */
/****************************************************************/

#include <util/delay.h>

#include "config.h"
#include "dogm.h"
#include <avr/pgmspace.h>
#include <string.h>

// Instruktionen mit ST7036 4 Bit Mode im "Extension mode"
#define CLEAR_DISPLAY                           0b00000001
#define FUNCTION_SET_INIT_0     0b00110011      // 0x30 & 0x30 als nibble
#define FUNCTION_SET_INIT_1     0b00110010      // 0x30 & 0x20 als nibble
#define FUNCTION_SET_INIT_2     0b00101001      // 0x29 4-bit, 2 Zeilen, kein DoubleHeight, InstructionTable1
#define INSTRUCTION_Table_0     0b00101000      // Instruction table 0
#define INSTRUCTION_Table_1     0b00101001      // Instruction table 1
#define SET_CGRAM                                               0b01000000      // für user defined Char
#define BIAS_SET                                                0b00010101      // table 1      DB3=Bias 1/4, DB0=3 Zeilen 0b00011101
#define FOLLOWER_CONTROL                0b01101110      // nach Datenblattbsp. 3,3V DOGM bei 5V 0b01101100
#define CONTRAST_SET                            0b01110000      // Kontrastwert Bit3 bis Bit0
#define POWER_CONTRAST                  0b01010100      // Bit1 und Bit0 entspricht Kontrastwert Bit5 und Bit4 3,3V 0b0101 0100 5V 0b0101 0000
#define DISPLAY_ON                                      0b00001100
#define ENTRY_MODE                                      0b00000110      // Cursor Auto-Increment
#define SET_DDRAM_ADDR                  0b10000000      // Bit7 bis Bit0 Adresse
#define BS                                                                      3                                               // 0 - 1/5 bias // 1 - 1/4 bias
#define RAB1                                                            1                                               // select follower amplified ratio
#define BON                                                                     2                                               // set booster circuit on/off bei Power_Contrast

#define lcdSetEnable()                  LCD_E_PORT      |=      (1<<LCD_ENABLE);
#define lcdClearEnable()                LCD_E_PORT      &= ~(1<<LCD_ENABLE);
#define lcdSetRegSelect()               LCD_RS_PORT     |=      (1<<LCD_REGSELECT)
#define lcdClearRegSelect()     LCD_RS_PORT     &= ~(1<<LCD_REGSELECT)

uint8_t CursorPos;                                      // ersetzt lesen der aktuellen LCD-CursorPosition

/************************************************************************************/
/*      sendet ein Nibble (4 Bit) zum LCD-Controller                                                                                                                                            */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char data               :Byte                                                                                                                                                                                                                                                           */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdSendNibble(char data)
{
        LCD_DATA_PORT |= (data & 0x0f);
        LCD_DATA_PORT &= (data | 0xf0);
        lcdSetEnable();
        _delay_us(2);
        lcdClearEnable();
        _delay_us(30);                                          // nach Datenblatt > 26,3µs
}

/************************************************************************************/
/*      sendet 8 Bit (2 Nibble) zum LCD-Controller                                                                                                                                                      */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char data               :Byte                                                                                                                                                                                                                                                           */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdSendByte(char data)
{
        lcdSendNibble(data>>4);
        lcdSendNibble(data);
}

/************************************************************************************/
/*      sendet instruction zum LCD-Controller                                                                                                                                                                           */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char instruction                :Byte                                                                                                                                                                                                                           */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdSendInstruction(char instruction)
{
        lcdClearRegSelect();                            // LCD-RS für Instruktionen
        lcdSendByte(instruction);
}

/************************************************************************************/
/*      sendet ein Zeichen zum LCD-Display                                                                                                                                                                                      */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char            c               :Zeichen                                                                                                                                                                                                                                                */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdSendC(char c)
{
        lcdSetRegSelect();                              // LCD-RS für Daten
        lcdSendByte(c);
}

/************************************************************************************/
/*      sendet ein Zeichen zum LCD-Display                                                                                                                                                                                      */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char            c               :Zeichen                                                                                                                                                                                                                                                */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdPutc(char c)
{
        lcdSendC(c);
        CursorPos++;
        if (CursorPos >= (LCD_LINES * LCD_COLS)) CursorPos = 0;
}

/************************************************************************************/
/*      sendet einen String zum LCD-Display                                                                                                                                                                                     */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char            *str :Zeichenkette                                                                                                                                                                                                                      */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdPuts(char *str)
{ uint8_t pos = CursorPos / LCD_COLS;

        while (*str) {
                if (*str == '\n') {
                        if (pos >= LCD_LINES)
                                pos = 0;
                        else
                                pos++;
                        lcdGotoXY(0, pos);
                }
                else
                        lcdPutc(*str);
                str++;
        }
}

/************************************************************************************/
/*      stellt eine String mittig auf Display dar                                                                                                                                                               */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      char            *str            : darzustellende Zeichenkette                                                                                                                                           */
/*      uint8_t zle                     : Display-Zeile                                                                                                                                                                                                 */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdPutStrMid(char *str, uint8_t zle)
{ int8_t x;

        lcdClearLine(zle);
        x = (LCD_COLS - strlen(str))/2;                         // Array-String mittig schreiben
        lcdGotoXY(x,zle);
        lcdPuts(str);
}

/************************************************************************/
/*      Definieren eines Sonderzeichen                                                                                                                                                  */
/*      Parameter:                                                                                                                                                                                                                                      */
/*      uint8_t lcd_addr         : Adresse, 1.Adresse 0                                                                                                         */
/*      char            *lcd_zeichen: Zeiger auf das 1. Byte der Zeichendefinition      */
/*                                                                                                                                                                                                                                                                                      */
/************************************************************************/
void lcdWriteCGRAM(uint8_t lcd_addr, char *lcdChr)
{ int8_t i;

        lcdSendInstruction(INSTRUCTION_Table_0);
        for(i = 0; i < 8; i++)
        {
                lcdSendInstruction(SET_CGRAM | (lcd_addr * 8 + i)); // CG RAM Adresse
                //lcdPutc(lcdChr[i]);   // Data Write 8x Pixelzeile
                lcdPutc(pgm_read_byte(&lcdChr[i])); // array im Flash
        }
        lcdSendInstruction(INSTRUCTION_Table_1);
}

/************************************************************************/
/*      Definieren von n <= 8 Sonderzeichen                                                                                                                                     */
/*      Parameter:                                                                                                                                                                                                                                      */
/*      SpecialChr_t lcdChr      : Array mit Sonderzeichen                                                                                      */
/*      uint8_t                  quantity : Anzahl der zu übertragenen Sonderzeichen            */
/*                                                                                                                                                                                                                                                                                      */
/************************************************************************/
void lcdWriteCGRAM_Array(SpecialChr_t *lcdChr, uint8_t quantity)
{
        for (uint8_t i = 0; i < quantity; i++)
                lcdWriteCGRAM(i, lcdChr[i]);                    // Sonderzeichen in CGRAM der LCD schreiben
}

/************************************************************************************/
/*      Löscht Inhalt auf LCD-Display                                                                                                                                                                                                           */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdClear()
{
        lcdSendInstruction(CLEAR_DISPLAY);
        CursorPos = 0;
        _delay_ms(2);
}

/************************************************************************************/
/*      Löscht Inhalt ab Cursorposition bis Zeilenende auf LCD-Display                                                                  */
/*      CursorPos bleibt auf ab zu löschenden Zeichen                                                                                                                                           */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdClearEOL()
{ uint8_t cp = CursorPos % LCD_COLS;
       
        if (cp > 0)             //falls letztes Zeichen auf letzte Spalte geschrieben, nicht nächste Zeile löschen
                for (; cp < LCD_COLS; cp++) lcdSendC(' ');
        lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}

/************************************************************************************/
/*      Löscht Inhalt der angegebenen Zeile auf LCD-Display                                                                                                                     */
/*      CursorPos bleibt auf Zeilenanfang                                                                                                                                                                                               */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdClearLine(uint8_t y)
{
        lcdGotoXY(0, y);
        for (uint8_t x = 0; x < LCD_COLS; x++) lcdSendC(' ');
        lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}

/************************************************************************************/
/*      Setzt Kontrast auf LCD-Display                                                                                                                                                                                                  */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      uint8_t contrast :Wert vo 0 bis max 63                                                                                                                                                                  */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdContrast(uint8_t dogm, uint8_t contrast)
{ uint8_t power_contrast = POWER_CONTRAST;

        if(dogm == DOGM5V) {
                power_contrast &= ~(1<<BON);
        }
        lcdSendInstruction(INSTRUCTION_Table_1);
        lcdSendInstruction(CONTRAST_SET | (contrast & 0x0F));
        lcdSendInstruction(power_contrast | ((contrast>>4) & 0x03));
}

//***********************************************************************************/
/*      Setzt setzt den Cursor zur Position x/y                                                                                                                                                                 */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      uint8_t x, :Position Spalte                                                                                                                                                                                                                     */
/*      uint8_t y, :Position Zeile                                                                                                                                                                                                                      */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdGotoXY(uint8_t x, uint8_t y)
{
        if(x > LCD_COLS)                x = 0;
        if(y > LCD_LINES)               y = 0;
        CursorPos = y * LCD_COLS + x;
        lcdSendInstruction(SET_DDRAM_ADDR | CursorPos);
}

/************************************************************************************/
/*      Initialisiert den LCD-Controller und der Atmega-Ausgänge                                                                                                */
/*      Parameter:                                                                                                                                                                                                                                                                                      */
/*      uint8_t dogm             :0=3,3V oder 1=5V DOGM                                                                                                                                                                 */
/*      uint8_t contrast :Wert vo 0 bis max 63                                                                                                                                                                  */
/*      uint8_t cursor   :Darstellung des Cursors ein oder 0 aus                                                                                                */
/*      uint8_t blink            :Cursor blinken, 0 kein blinken                                                                                                                                */
/*                                                                                                                                                                                                                                                                                                                                      */
/************************************************************************************/
void lcdInit(uint8_t dogm, uint8_t contrast, uint8_t cursor, uint8_t blink)
{ uint8_t bias_set = BIAS_SET;
        uint8_t follower_ctrl    = FOLLOWER_CONTROL;
        uint8_t power_contrast = POWER_CONTRAST;

        LCD_BACKLIGHT_DDR |= (1<<LCD_BACKLIGHT);
        LCD_E_DDR |= (1<<LCD_ENABLE);
        LCD_RS_DDR |= (1<<LCD_REGSELECT);
        LCD_DATA_DDR |= (1<<LCD_DATA7) | (1<<LCD_DATA6) | (1<<LCD_DATA5) | (1<<LCD_DATA4);

        lcdClearEnable();
        _delay_ms(40);                                          // lt. Datenblatt muss > 40ms nach Power On or ext. Reset

        if(dogm == DOGM5V) {
                follower_ctrl &= ~(1<<RAB1);
                bias_set |= (1 << BS);
                power_contrast &= ~(1<<BON);
        }

        //Initialisierung für DOGM (mit ST7036) 4 Bit Mode
        lcdClearRegSelect();                    // LCD-RS für Instruktionen
        lcdSendNibble(FUNCTION_SET_INIT_0>>4);
        _delay_ms(2);                                                   // lt. Datenblatt muss > 1,6ms Pause nach ersten Nibble
        lcdSendNibble(FUNCTION_SET_INIT_0);
        lcdSendInstruction(FUNCTION_SET_INIT_1);
        lcdSendInstruction(FUNCTION_SET_INIT_2);
        lcdSendInstruction(bias_set);
        lcdSendInstruction(CONTRAST_SET | (contrast & 0x0F));
        lcdSendInstruction(power_contrast | ((contrast>>4) & 0x03));
        lcdSendInstruction(follower_ctrl);
        lcdSendInstruction(INSTRUCTION_Table_0);
        lcdSendInstruction(DISPLAY_ON | (cursor & 0x01) << 1 | (blink & 0x01));
        lcdClear();
        lcdSendInstruction(ENTRY_MODE);
}