272 lines
7.3 KiB
C
272 lines
7.3 KiB
C
/*
|
||
* c't-Bot
|
||
*
|
||
* 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 2 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, write to the Free
|
||
* Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
||
* MA 02111-1307, USA.
|
||
*
|
||
*/
|
||
|
||
/*! @file display.c
|
||
* @brief Routinen zur Displaysteuerung
|
||
* @author Benjamin Benz (bbe@heise.de)
|
||
* @date 20.12.05
|
||
*/
|
||
#include "global.h"
|
||
#include "ct-Bot.h"
|
||
|
||
#ifdef MCU
|
||
#ifdef DISPLAY_AVAILABLE
|
||
|
||
#include <avr/io.h>
|
||
#ifdef NEW_AVR_LIB
|
||
#include <util/delay.h>
|
||
#else
|
||
#include <avr/delay.h>
|
||
#endif
|
||
#include <stdarg.h>
|
||
#include <stdio.h>
|
||
#include "command.h"
|
||
|
||
#include "display.h"
|
||
#include "led.h"
|
||
#include "delay.h"
|
||
#include "shift.h"
|
||
#include "display.h"
|
||
|
||
/*! Puffergroesse fuer eine Zeile in bytes */
|
||
#define DISPLAY_BUFFER_SIZE (DISPLAY_LENGTH + 1)
|
||
|
||
uint8 display_update=0; /*!< Muss das Display aktualisiert werden? */
|
||
#ifdef DISPLAY_SCREENS_AVAILABLE
|
||
#ifdef LOG_DISPLAY_AVAILABLE
|
||
uint8 display_screen=4; /*!< Muss das Display aktualisiert werden? */
|
||
#else
|
||
uint8 display_screen=0; /*!< Muss das Display aktualisiert werden? */
|
||
#endif
|
||
#endif
|
||
static char display_buf[DISPLAY_BUFFER_SIZE]; /*!< Pufferstring fuer Displayausgaben */
|
||
|
||
#define DISPLAY_CLEAR 0x01 /*!< Kommando zum Löschen */
|
||
#define DISPLAY_CURSORHOME 0x02 /*!< Kommando für den Cursor */
|
||
|
||
#define DISPLAY_OUT 0x07 /*!< Output-Pins Display */
|
||
#define DISPLAY_IN (1<<5) /*!< Input-Pins Display */
|
||
|
||
#define DISPLAY_PORT PORTC /*!< Port an dem das Display hängt */
|
||
#define DISPLAY_DDR DDRC /*!< Port an dem das Display hängt */
|
||
#define DPC (DISPLAY_PORT & ~DISPLAY_OUT) /*!< Port des Displays */
|
||
//#define DRC (DDRC & ~DISPLAY_PINS)
|
||
|
||
//#define DISPLAY_READY_PINR PINC /*!< Port an dem das Ready-Flag des Display hängt */
|
||
#define DISPLAY_READY_DDR DDRC /*!< Port an dem das Ready-Flag des Display hängt */
|
||
#define DISPLAY_READY_PIN (1<<5) /*!< Pin an dem das Ready-Flag des Display hängt */
|
||
|
||
/*! RS-Leitung
|
||
* legt fest, ob die Daten an das Display in den Textpuffer (RS=1) kommen
|
||
* oder als Steuercode interpretiert werden (RS=0)
|
||
*/
|
||
#define DISPLAY_RS (1<<0) /*!< Pin an dem die RS-Leitung des Displays hängt */
|
||
|
||
/*! RW-Leitung
|
||
* legt fest, ob zum Display geschrieben wird (RW=0)
|
||
* oder davon gelesen wird (RW=1)
|
||
*/
|
||
#define DISPLAY_RW (1<<1) /*!< Pin an dem die RW-Leitung des Displays hängt */
|
||
|
||
/*! Enable Leitung
|
||
* schaltet das Interface ein (E=1).
|
||
* Nur wenn Enable auf High-Pegel liegt, läßt sich das Display ansprechen
|
||
*/
|
||
#define DISPLAY_EN (1<<2) /*!< Pin an dem die EN-Leitung des Displays hängt */
|
||
|
||
/*
|
||
* Im Moment der Low-High-Flanke von ENABLE liest das Dislplay
|
||
* die Werte von RS und R/W ein. Ist zu diesem Zeitpunkt R/W=0,
|
||
* dann liest das Display mit der folgenden High-Low-Flanke von ENABLE
|
||
* den Datenbus ein (Schreibzyklus).
|
||
* War aber R/W=1, dann legt das Display ein Datenword auf den
|
||
* Datenbus (Lese-Zyklus), solange bis die High-Low-Flanke von ENABLE
|
||
* das Interface wieder deaktiviert.
|
||
*/
|
||
|
||
/*!
|
||
* Übertrage Kommando an das Display
|
||
* @param cmd Kommando
|
||
*/
|
||
void display_cmd(uint8 cmd){ //ein Kommando cmd an das Display senden
|
||
uint8 i;
|
||
shift_data_out(cmd,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY);
|
||
// Enable muss für mind. 450 ns High bleiben, bevor es fallen darf!
|
||
// ==> Also mind. 8 Zyklen warten
|
||
for (i=0; i<150; i++){
|
||
asm volatile("nop");
|
||
}
|
||
DISPLAY_PORT=DPC; // Alles zurück setzen ==> Fallende Flanke von Enable
|
||
}
|
||
|
||
|
||
/*!
|
||
* Ein Zeichen auf das Display schreiben
|
||
* @param data Das Zeichen
|
||
*/
|
||
void display_data(char data){ //ein Zeichen aus data in den Displayspeicher schreiben
|
||
uint8 i;
|
||
shift_data_out(data,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY|DISPLAY_RS);
|
||
|
||
// Enable muss für mind. 450 ns High bleiben, bevor es fallen darf!
|
||
// ==> Also mind. 8 Zyklen warten
|
||
for (i=0; i<150; i++){
|
||
asm volatile("nop");
|
||
}
|
||
DISPLAY_PORT=DPC; // Alles zurück setzen ==> Fallende Flanke von Enable
|
||
}
|
||
|
||
/*!
|
||
* Löscht das ganze Display
|
||
*/
|
||
void display_clear(void){
|
||
display_cmd(DISPLAY_CLEAR); // Display loeschen, Cursor Home
|
||
#ifdef DISPLAY_REMOTE_AVAILABLE
|
||
command_write(CMD_AKT_LCD, SUB_LCD_CLEAR, NULL, NULL,0);
|
||
#endif
|
||
}
|
||
|
||
/*!
|
||
* Positioniert den Cursor
|
||
* @param row Zeile
|
||
* @param column Spalte
|
||
*/
|
||
void display_cursor (uint8 row, uint8 column) {
|
||
switch (row) {
|
||
case 1:
|
||
display_cmd (0x80 + column - 1);
|
||
break;
|
||
case 2:
|
||
display_cmd (0xc0 + column - 1);
|
||
break;
|
||
case 3:
|
||
display_cmd (0x94 + column - 1);
|
||
break;
|
||
case 4:
|
||
display_cmd (0xd4 + column - 1);
|
||
break;
|
||
default: break;
|
||
}
|
||
|
||
#ifdef DISPLAY_REMOTE_AVAILABLE
|
||
int16 r=row-1;
|
||
int16 c=column-1;
|
||
command_write(CMD_AKT_LCD, SUB_LCD_CURSOR, &c,&r,0);
|
||
#endif
|
||
|
||
}
|
||
|
||
/*!
|
||
* Init Display
|
||
*/
|
||
void display_init(void){
|
||
shift_init();
|
||
|
||
DISPLAY_DDR |= DISPLAY_OUT; // Ausgänge
|
||
DISPLAY_DDR &= ~DISPLAY_IN; // Eingänge
|
||
|
||
delay(12); // Display steht erst 10ms nach dem Booten bereit
|
||
|
||
// Register in 8-Bit-Modus 3x Übertragen, dazwischen warten
|
||
shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY);
|
||
DISPLAY_PORT= DPC;
|
||
delay(5);
|
||
shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY);
|
||
DISPLAY_PORT= DPC;
|
||
delay(5);
|
||
shift_data_out(0x38,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY);
|
||
DISPLAY_PORT= DPC;
|
||
delay(5);
|
||
|
||
display_cmd(0x0f); //Display On, Cursor On, Cursor Blink
|
||
|
||
display_cmd(DISPLAY_CLEAR); // Display loeschen, Cursor Home
|
||
|
||
display_data('i');
|
||
}
|
||
|
||
/*!
|
||
* Zeigt einen String an
|
||
* @return -1 falls string zuende 0 falls Zeile (20 zeichen) zuende
|
||
*/
|
||
/*int display_string(char data[20]){
|
||
int i=0;
|
||
|
||
while ((i<20) && (data[i] != 0x00)){ // Abbruch, sobald ein Nullstring erreicht wird
|
||
// oder 20 Zeichen gesendet sind
|
||
display_data(data[i++]); // einzelnes Zeichen schicken
|
||
}
|
||
|
||
// return -1 falls string zuende, 0 falls zeile (20 zeichen) zuende
|
||
if (data[i]==0x00) return -1; else return 0;
|
||
}
|
||
*/
|
||
|
||
/*!
|
||
* Schreibt einen String auf das Display.
|
||
* @param format Format, wie beim printf
|
||
* @param ... Variable Argumentenliste, wie beim printf
|
||
*/
|
||
void display_printf(char *format, ...) {
|
||
|
||
unsigned int run = 0;
|
||
va_list args;
|
||
|
||
/* Sicher gehen, das der zur Verfuegung stehende Puffer nicht
|
||
* ueberschrieben wird.
|
||
*/
|
||
va_start(args, format);
|
||
vsnprintf(display_buf, DISPLAY_BUFFER_SIZE, format, args);
|
||
va_end(args);
|
||
|
||
/* Ausgeben bis Puffer leer ist */
|
||
while(display_buf[run] != '\0') {
|
||
display_data(display_buf[run]);
|
||
run++;
|
||
}
|
||
|
||
#ifdef DISPLAY_REMOTE_AVAILABLE
|
||
command_write_data(CMD_AKT_LCD, SUB_LCD_DATA, NULL, NULL, display_buf);
|
||
#endif
|
||
|
||
return;
|
||
}
|
||
|
||
/*
|
||
void display_test(){
|
||
shift_init();
|
||
|
||
// shift_data_out(0xAA,SHIFT_LATCH,SHIFT_REGISTER_DISPLAY);
|
||
|
||
display_cmd(0x38); //Display auf 8 Bit Betrieb
|
||
for(;;){}
|
||
display_cmd(0x0f); //Display On, Cursor On, Cursor Blink
|
||
|
||
display_cmd(DISPLAY_CLEAR); // Display l<>schen, Cursor Home
|
||
display_cursor(2,2);
|
||
|
||
display_string("Hallo");
|
||
for(;;){
|
||
}
|
||
}
|
||
*/
|
||
|
||
#endif
|
||
|
||
#endif
|