
// ----------------------------------------------------------------------------
void VNC_spi_init(void)
{
	uint8_t i;
	
	// Der Timer0 wird im Clear Timer on Compare MAtch Modus betrieben
	// Sobald der TCTN0 den Wert in OCR0A Überschreiten, wird er TCNT0
	// auf 0 zurückgesetzt und eine ISR angesprungen.
	// Hier wird allgemein die Zeit aktualisiert sowie die Variable VNC_timeout decrementiert
	TCCR0A  = (1<<WGM01);					// CTC-Modus
	TCCR0B  = (1<<CS02 | 1<< CS00);		// prescale 1024
	TIMSK0  = (1<<OCIE0A);					// enable COMPA
	OCR0A   = 120;
	
	
	SPI_DDR |= (1<<SPI_CS | 1<< SPI_SDI | 1<<SPI_SCLK);
	RST_DDR |= (1<<SPI_RST);
	
	VNC_error = VNC_NO_ERR;					// Vorgabe kein Fehler
	
  	R_CS_VNC;  									// SPI-Interface inaktiv
  	R_SCLK;    									// Ruhezustand der SPI-Leitungen herstellen
  	S_SDI;
  	R_RE_VNC;  									// Hardware-Reset VNC1L
  	VNC_timeout = 15;
	while (VNC_timeout);
	
  	S_RE_VNC;  									// VNC1L starten
	
	VNC_timeout = 120;						// alles was VDIP in der nächsten 3 Sekunde zu melden hat
													// wird von Timer0 in 1/30 Sekundentakt decrementiert
	i = 0;
	while (VNC_timeout)						// hier wird die Einschaltmeldung aufgezeichnet
		{
		if (VNC_spi_read()) vnc_buffer[i++] = spi_in;
		}
	vnc_buffer[i] = 0;

	put_s(vnc_buffer);						// hier die Einschaltmeldung ausgegeben

	VNC_switch_SCS();							// Umschalten in Short Command Set
}

// ----------------------------------------------------------------------------
// Schaltet in den Modus Short_Instruction_Set (Microcontroller-Befehlssatz)
// muss die erste Aktion sein.
void VNC_switch_SCS(void)
{
VNC_spi_write('S');							// Sendet den String 'SCS'
VNC_spi_write('C');
VNC_spi_write('S');
VNC_spi_write(CHR_RETURN);

VNC_wait_for_prompt();						// auf die Antwort warten
}



// --- [ spi_13bit.h ] --------------------------------------------------------

#define SPI_PORT  PORTC
#define SPI_PIN	PINC
#define SPI_DDR	DDRC
#define RST_PORT	PORTD
#define RST_DDR	DDRD

#define SPI_CS		PC0
#define SPI_SDO	PC1
#define SPI_SDI	PC2
#define SPI_SCLK	PC3
#define SPI_RST	PD5

#define WAIT		asm volatile("nop");asm volatile("nop");asm volatile("nop")

#define R_CS_VNC  SPI_PORT &= ~(1<<SPI_CS); WAIT
#define S_CS_VNC  SPI_PORT |=  (1<<SPI_CS); WAIT

#define SDO_VNC   (SPI_PIN & (1<<SPI_SDO))

#define R_SDI     SPI_PORT &= ~(1<<SPI_SDI); WAIT
#define S_SDI     SPI_PORT |=  (1<<SPI_SDI); WAIT

#define R_SCLK    SPI_PORT &= ~(1<<SPI_SCLK); WAIT
#define S_SCLK    SPI_PORT |=  (1<<SPI_SCLK); WAIT

#define R_RE_VNC 	RST_PORT &= ~(1<<SPI_RST); WAIT
#define S_RE_VNC 	RST_PORT |=  (1<<SPI_RST); WAIT

#define LED			PB0
#define LED_DDR	DDRB
#define LED_PORT	PORTB
#define R_LED  	LED_PORT &= ~(1<<LED)
#define S_LED  	LED_PORT |=  (1<<LED)

uint8_t VNC_spi_read(void);
uint8_t VNC_spi_write(uint8_t);

// --- [ eof ] ----------------------------------------------------------------


// --- [ spi_13bit.c ] --------------------------------------------------------
//
// tab = 3
// ----------------------------------------------------------------------------

#include <avr/io.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/interrupt.h>

#include "spi_13bit.h"
#include "rs232.h"
extern uint8_t spi_in;


// ----------------------------------------------------------------------------
// Schreibt ein Byte via SPI an einen VDIP1
// werden die Daten vom VDIP nicht quittiert, dann wird die Sendung wiederholt
// liefert bei erfolgreicher Ablieferung :TRUE
uint8_t VNC_spi_write(uint8_t spi_out)
{
uint8_t stelle, status, cnt;
cnt = 30;										// Anzahl der Schreibversuche bis zu einem Abbruch

do
  	{
	_delay_us(150);
  	cli();										// Interrupts sperren
		
	S_CS_VNC;        							// SPI-Interface aktiv
  	S_SDI;           							// Startbit (immer 1)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  	R_SDI;           							// RW-Bit (0=Write)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  	R_SDI;           							// ADDR (0=Daten)
  	S_SCLK;  R_SCLK; 							// L/H Flanke

  													// 8 Datenbits senden (MSB zuerst)
  	for ( stelle = 0x80; stelle; stelle >>= 1 )
  		{
    	if (spi_out & stelle) { S_SDI;} else {R_SDI;}
    	S_SCLK;  R_SCLK; 						// L/H Flanke
  	}
  													// Statusbit einlesen
  	status = SDO_VNC; 						// Statusbit (0=Accept, 1=Reject)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  													// End Sequenz
  	R_CS_VNC;        							// SPI-Interface inaktiv
  	S_SCLK;  R_SCLK;  						// L/H Flanke
	S_SDI;										// SDI auf high
	sei();
	cnt--;
	} while (status && cnt);				// solange wie Daten abgewiesen werden und cnt > 0

if (status) return (0); else return(1);// liefert TRUE falls erfolgreich, vertauscht 0/1
}													

// ----------------------------------------------------------------------------
// liest ein Byte via SPI vom VDIP
// die Daten werden über die globale Variable spi_in weitergereicht.
// gibt TRUE zurück, wenn ein neues Datenbyte empfangen wurde
// bei  FALSE muss ein neuer Leseversuch gestartet werden.
uint8_t VNC_spi_read(void)
{
uint8_t stelle, status;

	spi_in = 0;
	_delay_us(100);

	cli();
	
  	S_CS_VNC;       							// SPI-Interface aktiv
  	S_SDI;           							// Startbit (immer 1)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  	S_SDI;           							// RW-Bit (1=Read)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  	R_SDI;           							// ADDR (0=Daten, 1=SPI-Statusinformation)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  													// 8 Datenbits empfangen (MSB zuerst)
  	for ( stelle = 0x80; stelle; stelle >>= 1 )
  	{
   	if (SDO_VNC) spi_in |= stelle;
    	S_SCLK;  R_SCLK; 						// L/H Flanke
  	}
  													// Statusbit einlesen
  	status = SDO_VNC; 						// Statusbit (0=New Data, 1=Old Data)
  	S_SCLK;  R_SCLK; 							// L/H Flanke
  													// End Sequenz
  	R_CS_VNC;        							// SPI-Interface inaktiv
  	S_SCLK;  R_SCLK; 							// L/H Flanke
	S_SDI;										// SDI auf high
	sei();

if (status) return (0); else return(1);// liefert TRUE falls erfolgreich, vertauscht 0/1
}	


// --- [ eof ] ----------------------------------------------------------------