/******************************************************************************/ /* (C) Copyright HTL - HOLLABRUNN 2009-2010 All rights reserved. AUSTRIA */ /* */ /* File Name: armv10_serbus.h */ /* Autor: Jakob Maier */ /* Version: V1.00 */ /* Date: 23/07/2010 */ /* Description: Library für Serielle Busse (I2C und SPI) für ARM Corttex M3 */ /* */ /******************************************************************************/ /* History: 07.05.2010: Jakob Maier creation V1.00 (I2C) */ /* - Beinhaltet alle wesentlichen Unterprogramme */ /* die zur Kommunikation über den I2C-Bus */ /* 28.02.2011: REJ V1.1 */ /* - Library aus Funktionen erstellt */ /******************************************************************************/ /* Define to prevent recursive inclusion -------------------------------------*/ #ifndef __ARMV10_SERBUS_H #define __ARMV10_SERBUS_H //Hardware: //********* // //SCL=PB6 //SDA=PB7 //Wichtig: Die Leitungen zur Sicherheit mit 2stk. 4,7kOhm Pull-Up Widerständen an die 3,3V anpassen! // //Master Receiver: //**************** // //1 Byte + Stop: init (-) start(adr+1,1) - read(&dat,x) //1 Byte + Stop: init (-) I2C1_read_1(adr+x,&dat) // //2 Byte + Stop: init (-) start(adr+1,0) - read(&dat,1) - read(&dat,x) //2 Byte + Stop: init (-) start(adr+1,0) - I2C1_read_last2(&dat1,&dat2) // //3 Byte + Stop: init (-) start(adr+1,0) (-) read(&dat,0) - read(&dat,1) - read(&dat,x) //3 Byte + Stop: init (-) start(adr+1,0) (-) read(&dat,0) - I2C1_read_last2(&dat1,&dat2) // //4 Byte + Stop: init (-) start(adr+1,0) (-) read(&dat,0) (-) read(&dat,0) - read(&dat,1) - read(&dat,x) //4 Byte + Stop: init (-) start(adr+1,0) (-) read(&dat,0) (-) read(&dat,0) - I2C1_read_last2(&dat1,&dat2) // //5 Byte + Stop: init (-) start(adr+1,0) (-) read(&dat,0) (-) read(&dat,0) (-) read(&dat,0) - read(&dat,1) - read(&dat,x) //... //n Byte + Stop: init (-) I2C1_read_n(adr+x,daten[],anz) // //Master Transmitter: //******************* // //1 Byte + Stop: init (-) start(adr+0,x) (-) send(data,1) //2 Byte + Stop: init (-) start(adr+0,x) (-) send(data,0) (-) send(data,1) //3 Byte + Stop: init (-) start(adr+0,x) (-) send(data,0) (-) send(data,0) (-) send(data,1) //... //n Byte + Stop (Pause zw. Byteübertragung mögl.): init (-) I2C1_send_n(adr+x,daten[],anz,pause) // //Legende: //******** // // "(-)": Sofort danach oder nach einer beliebig langen Pause folgt die nächste Operation (Achtung: bei einem Reset kann es zu Error Nr. 0x86 kommen - Die Busleitungen sind noch immer auf 0, da mitten im Datenverkehr abgebrochen wurde) // " - ": Sofort danach folgt die nächste Operation (Es muss sofort reagiert werden) // /*-------------------------------------------------- I2C - Fehlercodes: -----------------------------*/ // Ein Fehlercode beinhaltet zwei Arten von Daten: Wo der Fehler auftrat und was der Fehlergrund ist. // Die ersten 4bit (MSB) geben an, in welcher Routine sich der Fehler ereignet hat (Fehlerposition), die // letzten 4bit (LSB) geben die Fehlerart an. Ist kein Fehler aufgetreten, wird 0x00 als Code verwendet, // die Fehlerposition nicht miteinberechnet. // Fehlercode-Berechnung: "Fehlercode" = "Fehlerposition" | "Fehlerart"; // #define info_success 0x00 //Kein Fehler aufgetreten (immer 0x00) /*------------ Fehlerposition:---------*/ #define err_at_init 0x80 //Fehler in der Initialisierungsroutine #define err_at_start 0x40 //Fehler in der Start- und Adressierungsroutine #define err_at_send 0x20 //Fehler in der Senderoutine #define err_at_read 0x10 //Fehler in der Empfangsroutine /*----------- Fehlerarten:-------------*/ #define error_I2C1_running 0x01 //Der I2C1-Bus ist bereits in Betrieb und kann nicht mehr initialisiert werden #define error_I2C1_disabled 0x02 //Es kann keine Startbedingung erzeugt werden, da der Bus außer Betrieb ist (Keine Initialisierung) #define error_no_master 0x03 //Der I2C1-Bus befindet sich nicht im Mastermode ("start()": Peripherie-Fehler; "send()": Startbedingung erzeugt?) #define error_no_transmitter 0x04 //Es können keine Daten gesandt werden, da der Slavebaustein zum lesen Adressiert wurde (R/W-bit muss 0 sein) #define error_not_addressed 0x05 //Die Hardware wurde nicht adressiert, NACK erhalten (Wurde die richtige Adresse eingestellt?) #define error_timeout_busy 0x06 //Der Bus kann derzeit noch nicht initialisiert werden, da bereits ein Datenverkehr ausgeführt wird //(Leitung auf "LOW" - PullUp-Widerstände vorhanden?) #define error_timeout_start 0x07 //Bei der Startbedingung ist es zu einem Time-Out gekommen (Ist der Bus belegt (Multimaster-Mode)?, //Ist vielleicht noch eine Datenübertragung im gange?) #define error_timeout_stop 0x08 //Bei der Stopbedingung ist es zu einem Time-Out gekommen (Ist vielleicht noch eine Datenübertragung im gange?) #define error_timeout_send 0x09 //Die Daten wurden nicht übertragen (Timeout) (Verwendet der Slave Clock-Streching? //Sind die Busleitungen auf "LOW" gefallen?) #define error_NACK 0x0A //Der Slave hat auf die Daten mit einem NACK geantwortet (Der Fehler liegt auf der Slave-Seite oder es wurde //dessen Übertragungsprotokoll verletzt/beendet) #define error_no_data 0x0B //Bei "read()". Entweder wurde noch kein Baustein adresiert oder nach Beendigung der letzten Übertragung //sind keine ausstehenden Daten mehr vorhanden (Adressiert? "I2C1_data_available()" verwendet?) #ifdef ARMV10_SERBUS_MOD #define EXPORT #else #define EXPORT extern #endif /* ---------------------------Exported functions ---------------------------- */ /******************************************************************************/ /* U N T E R P R O G R A M M: I2C_error_message */ /* */ /* Aufgabe: Gibt eine I2C Fehleranalyse auf UART aus */ /* Input: I2C Fehlercode */ /* return: I2C Fehlercode */ /* Remark: Der Fehler wird als Rückgabewert weitergegeben um das UPro direkt */ /* in einer Fehlerabfrage verwenden zu können: */ /* "if(I2C_error_message(I2C1_init())!=info_success)" */ /******************************************************************************/ EXPORT char I2C_error_message(char errorcode); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_init */ /* */ /* Aufgabe: Initialisiert den I2C1-Bus im Standard-Modus (100kHz) */ /* SCL=PB6, SDA=PB7 . Es wird die GPIOB und I2C1-Peripherie enabled. */ /* I2C1 kann mit "I2C1_disable()" disabled werden. */ /* Input: - */ /* return: I2C Fehlercode */ /* Remark: Nächster Schritt: "I2C1_start()" */ /* I2C Fehlerposition 0x80 */ /******************************************************************************/ EXPORT char I2C1_init(void); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_disable */ /* */ /* Aufgabe: Schaltet die I2C1-Peripherie ab. Es ist keine Buskommunikation */ /* mehr möglich. Die Ports werden als Output konfiguriert und auf */ /* 1 gesetzt. */ /* Input: - */ /* return: - */ /* Remark: */ /* */ /******************************************************************************/ /* !!!!!!!!!!!!!!!!! Noch nicht getestet: !!!!!!!!!!!!!!!!!!!!!! */ EXPORT void I2C1_disable(void); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_start */ /* */ /* Aufgabe: Erzeugt eine Startbedingung und Adressiert einen Slavebaustein. */ /* Je nach R/W-Bit ist man Master Transmitter (0) oder Master */ /* Receiver(1). */ /* Input: "adresse": 7bit Adresse und Read/!Write - Bit "single": */ /* Wenn das R/W-Bit 1 ist und nur ein Byte empfangen werden soll ist */ /* "single" ungleich 0. */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition 0x40 */ /* Nächster I2C Schritt: Senden oder Empfangen */ /******************************************************************************/ EXPORT char I2C1_start(char adresse, char single); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_get_mode() */ /* */ /* Aufgabe: Übergibt den Status des I2C-Busses (Slave, Master Transmitter */ /* oder Master Receiver). Damit kann im Nachhinein festgestellt */ /* werden was das R/W-Bit war. */ /* Input: - */ /* return: 0x00: Der Bus ist deaktiviert */ /* 0x01: Der Bus wurde als Slave adressiert */ /* 0x02: Master Transmitter */ /* 0x03: Master Receiver */ /* Remark: */ /* */ /******************************************************************************/ // !!!!!!!!!!!!!!!!!!!!!! Noch nicht getestet !!!!!!!!!!!!!!!!!!!! EXPORT char I2C1_get_mode(void); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_data_available() */ /* */ /* Aufgabe: Überprüft ob im Master-Receiver Modus Daten die Empfangen */ /* wurden zum Abruf bereit stehen. Damit kann im Unterprogramm */ /* "I2C1_read()" eine Endlosschleife vermieden werden. */ /* Input: - */ /* return: 0x00: Keine Daten vorhanden */ /* 0x01: Daten im Datenregister */ /* */ /* Remark: */ /* */ /******************************************************************************/ EXPORT char I2C1_data_available(void); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_read */ /* */ /* Aufgabe: Liest die Daten aus, die vom Slave gesendet wurden. Sind keine */ /* Daten vorhanden wird solange gewartet, bis welche empfangen */ /* wurden */ /* Input: "daten": Variable in die die Daten geschrieben werden. */ /* "last": Wenn dass das vorletzte Byte ist dass empfangen werden */ /* soll, ist "last" ungleich 0 */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition 0x10 */ /* Nächster Schritt: Lesen oder nach Stop "I2C1_data_available()" */ /* bzw. Start oder Disable */ /******************************************************************************/ EXPORT char I2C1_read(char *daten, char last); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_read_1 */ /* */ /* Aufgabe: Erzeugt eine Startbedingung, Übernimmt die Adressierung, empfangt*/ /* ein einzelnes Byte und erzeugt dann wieder eine Stopbedingung */ /* Input: "adresse": Slaveadresse (Das R/W-Bit wird im UPro auf 1 gesetzt) */ /* "daten": Variable in die das empfangene Byte geschrieben wird */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition 0x40 und 0x10 */ /* Nächster Schritt: Start oder Disable */ /******************************************************************************/ EXPORT int I2C1_read_1(char adresse, char *daten); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_read_last2 */ /* */ /* Aufgabe: Empfängt 2 Bytes und erzeugt dann eine Stopbedingung. */ /* Kann bei einem datenempfang ab 2 Bytes immer verwendet werden */ /* */ /* Input: "daten1": Variable für das vorletzte Empfangene Byte */ /* "daten2": Das letzte Empfangsbyte */ /* */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition: 0x10 */ /* Nächster I2CSchritt: Start oder Disable */ /******************************************************************************/ EXPORT char I2C1_read_last2(char *daten1, char *daten2); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_read_n */ /* */ /* Aufgabe: Liest eine bestimmte Anzahl an Daten ein. */ /* Übernimmt auch die Startbedingung, die Adressierung */ /* und die Stopbedingung. Das R/W-Bit wird im UPro gesetzt. */ /* Input: "adresse": Adresse des Slave-Bausteins */ /* "daten[]": Array, in das die Empfangsdaten geschrieben werden */ /* "anzahl": Wie viele Bytes empfangen werden sollen (ab 1 Byte) */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition: 0x40 und 0x20 */ /* */ /******************************************************************************/ EXPORT char I2C1_read_n(char adresse, char daten[],int anzahl); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_send */ /* */ /* Aufgabe: Sendet ein einzelnes Byte an den Slave und kann dann eine */ /* Stopbedingung erzeugen. Das R/W-Bit muss 0 (Master Transmitter) */ /* gewesen sein. */ /* */ /* Input: "daten": Die Sendedaten */ /* "stop": Wenn dies Variable ungleich 0 ist, wird nach der */ /* Übertragung eine Stopbedingung erzeugt */ /* return: */ /* Remark: I2C Fehlerposition: 0x20 */ /* Nächster Schritt: Senden, oder wenn "stop" ungleich 0: */ /* Start oder Disable */ /******************************************************************************/ EXPORT char I2C1_send(char daten,char stop); /******************************************************************************/ /* U N T E R P R O G R A M M: I2C1_send_n */ /* */ /* Aufgabe: Übernimmt die Startbedingung und die Adressierung. */ /* Sendet danach eine Reihe an Daten an den Slave wobei dazwischen */ /* Pausen eingelegt werden können. Danach kommt es zu einer */ /* Stopcondition */ /* Input: "adresse": Slaveadresse (Das R/W-Bit wird im UPro auf 0 gesetzt) */ /* "daten[]": Array dessen Inhalt an den Slave gesendet wird */ /* "anzahl": Anzahl der Bytes aus dem Array die gesendet werden */ /* "Pause": Pause in Millisekunden die zwischen den Übertragungen */ /* eingelegt wird */ /* return: Fehlercode */ /* Remark: I2C Fehlerposition: 0x40 und 0x20 */ /* Nächster Schritt: Start oder Disable */ /******************************************************************************/ EXPORT char I2C1_send_n(char adresse, char daten[],int anzahl,int pause); /******************************************************************************/ /* U N T E R P R O G R A M M: SPI1_Init */ /* */ /* Aufgabe: Initialisiert SPI 1 Schnittstelle */ /* Input: */ /* return: */ /* Remark: */ /* */ /******************************************************************************/ EXPORT void SPI1_Init(void); /******************************************************************************/ /* U N T E R P R O G R A M M: SPI1_Send */ /* */ /* Aufgabe: Sendet 1 Byte via SPI1 Schnittstelle */ /* Input: */ /* return: */ /* Remark: */ /* */ /******************************************************************************/ EXPORT void SPI1_Send(unsigned char send); /******************************************************************************/ /* U N T E R P R O G R A M M: SPI1_Receive */ /* */ /* Aufgabe: Empfängt 1 Byte von SPI1 Schnittstelle */ /* Input: */ /* return: */ /* Remark: */ /* */ /******************************************************************************/ EXPORT unsigned char SPI1_Receive(void); #undef EXPORT #endif /* __ARMV10_SERBUS_H */ /******************* (C) HTL - HOLLABRUNN 2009-2010 *****END OF FILE****/