Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions nrf24l01/const_bandwidth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package nrf24l01

type bandWidth uint8

const (
Bandwidth_256kbps bandWidth = iota
Bandwidth_1Mbps bandWidth = iota
Bandwidth_2Mbps bandWidth = iota
)
17 changes: 17 additions & 0 deletions nrf24l01/const_commands.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package nrf24l01

const (
R_REGISTER uint8 = 0x00
W_REGISTER uint8 = 0x20

R_RX_PL_WID uint8 = 0x60
R_RX_PAYLOAD uint8 = 0x61
W_TX_PAYLOAD uint8 = 0xA0

W_TX_PAYLOAD_NOACK uint8 = 0xB0

FLUSH_TX uint8 = 0xE1
FLUSH_RX uint8 = 0xE2

NOP uint8 = 0xFF
)
10 changes: 10 additions & 0 deletions nrf24l01/const_powerOutput.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nrf24l01

type powerOutput uint8

const (
PowerOutput_n18dBm powerOutput = iota
PowerOutput_n12dBm powerOutput = iota
PowerOutput_n6dBm powerOutput = iota
PowerOutput_0dBm powerOutput = iota
)
34 changes: 34 additions & 0 deletions nrf24l01/const_registers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package nrf24l01

const (
CONFIG uint8 = 0x00
EN_AA uint8 = 0x01 //ACK
EN_RXADDR uint8 = 0x02
SETUP_AW uint8 = 0x03
SETUP_RETR uint8 = 0x04 // RETRY
RF_CH uint8 = 0x05 //CHANNEL
RF_SETUP uint8 = 0x06
STATUS uint8 = 0x07
OBSERVE_TX uint8 = 0x08

RX_ADDR_P0 uint8 = 0x0A // RECEIVER ADDRESS
RX_ADDR_P1 uint8 = 0x0B
RX_ADDR_P2 uint8 = 0x0C
RX_ADDR_P3 uint8 = 0x0D
RX_ADDR_P4 uint8 = 0x0E
RX_ADDR_P5 uint8 = 0x0F

TX_ADDR uint8 = 0x10 // SENDER ADDRESS

RX_PW_P0 uint8 = 0x11 // PACKAGE WIDTH (SIZE)
RX_PW_P1 uint8 = 0x12
RX_PW_P2 uint8 = 0x13
RX_PW_P3 uint8 = 0x14
RX_PW_P4 uint8 = 0x15
RX_PW_P5 uint8 = 0x16

FIFO_STATUS uint8 = 0x17

DYNPD uint8 = 0x1C // DYNAMIC PACKAGE SIZE
FEATURE uint8 = 0x1D
)
69 changes: 69 additions & 0 deletions nrf24l01/func_New.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package nrf24l01

import (
"errors"
"time"
)

// initialize a new NRF24L01 New
func New(config Config) (NRF24L01, error) {
if len(config.SPIConfig.SenderAddress) != 5 || len(config.SPIConfig.ListenerAddress) != 5 {
return nil, errors.New("error: len(address) != 5")
}
// make sure that adresses can be written
if config.SPIConfig.PackageSize < 5 {
config.SPIConfig.PackageSize = 5
}
s := nrf24l01{
packageSize: int(config.SPIConfig.PackageSize),
channel: config.SPIConfig.Channel,
senderAddress: config.SPIConfig.SenderAddress,
listenerAddress: config.SPIConfig.ListenerAddress,
addressWidth: 5,
txCMD: make([]uint8, 2),
rxCMD: make([]uint8, 2),
tx: make([]uint8, int(config.SPIConfig.PackageSize)+1),
rx: make([]uint8, int(config.SPIConfig.PackageSize)+1),
spi: config.SPI,
ce: config.CE,
csn: config.CSN,
irq: config.IRQ,
}

s.ce.Low()
s.up()
defer s.down()
// RESET
s.WriteRegister(CONFIG, 0x00)
time.Sleep(time.Millisecond * 10)
// CLEAR
s.WriteRegister(STATUS, 0x70)
s.FlushTX()
s.FlushRX()
// BASIC CONFIG
s.WriteRegister(SETUP_AW, 0x03)
if config.SPIConfig.ACK {
s.WriteRegister(EN_AA, 0x01)
} else {
s.WriteRegister(EN_AA, 0x00)
}
s.WriteRegister(EN_RXADDR, 0x01)
s.WriteRegister(RF_SETUP, s.getRFSetup(config.SPIConfig))
s.WriteRegister(RF_CH, s.channel)
s.WriteRegister(RX_PW_P0, config.SPIConfig.PackageSize)
s.WriteRegister(DYNPD, 0x00)
s.WriteRegister(CONFIG, 0x3E)
if config.SPIConfig.Sender {
s.WriteRegister(CONFIG, 0x0A)
time.Sleep(time.Millisecond * 10)
s.WriteMultiRegister(TX_ADDR, s.senderAddress)
s.WriteMultiRegister(RX_ADDR_P0, s.listenerAddress)
} else {
s.WriteRegister(CONFIG, 0x0B)
time.Sleep(time.Millisecond * 10)
s.WriteMultiRegister(TX_ADDR, s.listenerAddress)
s.WriteMultiRegister(RX_ADDR_P0, s.senderAddress)
s.ce.High()
}
return &s, nil
}
15 changes: 15 additions & 0 deletions nrf24l01/interface_NRF24L01.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nrf24l01

type NRF24L01 interface {
FlushRX() error
FlushTX() error
HasIRQ() bool
HasData() bool
ReadMultiRegister(uint8, int) []uint8
ReadPayload() ([]uint8, error)
ReadRegister(uint8) uint8
Send([]uint8) error
WriteMultiRegister(uint8, []uint8) error
WritePayload([]uint8) error
WriteRegister(uint8, uint8) error
}
7 changes: 7 additions & 0 deletions nrf24l01/interface_Pin.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package nrf24l01

type Pin interface {
High()
Low()
Get() bool
}
6 changes: 6 additions & 0 deletions nrf24l01/interface_SPI.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package nrf24l01

type SPI interface {
Tx([]uint8, []uint8) error
Transfer(uint8) (uint8, error)
}
5 changes: 5 additions & 0 deletions nrf24l01/private_rfunc_down.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nrf24l01

func (s *nrf24l01) down() {
s.csn.High()
}
8 changes: 8 additions & 0 deletions nrf24l01/private_rfunc_getBuffer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package nrf24l01

func (s *nrf24l01) getBuffer(b []uint8) []uint8 {
for i, _ := range b {
b[i] = 0x00
}
return b
}
37 changes: 37 additions & 0 deletions nrf24l01/private_rfunc_getRFSetup.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package nrf24l01

func (s *nrf24l01) getRFSetup(config SPIConfig) uint8 {
var rfSetup uint8 = 0x00

// LNA_HCURR
rfSetup |= 1 << 1

// Bandwidth
switch config.Bandwidth {
case Bandwidth_256kbps:
rfSetup |= 1 << 6
break
case Bandwidth_1Mbps:
break
case Bandwidth_2Mbps:
rfSetup |= 1 << 4
break
}

// PowerOutput
switch config.PowerOutput {
case PowerOutput_n18dBm:
break
case PowerOutput_n12dBm:
rfSetup |= 1 << 2
break
case PowerOutput_n6dBm:
rfSetup |= 1 << 3
break
case PowerOutput_0dBm:
rfSetup |= 1 << 2
rfSetup |= 1 << 3
break
}
return rfSetup
}
5 changes: 5 additions & 0 deletions nrf24l01/private_rfunc_up.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nrf24l01

func (s *nrf24l01) up() {
s.csn.Low()
}
10 changes: 10 additions & 0 deletions nrf24l01/rfunc_FlushRX.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nrf24l01

func (s *nrf24l01) FlushRX() error {
s.up()
defer s.down()
tx := s.getBuffer(s.txCMD)
tx[0] = FLUSH_RX
txErr := s.spi.Tx(tx, nil)
return txErr
}
10 changes: 10 additions & 0 deletions nrf24l01/rfunc_FlushTX.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package nrf24l01

func (s *nrf24l01) FlushTX() error {
s.up()
defer s.down()
tx := s.getBuffer(s.txCMD)
tx[0] = FLUSH_TX
txErr := s.spi.Tx(tx, nil)
return txErr
}
5 changes: 5 additions & 0 deletions nrf24l01/rfunc_HasData.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nrf24l01

func (s *nrf24l01) HasData() bool {
return s.ReadRegister(FIFO_STATUS)&0x01 == 0
}
5 changes: 5 additions & 0 deletions nrf24l01/rfunc_HasIRQ.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package nrf24l01

func (s *nrf24l01) HasIRQ() bool {
return !s.irq.Get()
}
18 changes: 18 additions & 0 deletions nrf24l01/rfunc_ReadMultiRegister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package nrf24l01

func (s *nrf24l01) ReadMultiRegister(reg uint8, length int) []uint8 {
s.up()
defer s.down()

tx := s.getBuffer(s.tx)
rx := s.getBuffer(s.rx)
tx[0] = reg
for i := 1; i < length+1; i++ {
tx[i] = NOP
}
txErr := s.spi.Tx(tx, rx)
if txErr != nil {
println("SPI error: ", txErr.Error())
}
return rx
}
26 changes: 26 additions & 0 deletions nrf24l01/rfunc_ReadPayload.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package nrf24l01

import (
"errors"
"strconv"
)

// Opinionated read method.
// Fist bit is the length of data, therefore data is smaller than set package size
// Use ReadMultiRegister() for custom framing
func (s *nrf24l01) ReadPayload() ([]uint8, error) {
s.ce.Low()
defer s.ce.High()
payload := s.ReadMultiRegister(R_RX_PAYLOAD, s.packageSize)
payloadLength := payload[1]
if payloadLength == 0 || payloadLength > uint8(s.packageSize) {
s := string(payload) + " out of bounds " + strconv.Itoa(int(payloadLength))
return payload, errors.New(s)
}
if len(payload) < int(payloadLength)+2 {
s := "payload to small:" + strconv.Itoa(len(payload))
return payload, errors.New(s)
}
message := payload[1 : payloadLength+2]
return message, nil
}
15 changes: 15 additions & 0 deletions nrf24l01/rfunc_ReadRegister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package nrf24l01

func (s *nrf24l01) ReadRegister(reg uint8) uint8 {
s.up()
defer s.down()
tx := s.getBuffer(s.txCMD)
tx[0] = R_REGISTER | reg
tx[1] = NOP
rx := s.getBuffer(s.rxCMD)
txErr := s.spi.Tx(tx, rx)
if txErr != nil {
println("ERROR: SPI: ", txErr.Error())
}
return rx[1]
}
47 changes: 47 additions & 0 deletions nrf24l01/rfunc_Send.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package nrf24l01

import (
"errors"
"time"
)

// Opinionated send method.
// Fist bit is the length of data, therefore data must be smaller than set package size
// Use WritePayload() for custom framing
func (s *nrf24l01) Send(data []uint8) error {
if len(data) > s.packageSize-1 {
return errors.New("package size too big")
}
fifoStatus := s.ReadRegister(FIFO_STATUS)
if fifoStatus&0x20 != 0 { //TX_FULL
return errors.New("TX_FULL")
}
s.ce.Low()
s.WriteRegister(STATUS, 0x70)
tx := s.getBuffer(s.tx)
tx[0] = W_TX_PAYLOAD
tx[1] = uint8(len(data))
for i, d := range data {
tx[i+2] = d
}
writeErr := s.WritePayload(tx)
if writeErr != nil {
return writeErr
}
s.ce.High()
time.Sleep(time.Microsecond * 15)
s.ce.Low()
// wait for TX_DS or MAX_RT
for {
status := s.ReadRegister(STATUS)
if status&0x20 != 0 { // TX_DS
s.WriteRegister(STATUS, 0x20)
return nil
}
if status&0x10 != 0 { // MAX_RT
s.WriteRegister(STATUS, 0x10)
s.FlushTX()
return errors.New("MAX_RT")
}
}
}
16 changes: 16 additions & 0 deletions nrf24l01/rfunc_WriteMultiRegister.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package nrf24l01

func (s *nrf24l01) WriteMultiRegister(reg uint8, values []uint8) error {
s.up()
defer s.down()
tx := s.getBuffer(s.tx)
tx[0] = W_REGISTER | reg
for i, v := range values {
tx[i+1] = v
}
txErr := s.spi.Tx(tx, nil)
if txErr != nil {
return txErr
}
return nil
}
Loading