not finished RFM12 Libary

Files at this revision

API Documentation at this revision

Comitter:
dominik
Date:
Fri Feb 18 20:07:12 2011 +0000
Commit message:
not finished

Changed in this revision

rfm12.cpp Show annotated file Show diff for this revision Revisions of this file
rfm12.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rfm12.cpp	Fri Feb 18 20:07:12 2011 +0000
@@ -0,0 +1,392 @@
+#include "rfm12.h"
+
+char HammiEncode[16] = {0x15,0x02,0x49,0x5E,0x64,0x73,0x38,0x2F,0xD0,0xC7,0x8C,0x9B,0xA1,0xB6,0xFD,0xEA};
+char HammiDecode[256] =
+{
+    0x01,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x02,0x02,0x01,0x03,0x0A,0x02,0x03,0x07,
+    0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x00,0x06,0x02,0x03,0x0B,0x02,0x00,0x03,0x03,
+    0x04,0x0C,0x01,0x05,0x04,0x04,0x05,0x07,0x06,0x06,0x07,0x07,0x06,0x07,0x07,0x07,
+    0x06,0x04,0x05,0x05,0x04,0x00,0x0D,0x05,0x06,0x06,0x06,0x07,0x06,0x06,0x07,0x07,
+    0x00,0x02,0x01,0x01,0x04,0x00,0x01,0x09,0x02,0x02,0x03,0x02,0x02,0x02,0x03,0x03,
+    0x08,0x00,0x01,0x05,0x00,0x00,0x03,0x01,0x02,0x02,0x03,0x03,0x03,0x02,0x03,0x03,
+    0x04,0x04,0x05,0x05,0x04,0x04,0x04,0x05,0x06,0x02,0x0F,0x07,0x04,0x06,0x07,0x07,
+    0x04,0x05,0x05,0x05,0x04,0x04,0x05,0x05,0x06,0x06,0x07,0x05,0x06,0x0E,0x03,0x07,
+    0x08,0x0C,0x01,0x09,0x0A,0x08,0x09,0x09,0x0A,0x0A,0x0B,0x0B,0x0A,0x0A,0x0A,0x0B,
+    0x08,0x08,0x09,0x0B,0x08,0x00,0x0D,0x09,0x0A,0x0B,0x0B,0x0B,0x0A,0x0A,0x0B,0x0B,
+    0x0C,0x0C,0x0D,0x0C,0x0C,0x0C,0x0D,0x0D,0x0E,0x0C,0x0F,0x0F,0x0A,0x0E,0x0F,0x07,
+    0x0C,0x0C,0x0D,0x0D,0x0D,0x0C,0x0D,0x0D,0x06,0x0E,0x0F,0x0B,0x0E,0x0E,0x0D,0x0F,
+    0x08,0x08,0x09,0x09,0x08,0x09,0x09,0x09,0x0A,0x02,0x0F,0x0B,0x0A,0x0A,0x0B,0x09,
+    0x08,0x08,0x08,0x09,0x08,0x08,0x09,0x09,0x08,0x0A,0x0B,0x0B,0x0A,0x0E,0x03,0x0B,
+    0x0C,0x0C,0x0F,0x0D,0x04,0x0C,0x0D,0x09,0x0F,0x0E,0x0F,0x0F,0x0E,0x0E,0x0F,0x0F,
+    0x08,0x0C,0x0D,0x05,0x0C,0x0E,0x0D,0x0D,0x0E,0x0E,0x0F,0x0F,0x0E,0x0E,0x0F,0x0E
+};
+
+RFM12::RFM12(PinName irq, PinName sel, PinName sdi, PinName sdo, PinName sck) : _irq(irq), _sel(sel), _sdi(sdi), _sdo(sdo), _sck(sck)
+{ 
+    _irq.mode(PullNone);
+    _irq.fall(this, &RFM12::RF_PHY_Interrupt);
+
+    _sel = 1;
+    _sdi = 1;
+    _sck = 0;
+    
+    //Initialisierung des Modules
+    RF_PHY_Write(0x80D8);
+    RF_PHY_Write(0x8201);
+    RF_PHY_Write(0xA640);
+    RF_PHY_Write(0xC647);
+    RF_PHY_Write(0x94A0);
+    RF_PHY_Write(0xC2AC);
+    RF_PHY_Write(0xCA81);
+    RF_PHY_Write(0xC483);
+    RF_PHY_Write(0x9850);
+    RF_PHY_Write(0xE000);
+    RF_PHY_Write(0xC800);
+    RF_PHY_Write(0xC040);
+    
+    //Auf Listen Modus schalten
+    RF_PHY_Write(0x82C8);
+    RF_PHY_Write(0xCA81);
+    RF_PHY_Write(0xCA83);
+    RF_PHY_Write(0x0000);
+    RF_PHY_Write(0xB000);
+    
+    wait(0.001);
+    
+    status = LISTEN;
+}
+
+short RFM12::RF_PHY_Write(short b)
+{
+    char i;
+    short temp = 0;
+
+    _sck = 0;
+    _sel = 0;
+    
+    for(i = 0; i < 16; i++)
+    {
+        if(b & 0x8000)
+        {
+            _sdi = 1;
+        }
+        else
+        {
+            _sdi = 0;
+        }
+
+        _sck = 1;
+        temp <<= 1;
+
+        if(_sdo)
+        {
+            temp |= 0x0001;
+        }
+
+        _sck = 0;
+        b <<= 1;
+    }
+
+    _sel = 1;
+    
+    return temp;
+}
+
+void RFM12::RF_PHY_Interrupt()
+{
+    short stat = RF_PHY_Write(0x0000);
+    if(stat & RF_STATUS_RGITFFIT)
+    {
+        switch(status)
+        {
+            case TX:
+                if(sbufferi < sbufferlength)
+                {
+                    RF_PHY_Send(sbuffer[sbufferi]);
+                    sbufferi++;
+                }
+                else
+                {
+                    RF_PHY_Write(0x82C8);
+                    RF_PHY_Write(0xCA81);
+                    RF_PHY_Write(0xCA83);
+                    RF_PHY_Write(0x0000);
+                    RF_PHY_Write(0xB000);
+                    
+                    status = LISTEN;
+                    sbufferi = 0;
+                    sbufferlength = 0;
+                    
+                    delete [] sbuffer;
+                }
+            break;
+            
+            case LISTEN:
+                short tmp;
+                tmp = RF_PHY_Receive();
+                rbuffer = new char[tmp];
+                rbufferi = 0;
+                rbufferlength = tmp;
+                status = RX; 
+            break;
+            
+            case RX:
+                if(rbufferi < rbufferlength)
+                {
+                    rbuffer[rbufferi] = RF_PHY_Receive();
+                    rbufferi++;
+                }
+                else
+                {                     
+                                        
+                    //Auf Listen Modus schalten
+                    RF_PHY_Write(0x82C8);
+                    RF_PHY_Write(0xCA81);
+                    RF_PHY_Write(0xCA83);
+                    RF_PHY_Write(0x0000);
+                    RF_PHY_Write(0xB000);
+                    
+                    status = LISTEN;  
+                           
+                    //Weitergabe an Layer 3
+                    RF_L3_Empfangen(rbuffer, rbufferlength);
+                                        
+                    rbufferi = 0;
+                    rbufferlength = 0;                  
+                }
+            break;
+        }
+    }
+}
+
+void RFM12::RF_PHY_Send(char b)
+{
+    RF_PHY_Write(0xB800 + b);
+}
+
+char RFM12::RF_PHY_Receive()
+{
+    short tmp;
+    tmp = RF_PHY_Write(0xB000);
+    return (tmp & 0x00FF);
+}
+
+int RFM12::RF_PHY_Senden(char *buff, int length)
+{
+    if(status != LISTEN)
+        return -1;
+
+    sbuffer = new char[length + 9];
+    
+    sbuffer[0] = 0xAA;   //Preamble
+    sbuffer[1] = 0xAA;
+    sbuffer[2] = 0xAA;
+    sbuffer[3] = 0x2D;   //Sync HI
+    sbuffer[4] = 0xD4;   //Sync LO
+
+    sbuffer[5] = length;
+
+    memcpy(sbuffer + 6, buff, length);
+
+    delete [] sbufferl3;
+
+    sbuffer[length + 6] = 0xAA;
+    sbuffer[length + 7] = 0xAA;
+    sbuffer[length + 8] = 0xAA;
+
+    sbufferlength = length + 9;
+    sbufferi = 0;
+    status = TX;
+    
+    //In Sendemodus schalten...
+    RF_PHY_Write(0x0000);
+    RF_PHY_Write(0x8239);    
+        
+    return 0;
+}
+
+int RFM12::RF_L3_Senden(char *buff, char length)
+{
+    int i;
+    short crc = 0;
+
+    sbufferl3 = new char((length + 2)*2);
+
+    for(i = 0; i < length; i++)
+    {
+        sbufferl3[i*2]         = Hammi_EncodeHI(buff[i]);
+        sbufferl3[i*2 + 1]    = Hammi_EncodeLO(buff[i]);
+        crc = crcadd(crc, buff[i]);
+    }
+
+    delete [] sbufferl4;
+
+    sbufferl3[2*length]         = Hammi_EncodeHI(crc >> 8);
+    sbufferl3[2*length + 1]        = Hammi_EncodeLO(crc >> 8);
+    sbufferl3[2*length + 2]        = Hammi_EncodeHI(crc & 0x00FF);
+    sbufferl3[2*length + 3]        = Hammi_EncodeLO(crc & 0x00FF);
+
+    RF_PHY_Senden(sbufferl3, (length+2)*2);
+
+    return 0;
+}
+
+int RFM12::RF_L3_Empfangen(char *buff, char length)
+{
+    char i;
+    short crc = 0;
+
+    rbufferl3 = new char(length/2 - 2);
+
+    for(i = 0; i < (length/2 - 2); i++)
+    {
+        rbufferl3[i] = Hammi_DecodeHILO(buff[i*2], buff[i*2+1]);
+        crc = crcadd(crc, rbufferl3[i]);
+    }
+
+    crc = crcadd(crc, Hammi_DecodeHILO(buff[length - 4], buff[length - 3]));
+    crc = crcadd(crc, Hammi_DecodeHILO(buff[length - 2], buff[length - 1]));
+
+    delete [] rbuffer;
+
+    if(crc == 0)
+    {
+        RF_L4_Empfangen(rbufferl3, (length/2 - 2));
+
+        return 0;
+    }
+    else    //Paket verwerfen
+    {
+        delete [] rbufferl3;
+        return -1;
+    }
+}
+
+int RFM12::RF_L4_Senden(char *buff, header h, char length)
+{
+    char i;
+
+    sbufferl4 = new char(length + 2);
+
+    sbufferl4[0] = h.Byte.HI;
+    sbufferl4[1] = h.Byte.LO;
+
+    for(i = 0; i < length; i++)
+    {
+        sbufferl4[i+2]     = buff[i];
+    }
+
+    RF_L3_Senden(sbufferl4, length + 2);
+
+    return 0;
+}
+
+int RFM12::RF_L4_Empfangen(char *buff, char length)
+{
+    uint8_t i;
+    uint8_t valid = 0;
+    header h;
+
+    rbufferl4 = new char(length - 2);
+
+    for(i = 0; i < length - 2; i++)
+    {
+        rbufferl4[i] = buff[i+2];
+    }
+
+    h.Byte.HI = buff[0];
+    h.Byte.LO = buff[1];
+
+    delete [] rbufferl3;
+
+    //Broadcast
+    if(h.Bit.DestType == 0)
+    {
+        valid = 1;
+    }
+    if(h.Bit.DestType == 1)
+    {
+        if(h.Bit.Addresse == ADDR)
+        {
+            valid = 1;
+        }
+    }
+    if(h.Bit.DestType == 2)
+    {
+        //TODO: Gruppennummern durchlaufen...
+        //if(h.Bit.Addresse == 0x01)    valid = 1;
+        //if(h.Bit.Addresse == 0x02)  valid = 1;
+    }
+    if(h.Bit.DestType == 3)
+    {
+        //TODO: Typen durchlaufen...
+    }
+
+    //Je nach Port richtige "Anwendung" aufrufen...
+    if(valid)
+    {
+        if(h.Bit.Port == 1)
+        {
+            RF_P1_Empfangen(rbufferl4, length - 2);
+        }
+    }
+    else    //Paket verwerfen
+    {
+        delete [] rbufferl4;
+        return -1;
+    }
+
+    return 0;
+}
+
+int RFM12::RF_P1_Empfangen(char *buff, char length)
+{
+    delete [] rbufferl4;
+    
+    return 0;
+}
+
+short RFM12::crcadd(short crc, char b)
+{
+    
+    return update_crc16_1021(crc, b);
+}
+
+char RFM12::Hammi_EncodeHI(char b)
+{
+    return HammiEncode[b>>4];
+}
+
+char RFM12::Hammi_EncodeLO(char b)
+{
+    return HammiEncode[b & 0x0F];
+}
+
+char RFM12::Hammi_DecodeHILO(char hi, char lo)
+{
+    char b;
+    
+    b = (HammiDecode[hi] << 4);
+    b+= HammiDecode[lo];
+    
+    return b;
+}
+
+/*
+int RFM12::RF_PHY_Senden(string str)
+{
+    if(status != LISTEN)
+        return -1;
+
+    char *s;
+    s = new char[str.size() + 1];
+    
+    strcpy(s, str.c_str());
+    
+    RF_PHY_Senden(s, (int)str.size());
+    
+    delete [] s;
+    
+    return 0;
+}
+*/
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rfm12.h	Fri Feb 18 20:07:12 2011 +0000
@@ -0,0 +1,96 @@
+#ifndef MBED_RFM12_C_H
+#define MBED_RFM12_C_H
+
+#include "string"
+#include "lib_crc.h"
+#include "mbed.h"
+
+#define ADDR 0x00
+
+//Defines der Statusregister und Interruptflags
+#define RF_STATUS_RGITFFIT     (1<<15)
+#define RF_STATUS_POR          (1<<14)
+#define RF_STATUS_RGURFFOV     (1<<13)
+#define RF_STATUS_WKUP         (1<<12)
+#define RF_STATUS_EXT          (1<<11)
+#define RF_STATUS_LBD          (1<<10)
+
+enum status_t
+{
+    RX,
+    TX,
+    LISTEN
+};
+
+typedef union
+{
+    struct
+    {
+        uint8_t HI;
+        uint8_t LO;
+    }Byte;
+    struct
+    {
+        uint16_t Port        : 6;
+        uint16_t DestType    : 2;
+        uint16_t Addresse    : 8;
+    }Bit;
+}header;
+
+class RFM12
+{
+    public:
+        RFM12(PinName irq, PinName sel, PinName sdi, PinName sdo, PinName sck);
+        int RF_L4_Senden(char *buff, header h, char length);
+        
+    private:
+        //Ports
+        InterruptIn _irq;
+        DigitalOut  _sel;
+        DigitalOut  _sdi;
+        DigitalIn   _sdo;
+        DigitalOut  _sck;
+     
+        //Status des PHY Layers
+        status_t status;
+       
+        //SendBuffer
+        char *sbuffer;
+        int sbufferlength;
+        int sbufferi;
+        //ReceiveBuffer
+        char *rbuffer;
+        int rbufferlength;
+        int rbufferi;
+        
+        char *sbufferl3;
+        char *rbufferl3;
+        
+        char *sbufferl4;
+        char *rbufferl4;
+               
+        short RF_PHY_Write(short b);        
+        void  RF_PHY_Send(char b);
+        char  RF_PHY_Receive();
+        
+        void  RF_PHY_Interrupt();       
+        
+        int RF_PHY_Senden(char *buff, int length);
+        int RF_PHY_Senden(string str);
+        
+        int RF_L3_Senden(char *buff, char length);
+        int RF_L3_Empfangen(char *buff, char length);
+        
+        int RF_L4_Empfangen(char *buff, char length);
+        
+        int RF_P1_Empfangen(char *buff, char length);
+        
+        short crcadd(short crc, char b);
+        
+        char Hammi_EncodeHI(char b);
+        char Hammi_EncodeLO(char b);
+        
+        char Hammi_DecodeHILO(char hi, char lo);
+};
+
+#endif
\ No newline at end of file