edit
This commit is contained in:
parent
7a551a782e
commit
7fc1f953f5
4 changed files with 312 additions and 96 deletions
12
data.go
12
data.go
|
@ -2,18 +2,6 @@ package rfm69
|
|||
|
||||
// Data is the data structure for the protocol
|
||||
type Data struct {
|
||||
ToAddress byte
|
||||
FromAddress byte
|
||||
Data []byte
|
||||
RequestAck bool
|
||||
SendAck bool
|
||||
Rssi int
|
||||
}
|
||||
|
||||
// ToAck creates an ack
|
||||
func (d *Data) ToAck() *Data {
|
||||
return &Data{
|
||||
ToAddress: d.FromAddress,
|
||||
SendAck: true,
|
||||
}
|
||||
}
|
||||
|
|
214
device.go
214
device.go
|
@ -5,7 +5,6 @@ import (
|
|||
"errors"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/davecheney/gpio"
|
||||
"github.com/fulr/spidev"
|
||||
)
|
||||
|
@ -21,19 +20,18 @@ var frequencies = map[string][]byte{
|
|||
}
|
||||
|
||||
// OnReceiveHandler is the receive callback
|
||||
type OnReceiveHandler func(*Data)
|
||||
type OnReceiveHandler func(*RXStream)
|
||||
|
||||
// Device RFM69 Device
|
||||
type Device struct {
|
||||
spiDevice *spidev.SPIDevice
|
||||
gpio gpio.Pin
|
||||
mode byte
|
||||
address byte
|
||||
network byte
|
||||
isRFM69HW bool
|
||||
powerLevel byte
|
||||
tx chan *Data
|
||||
quit chan bool
|
||||
_invert bool
|
||||
OnReceive OnReceiveHandler
|
||||
}
|
||||
|
||||
|
@ -44,7 +42,7 @@ const (
|
|||
)
|
||||
|
||||
// NewDevice creates a new device
|
||||
func NewDevice(nodeID, networkID byte, isRfm69HW bool) (*Device, error) {
|
||||
func NewDevice(isRfm69HW bool) (*Device, error) {
|
||||
pin, err := getPin()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -58,10 +56,9 @@ func NewDevice(nodeID, networkID byte, isRfm69HW bool) (*Device, error) {
|
|||
ret := &Device{
|
||||
spiDevice: spi,
|
||||
gpio: pin,
|
||||
network: networkID,
|
||||
address: nodeID,
|
||||
isRFM69HW: isRfm69HW,
|
||||
powerLevel: 31,
|
||||
_invert: false,
|
||||
tx: make(chan *Data, 5),
|
||||
quit: make(chan bool),
|
||||
}
|
||||
|
@ -71,7 +68,7 @@ func NewDevice(nodeID, networkID byte, isRfm69HW bool) (*Device, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
go ret.loop()
|
||||
//go ret.loop()
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
@ -99,6 +96,21 @@ func (r *Device) writeReg(addr, data byte) error {
|
|||
}
|
||||
return err
|
||||
}
|
||||
func (r *Device) writeRegDouble(addr byte, data uint16) error {
|
||||
tx := make([]byte, 3)
|
||||
tx[0] = addr | 0x80
|
||||
tx[1] = byte((data >> 8) & 0xFF)
|
||||
tx[2] = byte(data & 0xFF)
|
||||
//log.Printf("write %x: %x", addr, data)
|
||||
_, err := r.spiDevice.Xfer(tx)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
func (r *Device) WriteReg(addr, data byte) error {
|
||||
return r.writeReg(addr, data)
|
||||
}
|
||||
|
||||
func (r *Device) readReg(addr byte) (byte, error) {
|
||||
tx := make([]uint8, 2)
|
||||
|
@ -115,10 +127,10 @@ func (r *Device) setup() error {
|
|||
config := [][]byte{
|
||||
/* 0x01 */ {REG_OPMODE, RF_OPMODE_SEQUENCER_ON | RF_OPMODE_LISTEN_OFF | RF_OPMODE_STANDBY},
|
||||
/* 0x02 */ {REG_DATAMODUL, RF_DATAMODUL_DATAMODE_PACKET | RF_DATAMODUL_MODULATIONTYPE_FSK | RF_DATAMODUL_MODULATIONSHAPING_00}, // no shaping
|
||||
/* 0x03 */ {REG_BITRATEMSB, RF_BITRATEMSB_55555}, // default: 4.8 KBPS
|
||||
/* 0x04 */ {REG_BITRATELSB, RF_BITRATELSB_55555},
|
||||
/* 0x05 */ {REG_FDEVMSB, RF_FDEVMSB_50000}, // default: 5KHz, (FDEV + BitRate / 2 <= 500KHz)
|
||||
/* 0x06 */ {REG_FDEVLSB, RF_FDEVLSB_50000},
|
||||
/* 0x03 */ {REG_BITRATEMSB, 0x68},
|
||||
/* 0x04 */ {REG_BITRATELSB, 0x2B},
|
||||
/* 0x05 */ {REG_FDEVMSB, 0x00}, // default: 5KHz, (FDEV + BitRate / 2 <= 500KHz)
|
||||
/* 0x06 */ {REG_FDEVLSB, 0x4a},
|
||||
/* 0x07 */ {REG_FRFMSB, RF_FRFMSB_868},
|
||||
/* 0x08 */ {REG_FRFMID, RF_FRFMID_868},
|
||||
/* 0x09 */ {REG_FRFLSB, RF_FRFLSB_868},
|
||||
|
@ -133,18 +145,23 @@ func (r *Device) setup() error {
|
|||
/* 0x19 */ {REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_16 | RF_RXBW_EXP_2}, // (BitRate < 2 * RxBw)
|
||||
//for BR-19200: /* 0x19 */ { REG_RXBW, RF_RXBW_DCCFREQ_010 | RF_RXBW_MANT_24 | RF_RXBW_EXP_3 },
|
||||
/* 0x25 */ {REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01}, // DIO0 is the only IRQ we're using
|
||||
/* 0x26 */ {REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF}, // DIO5 ClkOut disable for power saving
|
||||
/* 0x26 */ {REG_DIOMAPPING2, RF_DIOMAPPING2_CLKOUT_OFF }, // DIO5 ClkOut disable for power saving
|
||||
/* 0x28 */ {REG_IRQFLAGS2, RF_IRQFLAGS2_FIFOOVERRUN}, // writing to this bit ensures that the FIFO & status flags are reset
|
||||
/* 0x29 */ //{REG_RSSITHRESH, 220}, // must be set to dBm = (-Sensitivity / 2), default is 0xE4 = 228 so -114dBm
|
||||
/* 0x29 */ {REG_RSSITHRESH, 220}, // must be set to dBm = (-Sensitivity / 2), default is 0xE4 = 228 so -114dBm
|
||||
///* 0x2D */ { REG_PREAMBLELSB, RF_PREAMBLESIZE_LSB_VALUE } // default 3 preamble bytes 0xAAAAAA
|
||||
/* 0x2E */ {REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_2 | RF_SYNC_TOL_0},
|
||||
/* 0x2F */ {REG_SYNCVALUE1, 0x2D}, // attempt to make this compatible with sync1 byte of RFM12B lib
|
||||
/* 0x30 */ {REG_SYNCVALUE2, r.network}, // NETWORK ID
|
||||
/* 0x37 */ {REG_PACKETCONFIG1, RF_PACKET1_FORMAT_VARIABLE | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_ON | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF},
|
||||
/* 0x38 */ {REG_PAYLOADLENGTH, 66}, // in variable length mode: the max frame size, not used in TX
|
||||
/* 0x2E */ {REG_SYNCCONFIG, RF_SYNC_ON | RF_SYNC_FIFOFILL_AUTO | RF_SYNC_SIZE_6 | RF_SYNC_TOL_0},
|
||||
/* 0x2F */ {REG_SYNCVALUE1, 0xAA},
|
||||
/* 0x30 */ {REG_SYNCVALUE2, 0xAA},
|
||||
/* 0x30 */ {REG_SYNCVALUE3, 0xAA},
|
||||
/* 0x30 */ {REG_SYNCVALUE4, 0xAA},
|
||||
/* 0x30 */ {REG_SYNCVALUE5, 0xAA},
|
||||
/* 0x30 */ {REG_SYNCVALUE6, 0xAA},
|
||||
/* 0x37 */ {REG_PACKETCONFIG1, RF_PACKET1_FORMAT_FIXED | RF_PACKET1_DCFREE_OFF | RF_PACKET1_CRC_OFF | RF_PACKET1_CRCAUTOCLEAR_ON | RF_PACKET1_ADRSFILTERING_OFF},
|
||||
/* 0x38 */ {REG_PAYLOADLENGTH, 0x00}, // in variable length mode: the max frame size, not used in TX, 0: unlimited packet format
|
||||
///* 0x39 */ { REG_NODEADRS, nodeID }, // turned off because we're not using address filtering
|
||||
/* 0x3C */ {REG_FIFOTHRESH, RF_FIFOTHRESH_TXSTART_FIFONOTEMPTY | RF_FIFOTHRESH_VALUE}, // TX on FIFO not empty
|
||||
/* 0x3D */ {REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_2BITS | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF}, // RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
|
||||
/* 0x2D */ {REG_PREAMBLELSB, 0x00},
|
||||
//for BR-19200: /* 0x3D */ { REG_PACKETCONFIG2, RF_PACKET2_RXRESTARTDELAY_NONE | RF_PACKET2_AUTORXRESTART_ON | RF_PACKET2_AES_OFF }, // RXRESTARTDELAY must match transmitter PA ramp-down time (bitrate dependent)
|
||||
/* 0x6F */ {REG_TESTDAGC, RF_DAGC_IMPROVED_LOWBETA0}, // run DAGC continuously in RX mode for Fading Margin Improvement, recommended default for AfcLowBetaOn=0
|
||||
}
|
||||
|
@ -170,6 +187,10 @@ func (r *Device) setup() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = r.SetInvert(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = r.setHighPower(r.isRFM69HW)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -181,7 +202,19 @@ func (r *Device) setup() error {
|
|||
err = r.waitForMode()
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Device) SetInvert(invert bool) error {
|
||||
r._invert = invert
|
||||
if (r._invert) {
|
||||
r.WriteReg(REG_SYNCVALUE1, 0x55)
|
||||
r.WriteReg(REG_SYNCVALUE2, 0x55)
|
||||
r.WriteReg(REG_SYNCVALUE3, 0x55)
|
||||
} else {
|
||||
r.WriteReg(REG_SYNCVALUE1, 0xAA)
|
||||
r.WriteReg(REG_SYNCVALUE2, 0xAA)
|
||||
r.WriteReg(REG_SYNCVALUE3, 0xAA)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *Device) waitForMode() error {
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
|
@ -202,6 +235,9 @@ func (r *Device) waitForMode() error {
|
|||
})
|
||||
return <-errChan
|
||||
}
|
||||
func (r *Device) WaitForMode() error {
|
||||
return r.waitForMode();
|
||||
}
|
||||
|
||||
// Encrypt sets the encryption key and enables AES encryption
|
||||
func (r *Device) Encrypt(key []byte) error {
|
||||
|
@ -218,14 +254,29 @@ func (r *Device) Encrypt(key []byte) error {
|
|||
return r.readWriteReg(REG_PACKETCONFIG2, 0xFE, turnOn)
|
||||
}
|
||||
|
||||
func (r *Device) SetFrequency(freq string) error {
|
||||
freq_bytes, found := frequencies[freq]
|
||||
if !found {
|
||||
return errors.New("frequency not found")
|
||||
func (r *Device) SetBaudrate(rate int) error {
|
||||
var divider uint16 = (uint16)(32e6 / rate) //0x4F4F
|
||||
|
||||
/*switch(rate) {
|
||||
case 1200:
|
||||
divider = 0x682B
|
||||
case 2400:
|
||||
divider = 0x3415
|
||||
}*/
|
||||
return r.writeRegDouble(REG_BITRATEMSB, divider)
|
||||
}
|
||||
func (r *Device) SetFrequency(freqHz, offset int) error {
|
||||
//freqHz = // divide down by FSTEP to get FRF
|
||||
frf := (int)((float32(freqHz) / float32(61.03515625))) + offset // offset per chip (you may have to calibrate)
|
||||
if err := r.writeReg(REG_FRFMSB, byte((frf >> 16) & 0xFF)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.writeReg(REG_FRFMID, byte((frf >> 8) & 0xFF)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.writeReg(REG_FRFLSB, byte(frf & 0xFF)); err != nil {
|
||||
return err
|
||||
}
|
||||
r.writeReg(REG_FRFMSB, freq_bytes[0])
|
||||
r.writeReg(REG_FRFMID, freq_bytes[1])
|
||||
r.writeReg(REG_FRFLSB, freq_bytes[2])
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -303,18 +354,6 @@ func (r *Device) setHighPowerRegs(turnOn bool) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
// SetNetwork sets the network ID
|
||||
func (r *Device) SetNetwork(networkID byte) error {
|
||||
r.network = networkID
|
||||
return r.writeReg(REG_SYNCVALUE2, networkID)
|
||||
}
|
||||
|
||||
// SetAddress sets the node address
|
||||
func (r *Device) SetAddress(address byte) error {
|
||||
r.address = address
|
||||
return r.writeReg(REG_NODEADRS, address)
|
||||
}
|
||||
|
||||
// SetPowerLevel sets the TX power
|
||||
func (r *Device) SetPowerLevel(powerLevel byte) error {
|
||||
r.powerLevel = powerLevel
|
||||
|
@ -373,53 +412,92 @@ func (r *Device) readWriteReg(reg, andMask, orMask byte) error {
|
|||
return r.writeReg(reg, regValue)
|
||||
}
|
||||
|
||||
func (r *Device) writeFifo(data *Data) error {
|
||||
buffersize := len(data.Data)
|
||||
func (r *Device) writeFifo(data []byte) error {
|
||||
buffersize := len(data)
|
||||
if buffersize > MaxDataLen {
|
||||
buffersize = MaxDataLen
|
||||
}
|
||||
tx := make([]byte, buffersize+5)
|
||||
tx := make([]byte, buffersize+1)
|
||||
// write to FIFO
|
||||
tx[0] = REG_FIFO | 0x80
|
||||
tx[1] = byte(buffersize + 3)
|
||||
tx[2] = data.ToAddress
|
||||
tx[3] = r.address
|
||||
if data.RequestAck {
|
||||
tx[4] = 0x40
|
||||
}
|
||||
if data.SendAck {
|
||||
tx[4] = 0x80
|
||||
}
|
||||
copy(tx[5:], data.Data[:buffersize])
|
||||
copy(tx[1:], data[:buffersize])
|
||||
//log.Println("% X\n\n", tx)
|
||||
_, err := r.spiDevice.Xfer(tx)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Device) WriteFifoData(data []byte) error {
|
||||
if err := r.writeFifo(data); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func (r *Device) WriteFifoDataWait() error {
|
||||
errChan := make(chan error)
|
||||
go func() {
|
||||
for {
|
||||
reg, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
panic(err)
|
||||
errChan <- err
|
||||
break
|
||||
}
|
||||
log.Println("% X", reg)
|
||||
if reg&RF_IRQFLAGS2_FIFONOTEMPTY != 0 {
|
||||
errChan <- nil
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
time.AfterFunc(2*time.Second, func() {
|
||||
errChan <- errors.New("timeout fifowait")
|
||||
})
|
||||
return <-errChan
|
||||
}
|
||||
|
||||
func (r *Device) readFifo() (Data, error) {
|
||||
var err error
|
||||
data := Data{}
|
||||
data.Rssi, err = r.readRSSI(false)
|
||||
/*data.Rssi, err = r.readRSSI(false)
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
}*/
|
||||
tx := new([67]byte)
|
||||
tx[0] = REG_FIFO & 0x7f
|
||||
rx, err := r.spiDevice.Xfer(tx[:3])
|
||||
rx, err := r.spiDevice.Xfer(tx[:1])
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
rx, err = r.spiDevice.Xfer(tx[1:])
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
data.ToAddress = rx[2]
|
||||
length := rx[1] - 3
|
||||
if length > 66 {
|
||||
length = 66
|
||||
}
|
||||
rx, err = r.spiDevice.Xfer(tx[:length+3])
|
||||
if err != nil {
|
||||
return data, err
|
||||
}
|
||||
data.FromAddress = rx[1]
|
||||
data.SendAck = bool(rx[2]&0x80 > 0)
|
||||
data.RequestAck = bool(rx[2]&0x40 > 0)
|
||||
data.Data = rx[3:]
|
||||
data.Data = rx[1:]
|
||||
return data, nil
|
||||
}
|
||||
func (r *Device) readFifo1Byte() (byte, error) {
|
||||
var err error
|
||||
log.Println("readFifo1Byte()")
|
||||
tx := new([2]byte)
|
||||
tx[0] = REG_FIFO & 0x7f
|
||||
log.Println(tx)
|
||||
rx, err := r.spiDevice.Xfer(tx[:1])
|
||||
if err != nil {
|
||||
return rx[1], err
|
||||
}
|
||||
log.Println(rx)
|
||||
rx, err = r.spiDevice.Xfer(tx[1:])
|
||||
if err != nil {
|
||||
return rx[1], err
|
||||
}
|
||||
log.Println(rx)
|
||||
return rx[0], nil
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
180
loop.go
180
loop.go
|
@ -2,16 +2,29 @@ package rfm69
|
|||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"fmt"
|
||||
"github.com/davecheney/gpio"
|
||||
)
|
||||
|
||||
// Send data
|
||||
func (r *Device) Send(d *Data) {
|
||||
if (r._invert) {
|
||||
for i := 0; i < len(d.Data); i++ {
|
||||
d.Data[i] = 255 - d.Data[i]
|
||||
}
|
||||
}
|
||||
r.tx <- d
|
||||
log.Println("sending", len(d.Data));
|
||||
}
|
||||
|
||||
func (r *Device) loop() {
|
||||
func min(a, b int) int {
|
||||
if a <= b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
func (r *Device) Loop() {
|
||||
log.Println("entering loop");
|
||||
irq := make(chan int)
|
||||
r.gpio.BeginWatch(gpio.EdgeRising, func() {
|
||||
irq <- 1
|
||||
|
@ -27,6 +40,7 @@ func (r *Device) loop() {
|
|||
for {
|
||||
select {
|
||||
case dataToTransmit := <-r.tx:
|
||||
log.Println("going to transmit");
|
||||
// TODO: can send?
|
||||
r.readWriteReg(REG_PACKETCONFIG2, 0xFB, RF_PACKET2_RXRESTART) // avoid RX deadlocks
|
||||
err = r.SetModeAndWait(RF_OPMODE_STANDBY)
|
||||
|
@ -37,16 +51,51 @@ func (r *Device) loop() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = r.writeFifo(dataToTransmit)
|
||||
if err != nil {
|
||||
transferLimit := 16
|
||||
transferLength := len(dataToTransmit.Data)
|
||||
batch1 := dataToTransmit.Data[0:min(0+transferLimit, transferLength)]
|
||||
|
||||
if err = r.WriteFifoData(batch1); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
err = r.SetMode(RF_OPMODE_TRANSMITTER)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for i := 1; i < transferLength; i += transferLimit {
|
||||
batchN := dataToTransmit.Data[i:min(i+transferLimit, transferLength)]
|
||||
if err = r.WriteFifoData(batchN); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
for {
|
||||
reg, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
panic(err)
|
||||
break
|
||||
}
|
||||
//fmt.Printf("% d", reg & RF_IRQFLAGS2_FIFOLEVEL);
|
||||
if reg & RF_IRQFLAGS2_FIFOLEVEL < 16 {
|
||||
break
|
||||
}
|
||||
}
|
||||
//fmt.Printf("% d", i)
|
||||
//log.Println("Fifowrite2");
|
||||
}
|
||||
for {
|
||||
reg, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
panic(err)
|
||||
break
|
||||
}
|
||||
if reg&RF_IRQFLAGS2_PACKETSENT != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
<-irq
|
||||
//<-irq
|
||||
//log.Println("ieq");
|
||||
|
||||
err = r.SetModeAndWait(RF_OPMODE_STANDBY)
|
||||
if err != nil {
|
||||
|
@ -60,31 +109,132 @@ func (r *Device) loop() {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case <-irq:
|
||||
log.Println("tx done");
|
||||
|
||||
case <-r.quit:
|
||||
r.quit <- true
|
||||
return
|
||||
default:
|
||||
if r.mode != RF_OPMODE_RECEIVER {
|
||||
continue
|
||||
}
|
||||
|
||||
flags, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if flags&RF_IRQFLAGS2_PAYLOADREADY == 0 {
|
||||
if flags & RF_IRQFLAGS2_FIFONOTEMPTY == 0 { // Entry for [1] * if 0/Clear SKIP
|
||||
continue
|
||||
}
|
||||
data, err := r.readFifo()
|
||||
if err != nil {
|
||||
// fmt.Printf("% 08b\n", flags)
|
||||
fmt.Println("RX start")
|
||||
if err = r.EnterRX(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if r.OnReceive != nil {
|
||||
go r.OnReceive(&data)
|
||||
}
|
||||
err = r.SetMode(RF_OPMODE_RECEIVER)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
case <-r.quit:
|
||||
r.quit <- true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Device) EnterRX() (error) {
|
||||
/*
|
||||
1) Start reading bytes from the FIFO when FifoNotEmpty or FifoThreshold becomes set.
|
||||
2) Suspend reading from the FIFO if FifoNotEmpty clears before all bytes of the message have been read
|
||||
3) Continue to step 1 until PayloadReady or CrcOk fires
|
||||
4) Read all remaining bytes from the FIFO either in Rx or Sleep/Standby mode
|
||||
*/
|
||||
stream := &RXStream{
|
||||
ByteCounter: 0,
|
||||
ByteStream: make(chan byte, 1024e2), // 10 KiB Bufer
|
||||
RSSI: make(chan int),
|
||||
Cancel: false,
|
||||
Process: make(chan bool),
|
||||
}
|
||||
if r.OnReceive != nil {
|
||||
go r.OnReceive(stream)
|
||||
}
|
||||
|
||||
for {
|
||||
if stream.Cancel {
|
||||
fmt.Println("cancel request")
|
||||
break
|
||||
}
|
||||
for {
|
||||
if stream.Cancel {
|
||||
fmt.Println("cancel request")
|
||||
break
|
||||
}
|
||||
flags, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("% 08b\n", flags)
|
||||
if flags & RF_IRQFLAGS2_FIFONOTEMPTY == 0 { // Check if we need to Suspend for [2] if 0/Clear BREAK
|
||||
//fmt.Println("FIFO Not empty is cleared")
|
||||
break
|
||||
}
|
||||
if flags & RF_IRQFLAGS2_PAYLOADREADY != 0 { // Check if we need to STOP because of [3] if 1/Set BREAK
|
||||
//fmt.Println("PayloadReady set")
|
||||
break
|
||||
}
|
||||
byte1, err := r.readReg(0x00)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stream.ByteStream <- byte1
|
||||
stream.ByteCounter++
|
||||
|
||||
if (stream.ByteCounter % 4 == 0) {
|
||||
rssi, err := r.readRSSI(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stream.RSSI <- rssi
|
||||
}
|
||||
}
|
||||
if stream.Cancel {
|
||||
fmt.Println("cancel request")
|
||||
break
|
||||
}
|
||||
flags, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//fmt.Printf("% 08b\n", flags)
|
||||
if flags & RF_IRQFLAGS2_PAYLOADREADY != 0 { // Check if we need to STOP because of [3] if 1/Set BREAK
|
||||
fmt.Println("PayloadReady set")
|
||||
break
|
||||
}
|
||||
if (stream.ByteCounter % 4 == 0) {
|
||||
rssi, err := r.readRSSI(false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stream.RSSI <- rssi
|
||||
}
|
||||
}
|
||||
// reading the final content of the FIFO
|
||||
flags, err := r.readReg(REG_IRQFLAGS2)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if flags & RF_IRQFLAGS2_FIFONOTEMPTY != 0 {
|
||||
byte1, err := r.readReg(0x00)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stream.ByteStream <- byte1
|
||||
stream.ByteCounter++
|
||||
}
|
||||
|
||||
// ... done
|
||||
fmt.Println("RX end")
|
||||
stream.Process <- true
|
||||
//
|
||||
defer r.SetMode(RF_OPMODE_STANDBY)
|
||||
fmt.Println("RXMode end")
|
||||
return nil
|
||||
}
|
|
@ -3,7 +3,7 @@ package rfm69
|
|||
import "github.com/davecheney/gpio"
|
||||
|
||||
const (
|
||||
irqPin = gpio.GPIO25
|
||||
irqPin = 18
|
||||
)
|
||||
|
||||
func getPin() (gpio.Pin, error) {
|
||||
|
|
Loading…
Add table
Reference in a new issue