You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
5.1 KiB
Go

10 years ago
package rfm69
import (
"log"
4 years ago
"fmt"
"github.com/davecheney/gpio"
)
// Send data
func (r *Device) Send(d *Data) {
4 years ago
if (r._invert) {
for i := 0; i < len(d.Data); i++ {
d.Data[i] = 255 - d.Data[i]
}
}
r.tx <- d
4 years ago
log.Println("sending", len(d.Data));
10 years ago
}
4 years ago
func min(a, b int) int {
if a <= b {
return a
}
return b
}
func (r *Device) Loop() {
log.Println("entering loop");
10 years ago
irq := make(chan int)
r.gpio.BeginWatch(gpio.EdgeRising, func() {
irq <- 1
})
defer r.gpio.EndWatch()
err := r.SetMode(RF_OPMODE_RECEIVER)
if err != nil {
log.Fatal(err)
10 years ago
}
defer r.SetMode(RF_OPMODE_STANDBY)
for {
select {
case dataToTransmit := <-r.tx:
4 years ago
log.Println("going to transmit");
10 years ago
// TODO: can send?
r.readWriteReg(REG_PACKETCONFIG2, 0xFB, RF_PACKET2_RXRESTART) // avoid RX deadlocks
err = r.SetModeAndWait(RF_OPMODE_STANDBY)
if err != nil {
log.Fatal(err)
}
err = r.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_00)
if err != nil {
log.Fatal(err)
}
4 years ago
transferLimit := 16
transferLength := len(dataToTransmit.Data)
batch1 := dataToTransmit.Data[0:min(0+transferLimit, transferLength)]
if err = r.WriteFifoData(batch1); err != nil {
10 years ago
log.Fatal(err)
}
err = r.SetMode(RF_OPMODE_TRANSMITTER)
if err != nil {
log.Fatal(err)
}
4 years ago
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
}
}
10 years ago
4 years ago
//<-irq
//log.Println("ieq");
10 years ago
10 years ago
err = r.SetModeAndWait(RF_OPMODE_STANDBY)
if err != nil {
log.Fatal(err)
}
err = r.writeReg(REG_DIOMAPPING1, RF_DIOMAPPING1_DIO0_01)
if err != nil {
log.Fatal(err)
}
err = r.SetMode(RF_OPMODE_RECEIVER)
if err != nil {
log.Fatal(err)
}
4 years ago
log.Println("tx done");
case <-r.quit:
r.quit <- true
return
default:
10 years ago
if r.mode != RF_OPMODE_RECEIVER {
continue
}
4 years ago
10 years ago
flags, err := r.readReg(REG_IRQFLAGS2)
if err != nil {
log.Fatal(err)
}
4 years ago
if flags & RF_IRQFLAGS2_FIFONOTEMPTY == 0 { // Entry for [1] * if 0/Clear SKIP
10 years ago
continue
}
4 years ago
// fmt.Printf("% 08b\n", flags)
fmt.Println("RX start")
if err = r.EnterRX(); err != nil {
log.Fatal(err)
10 years ago
}
err = r.SetMode(RF_OPMODE_RECEIVER)
if err != nil {
log.Fatal(err)
}
}
10 years ago
}
10 years ago
}
4 years ago
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
}