/*
 * UsiTwiSlave.cfg.h
 *
 * Created: 08.12.2013
 *  Author: Ulli
 */ 

#ifndef USITWISLAVE_CFG_H
#define USITWISLAVE_CFG_H

// Diese Datei enthält applikationsspezifische Einstellungen für das USI-TWI-Slave-Modul. UsiTwiSlave.h und UsiTwiSlave.c bleiben unverändert 
// und werden i.d.R. nur als Link eingebunden.

#include "GeneralDefinitions.h"

/*
* Das Modul UsiTwiSlave stellt ein Framework zur Bereitstellung einer interruptgetriebenen 
* TWI-Slave-Schnittstelle (I²C) auf AVR-Prozessoren mit einer USI zur Verfügung.
*
* Die Einbindung in die Applikation (API) erfolgt prinzipiell über fünf Funktionen, die je nach
* Betriebsmodus unterschiedlich ausgeprägt sind:
* - TwiInitialize: ...... Initialisiert die USI-Register für den Twi-Modus. Ggf. kann eine Geräte-Adresse übergeben werden.
* - TwiSetAddress: ...... Legt die Geräte-Adresse fest.
* - TwiTransmissionStart: Der Beginn einer Datenübertragung wird gemeldet.
* - TwiDataReceived: .... Ein Byte wurde empfangen und kann bearbeitet werden.
* - TwiDataRequest: ..... Ein Byte wird zur Übertragung angefordert.
* Über Preprozessor-Kostanten können die verschiedenen Modi konfiguriert werden.
*
* === Geräte-Adresse ==================================================================================================================================================
* Das Modul besitzt zwei Adress-Modi:
*
*   1. Adress-Modus FIXED
*   --------------------------
*   Die Geräte-Adresse wird über die Preprozessor-Konstante 'TWI_FIXED_TWI_ADDRESS' vorgegeben
*   und beim Kompilieren fest eingestellt. Die Funktion 'TwiInitialize' wird als 'void TwiInitialize (void)' deklariert.
*   'TwiSetAddress' steht nicht zur Verfügung.
*
*   2. Adress-Modus VARIABLE
*   --------------------------
*   Die Preprozessor-Konstante 'TWI_FIXED_TWI_ADDRESS' hat die Ausprägung NONE. Die Geräte-Adresse wird bei der Modul-Initialisierung
*   über 'void TwiInitialize (uint8_t TwiAddress)' festgelegt und kann zu einem späteren Zeitpunkt über 'void TwiSetAddress(uint8_t TwiAddress)'
*   geändert werden.
*
* In beiden Adress-Modi kann über TWI_ACCEPT_BROADCAST_MSG festgelegt werden, ob zusätzlich zu der oben festgelegten Adresse auch die
* I²C-Broadcast-Adresse 0 akzeptiert wird.
*
* === Betriebs-Modi ===================================================================================================================================================
* Dieses Modul besitzt drei Betriebs-Modi. Der Modus wird über die Preprozessor-Konstante 'TWI_OPERATION_MODE' eingestellt:
* - TWI_MODE_STANDARD
* - TWI_MODE_SIMPLE
* - TWI_MODE_REGISTER
*
*  1. Betriebs-Modus STANDARD
*  --------------------------
*  Es werden keine Automatismen implementiert. Die CallBack-Funktionen
*  - uint8_t TwiDataRequest() ...................... zur Bereitstellung von Daten
*  - void TwiDataReceived(uint8_t data) ............ zum Empfang von Daten
*  - void TwiTransmissionStart(TwiTransferType rw).. zur Steuerung
*  müssen von der Applikation implementiert werden.
*
*  Die Implementierung von TwiDataRequest ist obligatorisch. TwiDataReceived und TwiTransmissionStart sind einstellbar:
*  - Die Notwendigkeit 'TwiTransmissionStart' zu implementieren kann über 'TWI_TRANSMISSION_START_MSG' (TRUE oder FALSE) abgeschaltet werden.
*  - Das Systemverhalten beim Datenempfang wird über die Preprozessor-Konstante TWI_RECEIVE gesteuert:
*   - NONE .......... Eingehende Daten werden ignoriert. 'TwiDataReceived' muss nicht impelemtiert werden.
*   - TWI_CALLBACK .. Die von der Applikation zu implementierende CallBack-Funktion 'void TwiDataReceived(uint8_t data)' wird aufgerufen.
*   - TWI_CB_INLINE . Die CallBack-Funktion 'void TwiDataReceived(uint8_t data)' wird aufgerufen. Sie muss als ALWAYS_INLINE in UsiSlave.cfg.h bereit gestellt werden.*
*
*  2. Betriebs-Modus SIMPLE
*  --------------------------
*  In diesem Modus wird jeweils nur ein einzelnes Byte übertragen. Dieses Byte wird in der Variablen 'TwiData' zur Verfügung gestellt bzw. dort abgelegt.
*  Die Funktion 'TwiDataRequest' zur Bereitstellung von Daten wird intern implementiert und muss NICHT durch die Applikation implementiert werden. Sie übergibt 
*  jeweils den Inhalt von TwiData.
*
* 'void TwiTransmissionStart(TwiTransferType rw)' kann von der Applikation implementiert werden. Die Notwendigkeit 'TwiTransmissionStart' zu implementieren
*  kann über 'TWI_TRANSMISSION_START_MSG' abgeschaltet werden.
* 
*  Das Systemverhalten beim Datenempfang wird über die Preprozessor-Konstante TWI_RECEIVE gesteuert:
*  - NONE .......... Eingehende Daten werden ignoriert. 'TwiDataReceived' muss nicht impelemtiert werden.
*  - TWI_SIMPLE .... Eingehende Bytes werden in der Variablen 'TwiData' abgelegt.
*  - TWI_FLAG ...... Eingehende Bytes werden in der Variablen 'TwiData' abgelegt. Zusätzlich wird die Variable 'TwiDataReceived' deklariert.
*                    Diese wird auf 'true' gesetzt, wenn ein Byte empfangen wurde. Die Applikation kann diese Variable bei Bedarf löschen.
*  - TWI_CALLBACK .. Die von der Applikation zu implementierende CallBack-Funktion 'void TwiDataReceived(uint8_t data)' wird aufgerufen.
*  - TWI_CB_INLINE . Die CallBack-Funktion 'void TwiDataReceived(uint8_t data)' wird aufgerufen. Sie muss als ALWAYS_INLINE in UsiTwiSlave.cfg.h bereit gestellt werden.
*
*
*  3. Betriebs-Modus REGISTER
*  --------------------------
*  In diesem Modus werden die Daten in einem strukturierten und adressierbaren I²C-Register zur Verfügung gestellt bzw. dort abgelegt. Jede Schreiboperation beginnt
*  zunächst mit der Übertragung des Registerindex (ein Byte). Jedes weitere Byte wird dann an der vom Index angegeben Stelle abgelegt und der Index inkrementiert. Das
*  Lesen erfolgt ebenfalls an der vom Index angegeben Stelle. Durch Schreiben eines einzelnen Bytes (= Registerindex) kann diese Stelle verschoben werden.
* 
*  Die Struktur des I²C-Registers wird über den Typ 'I2CRegister_t' festgelegt. Am sinnvollsten wird er als structure hinterlegt. Es sind aber auch andere Darstellungen
*  möglich. Intern wird auf das Register stets mit dem Typ-Konverter ((uint8_t *)&I2CRegister)[] zugegriffen.
*   typedef struct
*   { ...
*   } I2CRegister_t;
*
*  Die Vorbelegung des Registers geschieht -sofern gewollt über die Kosnstante I2C_REGISTER_DEFAULT. Sie wird so benutzt: "I2CRegister = {I2C_REGISTER_DEFAULT};". Auch 
*  wenn keine Vorbelegung notwendig ist, muss diese Konstante deiniert werden. Sie wird einfach leer gelassen: "#define I2C_REGISTER_DEFAULT".
*
*  Die Verwaltung des Index ('RegisterIndex') zum Zugriff auf das I²C-Register erfolgt intern. Wird der Index durch den Master auf einen Wert gesetzt, der größer als die
*  Größe des Registers ist, wird der Index auf das letzte Byte des Registers gesetzt. Ähnliches gilt beim Inkrementieren des Index. Würde er das Register verlassen, wird
*  das Inkrementieren unterdrückt. Sicherheitshalber fügt man an das Ende des Registers ein zusätzliches Byte ein, dass in solchen Situationen ohne weitere Seiteneffekte
*  beschrieben werden kann.
*
*  Die Funktion 'TwiDataRequest' zur Bereitstellung von Daten wird intern implementiert und muss NICHT durch die Applikation implementiert werden. Sie übergibt 
*  jeweils den durch den Registerindex gekennzeichneten Inhalt des I²C-Registers.
*
*  'void TwiTransmissionStart(TwiTransferType rw)' kann von der Applikation implementiert werden. Die Notwendigkeit 'TwiTransmissionStart' zu implementieren
*  kann über 'TWI_TRANSMISSION_START_MSG' abgeschaltet werden.
*
*  Das Systemverhalten beim Datenempfang wird über die Preprozessor-Konstante TWI_RECEIVE gesteuert:
*  - NONE .......... Eingehende Daten werden ignoriert. 'TwiDataReceived' muss nicht impelemtiert werden.
*  - TWI_SIMPLE .... Eingehende Bytes werden an der passenden Stelle im I²C-Register abgelegt.
*  - TWI_FLAG ...... Eingehende Bytes werden an der passenden Stelle im I²C-Register abgelegt. Zusätzlich wird die Variable 'TwiDataReceived' deklariert.
*                    Diese wird auf 'true' gesetzt, wenn ein Byte empfangen wurde. Die Applikation kann diese Variable bei Bedarf löschen.
*  - TWI_CALLBACK .. Die von der Applikation zu implementierende CallBack-Funktion 'void TwiDataReceived(uint8_t index, uint8_t data)' wird aufgerufen.
*  - TWI_CB_INLINE . Die CallBack-Funktion 'void TwiDataReceived(uint8_t index, uint8_t data)' wird aufgerufen. Sie muss als ALWAYS_INLINE in UsiTwiSlave.cfg.h bereit gestellt werden.
*
*   Über TWI_REGISTER_INDEX_REGISTER kann festgelegt werden, ob und welches Register zur Aufnahme der internen Variablen 'RegisterIndex' genutzt werden kann.
*   Ist die Konstante nicht definiert, wird die Variable im RAM abgelegt.
*   Über TWI_STATE_REGISTER kann festgelegt werden, ob und welches Register zur Aufnahme der internen Variablen 'TransmissionState' genutzt werden kann.
*   Ist die Konstante nicht definiert, wird die Variable im RAM abgelegt.
*
*   Im Modus TWI_SIMPLE und TWI_FLAG kann über die Preprozessor-Konstante TWI_WRITE_PERMIT ein schreibgeschützter Bereich zu Beginn des Registers festgelegt werden.
*   Schreiboperationen mit einem Index kleiner als TWI_WRITE_PERMIT werden unterdrückt. Wird kein schreibgeschützter Bereich benötigt, wird die Konstante mit 0 belegt.
*
*/

// Register-Belegung
// TWI_REGISTER_INDEX_REGISTER: .. 3
// TWI_STATE_REGISTER: ........... 4
// USI_OVF_TWI_STATE_REGISTER: ... 5 
// TWI_ADRESS_REGISTER: .......... 6

// --- Adress-Modus ------------------------------------------------------------------------------------------------------------------------------------------

#define TWI_FIXED_TWI_ADDRESS     NONE    // Feste Bus-Adresse des TWI-Slaves (Dezimal: 103).
                                          // Mögliche Werte: NONE, 0x01 .. 0x7F
                                          // Bei NONE wird die Adresse in der Initialisierungsroutine übergeben
										 
#define TWI_ACCEPT_BROADCAST_MSG TRUE     // Transferanforderung über die Broadcast-Adresse (0) werden akzeptiert.
										  // Mögliche Werte: TRUE, FALSE
										  
#define TWI_ADRESS_REGISTER      6        // Für die intern in UsiTwiSlave benötigte Variable 'TwiDeviceAddress' kann das angegebene Register benutzt werden.
                                          // Mögliche Werte: NONE, 2..32. Wird eine feste Adresse vorgegeben, wird dieser Wert intern auf NONE gesetzt.

// --- Betriebs-Modus ----------------------------------------------------------------------------------------------------------------------------------------

#define TWI_OPERATION_MODE TWI_MODE_REGISTER // Einstellung des Betriebs-Modus
										     // Mögliche Werte: TWI_MODE_STANDARD, TWI_MODE_SIMPLE, TWI_MODE_REGISTER

#define TWI_RECEIVE_MODE TWI_AUTO            // Art der Reaktion auf eingehende Daten
                                             // Mögliche Werte: NONE, TWI_AUTO, TWI_FLAG, TWI_CALLBACK, TWI_CB_INLINE
                                             // Im Betriebsmodus 'TWI_MODE_STANDARD' ist nur NONE, TWI_CALLBACK und TWI_CB_INLINE erlaubt.
											 // Bei NONE wird auf eine Schreibanfrage des Masters ignoriert.

#define TWI_TRANSMISSION_START_MSG FALSE     // Bei Beginn einer neuen Übertragung wird zunächst TwiTransmissionStart aufgerufen
                                             // Mögliche Werte: TRUE, INLINE, FALSE
                                             // TRUE:   Die Applikation implementiert die Funktion 'void TwiTransmissionStart(TwiTransferType rw)'.
                                             // INLINE: Die Funktion ist als 'ALWAYS_INLINE void TwiTransmissionStart(TwiTransferType rw) {...}' in UsiSlave.cfg.h hinterlegt.
                                             // FALSE:  Die Funktion wird nicht aufgerufen und muss nicht implementiert werden.											 
											 
#if (TWI_OPERATION_MODE == TWI_MODE_STANDARD)											 
  #define TWI_DATA_REQUEST_MODE INLINE       // Festlegung der Art, wie die obligatorische Funktion 'uint8_t TwiDataRequest(void)' zur Verfügung gestellt wird.
                                             // Mögliche Werte: STANDARD oder INLINE
											 // STANDARD: Die Applikation implementiert die Funktion 'uint8_t TwiDataRequest(void)'.
											 // INLINE:   Die Funktion ist als 'ALWAYS_INLINE uint8_t TwiDataRequest(void) {...}' in UsiSlave.cfg.h hinterlegt.
#endif // TWI_OPERATION_MODE == TWI_MODE_STANDARD

// --- Betriebs-Modus REGISTER -------------------------------------------------------------------------------------------------------------------------------
#if (TWI_OPERATION_MODE == TWI_MODE_REGISTER)
  //******************************************************************
  // Festlegung der I2C-Register-Struktur
  //******************************************************************
  typedef struct
  { uint16_t Touch[3];
	uint16_t Version;
	uint16_t Count;
  } I2CRegister_t;

  #define I2C_REGISTER_DEFAULT             // Vorbelegung des Registers. Wird so benutzt: I2CRegister = {I2C_REGISTER_DEFAULT};

  #define TWI_REGISTER_INDEX_REGISTER 3    // Für die intern in UsiTwiSlave benötigte Variable 'RegisterIndex' kann das angegebene Register benutzt werden.
                                           // Mögliche Werte: NONE, 2..32
  #define TWI_STATE_REGISTER          4    // Für die intern in UsiTwiSlave benötigte Variable 'TransmissionState' kann das angegebene Register benutzt werden.
                                           // Mögliche Werte: NONE, 2..32

  #if ((TWI_RECEIVE_MODE == TWI_AUTO) || (TWI_RECEIVE_MODE == TWI_FLAG))
    #define TWI_WRITE_PERMIT      0        // Schreiben ab dieser Position erlauben (nur bei TWI_AUTO & TWI_FLAG)
  #endif // (TWI_RECEIVE_MODE == TWI_AUTO) || (TWI_RECEIVE_MODE == TWI_FLAG)
  
#endif // TWI_OPERATION_MODE == TWI_MODE_REGISTER


// --- Ergänzungen ---------------------------------------------------------------------------------------------------------------------------------------
#define USI_INT_MESSAGE TRUE               // Bei jedem USI-Interrupt wird InteruptOccured mit TRUE belegt (s. GeneralDefinitions.h)
                                           // Mögliche Werte: TRUE, FALSE

#define USI_OVF_STATE_REGISTER 5           // Für die in UsiTwiSlave benötigte Variable 'USI_TWI_Overflow_State' kann das angegebene Register benutzt werden.
                                           // Mögliche Werte: NONE, 2..32
										 
										 
#endif // USITWISLAVE_CFG_H 