not finished RFM12 Libary

rfm12.cpp

Committer:
dominik
Date:
2011-02-18
Revision:
0:a634c7e3ea44

File content as of revision 0:a634c7e3ea44:

#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;
}
*/