Commit 7410493d authored by Peter Müller's avatar Peter Müller
Browse files

Initialer Commit

parents
/*
In dieser Datei werden allgemeine Infos zum Programm gesammelt.
Es sollte hier kein Quellcode enthalten sein.
*************************************
* ATMega8 I2C <-> Funk Adapter *
*************************************
Copyright (c) 2016 Peter Müller <peter@crycode.de>
Hiermit wird unentgeltlich jeder Person, die eine Kopie der Software und der zugehörigen Dokumentationen (die "Software") erhält, die Erlaubnis erteilt, sie uneingeschränkt zu nutzen, inklusive und ohne Ausnahme mit dem Recht, sie zu verwenden, zu kopieren, zu verändern, zusammenzufügen, zu veröffentlichen, zu verbreiten, zu unterlizenzieren und/oder zu verkaufen, und Personen, denen diese Software überlassen wird, diese Rechte zu verschaffen, unter den folgenden Bedingungen:
Der obige Urheberrechtsvermerk und dieser Erlaubnisvermerk sind in allen Kopien oder Teilkopien der Software beizulegen.
DIE SOFTWARE WIRD OHNE JEDE AUSDRÜCKLICHE ODER IMPLIZIERTE GARANTIE BEREITGESTELLT, EINSCHLIEẞLICH DER GARANTIE ZUR BENUTZUNG FÜR DEN VORGESEHENEN ODER EINEM BESTIMMTEN ZWECK SOWIE JEGLICHER RECHTSVERLETZUNG, JEDOCH NICHT DARAUF BESCHRÄNKT. IN KEINEM FALL SIND DIE AUTOREN ODER COPYRIGHTINHABER FÜR JEGLICHEN SCHADEN ODER SONSTIGE ANSPRÜCHE HAFTBAR ZU MACHEN, OB INFOLGE DER ERFÜLLUNG EINES VERTRAGES, EINES DELIKTES ODER ANDERS IM ZUSAMMENHANG MIT DER SOFTWARE ODER SONSTIGER VERWENDUNG DER SOFTWARE ENTSTANDEN.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*************************************
* ATMega8 Pins *
*************************************
+-\/-+
PC6 1| |28 PC5 (AI 5) (D 19)
RXD (D 0) PD0 2| |27 PC4 (AI 4) (D 18)
TXD (D 1) PD1 3| |26 PC3 (AI 3) (D 17)
(D 2) PD2 4| |25 PC2 (AI 2) (D 16)
PWM+ (D 3) PD3 5| |24 PC1 (AI 1) (D 15)
(D 4) PD4 6| |23 PC0 (AI 0) (D 14)
VCC 7| |22 GND
GND 8| |21 AREF
PB6 9| |20 AVCC
PB7 10| |19 PB5 (D 13)
PWM+ (D 5) PD5 11| |18 PB4 (D 12)
PWM+ (D 6) PD6 12| |17 PB3 (D 11) PWM
(D 7) PD7 13| |16 PB2 (D 10) PWM
(D 8) PB0 14| |15 PB1 (D 9) PWM
+----+
*************************************
* Allgemeines *
*************************************
Alle Veränderbaren Parameter sind in der Datei "defs.h" enthalten und können dort angepasst werden.
Zur Kommunikation über die Funkmodule wird die RadioHead-Library mit der RHDatagram-Klasse verwendet.
Der Server (dieses Programm) hat dabei die Adresse 0x01.
Alle anderen Geräte können die Adressen von 0x02 bis 0xFE nutzen. Die 0xFF ist eine Broadcast-Adresse.
Über den Master-Info-Pin kann der I2C-Master über im RX-Ring-Buffer vorhandene Daten informiert werden.
*************************************
* Senden *
*************************************
Zum Senden einer Nachricht wird diese zuerst vom I2C-Master in den TX-Buffer geschrieben.
Hierfür schreibt der Master die entsprechenden Bytes an die Adresse 0x50. (siehe auch "Aufbau der Buffer und Nachrichten")
Ist der TX-Buffer geschrieben, dann schreibt der Master in die Adresse 0x06. Die Nachricht wird daraufhin über Funk gesendet.
Der TX-Buffer kann komplett geleert werden, indem der Master in die Adresse 0x08 schreibt.
*************************************
* Empfangen *
*************************************
Über Funk Empfangene Nachrichten werden im RX-Ring-Buffer zwischengespeichert, bis diese über I2C abgerufen werden.
Ist der RX-Ring-Buffer voll, dann wird beim empfangen einer neuen Nachricht jeweils die älteste überschieben.
Sind Nachrichten im RX-Ring-Buffer vorhanden wird dem I2C-Master dies über ein LOW-Signal am Master-Info-Pin mitgeteilt.
Der Master kann dann durch schreiben an die Adresse 0x07 den jeweils ältesten Wert aus dem RX-Ring-Buffer in den RX-Buffer laden und anschließend diesen lesen.
Durch Lesen von der Adresse 0x20 kann der I2C-Master auch mehrfach den aktuellen RX-Buffer auslesen.
Wird aus dem RX-Ring-Buffer geladen, wenn dieser leer ist, dann enthält der gesamte RX-Buffer 0x00-Werte.
Die Anzahl der im RX-Ring-Buffer enthaltenen Nachrichten kann der I2C-Master durch lesen von der Adresse 0x00 abfragen.
*************************************
* I2C-Register *
*************************************
+---------+-----+----------------------------------------------+
| Adresse | r/w | Beschreibung |
+---------+-----+----------------------------------------------+
| 0x00 | r | aktuelle Größe des RX-Ring-Buffer |
+---------+-----+----------------------------------------------+
| 0x06 | w | aktuellen TX-Buffer senden |
+---------+-----+----------------------------------------------+
| 0x07 | w | Nachricht aus dem RX-Ring-Buffer in den |
| | r | RX-Buffer laden und anschließend lesen. |
+---------+-----+----------------------------------------------+
| 0x08 | w | TX-Buffer leeren |
+---------+-----+----------------------------------------------+
| 0x09 | w | RX-Buffer und RX-Ring-Buffer leeren |
+---------+-----+----------------------------------------------+
| 0x20 | r | Aktueller RX-Buffer. |
| ... | | Teilweises Lesen über z.B. 0x25 möglich. |
+---------+-----+----------------------------------------------+
| 0x50 | w | Aktueller TX-Buffer. |
| ... | | Teilweises Schreiben über z.B. 0x55 möglich. |
+---------+-----+----------------------------------------------+
Der Adressbereich der RX- (0x20...) und TX-Buffer (0x50...) ist abhängig von der definierten I2C-Buffer Größe (i2c_buffer_size).
Nach einem Schreiben an die Adresse 0x07 wird intern automaitsch auf die Adresse 0x20 gewechselt, sodass direkt (ohne neue Adressierung) gelesen werden kann.
*************************************
* Aufbau der Buffer und Nachrichten *
*************************************
+---------------------------------------------------------+
| I2C-Buffer |
+------------------+------------------+-------------------+
| 0 | 1 | 2 ... X |
| To-/From-Adresse | Nachrichtenlänge | Nachrichteninhalt |
+------------------+------------------+-------------------+
|------------------| Funk RX-/TX-Nachricht |
+------------------+--------------------------------------+
Der Inhalt einer Nachricht kann somit maximal i2c_buffer_size - 2 lang sein.
*************************************
* Sonstiges *
*************************************
Der Master-Info-Pin wird direkt von den Funktionen rx_circ_buf_in() und rx_circ_buf_out() geschaltet.
*/
/*
* ATMega8 I2C <-> Funk Adapter
*
* Copyright (c) 2016 Peter Müller <peter@crycode.de>
*/
// Definitionen laden
#include "defs.h"
// RX-Ring-Buffer
#include "rx_circ_buf.h"
// I2C-Kommunikation
#include "i2c.h"
//#include "xtea.h"
// RadioHead
#include <RH_ASK.h>
#include <RHDatagram.h>
// RadioHead initialisieren
RH_ASK rh_driver(rh_speed,rh_rx_pin,rh_tx_pin,rh_ptt_pin);
RHDatagram rh_manager(rh_driver,rh_addr);
// Buffer für RadioHead-Daten
uint8_t rh_buf[i2c_buffer_size] = { 0x00 };
/*
* Programmstart
*/
void setup() {
// Debug-Infos
#ifdef DEBUG
Serial.begin(9600);
delay(100);
Serial.println("I2C<->433MHz Adapter online");
delay(100);
// I2C RX- und TX-Buffer für Debug füllen
for(uint8_t i=0;i<i2c_buffer_size;i++){
i2c_buf_rx[i] = 0x10 + i;
i2c_buf_tx[i] = 0x20 + i;
}
#endif
// Den Master-Info-Pin auf HIGH setzen
pinMode(master_info_pin, OUTPUT);
digitalWrite(master_info_pin, HIGH);
// I2C initialisieren
i2c_init();
// RadioHead-Manager initialisieren
if(!rh_manager.init()){
#ifdef DEBUG
Serial.println("RH-Manager Init fehlgeschlagen!");
#endif
}
}
// Zählvariable für Ausgabe der Debug-Infos ca. jede Sekunde
#ifdef DEBUG
uint8_t loop_count = 0;
#endif
/*
* Hauptschleife
*/
void loop() {
// Debug-Infos ausgeben
// Inhalt von RX- und TX-I2C-Buffer und Anzahl Nachrichten im RX-Ring-Buffer
#ifdef DEBUG
if(loop_count == 99){
loop_count = 0;
Serial.print("RX: ");
for(uint8_t i=0;i<i2c_buffer_size;i++){
Serial.print(i2c_buf_rx[i],HEX);
Serial.print(" ");
}
Serial.print("TX: ");
for(uint8_t i=0;i<i2c_buffer_size;i++){
Serial.print(i2c_buf_tx[i],HEX);
Serial.print(" ");
}
Serial.print(" #RX: ");
Serial.print(rx_circ_buf_count);
Serial.println("");
}else{
loop_count++;
}
#endif
// Daten zu senden?
if(my_status & (1<<STATUS_BIT_SEND_TX_BUFFER)){
// Den aktuellen TX-Buffer senden
/* Prüfen ob zu sendende Daten im TX-Buffer sind
* i2c_buf_tx[0] = Empfängeradresse
* i2c_buf_tx[1] = Länge der Nachricht
*/
if(i2c_buf_tx[0] > 0 && i2c_buf_tx[1] > 0){
// Empfänger und Nachrichtenlänge sind größer als 0... Nachricht senden
uint8_t len = (i2c_buf_tx[1] <= i2c_buffer_size -1) ? i2c_buf_tx[1] : i2c_buffer_size - 1; // Länge wie angegeben, maximal aber i2c_buffer_size -1
rh_manager.sendto(&i2c_buf_tx[1], len, i2c_buf_tx[0]); // bool sendto (uint8_t *buf, uint8_t len, uint8_t address)
#ifdef DEBUG
Serial.println("Nachricht gesendet");
#endif
}
// Flag im Status-Byte löschen
my_status &= ~(1<<STATUS_BIT_SEND_TX_BUFFER);
}
// Daten empfangen?
if(rh_manager.available()){
// Nachricht verfügbar
#ifdef DEBUG
Serial.print("Nachricht empfangen: ");
#endif
// Nachricht lesen
uint8_t len = sizeof(rh_buf)-1;
if(rh_manager.recvfrom(&rh_buf[1], &len, &rh_buf[0])){ // bool recvfrom (uint8_t *buf, uint8_t *len, uint8_t *from=NULL, uint8_t *to=NULL, uint8_t *id=NULL, uint8_t *flags=NULL)
// gelesen
// Debug-Infos
#ifdef DEBUG
for(uint8_t i=0; i<i2c_buffer_size; i++){
Serial.print(" ");
Serial.print(rh_buf[i],HEX);
}
Serial.println("");
#endif
// in den RX-Ring-Buffer schreiben
rx_circ_buf_in(rh_buf);
// Buffer wieder leeren
memset(rh_buf, 0x00, i2c_buffer_size);
}else{
#ifdef DEBUG
Serial.println("lesen fehlgeschlagen!");
#endif
}
}
// Kurze Verzögerung der Hauptschleife
delay(10);
}
/*
* Definitionen von allgemeinen Parametern des Programms.
*/
#include "defs.h"
// Status-Byte
volatile uint8_t my_status = 0x00;
/*
* Definitionen von allgemeinen Parametern des Programms.
*/
#ifndef __DEFS_H__
#define __DEFS_H__
#include <stdint.h>
/*
* Debug aktivieren.
* Bei aktivem Debug werden Ausgaben zur UART-Schnittstelle erzeugt.
* Auskommentieren um Debug zu deaktivieren.
*/
#define DEBUG
/*
* Die Slave-Adresse für den I2C-Bus, über die der MC erreichbar ist.
* 7-Bit Adresse ohne r/w-Bit am Ende, wie sie z.B. vom RaspberryPi über i2cdetect ermittelt wird.
*/
#define i2c_slave_addr 0x28
/*
* Größe des I2C-Buffers in Byte für RX-/TX-Nachrichten.
*/
#define i2c_buffer_size 8
/*
* Größe des Ring-Buffers für die RX-Nachrichten.
* Muss 2^n betragen (4, 8, 16, 32, ...).
* Die tatsächlich verwendbare Größe des Ring-Buffers ist rx_circ_buf_size-1.
*/
#define rx_circ_buf_size 8
/*
* Adresse des MC im Funknetz von RadioHead.
*/
#define rh_addr 0x01
/*
* Bitrate in Bit/s vom RadioHead.
*/
#define rh_speed 2000
/*
* RX-/TX-/PTT-Pin für RadioHead.
* 433MHz Empfänger/Sender.
* PTT ungenutzt, sollte ein freier Pin des MC sein.
*/
#define rh_rx_pin 14
#define rh_tx_pin 15
#define rh_ptt_pin 17
/*
* Pin über den ein Signal an den I2C-Master gegeben wird, wenn Daten über Funk empfangen wurden.
*/
#define master_info_pin 16
/*
********************************************
* Ab hier muss nichts mehr geändert werden *
********************************************
*/
/*
* Status-Byte
*/
extern volatile uint8_t my_status;
/*
* Bit-Definitonen vom Status-Byte
*/
#define STATUS_BIT_SEND_TX_BUFFER 0
/*
* Maximale Nachrichtenlänge von RadioHead auf die Größe des I2C-Buffers - 1 festlegen.
* -1 da im I2C-Buffer 0=To/From
*/
#define RH_ASK_MAX_MESSAGE_LEN i2c_buffer_size-1
#endif /* __DEFS_H__ */
/*
* Kommunikation über den I2C-Bus als Slave.
*
* Copyright (c) 2016 Peter Müller <peter@crycode.de>
*/
// Definitionen laden
#include "defs.h"
// Arduino-Libs
#include <Arduino.h>
#include <Wire.h>
// eigener Header
#include "i2c.h"
// RX-Ring-Buffer
#include "rx_circ_buf.h"
// aktueller (letzter) I2C-Befehl
volatile uint8_t i2c_cmd = I2C_CMD_GET_RX_BUFFER_SIZE;
// RX-/TX-Buffer für die Nachrichten
uint8_t i2c_buf_rx[i2c_buffer_size] = { 0x00 };
uint8_t i2c_buf_tx[i2c_buffer_size] = { 0x00 };
/*
* Funktionzur Initialisierung des I2C.
*/
void i2c_init(){
Wire.begin(i2c_slave_addr);
Wire.onRequest(i2c_request_event);
Wire.onReceive(i2c_receive_event);
}
/*
* Anfrage zum Senden über I2C beantworten.
*/
void i2c_request_event(){
if(i2c_cmd == I2C_CMD_GET_RX_BUFFER_SIZE){
// Größe des RX-Ring-Buffers lesen
Wire.write(&rx_circ_buf_count, 1);
}else if(i2c_cmd >= I2C_CMD_GET_RX_BUFFER_START && i2c_cmd <= I2C_CMD_GET_RX_BUFFER_END){
// Lesen des RX-Buffers (ab bestimmter Adresse)
Wire.write(&i2c_buf_rx[i2c_cmd-I2C_CMD_GET_RX_BUFFER_START], I2C_CMD_GET_RX_BUFFER_END - i2c_cmd + 1);
}else{
// Ungültige Anfrage... 0x00 senden
uint8_t nix = 0x00;
Wire.write(&nix, 1);
}
}
/*
* Empfangen über den I2C-Bus.
* Das erste empfange Byte wird immer als Befehl interpretiert.
*/
void i2c_receive_event(int bytesReceived){
// Befehl lesen
if(bytesReceived > 0){
i2c_cmd = Wire.read();
}
if(i2c_cmd == I2C_CMD_GET_RX_BUFFER_SIZE){
// Größe des RX-Ring-Buffers lesen
}else if(i2c_cmd == I2C_CMD_SEND_TX_BUFFER){
// Den aktuellen TX-Buffer über Funk senden
// Flag im Status-Byte setzen, damit in der Hauptschleife die Daten gesendet werden
my_status |= (1<<STATUS_BIT_SEND_TX_BUFFER);
}else if(i2c_cmd == I2C_CMD_NEXT_RX_BUFFER){
// Den nächsten RX-Buffer aus dem RX-Ring-Buffer laden und anschließend ggf. direkt lesen
rx_circ_buf_out(i2c_buf_rx);
// i2c_cmd auf lesen vom RX-Buffer setzen, damit direkt gelesen werden kann
i2c_cmd = I2C_CMD_GET_RX_BUFFER_START;
}else if(i2c_cmd == I2C_CMD_CLEAR_TX_BUFFER){
// leeren des TX-Buffers
memset(i2c_buf_tx, 0x00, i2c_buffer_size);
}else if(i2c_cmd == I2C_CMD_CLEAR_RX_BUFFER){
// leeren des RX-Buffers und des RX-Ring-Buffers
memset(i2c_buf_rx, 0x00, i2c_buffer_size);
rx_circ_buf_clear();
}else if(i2c_cmd >= I2C_CMD_GET_RX_BUFFER_START && i2c_cmd <= I2C_CMD_GET_RX_BUFFER_END){
// Lesen des RX-Buffers (ab bestimmter Adresse)
}else if(i2c_cmd >= I2C_CMD_SET_TX_BUFFER_START && i2c_cmd <= I2C_CMD_SET_TX_BUFFER_END){
// Schreiben des TX-Buffers (ab bestimmter Adresse)
// Einlesen des Buffers vom I2C nach i2c_buf_tx
while(Wire.available() && i2c_cmd <= I2C_CMD_SET_TX_BUFFER_END){
i2c_buf_tx[i2c_cmd - I2C_CMD_SET_TX_BUFFER_START] = Wire.read();
i2c_cmd++;
}
}
// Ggf. zu viel gesendete Daten lesen und verwerfen
while(Wire.available()){
Wire.read();
}
}
#ifndef __I2C_H__
#define __I2C_H__
/**
* Header-Datei für die I2C-Kommunikation.
*
* @author Peter Müller <peter@crycode.de>
*/
// I2C-Befehle
#define I2C_CMD_GET_RX_BUFFER_SIZE 0x00
#define I2C_CMD_SEND_TX_BUFFER 0x06
#define I2C_CMD_NEXT_RX_BUFFER 0x07
#define I2C_CMD_CLEAR_TX_BUFFER 0x08
#define I2C_CMD_CLEAR_RX_BUFFER 0x09
// Adressen der RX- und TX-Buffers
#define I2C_CMD_GET_RX_BUFFER_START 0x20
#define I2C_CMD_GET_RX_BUFFER_END (I2C_CMD_GET_RX_BUFFER_START + i2c_buffer_size - 1)
#define I2C_CMD_SET_TX_BUFFER_START 0x50
#define I2C_CMD_SET_TX_BUFFER_END (I2C_CMD_SET_TX_BUFFER_START + i2c_buffer_size - 1)
// Variablen bekannt machen
extern uint8_t i2c_buf_rx[i2c_buffer_size];
extern uint8_t i2c_buf_tx[i2c_buffer_size];
// Funktionen bekannt machen
void i2c_init();
void i2c_request_event();
void i2c_receive_event(int bytesReceived);
void i2c_read_trash();
#endif /* __I2C_H__ */
/**
* Ring-Buffer (FIFO) für die eingehenden Nachrichten.
*
* @author Peter Müller <peter@crycode.de>
*/
// Definitionen laden
#include "defs.h"
// Arduino-Libs
#include <Arduino.h>
// eigener Header
#include "rx_circ_buf.h"
// Buffer-Variable
uint8_t rx_circ_buf[rx_circ_buf_size][i2c_buffer_size] = { 0x00 };
// Index für nächsten Schreibzugriff
uint8_t rx_circ_buf_w = 0;
// Index für nächten Lesezugriff
uint8_t rx_circ_buf_r = 0;
// Zähler für die im Ring-Buffer enthaltenen Elemente
uint8_t rx_circ_buf_count = 0;
/**
* Funktion zum Einfügen eines Arrays in den Ring-Buffer.
* Bei einem Überlauf wird der älteste Wert überschrieben und geht somit verloren.
* Der Leseindex wird im Falle eines Überlaufs angepasst, damit immer der älteste nicht gelesene Wert gelesen wird.
*
* @param uint8_t dat[i2c_buffer_size] Das einzufügende Array aus uint8_t-Werten mit einer Länge von i2c_buffer_size.
*/
void rx_circ_buf_in(uint8_t dat[i2c_buffer_size]){
// Nächtens Schreibindes ermitteln
uint8_t next = ((rx_circ_buf_w + 1) & rx_circ_buf_mask);
// Überlauf?
if(rx_circ_buf_r == next){
// Leseindex einen hochzählen, damit immer der älteste Wert gelesen wird
rx_circ_buf_r = (rx_circ_buf_r+1) & rx_circ_buf_mask;
}else{
// Kein Überlauf... Zähler mit den enthaltenen Elementen hochzählen
rx_circ_buf_count++;
}
// Speicherinhalt kopieren
memcpy(rx_circ_buf[rx_circ_buf_w],dat,i2c_buffer_size);
// Nächsten Schreibindex merken
rx_circ_buf_w = next;
// Den Master-Info-Pin auf LOW setzen, damit der Master die Meldung erhält, dass etwas im RX-Buffer ist.
digitalWrite(master_info_pin, LOW);
}
/**
* Funktion zum Lesen des letzten ungelesenen Arrays aus dem Ring-Buffer.
* Es wird immer das älteste nicht gelesene Array gelesen.
* Wenn der Ring-Buffer leer ist (Leseindex==Schreibindex) wird ein Array gefüllt mit 0x00 an den Pointer *dat geschrieben.
*
* @param uint8_t dat[i2c_buffer_size] Das zu füllende Array aus uint8_t-Werten mit einer Länge von i2c_buffer_size.
*
* Beispiel:
* rx_circ_buf_out(i2c_data_rx);
*/
void rx_circ_buf_out(uint8_t dat[i2c_buffer_size]){
// leerer Buffer?
if (rx_circ_buf_r == rx_circ_buf_w){
// Array mit 0x00 füllen
memset(dat, 0x00, i2c_buffer_size);
return;
}
// Zähler mit den enthaltenen Elementen runterzählen
rx_circ_buf_count--;
// Speicherinhalt kopieren
memcpy(dat,rx_circ_buf[rx_circ_buf_r],i2c_buffer_size);
// Nächsten Leseindex festlegen
rx_circ_buf_r = (rx_circ_buf_r+1) & rx_circ_buf_mask;
// Den Master-Info-Pin auf HIGH setzen wenn nichts mehr im RX-Buffer ist, damit der Master die Meldung erhält.
if(rx_circ_buf_count == 0){
digitalWrite(master_info_pin, HIGH);
}
}
/**
* Funktion zum Leeren des RX-Ring-Buffers.
* Dabei werden der r/w-Index und der Counter auf 0 zurückgesetzt.
*/
void rx_circ_buf_clear(){
rx_circ_buf_w = 0;