From 33d2db09abfcecdc5087ee773526a1ae910eafa3 Mon Sep 17 00:00:00 2001 From: Marius Staicu Date: Thu, 29 Jun 2017 15:52:16 +0300 Subject: [PATCH 01/10] - updated to latest version of RF24 --- .gitignore | 2 ++ RF24_c/build.sh | 2 +- build.sh | 17 ++++++++--------- 3 files changed, 11 insertions(+), 10 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2acce55 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +# Created by .ignore support plugin (hsz.mobi) +.idea/ diff --git a/RF24_c/build.sh b/RF24_c/build.sh index 270b16e..916b3da 100755 --- a/RF24_c/build.sh +++ b/RF24_c/build.sh @@ -5,7 +5,7 @@ # Project home: # Licensed under The MIT License (see README and LICENSE files) -rfhdrdir=../RF24/RPi/RF24/ +rfhdrdir=../RF24/ rflibdir=$rfhdrdir g++ -g -O2 -fPIC -I$rfhdrdir -lrf24-bcm -I. -L$rflibdir -shared -o librf24_c.so *.cpp -ansi -pedantic diff --git a/build.sh b/build.sh index 64e5337..5f89cbc 100755 --- a/build.sh +++ b/build.sh @@ -1,24 +1,23 @@ #!/bin/bash -# Copyright 2013, Raphael Estrada -# Author email: -# Project home: +# Copyright 2017, Marius Staicu +# Author email: +# Project home: # Licensed under The MIT License (see README and LICENSE files) echo "fetching C++ RF24 for Raspberry Pi" -git clone https://github.com/stanleyseow/RF24 +git clone https://github.com/TMRh20/RF24 echo "building C++ RF24 for Raspberry Pi" -# cd RF24/librf24-rpi/librf24 -cd RF24/RPi/RF24/ +cd RF24/ make make install -cd ../../.. +cd ../ echo "building C++ RF24 for Raspberry Pi EXAMPLES" -cd RF24/RPi/RF24/examples +cd RF24/examples_linux/ make -cd ../../../.. +cd ../.. echo "buliding ANSI C wrapper for C++ RF24 library" cd RF24_c From 131fac39033ff97795752534a79caa88654e37f6 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Mon, 3 Jul 2017 18:27:24 +0300 Subject: [PATCH 02/10] Updated only cgo Wrapper. --- RF24.go | 13 +- RF24_c/RF24_c.cpp | 362 +++++++++++++++++++++++++++++++--------------- RF24_c/RF24_c.h | 119 ++++++++++++--- 3 files changed, 354 insertions(+), 140 deletions(-) diff --git a/RF24.go b/RF24.go index 2a47ee0..ac0d526 100644 --- a/RF24.go +++ b/RF24.go @@ -1,7 +1,13 @@ /* Copyright 2013, Raphael Estrada Author email: Project home: - Licensed under The MIT License (see README and LICENSE files) */ + Licensed under The MIT License (see README and LICENSE files) + + Updated to RF24 v.13 + 2017, Marian Craciunescu, Marius Staicu + Authors email: , + Project home: +*/ package gorf24 /* @@ -67,11 +73,10 @@ func (r *R) Begin() { C.rf24_begin(r.cptr) } -/* func (r *R) ResetCfg() { C.rf24_resetcfg(r.cptr) } -*/ + func (r *R) StartListening() { C.rf24_startListening(r.cptr) } @@ -231,3 +236,5 @@ func cbool(b bool) C.cbool { } return C.cbool(0) } + +// TODO: @Marian Craciunescu add missing function implementation. diff --git a/RF24_c/RF24_c.cpp b/RF24_c/RF24_c.cpp index 1190de1..ead7fe3 100644 --- a/RF24_c/RF24_c.cpp +++ b/RF24_c/RF24_c.cpp @@ -1,181 +1,305 @@ /* Copyright 2013, Raphael Estrada - Author email: - Project home: - Licensed under The MIT License (see README and LICENSE files) */ + Author email: + Project home: + Licensed under The MIT License (see README and LICENSE files) + + Updated to RF24 v.13 + 2017, Marian Craciunescu, Marius Staicu + Authors email: , + Project home: + */ #include "RF24_c.h" #include "RF24.h" #include + #define to_rfh(ptr) (reinterpret_cast(ptr)) #define to_rf(ptr) (reinterpret_cast(ptr)) #define dbm_to_e(val) (static_cast(val)) #define crc_to_e(val) (static_cast(val)) #define dat_to_e(val) (static_cast(val)) -//RF24Handle new_rf24(cstring spidevice, uint32_t spispeed, uint8_t ce) { -// // RF24(uint8_t _cepin, uint8_t _cspin); -// RF24* r = new RF24(string(spidevice), spispeed, ce); -// return to_rfh(r); -//} + RF24Handle new_rf24(uint8_t ce, uint8_t cs, uint32_t spispeed) { - RF24* r = new RF24(ce, cs, spispeed); - return to_rfh(r); + RF24 *r = new RF24(ce, cs, spispeed); + return to_rfh(r); } + +RF24Handle new_rf24_optional(uint8_t ce, uint8_t cs) { + RF24 *r = new RF24(ce, cs); + return to_rfh(r); +} + void rf24_delete(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - delete r; + RF24 *r = to_rf(rf_handle); + delete r; } + void rf24_begin(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->begin(); + RF24 *r = to_rf(rf_handle); + r->begin(); +} + +cbool rf24_isChipConnected(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return cbool(r->isChipConnected()); } -//void rf24_resetcfg(RF24Handle rf_handle) { -// RF24* r = to_rf(rf_handle); -// r->resetcfg(); -//} + void rf24_startListening(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->startListening(); + RF24 *r = to_rf(rf_handle); + r->startListening(); } + void rf24_stopListening(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->stopListening(); + RF24 *r = to_rf(rf_handle); + r->stopListening(); } -cbool rf24_write(RF24Handle rf_handle, const void* source, uint8_t len) { - RF24* r = to_rf(rf_handle); - return cbool(r->write(source, len)); + +cbool rf24_available(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return cbool(r->available()); +} + +cbool rf24_read(RF24Handle rf_handle, void *target, uint8_t len) { + RF24 *r = to_rf(rf_handle); + if (r->available()) { + r->read(target, len); + return TRUE; + } + return FALSE; +} + +cbool rf24_write(RF24Handle rf_handle, const void *source, uint8_t len) { + RF24 *r = to_rf(rf_handle); + return cbool(r->write(source, len)); +} + + +void rf24_openWritingPipe(RF24Handle rf_handle, uint64_t address) { + RF24 *r = to_rf(rf_handle); + r->openWritingPipe(address); } -void rf24_startWrite(RF24Handle rf_handle, const void* source, uint8_t len) { - RF24* r = to_rf(rf_handle); - r->startWrite(source, len, TRUE); + +void rf24_openReadingPipe(RF24Handle rf_handle, uint8_t pipe, + uint64_t address) { + RF24 *r = to_rf(rf_handle); + r->openReadingPipe(pipe, address); } -void rf24_writeAckPayload(RF24Handle rf_handle, uint8_t pipe, - const void* source, uint8_t len) { - RF24* r = to_rf(rf_handle); - r->writeAckPayload(pipe, source, len); + +void rf24_printDetails(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->printDetails(); } -cbool rf24_available(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return cbool(r->available()); + +cbool rf24_available_pipe(RF24Handle rf_handle, uint8_t *out_pipe) { + RF24 *r = to_rf(rf_handle); + return cbool(r->available(out_pipe)); } -cbool rf24_available_pipe(RF24Handle rf_handle, uint8_t* out_pipe) { - RF24* r = to_rf(rf_handle); - return cbool(r->available(out_pipe)); + +cbool rf24_rxFifoFull(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return cbool(r->rxFifoFull()); } + +void rf24_powerDown(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->powerDown(); +} + +void rf24_powerUp(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->powerUp(); +} + +cbool rf24_writeMulticast(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast) { + RF24 *r = to_rf(rf_handle); + return cbool(r->write(buf, len, multicast)); +} + +cbool rf24_writeFast(RF24Handle rf_handle, const void *buf, uint8_t len) { + RF24 *r = to_rf(rf_handle); + return cbool(r->writeFast(buf, len)); +} + +cbool rf24_writeFastMulticast(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast) { + RF24 *r = to_rf(rf_handle); + return cbool(r->writeFast(buf, len, multicast)); +} + +cbool rf24_writeBlocking(RF24Handle rf_handle, const void *buf, uint8_t len, uint32_t timeout) { + RF24 *r = to_rf(rf_handle); + return cbool(r->writeBlocking(buf, len, timeout)); +} + +cbool rf24_txStandBy(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return cbool(r->txStandBy()); +} + +cbool rf24_txStandByExtended(RF24Handle rf_handle, uint32_t timeout, cbool startTx) { + RF24 *r = to_rf(rf_handle); + return cbool(r->txStandBy(timeout, startTx)); +} + +void rf24_writeAckPayload(RF24Handle rf_handle, uint8_t pipe, + const void *source, uint8_t len) { + RF24 *r = to_rf(rf_handle); + r->writeAckPayload(pipe, source, len); +} + cbool rf24_isAckPayloadAvailable(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return cbool(r->isAckPayloadAvailable()); + RF24 *r = to_rf(rf_handle); + return cbool(r->isAckPayloadAvailable()); +} + +void rf24_whatHappened(RF24Handle rf_handle, cbool *out_tx_ok, cbool *out_tx_fail, cbool *out_rx_ready) { + bool tx_ok, tx_fail, rx_ready; + RF24 *r = to_rf(rf_handle); + r->whatHappened(tx_ok, tx_fail, rx_ready); + *out_tx_ok = cbool(tx_ok); + *out_tx_fail = cbool(tx_fail); + *out_rx_ready = cbool(rx_ready); +} + +void rf24_startWrite(RF24Handle rf_handle, const void *source, uint8_t len, const cbool multicast) { + RF24 *r = to_rf(rf_handle); + r->startWrite(source, len, multicast); +} + +void rf24_startFastWrite(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast, cbool startTx) { + RF24 *r = to_rf(rf_handle); + r->startFastWrite(buf, len, multicast, TRUE); +} + +void rf24_reUseTX(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->reUseTX(); +} + +uint8_t rf24_flush_tx(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return r->flush_tx(); +} + +cbool rf24_testCarrier(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return (cbool(r->testCarrier())); } -cbool rf24_read(RF24Handle rf_handle, void* target, uint8_t len) { - RF24* r = to_rf(rf_handle); - if (r->available()) { - r->read(target, len); - return TRUE; - } - return FALSE; + +cbool rf24_testRPD(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return cbool(r->testRPD()); } -void rf24_openWritingPipe(RF24Handle rf_handle, uint64_t address) { - RF24* r = to_rf(rf_handle); - r->openWritingPipe(address); + +void rf24_closeReadingPipe(RF24Handle rf_handle, uint8_t pipe) { + RF24 *r = to_rf(rf_handle); + r->closeReadingPipe(pipe); } -void rf24_openReadingPipe(RF24Handle rf_handle, uint8_t pipe, - uint64_t address) { - RF24* r = to_rf(rf_handle); - r->openReadingPipe(pipe, address); + +void rf24_setAddressWidth(RF24Handle rf_handle, uint8_t a_width) { + RF24 *r = to_rf(rf_handle); + r->setAddressWidth(a_width); } + void rf24_setRetries(RF24Handle rf_handle, uint8_t delay, uint8_t count) { - RF24* r = to_rf(rf_handle); - r->setRetries(delay, count); + RF24 *r = to_rf(rf_handle); + r->setRetries(delay, count); } + void rf24_setChannel(RF24Handle rf_handle, uint8_t channel) { - RF24* r = to_rf(rf_handle); - r->setChannel(channel); + RF24 *r = to_rf(rf_handle); + r->setChannel(channel); +} + +uint8_t rf24_getChannel(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + return r->getChannel(); } + void rf24_setPayloadSize(RF24Handle rf_handle, uint8_t size) { - RF24* r = to_rf(rf_handle); - r->setPayloadSize(size); + RF24 *r = to_rf(rf_handle); + r->setPayloadSize(size); } + uint8_t rf24_getPayloadSize(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return r->getPayloadSize(); + RF24 *r = to_rf(rf_handle); + return r->getPayloadSize(); } + uint8_t rf24_getDynamicPayloadSize(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return r->getDynamicPayloadSize(); + RF24 *r = to_rf(rf_handle); + return r->getDynamicPayloadSize(); } + void rf24_enableAckPayload(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->enableAckPayload(); + RF24 *r = to_rf(rf_handle); + r->enableAckPayload(); } + void rf24_enableDynamicPayloads(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->enableDynamicPayloads(); + RF24 *r = to_rf(rf_handle); + r->enableDynamicPayloads(); +} + +void rf24_disableDynamicPayloads(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->disableDynamicPayloads(); +} + +void rf24_enableDynamicAck(RF24Handle rf_handle) { + RF24 *r = to_rf(rf_handle); + r->enableDynamicAck(); } + cbool rf24_isPVariant(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return cbool(r->isPVariant()); + RF24 *r = to_rf(rf_handle); + return cbool(r->isPVariant()); } + void rf24_setAutoAck(RF24Handle rf_handle, cbool enable) { - RF24* r = to_rf(rf_handle); - r->setAutoAck(enable); + RF24 *r = to_rf(rf_handle); + r->setAutoAck(enable); } + void rf24_setAutoAck_pipe(RF24Handle rf_handle, uint8_t pipe, cbool enable) { - RF24* r = to_rf(rf_handle); - r->setAutoAck(pipe, enable); + RF24 *r = to_rf(rf_handle); + r->setAutoAck(pipe, enable); } + void rf24_setPALevel(RF24Handle rf_handle, rf24_pa_dbm_val level) { - RF24* r = to_rf(rf_handle); - r->setPALevel(dbm_to_e(level)); + RF24 *r = to_rf(rf_handle); + r->setPALevel(dbm_to_e(level)); } + rf24_pa_dbm_val rf24_getPALevel(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return r->getPALevel(); + RF24 *r = to_rf(rf_handle); + return r->getPALevel(); } + cbool rf24_setDataRate(RF24Handle rf_handle, rf24_datarate_val speed) { - RF24* r = to_rf(rf_handle); - return cbool(r->setDataRate(dat_to_e(speed))); + RF24 *r = to_rf(rf_handle); + return cbool(r->setDataRate(dat_to_e(speed))); } + rf24_datarate_val rf24_getDataRate(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return r->getDataRate(); + RF24 *r = to_rf(rf_handle); + return r->getDataRate(); } + void rf24_setCRCLength(RF24Handle rf_handle, rf24_crclength_val length) { - RF24* r = to_rf(rf_handle); - r->setCRCLength(crc_to_e(length)); + RF24 *r = to_rf(rf_handle); + r->setCRCLength(crc_to_e(length)); } + rf24_crclength_val rf24_getCRCLength(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return r->getCRCLength(); + RF24 *r = to_rf(rf_handle); + return r->getCRCLength(); } + void rf24_disableCRC(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->disableCRC(); -} -void rf24_printDetails(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->printDetails(); -} -// TODO: string rf24_getDetails()? -void rf24_powerDown(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->powerDown(); -} -void rf24_powerUp(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - r->powerUp(); -} -void rf24_whatHappened(RF24Handle rf_handle, cbool* out_tx_ok, - cbool* out_tx_fail, cbool* out_rx_ready) { - bool tx_ok, tx_fail, rx_ready; - RF24* r = to_rf(rf_handle); - r->whatHappened(tx_ok, tx_fail, rx_ready); - *out_tx_ok = cbool(tx_ok); - *out_tx_fail = cbool(tx_fail); - *out_rx_ready = cbool(rx_ready); -} -cbool rf24_testCarrier(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return (cbool(r->testCarrier())); -} -cbool rf24_testRPD(RF24Handle rf_handle) { - RF24* r = to_rf(rf_handle); - return cbool(r->testRPD()); -} + RF24 *r = to_rf(rf_handle); + r->disableCRC(); +} + +void rf24_maskIRQ(RF24Handle rf_handle, cbool tx_ok, cbool tx_fail, cbool rx_ready) { + RF24 *r = to_rf(rf_handle); + r->maskIRQ(tx_ok, tx_fail, rx_ready); +} \ No newline at end of file diff --git a/RF24_c/RF24_c.h b/RF24_c/RF24_c.h index 730bed4..3921c4e 100644 --- a/RF24_c/RF24_c.h +++ b/RF24_c/RF24_c.h @@ -1,13 +1,23 @@ /* Copyright 2013, Raphael Estrada Author email: Project home: - Licensed under The MIT License (see README and LICENSE files) */ + Licensed under The MIT License (see README and LICENSE files) + + Updated to RF24 v.13 + 2017, Marian Craciunescu, Marius Staicu + Authors email: , + Project home: + */ #pragma once + #include -typedef void* RF24Handle; -typedef const char* cstring; + +typedef void *RF24Handle; +typedef const char *cstring; // poor man's boolean -typedef enum { FALSE = 0, TRUE } cbool; +typedef enum { + FALSE = 0, TRUE +} cbool; #define cbool(X) ((X) ? TRUE : FALSE) // cannot re-use enums because they are delcared in c++ // cannot re-declare them, either, won't compile @@ -20,42 +30,115 @@ typedef uint8_t rf24_crclength_val; #else #define DLL #endif + DLL RF24Handle new_rf24(uint8_t ce, uint8_t cs, uint32_t spispeed); + +DLL RF24Handle new_rf24_optional(uint8_t ce, uint8_t cs); + DLL void rf24_delete(RF24Handle rf_handle); + DLL void rf24_begin(RF24Handle rf_handle); -//DLL void rf24_resetcfg(RF24Handle rf_handle); + +DLL cbool rf24_isChipConnected(RF24Handle rf_handle); + DLL void rf24_startListening(RF24Handle rf_handle); + DLL void rf24_stopListening(RF24Handle rf_handle); -DLL cbool rf24_write(RF24Handle rf_handle, const void* source, uint8_t len); -DLL void rf24_startWrite(RF24Handle rf_handle, const void* source, uint8_t len); -DLL void rf24_writeAckPayload(RF24Handle, uint8_t pipe, const void* source, uint8_t len); + DLL cbool rf24_available(RF24Handle rf_handle); -DLL cbool rf24_available_pipe(RF24Handle rf_handle, uint8_t* out_pipe); -DLL cbool rf24_isAckPayloadAvailable(RF24Handle rf_handle); -DLL cbool rf24_read(RF24Handle rf_handle, void* target, uint8_t len); + +DLL cbool rf24_read(RF24Handle rf_handle, void *target, uint8_t len); + +DLL cbool rf24_write(RF24Handle rf_handle, const void *source, uint8_t len); + DLL void rf24_openWritingPipe(RF24Handle rf_handle, uint64_t address); + DLL void rf24_openReadingPipe(RF24Handle rf_handle, uint8_t pipe, uint64_t address); + +DLL void rf24_printDetails(RF24Handle rf_handle); +// correspond to bool available(uint8_t* pipe_num); +DLL cbool rf24_available_pipe(RF24Handle rf_handle, uint8_t *out_pipe); + +DLL cbool rf24_rxFifoFull(RF24Handle rf_handle); + +DLL void rf24_powerDown(RF24Handle rf_handle); + +DLL void rf24_powerUp(RF24Handle rf_handle); + +DLL cbool rf24_writeMulticast(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast); + +DLL cbool rf24_writeFast(RF24Handle rf_handle, const void *buf, uint8_t len); + +DLL cbool rf24_writeFastMulticast(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast); + +DLL cbool rf24_writeBlocking(RF24Handle rf_handle, const void *buf, uint8_t len, uint32_t timeout); + +DLL cbool rf24_txStandBy(RF24Handle rf_handle); + +DLL cbool rf24_txStandByExtended(RF24Handle rf_handle, uint32_t timeout, cbool startTx); + +DLL void rf24_writeAckPayload(RF24Handle, uint8_t pipe, const void *source, uint8_t len); + +DLL cbool rf24_isAckPayloadAvailable(RF24Handle rf_handle); + +DLL void rf24_whatHappened(RF24Handle rf_handle, cbool *tx_ok, cbool *tx_fail, cbool *rx_ready); + +DLL void rf24_startWrite(RF24Handle rf_handle, const void *source, uint8_t len, const cbool multicast); + +DLL void rf24_startFastWrite(RF24Handle rf_handle, const void *buf, uint8_t len, const cbool multicast, cbool startTx); + +DLL void rf24_reUseTX(RF24Handle rf_handle); + +DLL uint8_t rf24_flush_tx(RF24Handle rf_handle); + +DLL cbool rf24_testCarrier(RF24Handle rf_handle); + +DLL cbool rf24_testRPD(RF24Handle rf_handle); + +DLL void rf24_closeReadingPipe(RF24Handle rf_handle, uint8_t pipe); + +DLL void rf24_setAddressWidth(RF24Handle rf_handle, uint8_t a_width); + DLL void rf24_setRetries(RF24Handle rf_handle, uint8_t delay, uint8_t count); + DLL void rf24_setChannel(RF24Handle rf_handle, uint8_t channel); + +DLL uint8_t rf24_getChannel(RF24Handle rf_handle); + DLL void rf24_setPayloadSize(RF24Handle rf_handle, uint8_t size); + DLL uint8_t rf24_getPayloadSize(RF24Handle rf_handle); + DLL uint8_t rf24_getDynamicPayloadSize(RF24Handle rf_handle); + DLL void rf24_enableAckPayload(RF24Handle rf_handle); + DLL void rf24_enableDynamicPayloads(RF24Handle rf_handle); + +DLL void rf24_disableDynamicPayloads(RF24Handle rf_handle); + +DLL void rf24_enableDynamicAck(RF24Handle rf_handle); + DLL cbool rf24_isPVariant(RF24Handle rf_handle); + DLL void rf24_setAutoAck(RF24Handle rf_handle, cbool enable); + DLL void rf24_setAutoAck_pipe(RF24Handle rf_handle, uint8_t pipe, cbool enable); + DLL void rf24_setPALevel(RF24Handle rf_handle, rf24_pa_dbm_val level); + DLL rf24_pa_dbm_val rf24_getPALevel(RF24Handle rf_handle); + DLL cbool rf24_setDataRate(RF24Handle rf_handle, rf24_datarate_val speed); + DLL rf24_datarate_val rf24_getDataRate(RF24Handle rf_handle); + DLL void rf24_setCRCLength(RF24Handle rf_handle, rf24_crclength_val length); + DLL rf24_crclength_val rf24_getCRCLength(RF24Handle rf_handle); + DLL void rf24_disableCRC(RF24Handle rf_handle); -DLL void rf24_printDetails(RF24Handle rf_handle); -// TODO: string rf24_getDetails()? -DLL void rf24_powerDown(RF24Handle rf_handle); -DLL void rf24_powerUp(RF24Handle rf_handle); -DLL void rf24_whatHappened(RF24Handle rf_handle, cbool* out_tx_ok, cbool* out_tx_fail, cbool* out_rx_ready); -DLL cbool rf24_testCarrier(RF24Handle rf_handle); -DLL cbool rf24_testRPD(RF24Handle rf_handle); + +DLL void rf24_maskIRQ(RF24Handle rf_handle, cbool tx_ok, cbool tx_fail, cbool rx_ready); + + From 8d0c19f7e442bc8392504dbf8533464a6e037144 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 00:06:24 +0300 Subject: [PATCH 03/10] Extracted some types and interfaces. --- RF24.go | 167 +++++++++++++++++++++++----------------------- gorf24_helpers.go | 28 ++++++++ gorf24_types.go | 27 ++++++++ 3 files changed, 137 insertions(+), 85 deletions(-) create mode 100644 gorf24_helpers.go create mode 100644 gorf24_types.go diff --git a/RF24.go b/RF24.go index ac0d526..4a4d9ea 100644 --- a/RF24.go +++ b/RF24.go @@ -24,13 +24,52 @@ import ( "unsafe" ) +type LibRF24 interface { + Begin() + Delete() + StartListening() + StopListening() + Write(data []byte, length uint8) bool + StartWrite(data []byte, length uint8) + WriteAckPayload(pipe uint8, data []byte, length uint8) + Available() bool + AvailablePipe() (bool, uint8) + IsAckPayloadAvailable() bool + Read(length uint8) ([]byte, bool) + OpenWritingPipe(address uint64) + OpenReadingPipe(pipe uint8, address uint64) + SetRetries(delay uint8, count uint8) + SetChannel(channel uint8) + SetPayloadSize(size uint8) + GetPayloadSize() uint8 + GetDynamicPayloadSize() uint8 + EnableAckPayload() + EnableDynamicPayloads() + IsPVariant() bool + SetAutoAck(enable bool) + SetAutoAckPipe(pipe uint8, enable bool) + SetPALevel(level PA_DBM) + GetPALevel() PA_DBM + SetDataRate(rate DATARATE) + GetDataRate() DATARATE + SetCRCLength(length CRCLENGTH) + GetCRCLength() CRCLENGTH + DisableCRC() + PrintDetails() + PowerDown() + PowerUp() + WhatHappened() (tx_ok, tx_fail, rx_ready bool) + TestCarrier() bool + TestRPD() bool +} + // TODO: more idiomatic: // error handling // Read/Write interfaces // possibly more conventional byte slice passing // more type safety? // channel for available data, like time.Tick? r.Available() <-chan []byte or so? -type R struct { +type RF24 struct { cptr C.RF24Handle buffer_size uint8 buffer []byte @@ -59,182 +98,140 @@ func main() { } } */ -func New(cepin uint8, cspin uint8, spispeed uint32) R { - var r R +func New(cepin uint8, cspin uint8, spispeed uint32) LibRF24 { + var r RF24 r.cptr = C.new_rf24(C.uint8_t(cepin), C.uint8_t(cspin), C.uint32_t(spispeed)) r.buffer = make([]byte, 128) // max payload length according to nrf24 spec - return r + return &r } -func (r *R) Delete() { + +func (r *RF24) Delete() { C.rf24_delete(r.cptr) r.cptr = nil } -func (r *R) Begin() { +func (r *RF24) Begin() { C.rf24_begin(r.cptr) } -func (r *R) ResetCfg() { - C.rf24_resetcfg(r.cptr) -} - -func (r *R) StartListening() { +func (r *RF24) StartListening() { C.rf24_startListening(r.cptr) } -func (r *R) StopListening() { + +func (r *RF24) StopListening() { C.rf24_stopListening(r.cptr) } // TODO: implement Reader/Writer compatible interfaces -func (r *R) Write(data []byte, length uint8) bool { +func (r *RF24) Write(data []byte, length uint8) bool { return gobool(C.rf24_write(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length))) } -func (r *R) StartWrite(data []byte, length uint8) { +func (r *RF24) StartWrite(data []byte, length uint8) { C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length)) } -func (r *R) WriteAckPayload(pipe uint8, data []byte, length uint8) { +func (r *RF24) WriteAckPayload(pipe uint8, data []byte, length uint8) { C.rf24_writeAckPayload(r.cptr, C.uint8_t(pipe), unsafe.Pointer(&data), C.uint8_t(length)) } -func (r *R) Available() bool { +func (r *RF24) Available() bool { return gobool(C.rf24_available(r.cptr)) } // TODO: create Pipe type, make this a func on Pipe -func (r *R) AvailablePipe() (bool, uint8) { +func (r *RF24) AvailablePipe() (bool, uint8) { var pipe C.uint8_t available := gobool(C.rf24_available_pipe(r.cptr, &pipe)) return available, uint8(pipe) } -func (r *R) IsAckPayloadAvailable() bool { +func (r *RF24) IsAckPayloadAvailable() bool { return gobool(C.rf24_isAckPayloadAvailable(r.cptr)) } -func (r *R) Read(length uint8) ([]byte, bool) { +func (r *RF24) Read(length uint8) ([]byte, bool) { ok := gobool(C.rf24_read(r.cptr, unsafe.Pointer(&r.buffer[0]), C.uint8_t(length))) return r.buffer[:length], ok } -func (r *R) OpenWritingPipe(address uint64) { +func (r *RF24) OpenWritingPipe(address uint64) { C.rf24_openWritingPipe(r.cptr, C.uint64_t(address)) } -func (r *R) OpenReadingPipe(pipe uint8, address uint64) { +func (r *RF24) OpenReadingPipe(pipe uint8, address uint64) { C.rf24_openReadingPipe(r.cptr, C.uint8_t(pipe), C.uint64_t(address)) } -func (r *R) SetRetries(delay uint8, count uint8) { +func (r *RF24) SetRetries(delay uint8, count uint8) { C.rf24_setRetries(r.cptr, C.uint8_t(delay), C.uint8_t(count)) } -func (r *R) SetChannel(channel uint8) { +func (r *RF24) SetChannel(channel uint8) { C.rf24_setChannel(r.cptr, C.uint8_t(channel)) } -func (r *R) SetPayloadSize(size uint8) { +func (r *RF24) SetPayloadSize(size uint8) { C.rf24_setPayloadSize(r.cptr, C.uint8_t(size)) } -func (r *R) GetPayloadSize() uint8 { +func (r *RF24) GetPayloadSize() uint8 { return uint8(C.rf24_getPayloadSize(r.cptr)) } -func (r *R) GetDynamicPayloadSize() uint8 { +func (r *RF24) GetDynamicPayloadSize() uint8 { return uint8(C.rf24_getDynamicPayloadSize(r.cptr)) } -func (r *R) EnableAckPayload() { +func (r *RF24) EnableAckPayload() { C.rf24_enableAckPayload(r.cptr) } -func (r *R) EnableDynamicPayloads() { +func (r *RF24) EnableDynamicPayloads() { C.rf24_enableDynamicPayloads(r.cptr) } -func (r *R) IsPVariant() bool { +func (r *RF24) IsPVariant() bool { return gobool(C.rf24_isPVariant(r.cptr)) } -func (r *R) SetAutoAck(enable bool) { +func (r *RF24) SetAutoAck(enable bool) { C.rf24_setAutoAck(r.cptr, cbool(enable)) } -func (r *R) SetAutoAckPipe(pipe uint8, enable bool) { +func (r *RF24) SetAutoAckPipe(pipe uint8, enable bool) { C.rf24_setAutoAck_pipe(r.cptr, C.uint8_t(pipe), cbool(enable)) } -// TODO: move to named package -type PA_DBM byte - -const ( - PA_MIN PA_DBM = iota - PA_LOW - PA_HIGH - PA_MAX - PA_ERROR // what is this for? -) - // Is there any way to use the rf24_pa_dbm_e enum type directly -func (r *R) SetPALevel(level PA_DBM) { +func (r *RF24) SetPALevel(level PA_DBM) { C.rf24_setPALevel(r.cptr, C.rf24_pa_dbm_val(level)) } -func (r *R) GetPALevel() PA_DBM { +func (r *RF24) GetPALevel() PA_DBM { return PA_DBM(C.rf24_getPALevel(r.cptr)) } -type DATARATE byte - -const ( - RATE_1MBPS DATARATE = iota - RATE_2MBPS - RATE_250KBPS -) - -func (r *R) SetDataRate(rate DATARATE) { +func (r *RF24) SetDataRate(rate DATARATE) { C.rf24_setDataRate(r.cptr, C.rf24_datarate_val(rate)) } -func (r *R) GetDataRate() DATARATE { +func (r *RF24) GetDataRate() DATARATE { return DATARATE(C.rf24_getDataRate(r.cptr)) } -type CRCLENGTH byte - -const ( - CRC_DISABLED = iota - CRC_8BIT - CRC_16BIT -) - -func (r *R) SetCRCLength(length CRCLENGTH) { +func (r *RF24) SetCRCLength(length CRCLENGTH) { C.rf24_setCRCLength(r.cptr, C.rf24_crclength_val(length)) } -func (r *R) GetCRCLength() CRCLENGTH { +func (r *RF24) GetCRCLength() CRCLENGTH { return CRCLENGTH(C.rf24_getCRCLength(r.cptr)) } -func (r *R) DisableCRC() { +func (r *RF24) DisableCRC() { C.rf24_disableCRC(r.cptr) } // TODO: String() method would be great -func (r *R) PrintDetails() { +func (r *RF24) PrintDetails() { C.rf24_printDetails(r.cptr) } -func (r *R) PowerDown() { +func (r *RF24) PowerDown() { C.rf24_powerDown(r.cptr) } -func (r *R) PowerUp() { +func (r *RF24) PowerUp() { C.rf24_powerUp(r.cptr) } -func (r *R) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { +func (r *RF24) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { var out_tx_ok, out_tx_fail, out_rx_ready C.cbool C.rf24_whatHappened(r.cptr, &out_tx_ok, &out_tx_fail, &out_rx_ready) tx_ok, tx_fail, rx_ready = gobool(out_tx_ok), gobool(out_tx_fail), gobool(out_rx_ready) return } -func (r *R) TestCarrier() bool { + +func (r *RF24) TestCarrier() bool { return gobool(C.rf24_testCarrier(r.cptr)) } -func (r *R) TestRPD() bool { +func (r *RF24) TestRPD() bool { return gobool(C.rf24_testRPD(r.cptr)) } -// TODO: move out to util.go -func gobool(b C.cbool) bool { - if b == C.cbool(0) { - return false - } - return true -} -func cbool(b bool) C.cbool { - if b { - return C.cbool(1) - } - return C.cbool(0) -} - // TODO: @Marian Craciunescu add missing function implementation. diff --git a/gorf24_helpers.go b/gorf24_helpers.go new file mode 100644 index 0000000..7ed9bc8 --- /dev/null +++ b/gorf24_helpers.go @@ -0,0 +1,28 @@ +package gorf24 + +/* + #cgo LDFLAGS: -L./RF24_c + #cgo LDFLAGS: -lrf24_c + #cgo CFLAGS: -I./RF24_c + #include "RF24_c.h" + #include +*/ +import "C" +//import ( +// // "encoding/binary" +// // "fmt" +// "unsafe" +//) +func gobool(b C.cbool) bool { + if b == C.cbool(0) { + return false + } + return true +} + +func cbool(b bool) C.cbool { + if b { + return C.cbool(1) + } + return C.cbool(0) +} diff --git a/gorf24_types.go b/gorf24_types.go new file mode 100644 index 0000000..893cfa1 --- /dev/null +++ b/gorf24_types.go @@ -0,0 +1,27 @@ +package gorf24 + +type CRCLENGTH byte + +const ( + CRC_DISABLED = iota + CRC_8BIT + CRC_16BIT +) + +type DATARATE byte + +const ( + RATE_1MBPS DATARATE = iota + RATE_2MBPS + RATE_250KBPS +) + +type PA_DBM byte + +const ( + PA_MIN PA_DBM = iota + PA_LOW + PA_HIGH + PA_MAX + PA_ERROR // what is this for? +) From 7c1682923cb6f3293a5b9f93b2eb475fc12bc5c5 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 10:31:18 +0300 Subject: [PATCH 04/10] Added missing function implementations. --- RF24.go | 212 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 160 insertions(+), 52 deletions(-) diff --git a/RF24.go b/RF24.go index 4a4d9ea..541c92d 100644 --- a/RF24.go +++ b/RF24.go @@ -25,26 +25,48 @@ import ( ) type LibRF24 interface { - Begin() Delete() + Begin() + IsChipConnected() bool StartListening() StopListening() - Write(data []byte, length uint8) bool - StartWrite(data []byte, length uint8) - WriteAckPayload(pipe uint8, data []byte, length uint8) Available() bool - AvailablePipe() (bool, uint8) - IsAckPayloadAvailable() bool Read(length uint8) ([]byte, bool) OpenWritingPipe(address uint64) OpenReadingPipe(pipe uint8, address uint64) + Write(data []byte, length uint8) bool + PrintDetails() + AvailablePipe() (bool, uint8) + IsRxFifoFull() bool + PowerDown() + PowerUp() + WriteMulticast(data []byte, length uint8, multicast bool) bool + WriteFast(data []byte, length uint8) bool + WriteFastMulticast(data []byte, length uint8, multicast bool) bool + WriteBlocking(data []byte, length uint8, timeout uint32) bool + IsTxStandBy() bool + IsTxStandByExtended(timeout uint32, startTx bool) bool + WriteAckPayload(pipe uint8, data []byte, length uint8) + IsAckPayloadAvailable() bool + WhatHappened() (tx_ok, tx_fail, rx_ready bool) + StartWrite(data []byte, length uint8) + StartFastWrite(data []byte, length uint8, multicast bool, startTx bool) + ReUseTx() + FlushTx() uint8 + TestCarrier() bool + TestRPD() bool + CloseReadingPipe(pipe uint8) + SetAddressWidth(width uint8) SetRetries(delay uint8, count uint8) SetChannel(channel uint8) + GetChannel(channel uint8) uint8 SetPayloadSize(size uint8) GetPayloadSize() uint8 GetDynamicPayloadSize() uint8 EnableAckPayload() EnableDynamicPayloads() + DisableDynamicPayloads() + EnableDynamicAck() IsPVariant() bool SetAutoAck(enable bool) SetAutoAckPipe(pipe uint8, enable bool) @@ -55,12 +77,7 @@ type LibRF24 interface { SetCRCLength(length CRCLENGTH) GetCRCLength() CRCLENGTH DisableCRC() - PrintDetails() - PowerDown() - PowerUp() - WhatHappened() (tx_ok, tx_fail, rx_ready bool) - TestCarrier() bool - TestRPD() bool + MaskIRQ(txOk, txFail, rxReady bool) } // TODO: more idiomatic: @@ -98,7 +115,7 @@ func main() { } } */ -func New(cepin uint8, cspin uint8, spispeed uint32) LibRF24 { +func New(cepin uint8, cspin uint8, spispeed uint32) *RF24 { var r RF24 r.cptr = C.new_rf24(C.uint8_t(cepin), C.uint8_t(cspin), C.uint32_t(spispeed)) r.buffer = make([]byte, 128) // max payload length according to nrf24 spec @@ -113,6 +130,10 @@ func (r *RF24) Begin() { C.rf24_begin(r.cptr) } +func (r *RF24) IsChipConnected() bool { + return gobool(C.rf24_isChipConnected(r.cptr)) +} + func (r *RF24) StartListening() { C.rf24_startListening(r.cptr) } @@ -121,18 +142,31 @@ func (r *RF24) StopListening() { C.rf24_stopListening(r.cptr) } +func (r *RF24) Available() bool { + return gobool(C.rf24_available(r.cptr)) +} + +func (r *RF24) Read(length uint8) ([]byte, bool) { + ok := gobool(C.rf24_read(r.cptr, unsafe.Pointer(&r.buffer[0]), C.uint8_t(length))) + return r.buffer[:length], ok +} + +func (r *RF24) OpenWritingPipe(address uint64) { + C.rf24_openWritingPipe(r.cptr, C.uint64_t(address)) +} + +func (r *RF24) OpenReadingPipe(pipe uint8, address uint64) { + C.rf24_openReadingPipe(r.cptr, C.uint8_t(pipe), C.uint64_t(address)) +} + // TODO: implement Reader/Writer compatible interfaces func (r *RF24) Write(data []byte, length uint8) bool { return gobool(C.rf24_write(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length))) } -func (r *RF24) StartWrite(data []byte, length uint8) { - C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length)) -} -func (r *RF24) WriteAckPayload(pipe uint8, data []byte, length uint8) { - C.rf24_writeAckPayload(r.cptr, C.uint8_t(pipe), unsafe.Pointer(&data), C.uint8_t(length)) -} -func (r *RF24) Available() bool { - return gobool(C.rf24_available(r.cptr)) + +// TODO: String() method would be great +func (r *RF24) PrintDetails() { + C.rf24_printDetails(r.cptr) } // TODO: create Pipe type, make this a func on Pipe @@ -141,46 +175,138 @@ func (r *RF24) AvailablePipe() (bool, uint8) { available := gobool(C.rf24_available_pipe(r.cptr, &pipe)) return available, uint8(pipe) } + +func (r *RF24) IsRxFifoFull() bool { + return gobool(C.rf24_rxFifoFull(r.cptr)) +} + +func (r *RF24) PowerDown() { + C.rf24_powerDown(r.cptr) +} + +func (r *RF24) PowerUp() { + C.rf24_powerUp(r.cptr) +} + +func (r *RF24) WriteMulticast(data []byte, length uint8, multicast bool) bool { + return gobool(C.rf24_writeMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(len), cbool(multicast))) +} + +func (r *RF24) WriteFast(data []byte, length uint8) bool { + return gobool(C.rf24_writeFast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length))) +} + +func (r *RF24) WriteFastMulticast(data []byte, length uint8, multicast bool) bool { + return gobool(C.rf24_writeFastMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast))) +} + +func (r *RF24) WriteBlocking(data []byte, length uint8, timeout uint32) bool { + return gobool(C.rf24_writeBlocking(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), C.uint32_t(timeout))) +} + +func (r *RF24) IsTxStandBy() bool { + return gobool(C.rf24_txStandBy(r.cptr)) +} + +func (r *RF24) IsTxStandByExtended(timeout uint32, startTx bool) bool { + return gobool(C.rf24_txStandByExtended(r.cptr, C.uint32_t(timeout), cbool(startTx))) +} + +func (r *RF24) WriteAckPayload(pipe uint8, data []byte, length uint8) { + C.rf24_writeAckPayload(r.cptr, C.uint8_t(pipe), unsafe.Pointer(&data), C.uint8_t(length)) +} + func (r *RF24) IsAckPayloadAvailable() bool { return gobool(C.rf24_isAckPayloadAvailable(r.cptr)) } -func (r *RF24) Read(length uint8) ([]byte, bool) { - ok := gobool(C.rf24_read(r.cptr, unsafe.Pointer(&r.buffer[0]), C.uint8_t(length))) - return r.buffer[:length], ok + +func (r *RF24) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { + var out_tx_ok, out_tx_fail, out_rx_ready C.cbool + C.rf24_whatHappened(r.cptr, &out_tx_ok, &out_tx_fail, &out_rx_ready) + tx_ok, tx_fail, rx_ready = gobool(out_tx_ok), gobool(out_tx_fail), gobool(out_rx_ready) + return } -func (r *RF24) OpenWritingPipe(address uint64) { - C.rf24_openWritingPipe(r.cptr, C.uint64_t(address)) + +func (r *RF24) StartWrite(data []byte, length uint8) { + C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length)) } -func (r *RF24) OpenReadingPipe(pipe uint8, address uint64) { - C.rf24_openReadingPipe(r.cptr, C.uint8_t(pipe), C.uint64_t(address)) + +func (r *RF24) StartFastWrite(data []byte, length uint8, multicast bool, startTx bool) { + C.rf24_startFastWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast), cbool(startTx)) } + +func (r *RF24) ReUseTx() { + C.rf24_reUseTX(r.cptr) +} + +func (r *RF24) FlushTx() uint8 { + return uint8(C.rf24_flush_tx(r.cptr)) +} + +func (r *RF24) TestCarrier() bool { + return gobool(C.rf24_testCarrier(r.cptr)) +} + +func (r *RF24) TestRPD() bool { + return gobool(C.rf24_testRPD(r.cptr)) +} + +func (r *RF24) CloseReadingPipe(pipe uint8) { + C.rf24_closeReadingPipe(r.cptr, C.uint8_t(pipe)) +} + +func (r *RF24) SetAddressWidth(width uint8) { + C.rf24_setAddressWidth(r.cptr, C.uint8_t(width)) +} + func (r *RF24) SetRetries(delay uint8, count uint8) { C.rf24_setRetries(r.cptr, C.uint8_t(delay), C.uint8_t(count)) } + func (r *RF24) SetChannel(channel uint8) { C.rf24_setChannel(r.cptr, C.uint8_t(channel)) } + +func (r *RF24) GetChannel(channel uint8) uint8 { + return uint8(C.rf24_getChannel(r.cptr)) +} + func (r *RF24) SetPayloadSize(size uint8) { C.rf24_setPayloadSize(r.cptr, C.uint8_t(size)) } + func (r *RF24) GetPayloadSize() uint8 { return uint8(C.rf24_getPayloadSize(r.cptr)) } + func (r *RF24) GetDynamicPayloadSize() uint8 { return uint8(C.rf24_getDynamicPayloadSize(r.cptr)) } + func (r *RF24) EnableAckPayload() { C.rf24_enableAckPayload(r.cptr) } + func (r *RF24) EnableDynamicPayloads() { C.rf24_enableDynamicPayloads(r.cptr) } + +func (r *RF24) DisableDynamicPayloads() { + C.rf24_disableDynamicPayloads(r.cptr) +} + +func (r *RF24) EnableDynamicAck() { + C.rf24_enableDynamicAck(r.cptr) +} + func (r *RF24) IsPVariant() bool { return gobool(C.rf24_isPVariant(r.cptr)) } + func (r *RF24) SetAutoAck(enable bool) { C.rf24_setAutoAck(r.cptr, cbool(enable)) } + func (r *RF24) SetAutoAckPipe(pipe uint8, enable bool) { C.rf24_setAutoAck_pipe(r.cptr, C.uint8_t(pipe), cbool(enable)) } @@ -189,6 +315,7 @@ func (r *RF24) SetAutoAckPipe(pipe uint8, enable bool) { func (r *RF24) SetPALevel(level PA_DBM) { C.rf24_setPALevel(r.cptr, C.rf24_pa_dbm_val(level)) } + func (r *RF24) GetPALevel() PA_DBM { return PA_DBM(C.rf24_getPALevel(r.cptr)) } @@ -196,6 +323,7 @@ func (r *RF24) GetPALevel() PA_DBM { func (r *RF24) SetDataRate(rate DATARATE) { C.rf24_setDataRate(r.cptr, C.rf24_datarate_val(rate)) } + func (r *RF24) GetDataRate() DATARATE { return DATARATE(C.rf24_getDataRate(r.cptr)) } @@ -203,35 +331,15 @@ func (r *RF24) GetDataRate() DATARATE { func (r *RF24) SetCRCLength(length CRCLENGTH) { C.rf24_setCRCLength(r.cptr, C.rf24_crclength_val(length)) } + func (r *RF24) GetCRCLength() CRCLENGTH { return CRCLENGTH(C.rf24_getCRCLength(r.cptr)) } + func (r *RF24) DisableCRC() { C.rf24_disableCRC(r.cptr) } -// TODO: String() method would be great -func (r *RF24) PrintDetails() { - C.rf24_printDetails(r.cptr) +func (r *RF24) MaskIRQ(txOk, txFail, rxReady bool) { + C.rf24_maskIRQ(r.cptr, cbool(txOk), cbool(txFail), cbool(rxReady)) } -func (r *RF24) PowerDown() { - C.rf24_powerDown(r.cptr) -} -func (r *RF24) PowerUp() { - C.rf24_powerUp(r.cptr) -} -func (r *RF24) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { - var out_tx_ok, out_tx_fail, out_rx_ready C.cbool - C.rf24_whatHappened(r.cptr, &out_tx_ok, &out_tx_fail, &out_rx_ready) - tx_ok, tx_fail, rx_ready = gobool(out_tx_ok), gobool(out_tx_fail), gobool(out_rx_ready) - return -} - -func (r *RF24) TestCarrier() bool { - return gobool(C.rf24_testCarrier(r.cptr)) -} -func (r *RF24) TestRPD() bool { - return gobool(C.rf24_testRPD(r.cptr)) -} - -// TODO: @Marian Craciunescu add missing function implementation. From 4f965c71950aedf5fb865ef525ed23b66e654703 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 16:12:25 +0300 Subject: [PATCH 05/10] minor improvement --- RF24.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/RF24.go b/RF24.go index 541c92d..cf4dd83 100644 --- a/RF24.go +++ b/RF24.go @@ -49,7 +49,7 @@ type LibRF24 interface { WriteAckPayload(pipe uint8, data []byte, length uint8) IsAckPayloadAvailable() bool WhatHappened() (tx_ok, tx_fail, rx_ready bool) - StartWrite(data []byte, length uint8) + StartWrite(data []byte, length uint8, multicast bool) StartFastWrite(data []byte, length uint8, multicast bool, startTx bool) ReUseTx() FlushTx() uint8 @@ -189,7 +189,7 @@ func (r *RF24) PowerUp() { } func (r *RF24) WriteMulticast(data []byte, length uint8, multicast bool) bool { - return gobool(C.rf24_writeMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(len), cbool(multicast))) + return gobool(C.rf24_writeMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast))) } func (r *RF24) WriteFast(data []byte, length uint8) bool { @@ -227,8 +227,8 @@ func (r *RF24) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { return } -func (r *RF24) StartWrite(data []byte, length uint8) { - C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length)) +func (r *RF24) StartWrite(data []byte, length uint8, multicast bool) { + C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast)) } func (r *RF24) StartFastWrite(data []byte, length uint8, multicast bool, startTx bool) { From bb7bc5cb704233c31e0bbed52fe00c19cecdf48a Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 16:38:15 +0300 Subject: [PATCH 06/10] Updated Readme. --- README | 108 ------------------------------------------------------ README.md | 78 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 108 deletions(-) delete mode 100644 README create mode 100644 README.md diff --git a/README b/README deleted file mode 100644 index 8e13804..0000000 --- a/README +++ /dev/null @@ -1,108 +0,0 @@ -*************************** - HOW TO INSTALL -*************************** -TODO! More detail (on the way) - -The gist of it: - -1) install and set up basic developer tools, git as well as golang on your RPi - e.g. on Arch ARM: - $> sudo pacman -S base-devel git go - - be sure to export GOPATH and add $GOPATH/bin to your PATH; e.g. - $> mkdir ~/mygo - $> echo "export GOPATH=~/mygo" >> ~/.bashrc - $> echo "export PATH=$PATH:$GOPATH/bin" >> ~/.bashrc - - log off and on again for GOPATH changes to take effect - -2) fetch gorf24 using - $> go get github.com/galaktor/gorf24 (you will get an "ld" type error; ignore!) -3) $> cd $GOPATH/src/github.com/galaktor/gorf24 -4) $> chmod +x build.sh -5) $> sudo ./build.sh -6) you might have to add /usr/local/lib to your /etc/ld.so.conf file (see below) -7) include gorf24 in your golang source code as usual, i.e. 'import "github.com/galaktor/gorf24"' -8) Accessing GPIO on Rpi requies elevated permissions, so it makes sense to build normally ("go build") - then run the executable as sudo, i.e. - $> go build mycode.go - $> sudo ./mycode - If you do not use sudo, you will get segfaults and panics - -(Tested on an overclocked (900 MHz) Model A RPi running Arch Linux for Rpi/ARM.) - -Note that this is project is in progress, and the golang or ansi C wrapper haven't been fully tested yet. -Basic send/receive testing has occured, but many functions might have bugs. -Please log any issue you might find and I will try to address it when I get a chance! -Or even better, fork and contribute, that would be much appreciated. - -*************************** -ADD /USR/LOCAL/LIB LDCONFIG -*************************** - -On Arch ARM for RPi, /usr/local/lib had to be added to ld.so.conf in order for golang to find the librf24*.so files at runtime. -you can check if the librf shared objects are detected by running: - -$> ldconfig -v | grep librf - -If the result is empty, then you need to add /usr/local/lib to /etc/ld.so.conf so that the golang runtime will detect the librf libraries. -NOTE: despite the "include ld.so.conf.d/*.conf" line in /etc/ld.so.conf, adding such a file had no effect. Needed to add directly to -ld.so.conf! - -### 1. Open /etc/ld.so.conf with a text editor: -$> sudo nano /etc/ld.so.conf - -### 2. Add the line "/usr/local/lib" and save (in nano, "Ctrl+X", "Y" then "Return") - -### 3. Run ldconfig to update -$> sudo ldconfig - -### 4. Verify detection of librf* shared objects using ldconfig -$> ldconfig -v | grep rf - librf24.so.1 -> librf24.so.1.0 - librf24_c.so -> librf24_c.so - - - -*************************** - TODOS -*************************** -* Makefiles instead of shell scripts -* maybe better way of installing via go get? -* more testing of correct wrapping, data types etc -* branch that includes verified-working snap of RF24-rpi -* download with RPi binaries for armv6? - - - -*************************** - COPYRIGHT AND LICENSE -*************************** - -Copyright 2013, Raphael Estrada - -gorf24 is licensed under the MIT license. -You should have received a copy of the MIT License along -with gorf24 (file "LICENSE"). If not, see - - - - -************************** - THE GIANTS' SHOULDERS -************************** - -NOTE: gorf24 dynamiclly links to the C++ RF24 library for Raspberry -Pi by Stanley Seow. At the time gorf24 was created, Seow's software -had no apparent license included. The license for gorf24 described -here applies exclusively to the software provided as part of gorf24, -but does not extend to Seow's RF24 software. - -https://github.com/stanleyseow/RF24 - -Seow's work is stronly derived from maniacbug's original RF24 library. -Much kudos to maniacbug for the great work. -https://github.com/maniacbug/RF24 -http://maniacbug.wordpress.com/ - - diff --git a/README.md b/README.md new file mode 100644 index 0000000..add990c --- /dev/null +++ b/README.md @@ -0,0 +1,78 @@ +# Travis CI build status +[![Build Status](https://travis-ci.org/mariusstaicu/gorf24.svg?branch=port)](https://travis-ci.org/mariusstaicu/gorf24) + +# Radio-fy your Raspberry Pi +It's software that allows you to control the low-cost Nordic Semiconductor nRF24L01+ radio transceiver. It's written and tested on/for Raspberry Pi, but can be slightly modified to work for other end devices as well. + +Note that this is project is in progress, and the golang or ansi C wrapper haven't been fully tested yet. +Basic send/receive testing has occured, but many functions might have bugs. +Please log any issue you might find and I will try to address it when I get a chance! +Or even better, fork and contribute, that would be much appreciated. + + +## Changing GPIO and SPI access +* This is just an up-to-date for the older version of the library written by galaktor ((https://travis-ci.org/galaktor/gorf24)).It is working wit the lastest RF24 Library. +It works or can be modified to make it work on any system that satisfies the following conditions: +* Linux OS +* SPI +I developed it on/for the Raspberry Pi running Arch Linux for ARM. The Pi has GPIO pins with SPI. If your device needs to control the pins and/or SPI differently, the relevant code is simple and not very hard to change. The majority of gorf24 code deals with the transceiver logic according to the official specification and will work if you can make the gpio and spi code work for you. + +## HOW TO INSTALL +``` +$> go get github.com/mariusstaicu/gorf24 +``` + +TODO: setup details with Arch on Pi + +# COPYRIGHT AND LICENSE + +Copyright 2013, 2014 Raphael Estrada + +Licensed under the [GNU General Public License verison 3](http://www.gnu.org/licenses/gpl-3.0.txt "GNU GPL v3") + +``` +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +``` + + +# THE GIANTS' SHOULDERS +Kudos to Galaktor for the initial work .Also check the native go port he has made. + +I wrote the current version of gorf24 entirely from +scratch, mostly based on the following sources: + +* spidev documentation: +* RPi gpio tutorial: +* nRF24L01+ specification: + +Early versions of gorf24 dynamically linked to the RF24 +library for Raspberry Pi by Stanley Seow. Some of the +comments in the code pointed me in the right direction, +most notably with regards to timing. + + +Seow's work is stronly derived from maniacbug's original RF24 library. +Much kudos to maniacbug for the great work. +https://github.com/maniacbug/RF24 +http://maniacbug.wordpress.com/ + + +# TODOS +* Makefiles instead of shell scripts +* maybe better way of installing via go get? +* more testing of correct wrapping, data types etc +* branch that includes verified-working snap of RF24-rpi +* download with RPi binaries for armv6? + + From 47637217922e127bac51a7b26f41bcc773b0d56a Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 16:41:40 +0300 Subject: [PATCH 07/10] Added Travis file. --- .travis.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..6fddfe2 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: go + +go: + - tip + +sudo: required + +install: true + +script: + - ./build.sh \ No newline at end of file From 0470c403156f7ebbbfc145890936b1d50b8e7c3d Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Tue, 4 Jul 2017 16:54:38 +0300 Subject: [PATCH 08/10] Updated Readme to build on master. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index add990c..2481656 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Travis CI build status -[![Build Status](https://travis-ci.org/mariusstaicu/gorf24.svg?branch=port)](https://travis-ci.org/mariusstaicu/gorf24) +[![Build Status](https://travis-ci.org/mariusstaicu/gorf24.svg?branch=master)](https://travis-ci.org/mariusstaicu/gorf24) # Radio-fy your Raspberry Pi It's software that allows you to control the low-cost Nordic Semiconductor nRF24L01+ radio transceiver. It's written and tested on/for Raspberry Pi, but can be slightly modified to work for other end devices as well. From 7dc05e7e4cd7100f290c476fa16860660261f844 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Thu, 6 Jul 2017 12:27:32 +0300 Subject: [PATCH 09/10] Added makefile for cgo wrapper.Added build.sh step. --- LICENSE | 1 + RF24_c/Makefile | 18 ++++++++++++++++++ RF24_c/build.sh | 19 ------------------- build.sh | 28 ++++++++++++++++------------ gorf24_helpers.go | 6 +----- 5 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 RF24_c/Makefile delete mode 100755 RF24_c/build.sh diff --git a/LICENSE b/LICENSE index eb308cc..5660561 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ The MIT License (MIT) Copyright (c) 2013 Raphael Estrada +Copyright (c) 2017 Marius Staicu, Marian Craciunescu Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/RF24_c/Makefile b/RF24_c/Makefile new file mode 100644 index 0000000..79078c7 --- /dev/null +++ b/RF24_c/Makefile @@ -0,0 +1,18 @@ +all:build install + +RF24_LIB_ROOT=../RF24/ +CC=g++ +CC_FLAGS=-g -O2 -fPIC -Wall -ansi -pedantic -shared + +build: + $(CC) $(CC_FLAGS) -I$(RF24_LIB_ROOT) -lrf24-bcm -I. -L$(RF24_LIB_ROOT) -o librf24_c.so *.cpp + +install: + @echo "Copying cgo wrapper in /usr/lib. Sudo needed." + cp librf24_c.so /usr/local/lib + cp librf24_c.so /usr/lib + @echo "Executing ldconfig." + ldconfig + +clean: + rm -rf *.so \ No newline at end of file diff --git a/RF24_c/build.sh b/RF24_c/build.sh deleted file mode 100755 index 916b3da..0000000 --- a/RF24_c/build.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -# Copyright 2013, Raphael Estrada -# Author email: -# Project home: -# Licensed under The MIT License (see README and LICENSE files) - -rfhdrdir=../RF24/ -rflibdir=$rfhdrdir - -g++ -g -O2 -fPIC -I$rfhdrdir -lrf24-bcm -I. -L$rflibdir -shared -o librf24_c.so *.cpp -ansi -pedantic - -cp librf24_c.so /usr/local/lib - -# pick up new shared objects -# will only work if /usr/local/lib is in /etc/ld.so.conf! -# see README for details -ldconfig - diff --git a/build.sh b/build.sh index 5f89cbc..fe3405a 100755 --- a/build.sh +++ b/build.sh @@ -1,28 +1,32 @@ -#!/bin/bash +#!/bin/sh -# Copyright 2017, Marius Staicu -# Author email: +# Copyright 2017, Marius Staicu,Marian Craciunescu +# Authors email: # Project home: # Licensed under The MIT License (see README and LICENSE files) -echo "fetching C++ RF24 for Raspberry Pi" -git clone https://github.com/TMRh20/RF24 +echo "Fetching latest C++ RF24 for Raspberry Pi" +if cd RF24; then + git pull origin master; +else + git clone https://github.com/TMRh20/RF24 RF24; +fi -echo "building C++ RF24 for Raspberry Pi" +echo "Building C++ RF24 for Raspberry Pi" cd RF24/ make make install cd ../ -echo "building C++ RF24 for Raspberry Pi EXAMPLES" +echo "Building C++ RF24 for Raspberry Pi EXAMPLES" cd RF24/examples_linux/ make cd ../.. -echo "buliding ANSI C wrapper for C++ RF24 library" +echo "Building ANSI C wrapper for C++ RF24 library" cd RF24_c -bash build.sh -cd .. - - +make +make install +cd ../ +echo "Building goRF24 library." \ No newline at end of file diff --git a/gorf24_helpers.go b/gorf24_helpers.go index 7ed9bc8..81e7307 100644 --- a/gorf24_helpers.go +++ b/gorf24_helpers.go @@ -8,11 +8,7 @@ package gorf24 #include */ import "C" -//import ( -// // "encoding/binary" -// // "fmt" -// "unsafe" -//) + func gobool(b C.cbool) bool { if b == C.cbool(0) { return false From 7ce8995cce03b67b5821bf27d0e183a917589953 Mon Sep 17 00:00:00 2001 From: Marian Craciunescu Date: Fri, 14 Jul 2017 17:38:43 +0300 Subject: [PATCH 10/10] Fix Pointer to Pointer error --- RF24.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/RF24.go b/RF24.go index cf4dd83..3ec55ea 100644 --- a/RF24.go +++ b/RF24.go @@ -189,19 +189,19 @@ func (r *RF24) PowerUp() { } func (r *RF24) WriteMulticast(data []byte, length uint8, multicast bool) bool { - return gobool(C.rf24_writeMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast))) + return gobool(C.rf24_writeMulticast(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length), cbool(multicast))) } func (r *RF24) WriteFast(data []byte, length uint8) bool { - return gobool(C.rf24_writeFast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length))) + return gobool(C.rf24_writeFast(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length))) } func (r *RF24) WriteFastMulticast(data []byte, length uint8, multicast bool) bool { - return gobool(C.rf24_writeFastMulticast(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast))) + return gobool(C.rf24_writeFastMulticast(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length), cbool(multicast))) } func (r *RF24) WriteBlocking(data []byte, length uint8, timeout uint32) bool { - return gobool(C.rf24_writeBlocking(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), C.uint32_t(timeout))) + return gobool(C.rf24_writeBlocking(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length), C.uint32_t(timeout))) } func (r *RF24) IsTxStandBy() bool { @@ -213,7 +213,7 @@ func (r *RF24) IsTxStandByExtended(timeout uint32, startTx bool) bool { } func (r *RF24) WriteAckPayload(pipe uint8, data []byte, length uint8) { - C.rf24_writeAckPayload(r.cptr, C.uint8_t(pipe), unsafe.Pointer(&data), C.uint8_t(length)) + C.rf24_writeAckPayload(r.cptr, C.uint8_t(pipe), unsafe.Pointer(&data[0]), C.uint8_t(length)) } func (r *RF24) IsAckPayloadAvailable() bool { @@ -228,11 +228,11 @@ func (r *RF24) WhatHappened() (tx_ok, tx_fail, rx_ready bool) { } func (r *RF24) StartWrite(data []byte, length uint8, multicast bool) { - C.rf24_startWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast)) + C.rf24_startWrite(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length), cbool(multicast)) } func (r *RF24) StartFastWrite(data []byte, length uint8, multicast bool, startTx bool) { - C.rf24_startFastWrite(r.cptr, unsafe.Pointer(&data), C.uint8_t(length), cbool(multicast), cbool(startTx)) + C.rf24_startFastWrite(r.cptr, unsafe.Pointer(&data[0]), C.uint8_t(length), cbool(multicast), cbool(startTx)) } func (r *RF24) ReUseTx() {