You are reading a single comment by @Gordon and its replies. Click here to read the full conversation.
  • Hi,

    I just hacked up a very basic RFM69 driver. Not in a module yet because I'm sure it needs a lot of refinement, but:

    var RFM69HFreqTbl = { 
      315 : new Uint16Array([0x074e, 0x08c0, 0x0900]), //315MHz
      434 : new Uint16Array([0x076c, 0x0880, 0x0900]), //434MHz
      868 : new Uint16Array([0x07d9, 0x0800, 0x0900]), //868MHz
      915 : new Uint16Array([0x07e4, 0x08c0, 0x0900]), //915MHz
    };
    
    var RFM69HRateTbl = [
      [0x0368, 0x042B],         //BR=1.2K BW=83.333K
      [0x0334, 0x0415],         //BR=2.4K BW=83.333K  
      [0x031A, 0x040B],         //BR=4.8K BW=83.333K
      [0x030D, 0x0405],         //BR=9.6K BW=83.333K
    ];
    
    var RFM69HPowerTbl = new Uint16Array([ 
      0x117F,                   //20dbm  
      0x117C,                   //17dbm
      0x1179,                   //14dbm
      0x1176,                   //11dbm 
    ]);
    
    var RFM69HConfigTbl = new Uint16Array([ 
      0x0200,                   //RegDataModul, FSK Packet  
      0x0502,                   //RegFdevMsb, 241*61Hz = 35KHz  
      0x0641,                   //RegFdevLsb
      0x1952,                   //RegRxBw , RxBW, 83KHz
      
      0x2C00,                   //RegPreambleMsb  
      0x2D05,                   //RegPreambleLsb, 5Byte Preamble
      0x2E90,                   //enable Sync.Word, 2+1=3bytes
      0x2FAA,                   //0xAA, SyncWord = aa2dd4
      0x302D,                   //0x2D
      0x31D4,                   //0xD4  
    //  0x3700,                 //RegPacketConfig1, Fixed length, Disable CRC, No DC-free encode, No address filter
    //  0x3815,                 //RegPayloadLength, 21 bytes for length & Fixed length
      0x3790,                   //RegPacketConfig1, Variable length, Enable CRC, No address filter
      0x3842,                   //RegPayloadLength, 66 bytes MAX for variable length
      0x3C95,                   //RegFiFoThresh   
      
      0x1888,                   //RegLNA, 200R  
      0x581B,                   //RegTestLna, Normal sensitivity
      //0x582D,                 //RegTestLna, increase sensitivity with LNA (Note: consumption also increase!)
      0x6F30,                   //RegTestDAGC, Improved DAGC
      //0x6F00,                 //RegTestDAGC, Normal DAGC
      0x0104,                   //Enter standby mode    
    ]);
    
      
    var RFM69HRxTbl = new Uint16Array([
      0x119F,                   //      
      0x2544,                   //DIO Mapping for Rx. DIO 0..5 = PayloadReady,FifoLevel,Data,FifoFull
      0x1310,                   //OCP enabled
      0x5A55,                   //Normal and Rx
      0x5C70,                   //Normal and Rx   
      0x0110                    //Enter Rx mode
    ]);         
    
        
    var RFM69HTxTbl = new Uint16Array([
      0x2504,                   //DIO Mapping for Tx. DIO 0..5 = PacketSent,FifoLevel,Data,FifoFull
      0x130F,                   //Disable OCP
      0x5A5D,                   //High power mode
      0x5C7C,                   //High power mode
      0x010C,                   //Enter Tx mode
    ]);
    
    
    SPI2.setup({mosi:B15,miso:B14,sck:B13});
    var spi = SPI2;
    var cs = B10;
    var rst = B1;
    
    function r(a) {
      return spi.send([a&0x7f,0], cs)[1];
    }
    
    function w(a,v) {
      spi.send([a|128,v], cs);
    }
    function w16(v) {
      spi.send([(v>>8)|128,v], cs);
    }
    
    function connect(callback) {
      digitalPulse(rst,1,100);
      setTimeout(function() {
        w(0x2F,0xAA);
        if (r(0x2F)!=0xAA) throw new Error("RFM69 not found");
        w(0x2F,0x55);
        if (r(0x2F)!=0x55) throw new Error("RFM69 not found");
        // setup freq
        RFM69HFreqTbl[434].forEach(w16);
        // setup rate
        RFM69HRateTbl[0].forEach(w16);
        // general init
        RFM69HConfigTbl.forEach(w16);
        if (callback) callback();
      }, 100);
    }
    
    function rxmode() {
      RFM69HRxTbl.forEach(w16);
    }
    
    function getPacket() {
      if (!(r(0x28)&4)) return undefined; // no packet
      w16(0x0104); // standby
      cs.reset(); // chip select
      var len = spi.send([0,0])[1];
      var d = spi.send(new Uint8Array(len));
      cs.set(); // let go of CS
      w16(0x0110); // enter RX mode again
      return d;
    }
    
    function hasPacket() {
      return !!(r(0x28)&4);
    }
    
    function sendPacket(d, callback) { 
      w16(0x0104); // standby
      setTimeout(function() { // wait for us to hit standby
        spi.write(0x80, d.length, d, cs);
        RFM69HTxTbl.forEach(w16); // enter TX mode
    
        var t = 100; // 1 sec
        var i = setInterval(function() {
          if (r(0x28)&8 || t-- < 0) {
            w16(0x0104); // standby
            clearInterval(i);
            if (t<0) throw "Timeout in RF69 send";
            if (callback) callback();
          }
        }, 10);
      }, 1);
    }
    

    Transmit:

    sendPacket("Hello World", 
      function() { console.log("Done"); 
    });
    

    Receive:

    rxmode();
    setInterval(function() { 
      if (hasPacket()) console.log(JSON.stringify(E.toString(getPacket()))); 
    },10);
    

    If anyone has some RFM69s they want to try out (@DrAzzy? :) ) I'd be interested to see how this works :) Currently this uses 433Mhz, but it can be changed pretty easily in the connect function.

About

Avatar for Gordon @Gordon started