Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
R
RF24
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
RF24
Commits
9e717722
Commit
9e717722
authored
Apr 02, 2016
by
akatran
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
https://github.com/TMRh20/RF24
parents
a9255c80
a1d346a9
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
555 additions
and
108 deletions
+555
-108
Makefile
Makefile
+2
-1
RF24.cpp
RF24.cpp
+43
-31
RF24_config.h
RF24_config.h
+1
-2
examples/GettingStarted/GettingStarted.ino
examples/GettingStarted/GettingStarted.ino
+5
-5
library.properties
library.properties
+1
-1
nRF24L01.h
nRF24L01.h
+1
-1
utility/BBB/gpio.cpp
utility/BBB/gpio.cpp
+20
-6
utility/BBB/includes.h
utility/BBB/includes.h
+1
-0
utility/BBB/interrupt.c
utility/BBB/interrupt.c
+226
-0
utility/BBB/interrupt.h
utility/BBB/interrupt.h
+69
-0
utility/BBB/spi.cpp
utility/BBB/spi.cpp
+23
-16
utility/RPi/bcm2835.c
utility/RPi/bcm2835.c
+101
-29
utility/RPi/bcm2835.h
utility/RPi/bcm2835.h
+62
-16
No files found.
Makefile
View file @
9e717722
...
@@ -66,7 +66,8 @@ CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=$(ARCH) -mtune=arm1176jzf-s
...
@@ -66,7 +66,8 @@ CCFLAGS=-Ofast -mfpu=vfp -mfloat-abi=hard -march=$(ARCH) -mtune=arm1176jzf-s
else
else
DRIVER_DIR
=
$(ARCH_DIR)
/BBB
DRIVER_DIR
=
$(ARCH_DIR)
/BBB
OBJECTS
+=
gpio.o compatibility.o
OBJECTS
+=
gpio.o compatibility.o interrupt.o
SHARED_LINKER_FLAGS
+=
-pthread
endif
endif
...
...
RF24.cpp
View file @
9e717722
...
@@ -290,10 +290,12 @@ uint8_t RF24::read_payload(void* buf, uint8_t data_len)
...
@@ -290,10 +290,12 @@ uint8_t RF24::read_payload(void* buf, uint8_t data_len)
status
=
*
prx
++
;
// 1st byte is status
status
=
*
prx
++
;
// 1st byte is status
while
(
--
data_len
)
// Decrement before to skip 1st status byte
if
(
data_len
>
0
)
{
*
current
++
=
*
prx
++
;
while
(
--
data_len
)
// Decrement before to skip 1st status byte
*
current
++
=
*
prx
++
;
*
current
=
*
prx
;
*
current
=
*
prx
;
}
endTransaction
();
endTransaction
();
#else
#else
...
@@ -553,13 +555,13 @@ void RF24::printDetails(void)
...
@@ -553,13 +555,13 @@ void RF24::printDetails(void)
print_byte_register
(
PSTR
(
"EN_RXADDR"
),
EN_RXADDR
);
print_byte_register
(
PSTR
(
"EN_RXADDR"
),
EN_RXADDR
);
print_byte_register
(
PSTR
(
"RF_CH
\t
"
),
RF_CH
);
print_byte_register
(
PSTR
(
"RF_CH
\t
"
),
RF_CH
);
print_byte_register
(
PSTR
(
"RF_SETUP"
),
RF_SETUP
);
print_byte_register
(
PSTR
(
"RF_SETUP"
),
RF_SETUP
);
print_byte_register
(
PSTR
(
"CONFIG
\t
"
),
CONFIG
);
print_byte_register
(
PSTR
(
"CONFIG
\t
"
),
NRF_
CONFIG
);
print_byte_register
(
PSTR
(
"DYNPD/FEATURE"
),
DYNPD
,
2
);
print_byte_register
(
PSTR
(
"DYNPD/FEATURE"
),
DYNPD
,
2
);
printf_P
(
PSTR
(
"Data Rate
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_datarate_e_str_P
[
getDataRate
()]));
printf_P
(
PSTR
(
"Data Rate
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_datarate_e_str_P
[
getDataRate
()]));
printf_P
(
PSTR
(
"Model
\t\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_model_e_str_P
[
isPVariant
()]));
printf_P
(
PSTR
(
"Model
\t\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_model_e_str_P
[
isPVariant
()]));
printf_P
(
PSTR
(
"CRC Length
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_crclength_e_str_P
[
getCRCLength
()]));
printf_P
(
PSTR
(
"CRC Length
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_crclength_e_str_P
[
getCRCLength
()]));
printf_P
(
PSTR
(
"PA Power
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_pa_dbm_e_str_P
[
getPALevel
()]));
printf_P
(
PSTR
(
"PA Power
\t
= "
PRIPSTR
"
\r\n
"
),
pgm_read_word
(
&
rf24_pa_dbm_e_str_P
[
getPALevel
()]));
}
}
...
@@ -573,8 +575,6 @@ bool RF24::begin(void)
...
@@ -573,8 +575,6 @@ bool RF24::begin(void)
#if defined (RF24_LINUX)
#if defined (RF24_LINUX)
SPI
();
#if defined (MRAA)
#if defined (MRAA)
GPIO
();
GPIO
();
gpio
.
begin
(
ce_pin
,
csn_pin
);
gpio
.
begin
(
ce_pin
,
csn_pin
);
...
@@ -632,8 +632,8 @@ bool RF24::begin(void)
...
@@ -632,8 +632,8 @@ bool RF24::begin(void)
// WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
// WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
delay
(
5
)
;
delay
(
5
)
;
// Reset CONFIG and enable 16-bit CRC.
// Reset
NRF_
CONFIG and enable 16-bit CRC.
write_register
(
CONFIG
,
0b00001100
)
;
write_register
(
NRF_
CONFIG
,
0b00001100
)
;
// Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
// Set 1500uS (minimum for 32B payload in ESB@250KBPS) timeouts, to make testing a little easier
// WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
// WARNING: If this is ever lowered, either 250KBS mode with AA is broken or maximum packet
...
@@ -649,8 +649,8 @@ bool RF24::begin(void)
...
@@ -649,8 +649,8 @@ bool RF24::begin(void)
{
{
p_variant
=
true
;
p_variant
=
true
;
}
}
/*
setup = read_register(RF_SETUP);
setup
=
read_register
(
RF_SETUP
);
if( setup == 0b00001110 ) // register default for nRF24L01P
/*
if( setup == 0b00001110 ) // register default for nRF24L01P
{
{
p_variant = true ;
p_variant = true ;
}*/
}*/
...
@@ -684,7 +684,7 @@ bool RF24::begin(void)
...
@@ -684,7 +684,7 @@ bool RF24::begin(void)
// Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp )
// Enable PTX, do not write CE high so radio will remain in standby I mode ( 130us max to transition to RX or TX instead of 1500us from powerUp )
// PTX should use only 22uA of power
// PTX should use only 22uA of power
write_register
(
CONFIG
,
(
read_register
(
CONFIG
)
)
&
~
_BV
(
PRIM_RX
)
);
write_register
(
NRF_CONFIG
,
(
read_register
(
NRF_
CONFIG
)
)
&
~
_BV
(
PRIM_RX
)
);
// if setup is 0 or ff then there was no response from module
// if setup is 0 or ff then there was no response from module
return
(
setup
!=
0
&&
setup
!=
0xff
);
return
(
setup
!=
0
&&
setup
!=
0xff
);
...
@@ -697,7 +697,7 @@ void RF24::startListening(void)
...
@@ -697,7 +697,7 @@ void RF24::startListening(void)
#if !defined (RF24_TINY) && ! defined(LITTLEWIRE)
#if !defined (RF24_TINY) && ! defined(LITTLEWIRE)
powerUp
();
powerUp
();
#endif
#endif
write_register
(
CONFIG
,
read_register
(
CONFIG
)
|
_BV
(
PRIM_RX
));
write_register
(
NRF_CONFIG
,
read_register
(
NRF_
CONFIG
)
|
_BV
(
PRIM_RX
));
write_register
(
NRF_STATUS
,
_BV
(
RX_DR
)
|
_BV
(
TX_DS
)
|
_BV
(
MAX_RT
)
);
write_register
(
NRF_STATUS
,
_BV
(
RX_DR
)
|
_BV
(
TX_DS
)
|
_BV
(
MAX_RT
)
);
ce
(
HIGH
);
ce
(
HIGH
);
// Restore the pipe0 adddress, if exists
// Restore the pipe0 adddress, if exists
...
@@ -734,7 +734,7 @@ void RF24::stopListening(void)
...
@@ -734,7 +734,7 @@ void RF24::stopListening(void)
flush_tx
();
flush_tx
();
}
}
//flush_rx();
//flush_rx();
write_register
(
CONFIG
,
(
read_register
(
CONFIG
)
)
&
~
_BV
(
PRIM_RX
)
);
write_register
(
NRF_CONFIG
,
(
read_register
(
NRF_
CONFIG
)
)
&
~
_BV
(
PRIM_RX
)
);
#if defined (RF24_TINY) || defined (LITTLEWIRE)
#if defined (RF24_TINY) || defined (LITTLEWIRE)
// for 3 pins solution TX mode is only left with additonal powerDown/powerUp cycle
// for 3 pins solution TX mode is only left with additonal powerDown/powerUp cycle
...
@@ -754,7 +754,7 @@ void RF24::stopListening(void)
...
@@ -754,7 +754,7 @@ void RF24::stopListening(void)
void
RF24
::
powerDown
(
void
)
void
RF24
::
powerDown
(
void
)
{
{
ce
(
LOW
);
// Guarantee CE is low on powerDown
ce
(
LOW
);
// Guarantee CE is low on powerDown
write_register
(
CONFIG
,
read_register
(
CONFIG
)
&
~
_BV
(
PWR_UP
));
write_register
(
NRF_CONFIG
,
read_register
(
NRF_
CONFIG
)
&
~
_BV
(
PWR_UP
));
}
}
/****************************************************************************/
/****************************************************************************/
...
@@ -762,11 +762,11 @@ void RF24::powerDown(void)
...
@@ -762,11 +762,11 @@ void RF24::powerDown(void)
//Power up now. Radio will not power down unless instructed by MCU for config changes etc.
//Power up now. Radio will not power down unless instructed by MCU for config changes etc.
void
RF24
::
powerUp
(
void
)
void
RF24
::
powerUp
(
void
)
{
{
uint8_t
cfg
=
read_register
(
CONFIG
);
uint8_t
cfg
=
read_register
(
NRF_
CONFIG
);
// if not powered up then power up and wait for the radio to initialize
// if not powered up then power up and wait for the radio to initialize
if
(
!
(
cfg
&
_BV
(
PWR_UP
))){
if
(
!
(
cfg
&
_BV
(
PWR_UP
))){
write_register
(
CONFIG
,
read_register
(
CONFIG
)
|
_BV
(
PWR_UP
));
write_register
(
NRF_CONFIG
,
cfg
|
_BV
(
PWR_UP
));
// For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode.
// For nRF24L01+ to go from power down mode to TX or RX mode it must first pass through stand-by mode.
// There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before
// There must be a delay of Tpd2stby (see Table 16.) after the nRF24L01+ leaves power down mode before
...
@@ -803,7 +803,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast )
...
@@ -803,7 +803,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast )
while
(
!
(
get_status
()
&
(
_BV
(
TX_DS
)
|
_BV
(
MAX_RT
)
)))
{
while
(
!
(
get_status
()
&
(
_BV
(
TX_DS
)
|
_BV
(
MAX_RT
)
)))
{
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
if
(
millis
()
-
timer
>
8
5
){
if
(
millis
()
-
timer
>
9
5
){
errNotify
();
errNotify
();
#if defined (FAILURE_HANDLING)
#if defined (FAILURE_HANDLING)
return
0
;
return
0
;
...
@@ -849,7 +849,7 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
...
@@ -849,7 +849,7 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
if
(
millis
()
-
timer
>
timeout
){
return
0
;
}
//If this payload has exceeded the user-defined timeout, exit and return 0
if
(
millis
()
-
timer
>
timeout
){
return
0
;
}
//If this payload has exceeded the user-defined timeout, exit and return 0
}
}
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
if
(
millis
()
-
timer
>
(
timeout
+
8
5
)
){
if
(
millis
()
-
timer
>
(
timeout
+
9
5
)
){
errNotify
();
errNotify
();
#if defined (FAILURE_HANDLING)
#if defined (FAILURE_HANDLING)
return
0
;
return
0
;
...
@@ -896,7 +896,7 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
...
@@ -896,7 +896,7 @@ bool RF24::writeFast( const void* buf, uint8_t len, const bool multicast )
//From the user perspective, if you get a 0, just keep trying to send the same payload
//From the user perspective, if you get a 0, just keep trying to send the same payload
}
}
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
if
(
millis
()
-
timer
>
8
5
){
if
(
millis
()
-
timer
>
9
5
){
errNotify
();
errNotify
();
#if defined (FAILURE_HANDLING)
#if defined (FAILURE_HANDLING)
return
0
;
return
0
;
...
@@ -970,7 +970,7 @@ bool RF24::txStandBy(){
...
@@ -970,7 +970,7 @@ bool RF24::txStandBy(){
return
0
;
return
0
;
}
}
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
if
(
millis
()
-
timeout
>
8
5
){
if
(
millis
()
-
timeout
>
9
5
){
errNotify
();
errNotify
();
#if defined (FAILURE_HANDLING)
#if defined (FAILURE_HANDLING)
return
0
;
return
0
;
...
@@ -1003,7 +1003,7 @@ bool RF24::txStandBy(uint32_t timeout, bool startTx){
...
@@ -1003,7 +1003,7 @@ bool RF24::txStandBy(uint32_t timeout, bool startTx){
}
}
}
}
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
#if defined (FAILURE_HANDLING) || defined (RF24_LINUX)
if
(
millis
()
-
start
>
(
timeout
+
8
5
)){
if
(
millis
()
-
start
>
(
timeout
+
9
5
)){
errNotify
();
errNotify
();
#if defined (FAILURE_HANDLING)
#if defined (FAILURE_HANDLING)
return
0
;
return
0
;
...
@@ -1022,7 +1022,12 @@ bool RF24::txStandBy(uint32_t timeout, bool startTx){
...
@@ -1022,7 +1022,12 @@ bool RF24::txStandBy(uint32_t timeout, bool startTx){
void
RF24
::
maskIRQ
(
bool
tx
,
bool
fail
,
bool
rx
){
void
RF24
::
maskIRQ
(
bool
tx
,
bool
fail
,
bool
rx
){
write_register
(
CONFIG
,
(
read_register
(
CONFIG
)
)
|
fail
<<
MASK_MAX_RT
|
tx
<<
MASK_TX_DS
|
rx
<<
MASK_RX_DR
);
uint8_t
config
=
read_register
(
NRF_CONFIG
);
/* clear the interrupt flags */
config
&=
~
(
1
<<
MASK_MAX_RT
|
1
<<
MASK_TX_DS
|
1
<<
MASK_RX_DR
);
/* set the specified interrupt flags */
config
|=
fail
<<
MASK_MAX_RT
|
tx
<<
MASK_TX_DS
|
rx
<<
MASK_RX_DR
;
write_register
(
NRF_CONFIG
,
config
);
}
}
/****************************************************************************/
/****************************************************************************/
...
@@ -1474,7 +1479,7 @@ rf24_datarate_e RF24::getDataRate( void )
...
@@ -1474,7 +1479,7 @@ rf24_datarate_e RF24::getDataRate( void )
void
RF24
::
setCRCLength
(
rf24_crclength_e
length
)
void
RF24
::
setCRCLength
(
rf24_crclength_e
length
)
{
{
uint8_t
config
=
read_register
(
CONFIG
)
&
~
(
_BV
(
CRCO
)
|
_BV
(
EN_CRC
))
;
uint8_t
config
=
read_register
(
NRF_
CONFIG
)
&
~
(
_BV
(
CRCO
)
|
_BV
(
EN_CRC
))
;
// switch uses RAM (evil!)
// switch uses RAM (evil!)
if
(
length
==
RF24_CRC_DISABLED
)
if
(
length
==
RF24_CRC_DISABLED
)
...
@@ -1490,7 +1495,7 @@ void RF24::setCRCLength(rf24_crclength_e length)
...
@@ -1490,7 +1495,7 @@ void RF24::setCRCLength(rf24_crclength_e length)
config
|=
_BV
(
EN_CRC
);
config
|=
_BV
(
EN_CRC
);
config
|=
_BV
(
CRCO
);
config
|=
_BV
(
CRCO
);
}
}
write_register
(
CONFIG
,
config
)
;
write_register
(
NRF_
CONFIG
,
config
)
;
}
}
/****************************************************************************/
/****************************************************************************/
...
@@ -1499,7 +1504,7 @@ rf24_crclength_e RF24::getCRCLength(void)
...
@@ -1499,7 +1504,7 @@ rf24_crclength_e RF24::getCRCLength(void)
{
{
rf24_crclength_e
result
=
RF24_CRC_DISABLED
;
rf24_crclength_e
result
=
RF24_CRC_DISABLED
;
uint8_t
config
=
read_register
(
CONFIG
)
&
(
_BV
(
CRCO
)
|
_BV
(
EN_CRC
))
;
uint8_t
config
=
read_register
(
NRF_
CONFIG
)
&
(
_BV
(
CRCO
)
|
_BV
(
EN_CRC
))
;
uint8_t
AA
=
read_register
(
EN_AA
);
uint8_t
AA
=
read_register
(
EN_AA
);
if
(
config
&
_BV
(
EN_CRC
)
||
AA
)
if
(
config
&
_BV
(
EN_CRC
)
||
AA
)
...
@@ -1517,8 +1522,8 @@ rf24_crclength_e RF24::getCRCLength(void)
...
@@ -1517,8 +1522,8 @@ rf24_crclength_e RF24::getCRCLength(void)
void
RF24
::
disableCRC
(
void
)
void
RF24
::
disableCRC
(
void
)
{
{
uint8_t
disable
=
read_register
(
CONFIG
)
&
~
_BV
(
EN_CRC
)
;
uint8_t
disable
=
read_register
(
NRF_
CONFIG
)
&
~
_BV
(
EN_CRC
)
;
write_register
(
CONFIG
,
disable
)
;
write_register
(
NRF_
CONFIG
,
disable
)
;
}
}
/****************************************************************************/
/****************************************************************************/
...
@@ -1550,6 +1555,13 @@ void RF24::setRetries(uint8_t delay, uint8_t count)
...
@@ -1550,6 +1555,13 @@ void RF24::setRetries(uint8_t delay, uint8_t count)
# define DO 15 // PB6
# define DO 15 // PB6
# define USCK 16 // PB7
# define USCK 16 // PB7
# define SS 13 // PB4
# define SS 13 // PB4
#elif defined(__AVR_ATtiny861__)
// these depend on the core used (check pins_arduino.h)
// tested with google-code core
# define DI 9 // PB0
# define DO 8 // PB1
# define USCK 7 // PB2
# define SS 6 // PB3
#endif
#endif
#if defined(RF24_TINY)
#if defined(RF24_TINY)
...
...
RF24_config.h
View file @
9e717722
...
@@ -38,8 +38,7 @@
...
@@ -38,8 +38,7 @@
#include "utility/includes.h"
#include "utility/includes.h"
//ATTiny
//ATTiny
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__)
#elif defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__) || defined(__AVR_ATtiny2313__) || defined(__AVR_ATtiny4313__) || defined(__AVR_ATtiny861__)
#define RF24_TINY
#define RF24_TINY
#include "utility/ATTiny/RF24_arch_config.h"
#include "utility/ATTiny/RF24_arch_config.h"
...
...
examples/GettingStarted/GettingStarted.ino
View file @
9e717722
...
@@ -56,8 +56,8 @@ if (role == 1) {
...
@@ -56,8 +56,8 @@ if (role == 1) {
Serial
.
println
(
F
(
"Now sending"
));
Serial
.
println
(
F
(
"Now sending"
));
unsigned
long
time
=
micros
();
// Take the time, and send it. This will block until complete
unsigned
long
start_
time
=
micros
();
// Take the time, and send it. This will block until complete
if
(
!
radio
.
write
(
&
time
,
sizeof
(
unsigned
long
)
)){
if
(
!
radio
.
write
(
&
start_
time
,
sizeof
(
unsigned
long
)
)){
Serial
.
println
(
F
(
"failed"
));
Serial
.
println
(
F
(
"failed"
));
}
}
...
@@ -78,15 +78,15 @@ if (role == 1) {
...
@@ -78,15 +78,15 @@ if (role == 1) {
}
else
{
}
else
{
unsigned
long
got_time
;
// Grab the response, compare, and send to debugging spew
unsigned
long
got_time
;
// Grab the response, compare, and send to debugging spew
radio
.
read
(
&
got_time
,
sizeof
(
unsigned
long
)
);
radio
.
read
(
&
got_time
,
sizeof
(
unsigned
long
)
);
unsigned
long
time
=
micros
();
unsigned
long
end_
time
=
micros
();
// Spew it
// Spew it
Serial
.
print
(
F
(
"Sent "
));
Serial
.
print
(
F
(
"Sent "
));
Serial
.
print
(
time
);
Serial
.
print
(
start_
time
);
Serial
.
print
(
F
(
", Got response "
));
Serial
.
print
(
F
(
", Got response "
));
Serial
.
print
(
got_time
);
Serial
.
print
(
got_time
);
Serial
.
print
(
F
(
", Round-trip delay "
));
Serial
.
print
(
F
(
", Round-trip delay "
));
Serial
.
print
(
time
-
go
t_time
);
Serial
.
print
(
end_time
-
star
t_time
);
Serial
.
println
(
F
(
" microseconds"
));
Serial
.
println
(
F
(
" microseconds"
));
}
}
...
...
library.properties
View file @
9e717722
name
=
RF24
name
=
RF24
version
=
1.1.
5
version
=
1.1.
6
author
=
TMRh20
author
=
TMRh20
maintainer
=
TMRh20
maintainer
=
TMRh20
sentence
=
A library for NRF24L01(+) communication.
sentence
=
A library for NRF24L01(+) communication.
...
...
nRF24L01.h
View file @
9e717722
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
*/
*/
/* Memory Map */
/* Memory Map */
#define CONFIG 0x00
#define
NRF_
CONFIG 0x00
#define EN_AA 0x01
#define EN_AA 0x01
#define EN_RXADDR 0x02
#define EN_RXADDR 0x02
#define SETUP_AW 0x03
#define SETUP_AW 0x03
...
...
utility/BBB/gpio.cpp
View file @
9e717722
...
@@ -10,6 +10,8 @@
...
@@ -10,6 +10,8 @@
*/
*/
#include "gpio.h"
#include "gpio.h"
#include <stdlib.h>
#include <unistd.h>
GPIO
::
GPIO
()
{
GPIO
::
GPIO
()
{
}
}
...
@@ -24,12 +26,24 @@ void GPIO::open(int port, int DDR)
...
@@ -24,12 +26,24 @@ void GPIO::open(int port, int DDR)
fprintf
(
f
,
"%d
\n
"
,
port
);
fprintf
(
f
,
"%d
\n
"
,
port
);
fclose
(
f
);
fclose
(
f
);
char
file
[
128
];
int
counter
=
0
;
sprintf
(
file
,
"/sys/class/gpio/gpio%d/direction"
,
port
);
char
file
[
128
];
f
=
fopen
(
file
,
"w"
);
sprintf
(
file
,
"/sys/class/gpio/gpio%d/direction"
,
port
);
if
(
DDR
==
0
)
fprintf
(
f
,
"in
\n
"
);
else
fprintf
(
f
,
"out
\n
"
);
while
(
(
f
=
fopen
(
file
,
"w"
))
==
NULL
){
//Wait 10 seconds for the file to be accessible if not open on first attempt
fclose
(
f
);
sleep
(
1
);
counter
++
;
if
(
counter
>
10
){
perror
(
"Could not open /sys/class/gpio/gpio%d/direction"
);
exit
(
0
);
}
}
if
(
DDR
==
0
)
fprintf
(
f
,
"in
\n
"
);
else
fprintf
(
f
,
"out
\n
"
);
fclose
(
f
);
}
}
void
GPIO
::
close
(
int
port
)
void
GPIO
::
close
(
int
port
)
...
...
utility/BBB/includes.h
View file @
9e717722
...
@@ -4,5 +4,6 @@
...
@@ -4,5 +4,6 @@
#define RF24_BBB
#define RF24_BBB
#include "BBB/RF24_arch_config.h"
#include "BBB/RF24_arch_config.h"
#include "BBB/interrupt.h"
#endif
#endif
\ No newline at end of file
utility/BBB/interrupt.c
0 → 100644
View file @
9e717722
/*
Interrupts functions extruded from wiringPi library by Oitzu.
wiringPi Copyright (c) 2012 Gordon Henderson
https://projects.drogon.net/raspberry-pi/wiringpi
wiringPi is free software: GNU Lesser General Public License
see <http://www.gnu.org/licenses/>
*/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <sys/wait.h>
#include <sys/ioctl.h>
#include <poll.h>
#include <sys/stat.h>
#include "interrupt.h"
#include <pthread.h>
//#define delay(x) bcm2835_delay(x)
static
pthread_mutex_t
pinMutex
=
PTHREAD_MUTEX_INITIALIZER
;
static
volatile
int
pinPass
=
-
1
;
pthread_t
threadId
[
64
];
// sysFds:
// Map a file descriptor from the /sys/class/gpio/gpioX/value
static
int
sysFds
[
64
]
=
{
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
}
;
// ISR Data
static
void
(
*
isrFunctions
[
64
])(
void
)
;
int
waitForInterrupt
(
int
pin
,
int
mS
)
{
int
fd
,
x
;
uint8_t
c
;
struct
pollfd
polls
;
if
((
fd
=
sysFds
[
pin
])
==
-
1
)
return
-
2
;
// Setup poll structure
polls
.
fd
=
fd
;
polls
.
events
=
POLLPRI
;
// Urgent data!
// Wait for it ...
x
=
poll
(
&
polls
,
1
,
mS
)
;
// Do a dummy read to clear the interrupt
// A one character read appars to be enough.
// Followed by a seek to reset it.
(
void
)
read
(
fd
,
&
c
,
1
)
;
lseek
(
fd
,
0
,
SEEK_SET
)
;
return
x
;
}
int
piHiPri
(
const
int
pri
)
{
struct
sched_param
sched
;
memset
(
&
sched
,
0
,
sizeof
(
sched
))
;
if
(
pri
>
sched_get_priority_max
(
SCHED_RR
))
sched
.
sched_priority
=
sched_get_priority_max
(
SCHED_RR
)
;
else
sched
.
sched_priority
=
pri
;
return
sched_setscheduler
(
0
,
SCHED_RR
,
&
sched
)
;
}
void
*
interruptHandler
(
void
*
arg
)
{
int
myPin
;
(
void
)
piHiPri
(
55
)
;
// Only effective if we run as root
myPin
=
pinPass
;
pinPass
=
-
1
;
for
(;;)
if
(
waitForInterrupt
(
myPin
,
-
1
)
>
0
){
pthread_mutex_lock
(
&
pinMutex
)
;
isrFunctions
[
myPin
]
()
;
pthread_mutex_unlock
(
&
pinMutex
)
;
pthread_testcancel
();
//Cancel at this point if we have an cancellation request.
}
return
NULL
;
}
int
attachInterrupt
(
int
pin
,
int
mode
,
void
(
*
function
)(
void
))
{
const
char
*
modeS
;
char
fName
[
64
]
;
char
pinS
[
8
]
;
pid_t
pid
;
int
count
,
i
;
char
c
;
int
bcmGpioPin
;
bcmGpioPin
=
pin
;
if
(
mode
!=
INT_EDGE_SETUP
)
{
/**/
if
(
mode
==
INT_EDGE_FALLING
)
modeS
=
"falling"
;
else
if
(
mode
==
INT_EDGE_RISING
)
modeS
=
"rising"
;
else
modeS
=
"both"
;
sprintf
(
pinS
,
"%d"
,
bcmGpioPin
)
;
if
((
pid
=
fork
())
<
0
)
// Fail
return
printf
(
"wiringPiISR: fork failed: %s
\n
"
,
strerror
(
errno
))
;
if
(
pid
==
0
)
// Child, exec
{
/**/
if
(
access
(
"/usr/local/bin/gpio"
,
X_OK
)
==
0
)
{
execl
(
"/usr/local/bin/gpio"
,
"gpio"
,
"edge"
,
pinS
,
modeS
,
(
char
*
)
NULL
)
;
return
printf
(
"wiringPiISR: execl failed: %s
\n
"
,
strerror
(
errno
))
;
}
else
if
(
access
(
"/usr/bin/gpio"
,
X_OK
)
==
0
)
{
execl
(
"/usr/bin/gpio"
,
"gpio"
,
"edge"
,
pinS
,
modeS
,
(
char
*
)
NULL
)
;
return
printf
(
"wiringPiISR: execl failed: %s
\n
"
,
strerror
(
errno
))
;
}
else
return
printf
(
"wiringPiISR: Can't find gpio program
\n
"
)
;
}
else
// Parent, wait
wait
(
NULL
)
;
}
if
(
sysFds
[
bcmGpioPin
]
==
-
1
)
{
sprintf
(
fName
,
"/sys/class/gpio/gpio%d/value"
,
bcmGpioPin
);
if
((
sysFds
[
bcmGpioPin
]
=
open
(
fName
,
O_RDWR
))
<
0
)
return
printf
(
"wiringPiISR: unable to open %s: %s
\n
"
,
fName
,
strerror
(
errno
))
;
}
ioctl
(
sysFds
[
bcmGpioPin
],
FIONREAD
,
&
count
)
;
for
(
i
=
0
;
i
<
count
;
++
i
)
read
(
sysFds
[
bcmGpioPin
],
&
c
,
1
)
;
isrFunctions
[
pin
]
=
function
;
pthread_mutex_lock
(
&
pinMutex
)
;
pinPass
=
pin
;
pthread_create
(
&
threadId
[
bcmGpioPin
],
NULL
,
interruptHandler
,
NULL
)
;
while
(
pinPass
!=
-
1
)
delay
(
1
)
;
pthread_mutex_unlock
(
&
pinMutex
)
;
return
0
;
}
int
detachInterrupt
(
int
pin
)
{
char
pinS
[
8
];
const
char
*
modeS
=
"none"
;
pid_t
pid
;
if
(
!
pthread_cancel
(
threadId
[
pin
]))
//Cancel the thread
{
return
0
;
}
if
(
!
close
(
sysFds
[
pin
]))
//Close filehandle
{
return
0
;
}
/* Set wiringPi to 'none' interrupt mode */
sprintf
(
pinS
,
"%d"
,
pin
)
;
if
((
pid
=
fork
())
<
0
)
// Fail
return
printf
(
"wiringPiISR: fork failed: %s
\n
"
,
strerror
(
errno
))
;
if
(
pid
==
0
)
// Child, exec
{
/**/
if
(
access
(
"/usr/local/bin/gpio"
,
X_OK
)
==
0
)
{
execl
(
"/usr/local/bin/gpio"
,
"gpio"
,
"edge"
,
pinS
,
modeS
,
(
char
*
)
NULL
)
;
return
printf
(
"wiringPiISR: execl failed: %s
\n
"
,
strerror
(
errno
))
;
}
else
if
(
access
(
"/usr/bin/gpio"
,
X_OK
)
==
0
)
{
execl
(
"/usr/bin/gpio"
,
"gpio"
,
"edge"
,
pinS
,
modeS
,
(
char
*
)
NULL
)
;
return
printf
(
"wiringPiISR: execl failed: %s
\n
"
,
strerror
(
errno
))
;
}
else
return
printf
(
"wiringPiISR: Can't find gpio program
\n
"
)
;
}
else
// Parent, wait
wait
(
NULL
)
;
return
1
;
}
void
rfNoInterrupts
(){
pthread_mutex_lock
(
&
pinMutex
)
;
}
void
rfInterrupts
(){
pthread_mutex_unlock
(
&
pinMutex
)
;
}
\ No newline at end of file
utility/BBB/interrupt.h
0 → 100644
View file @
9e717722
/*
Interrupts functions extruded from wiringPi library by Oitzu.
wiringPi Copyright (c) 2012 Gordon Henderson
https://projects.drogon.net/raspberry-pi/wiringpi
wiringPi is free software: GNU Lesser General Public License
see <http://www.gnu.org/licenses/>
*/
#include "RF24_arch_config.h"
#define INT_EDGE_SETUP 0
#define INT_EDGE_FALLING 1
#define INT_EDGE_RISING 2
#define INT_EDGE_BOTH 3
/*
* interruptHandler:
* This is a thread and gets started to wait for the interrupt we're
* hoping to catch. It will call the user-function when the interrupt
* fires.
*********************************************************************************
*/
void
*
interruptHandler
(
void
*
arg
);
#ifdef __cplusplus
extern
"C"
{
#endif
/*
* waitForInterrupt:
* Pi Specific.
* Wait for Interrupt on a GPIO pin.
* This is actually done via the /sys/class/gpio interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
* way for a bit more efficiency.
*********************************************************************************
*/
extern
int
waitForInterrupt
(
int
pin
,
int
mS
);
/*
* piHiPri:
* Attempt to set a high priority schedulling for the running program
*********************************************************************************
*/
extern
int
piHiPri
(
const
int
pri
);
/*
* attachInterrupt (Original: wiringPiISR):
* Pi Specific.
* Take the details and create an interrupt handler that will do a call-
* back to the user supplied function.
*********************************************************************************
*/
extern
int
attachInterrupt
(
int
pin
,
int
mode
,
void
(
*
function
)(
void
));
/*
* detachInterrupt:
* Pi Specific detachInterrupt.
* Will cancel the interrupt thread, close the filehandle and
* setting wiringPi back to 'none' mode.
*********************************************************************************
*/
extern
int
detachInterrupt
(
int
pin
);
extern
void
rfNoInterrupts
();
extern
void
rfInterrupts
();
#ifdef __cplusplus
}
#endif
\ No newline at end of file
utility/BBB/spi.cpp
View file @
9e717722
...
@@ -10,8 +10,10 @@
...
@@ -10,8 +10,10 @@
#include "spi.h"
#include "spi.h"
SPI
::
SPI
()
{
#include <pthread.h>
static
pthread_mutex_t
spiMutex
;
SPI
::
SPI
()
:
fd
(
-
1
)
{
}
}
void
SPI
::
begin
(
int
busNo
){
void
SPI
::
begin
(
int
busNo
){
...
@@ -48,17 +50,16 @@ void SPI::init()
...
@@ -48,17 +50,16 @@ void SPI::init()
{
{
int
ret
;
int
ret
;
if
(
this
->
fd
>
0
)
{
if
(
this
->
fd
<
0
)
// check whether spi is already open
close
(
this
->
fd
);
{
this
->
fd
=
open
(
this
->
device
.
c_str
(),
O_RDWR
);
if
(
this
->
fd
<
0
)
{
perror
(
"can't open device"
);
abort
();
}
}
}
this
->
fd
=
open
(
this
->
device
.
c_str
(),
O_RDWR
);
if
(
this
->
fd
<
0
)
{
perror
(
"can't open device"
);
abort
();
}
/*
/*
* spi mode
* spi mode
...
@@ -113,6 +114,7 @@ void SPI::init()
...
@@ -113,6 +114,7 @@ void SPI::init()
uint8_t
SPI
::
transfer
(
uint8_t
tx_
)
uint8_t
SPI
::
transfer
(
uint8_t
tx_
)
{
{
pthread_mutex_lock
(
&
spiMutex
);
int
ret
;
int
ret
;
uint8_t
tx
[
1
]
=
{
tx_
};
uint8_t
tx
[
1
]
=
{
tx_
};
uint8_t
rx
[
1
];
uint8_t
rx
[
1
];
...
@@ -124,10 +126,10 @@ uint8_t SPI::transfer(uint8_t tx_)
...
@@ -124,10 +126,10 @@ uint8_t SPI::transfer(uint8_t tx_)
tr
.
len
=
1
,
//ARRAY_SIZE(tx),
tr
.
len
=
1
,
//ARRAY_SIZE(tx),
tr
.
delay_usecs
=
0
,
tr
.
delay_usecs
=
0
,
tr
.
cs_change
=
1
,
tr
.
cs_change
=
1
,
tr
.
speed_hz
=
this
->
speed
,
tr
.
bits_per_word
=
this
->
bits
,
tr
.
bits_per_word
=
this
->
bits
,
};
};
tr
.
speed_hz
=
this
->
speed
,
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
//
//
/* // One byte is transfered at once
/* // One byte is transfered at once
...
@@ -146,10 +148,12 @@ uint8_t SPI::transfer(uint8_t tx_)
...
@@ -146,10 +148,12 @@ uint8_t SPI::transfer(uint8_t tx_)
ret
=
ioctl
(
this
->
fd
,
SPI_IOC_MESSAGE
(
1
),
&
tr
);
ret
=
ioctl
(
this
->
fd
,
SPI_IOC_MESSAGE
(
1
),
&
tr
);
if
(
ret
<
1
)
if
(
ret
<
1
)
{
{
pthread_mutex_unlock
(
&
spiMutex
);
perror
(
"can't send spi message"
);
perror
(
"can't send spi message"
);
abort
();
abort
();
}
}
pthread_mutex_unlock
(
&
spiMutex
);
return
rx
[
0
];
return
rx
[
0
];
}
}
...
@@ -157,6 +161,7 @@ uint8_t SPI::transfer(uint8_t tx_)
...
@@ -157,6 +161,7 @@ uint8_t SPI::transfer(uint8_t tx_)
void
SPI
::
transfernb
(
char
*
tbuf
,
char
*
rbuf
,
uint32_t
len
)
void
SPI
::
transfernb
(
char
*
tbuf
,
char
*
rbuf
,
uint32_t
len
)
{
{
pthread_mutex_lock
(
&
spiMutex
);
int
ret
;
int
ret
;
this
->
init
();
this
->
init
();
struct
spi_ioc_transfer
tr
=
{
struct
spi_ioc_transfer
tr
=
{
...
@@ -165,9 +170,9 @@ void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
...
@@ -165,9 +170,9 @@ void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
tr
.
len
=
len
,
//ARRAY_SIZE(tx),
tr
.
len
=
len
,
//ARRAY_SIZE(tx),
tr
.
cs_change
=
1
,
tr
.
cs_change
=
1
,
tr
.
delay_usecs
=
0
,
tr
.
delay_usecs
=
0
,
tr
.
speed_hz
=
this
->
speed
,
tr
.
bits_per_word
=
this
->
bits
,
tr
.
bits_per_word
=
this
->
bits
,
};
};
tr
.
speed_hz
=
this
->
speed
,
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
//Note: On RPi, for some reason I started getting 'bad message' errors, and changing the struct as below fixed it, until an update...??
// One byte is transfered at once
// One byte is transfered at once
...
@@ -187,10 +192,11 @@ void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
...
@@ -187,10 +192,11 @@ void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
ret
=
ioctl
(
this
->
fd
,
SPI_IOC_MESSAGE
(
1
),
&
tr
);
ret
=
ioctl
(
this
->
fd
,
SPI_IOC_MESSAGE
(
1
),
&
tr
);
if
(
ret
<
1
)
if
(
ret
<
1
)
{
{
pthread_mutex_unlock
(
&
spiMutex
);
perror
(
"can't send spi message"
);
perror
(
"can't send spi message"
);
abort
();
abort
();
}
}
pthread_mutex_unlock
(
&
spiMutex
);
//return rx[0];
//return rx[0];
}
}
...
@@ -201,6 +207,7 @@ void SPI::transfern(char* buf, uint32_t len)
...
@@ -201,6 +207,7 @@ void SPI::transfern(char* buf, uint32_t len)
SPI
::~
SPI
()
{
SPI
::~
SPI
()
{
close
(
this
->
fd
);
if
(
!
(
this
->
fd
<
0
))
close
(
this
->
fd
);
}
}
utility/RPi/bcm2835.c
View file @
9e717722
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
#include <sys/time.h>
#include <sys/time.h>
#include <time.h>
#include <time.h>
#include <unistd.h>
#include <unistd.h>
#include <sys/types.h>
#define BCK2835_LIBRARY_BUILD
#define BCK2835_LIBRARY_BUILD
#include "bcm2835.h"
#include "bcm2835.h"
...
@@ -271,6 +272,13 @@ uint8_t bcm2835_gpio_eds(uint8_t pin)
...
@@ -271,6 +272,13 @@ uint8_t bcm2835_gpio_eds(uint8_t pin)
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
return
(
value
&
(
1
<<
shift
))
?
HIGH
:
LOW
;
}
}
uint32_t
bcm2835_gpio_eds_multi
(
uint32_t
mask
)
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
;
uint32_t
value
=
bcm2835_peri_read
(
paddr
);
return
(
value
&
mask
);
}
/* Write a 1 to clear the bit in EDS */
/* Write a 1 to clear the bit in EDS */
void
bcm2835_gpio_set_eds
(
uint8_t
pin
)
void
bcm2835_gpio_set_eds
(
uint8_t
pin
)
{
{
...
@@ -280,6 +288,12 @@ void bcm2835_gpio_set_eds(uint8_t pin)
...
@@ -280,6 +288,12 @@ void bcm2835_gpio_set_eds(uint8_t pin)
bcm2835_peri_write
(
paddr
,
value
);
bcm2835_peri_write
(
paddr
,
value
);
}
}
void
bcm2835_gpio_set_eds_multi
(
uint32_t
mask
)
{
volatile
uint32_t
*
paddr
=
bcm2835_gpio
+
BCM2835_GPEDS0
/
4
;
bcm2835_peri_write
(
paddr
,
mask
);
}
/* Rising edge detect enable */
/* Rising edge detect enable */
void
bcm2835_gpio_ren
(
uint8_t
pin
)
void
bcm2835_gpio_ren
(
uint8_t
pin
)
{
{
...
@@ -396,16 +410,22 @@ void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
...
@@ -396,16 +410,22 @@ void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on)
/* Read GPIO pad behaviour for groups of GPIOs */
/* Read GPIO pad behaviour for groups of GPIOs */
uint32_t
bcm2835_gpio_pad
(
uint8_t
group
)
uint32_t
bcm2835_gpio_pad
(
uint8_t
group
)
{
{
if
(
bcm2835_pads
==
MAP_FAILED
)
return
0
;
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
;
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
;
return
bcm2835_peri_read
(
paddr
);
return
bcm2835_peri_read
(
paddr
);
}
}
/* Set GPIO pad behaviour for groups of GPIOs
/* Set GPIO pad behaviour for groups of GPIOs
// powerup value for al pads is
// powerup value for al
l
pads is
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
// BCM2835_PAD_SLEW_RATE_UNLIMITED | BCM2835_PAD_HYSTERESIS_ENABLED | BCM2835_PAD_DRIVE_8mA
*/
*/
void
bcm2835_gpio_set_pad
(
uint8_t
group
,
uint32_t
control
)
void
bcm2835_gpio_set_pad
(
uint8_t
group
,
uint32_t
control
)
{
{
if
(
bcm2835_pads
==
MAP_FAILED
)
return
;
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
;
volatile
uint32_t
*
paddr
=
bcm2835_pads
+
BCM2835_PADS_GPIO_0_27
/
4
+
group
;
bcm2835_peri_write
(
paddr
,
control
|
BCM2835_PAD_PASSWRD
);
bcm2835_peri_write
(
paddr
,
control
|
BCM2835_PAD_PASSWRD
);
}
}
...
@@ -520,10 +540,13 @@ void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
...
@@ -520,10 +540,13 @@ void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
bcm2835_gpio_pudclk
(
pin
,
0
);
bcm2835_gpio_pudclk
(
pin
,
0
);
}
}
void
bcm2835_spi_begin
(
void
)
int
bcm2835_spi_begin
(
void
)
{
{
volatile
uint32_t
*
paddr
;
volatile
uint32_t
*
paddr
;
if
(
bcm2835_spi0
==
MAP_FAILED
)
return
0
;
/* bcm2835_init() failed, or not root */
/* Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them */
/* Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them */
bcm2835_gpio_fsel
(
RPI_GPIO_P1_26
,
BCM2835_GPIO_FSEL_ALT0
);
/* CE1 */
bcm2835_gpio_fsel
(
RPI_GPIO_P1_26
,
BCM2835_GPIO_FSEL_ALT0
);
/* CE1 */
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_ALT0
);
/* CE0 */
bcm2835_gpio_fsel
(
RPI_GPIO_P1_24
,
BCM2835_GPIO_FSEL_ALT0
);
/* CE0 */
...
@@ -537,6 +560,8 @@ void bcm2835_spi_begin(void)
...
@@ -537,6 +560,8 @@ void bcm2835_spi_begin(void)
/* Clear TX and RX fifos */
/* Clear TX and RX fifos */
bcm2835_peri_write_nb
(
paddr
,
BCM2835_SPI0_CS_CLEAR
);
bcm2835_peri_write_nb
(
paddr
,
BCM2835_SPI0_CS_CLEAR
);
return
1
;
// OK
}
}
void
bcm2835_spi_end
(
void
)
void
bcm2835_spi_end
(
void
)
...
@@ -551,7 +576,7 @@ void bcm2835_spi_end(void)
...
@@ -551,7 +576,7 @@ void bcm2835_spi_end(void)
void
bcm2835_spi_setBitOrder
(
uint8_t
__attribute__
((
unused
))
order
)
void
bcm2835_spi_setBitOrder
(
uint8_t
__attribute__
((
unused
))
order
)
{
{
/* BCM2835_SPI_BIT_ORDER_MSBFIRST is the only one suported by SPI0 */
/* BCM2835_SPI_BIT_ORDER_MSBFIRST is the only one sup
p
orted by SPI0 */
}
}
/* defaults to 0, which means a divider of 65536.
/* defaults to 0, which means a divider of 65536.
...
@@ -718,10 +743,14 @@ void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active)
...
@@ -718,10 +743,14 @@ void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active)
bcm2835_peri_set_bits
(
paddr
,
active
<<
shift
,
1
<<
shift
);
bcm2835_peri_set_bits
(
paddr
,
active
<<
shift
,
1
<<
shift
);
}
}
void
bcm2835_i2c_begin
(
void
)
int
bcm2835_i2c_begin
(
void
)
{
{
uint16_t
cdiv
;
uint16_t
cdiv
;
if
(
bcm2835_bsc0
==
MAP_FAILED
||
bcm2835_bsc1
==
MAP_FAILED
)
return
0
;
/* bcm2835_init() failed, or not root */
#ifdef I2C_V1
#ifdef I2C_V1
volatile
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
volatile
uint32_t
*
paddr
=
bcm2835_bsc0
+
BCM2835_BSC_DIV
/
4
;
/* Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them */
/* Set the I2C/BSC0 pins to the Alt 0 function to enable I2C access on them */
...
@@ -741,6 +770,8 @@ void bcm2835_i2c_begin(void)
...
@@ -741,6 +770,8 @@ void bcm2835_i2c_begin(void)
// 9 = Clocks per byte : 8 bits + ACK
// 9 = Clocks per byte : 8 bits + ACK
*/
*/
i2c_byte_wait_us
=
((
float
)
cdiv
/
BCM2835_CORE_CLK_HZ
)
*
1000000
*
9
;
i2c_byte_wait_us
=
((
float
)
cdiv
/
BCM2835_CORE_CLK_HZ
)
*
1000000
*
9
;
return
1
;
}
}
void
bcm2835_i2c_end
(
void
)
void
bcm2835_i2c_end
(
void
)
...
@@ -1177,6 +1208,10 @@ void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros)
...
@@ -1177,6 +1208,10 @@ void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros)
void
bcm2835_pwm_set_clock
(
uint32_t
divisor
)
void
bcm2835_pwm_set_clock
(
uint32_t
divisor
)
{
{
if
(
bcm2835_clk
==
MAP_FAILED
||
bcm2835_pwm
==
MAP_FAILED
)
return
;
/* bcm2835_init() failed or not root */
/* From Gerts code */
/* From Gerts code */
divisor
&=
0xfff
;
divisor
&=
0xfff
;
/* Stop PWM clock */
/* Stop PWM clock */
...
@@ -1192,6 +1227,10 @@ void bcm2835_pwm_set_clock(uint32_t divisor)
...
@@ -1192,6 +1227,10 @@ void bcm2835_pwm_set_clock(uint32_t divisor)
void
bcm2835_pwm_set_mode
(
uint8_t
channel
,
uint8_t
markspace
,
uint8_t
enabled
)
void
bcm2835_pwm_set_mode
(
uint8_t
channel
,
uint8_t
markspace
,
uint8_t
enabled
)
{
{
if
(
bcm2835_clk
==
MAP_FAILED
||
bcm2835_pwm
==
MAP_FAILED
)
return
;
/* bcm2835_init() failed or not root */
uint32_t
control
=
bcm2835_peri_read
(
bcm2835_pwm
+
BCM2835_PWM_CONTROL
);
uint32_t
control
=
bcm2835_peri_read
(
bcm2835_pwm
+
BCM2835_PWM_CONTROL
);
if
(
channel
==
0
)
if
(
channel
==
0
)
...
@@ -1225,6 +1264,10 @@ void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled)
...
@@ -1225,6 +1264,10 @@ void bcm2835_pwm_set_mode(uint8_t channel, uint8_t markspace, uint8_t enabled)
void
bcm2835_pwm_set_range
(
uint8_t
channel
,
uint32_t
range
)
void
bcm2835_pwm_set_range
(
uint8_t
channel
,
uint32_t
range
)
{
{
if
(
bcm2835_clk
==
MAP_FAILED
||
bcm2835_pwm
==
MAP_FAILED
)
return
;
/* bcm2835_init() failed or not root */
if
(
channel
==
0
)
if
(
channel
==
0
)
bcm2835_peri_write_nb
(
bcm2835_pwm
+
BCM2835_PWM0_RANGE
,
range
);
bcm2835_peri_write_nb
(
bcm2835_pwm
+
BCM2835_PWM0_RANGE
,
range
);
else
if
(
channel
==
1
)
else
if
(
channel
==
1
)
...
@@ -1233,6 +1276,10 @@ void bcm2835_pwm_set_range(uint8_t channel, uint32_t range)
...
@@ -1233,6 +1276,10 @@ void bcm2835_pwm_set_range(uint8_t channel, uint32_t range)
void
bcm2835_pwm_set_data
(
uint8_t
channel
,
uint32_t
data
)
void
bcm2835_pwm_set_data
(
uint8_t
channel
,
uint32_t
data
)
{
{
if
(
bcm2835_clk
==
MAP_FAILED
||
bcm2835_pwm
==
MAP_FAILED
)
return
;
/* bcm2835_init() failed or not root */
if
(
channel
==
0
)
if
(
channel
==
0
)
bcm2835_peri_write_nb
(
bcm2835_pwm
+
BCM2835_PWM0_DATA
,
data
);
bcm2835_peri_write_nb
(
bcm2835_pwm
+
BCM2835_PWM0_DATA
,
data
);
else
if
(
channel
==
1
)
else
if
(
channel
==
1
)
...
@@ -1304,35 +1351,60 @@ int bcm2835_init(void)
...
@@ -1304,35 +1351,60 @@ int bcm2835_init(void)
}
}
/* else we are prob on RPi 1 with BCM2835, and use the hardwired defaults */
/* else we are prob on RPi 1 with BCM2835, and use the hardwired defaults */
/* Now get ready to map the peripherals block */
/* Now get ready to map the peripherals block
* If we are not root, try for the new /dev/gpiomem interface and accept
* the fact that we can only access GPIO
* else try for the /dev/mem interface and get access to everything
*/
memfd
=
-
1
;
memfd
=
-
1
;
ok
=
0
;
ok
=
0
;
/* Open the master /dev/memory device */
if
(
geteuid
()
==
0
)
if
((
memfd
=
open
(
"/dev/mem"
,
O_RDWR
|
O_SYNC
)
)
<
0
)
{
{
fprintf
(
stderr
,
"bcm2835_init: Unable to open /dev/mem: %s
\n
"
,
/* Open the master /dev/mem device */
strerror
(
errno
))
;
if
((
memfd
=
open
(
"/dev/mem"
,
O_RDWR
|
O_SYNC
)
)
<
0
)
goto
exit
;
{
fprintf
(
stderr
,
"bcm2835_init: Unable to open /dev/mem: %s
\n
"
,
strerror
(
errno
))
;
goto
exit
;
}
/* Base of the peripherals block is mapped to VM */
bcm2835_peripherals
=
mapmem
(
"gpio"
,
bcm2835_peripherals_size
,
memfd
,
(
uint32_t
)
bcm2835_peripherals_base
);
if
(
bcm2835_peripherals
==
MAP_FAILED
)
goto
exit
;
/* Now compute the base addresses of various peripherals,
// which are at fixed offsets within the mapped peripherals block
// Caution: bcm2835_peripherals is uint32_t*, so divide offsets by 4
*/
bcm2835_gpio
=
bcm2835_peripherals
+
BCM2835_GPIO_BASE
/
4
;
bcm2835_pwm
=
bcm2835_peripherals
+
BCM2835_GPIO_PWM
/
4
;
bcm2835_clk
=
bcm2835_peripherals
+
BCM2835_CLOCK_BASE
/
4
;
bcm2835_pads
=
bcm2835_peripherals
+
BCM2835_GPIO_PADS
/
4
;
bcm2835_spi0
=
bcm2835_peripherals
+
BCM2835_SPI0_BASE
/
4
;
bcm2835_bsc0
=
bcm2835_peripherals
+
BCM2835_BSC0_BASE
/
4
;
/* I2C */
bcm2835_bsc1
=
bcm2835_peripherals
+
BCM2835_BSC1_BASE
/
4
;
/* I2C */
bcm2835_st
=
bcm2835_peripherals
+
BCM2835_ST_BASE
/
4
;
ok
=
1
;
}
else
{
/* Not root, try /dev/gpiomem */
/* Open the master /dev/mem device */
if
((
memfd
=
open
(
"/dev/gpiomem"
,
O_RDWR
|
O_SYNC
)
)
<
0
)
{
fprintf
(
stderr
,
"bcm2835_init: Unable to open /dev/gpiomem: %s
\n
"
,
strerror
(
errno
))
;
goto
exit
;
}
/* Base of the peripherals block is mapped to VM */
bcm2835_peripherals_base
=
0
;
bcm2835_peripherals
=
mapmem
(
"gpio"
,
bcm2835_peripherals_size
,
memfd
,
(
uint32_t
)
bcm2835_peripherals_base
);
if
(
bcm2835_peripherals
==
MAP_FAILED
)
goto
exit
;
bcm2835_gpio
=
bcm2835_peripherals
;
ok
=
1
;
}
}
/* Base of the peripherals block is mapped to VM */
bcm2835_peripherals
=
mapmem
(
"gpio"
,
bcm2835_peripherals_size
,
memfd
,
(
uint32_t
)
bcm2835_peripherals_base
);
if
(
bcm2835_peripherals
==
MAP_FAILED
)
goto
exit
;
/* Now compute the base addresses of various peripherals,
// which are at fixed offsets within the mapped peripherals block
// Caution: bcm2835_peripherals is uint32_t*, so divide offsets by 4
*/
bcm2835_gpio
=
bcm2835_peripherals
+
BCM2835_GPIO_BASE
/
4
;
bcm2835_pwm
=
bcm2835_peripherals
+
BCM2835_GPIO_PWM
/
4
;
bcm2835_clk
=
bcm2835_peripherals
+
BCM2835_CLOCK_BASE
/
4
;
bcm2835_pads
=
bcm2835_peripherals
+
BCM2835_GPIO_PADS
/
4
;
bcm2835_spi0
=
bcm2835_peripherals
+
BCM2835_SPI0_BASE
/
4
;
bcm2835_bsc0
=
bcm2835_peripherals
+
BCM2835_BSC0_BASE
/
4
;
/* I2C */
bcm2835_bsc1
=
bcm2835_peripherals
+
BCM2835_BSC1_BASE
/
4
;
/* I2C */
bcm2835_st
=
bcm2835_peripherals
+
BCM2835_ST_BASE
/
4
;
ok
=
1
;
exit:
exit:
if
(
memfd
>=
0
)
if
(
memfd
>=
0
)
...
...
utility/RPi/bcm2835.h
View file @
9e717722
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
BCM 2835).
BCM 2835).
The version of the package that this documentation refers to can be downloaded
The version of the package that this documentation refers to can be downloaded
from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.
48
.tar.gz
from http://www.airspayce.com/mikem/bcm2835/bcm2835-1.
50
.tar.gz
You can find the latest version at http://www.airspayce.com/mikem/bcm2835
You can find the latest version at http://www.airspayce.com/mikem/bcm2835
Several example programs are provided.
Several example programs are provided.
...
@@ -38,7 +38,7 @@
...
@@ -38,7 +38,7 @@
Before asking a question or reporting a bug, please read http://www.catb.org/esr/faqs/smart-questions.html
Before asking a question or reporting a bug, please read http://www.catb.org/esr/faqs/smart-questions.html
Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
and Occidentalisv01
and Occidentalisv01
, 2016-02-09 Raspbian Jessie.
CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len()
CAUTION: it has been observed that when detect enables such as bcm2835_gpio_len()
are used and the pin is pulled LOW
are used and the pin is pulled LOW
it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
...
@@ -48,6 +48,24 @@
...
@@ -48,6 +48,24 @@
If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with
If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with
bcm2835_gpio_clr_len() and friends after use.
bcm2835_gpio_clr_len() and friends after use.
\par Running as root
Prior to the release of Raspbian Jessie in Feb 2016, access to any
peripheral device via /dev/mem on the RPi required the process to
run as root. Raspbian Jessie permits non-root users to access the
GPIO peripheral (only) via /dev/gpiomem, and this library supports
that limited mode of operation.
If the library runs with effective UID of 0 (ie root), then
bcm2835_init() will attempt to open /dev/mem, and, if successful, it
will permit use of all peripherals and library functions.
If the library runs with any other effective UID (ie not root), then
bcm2835_init() will attempt to open /dev/gpiomem, and, if
successful, will only permit GPIO operations. In particular,
bcm2835_spi_begin() and bcm2835_i2c_begin() will return false and all
other non-gpio operations may fail silently or crash.
\par Installation
\par Installation
This library consists of a single non-shared library and header file, which will be
This library consists of a single non-shared library and header file, which will be
...
@@ -421,6 +439,15 @@
...
@@ -421,6 +439,15 @@
Added patch from Eckhardt Ulrich that fixed problems that could cause hanging with bcm2835_i2c_read_register_rs
Added patch from Eckhardt Ulrich that fixed problems that could cause hanging with bcm2835_i2c_read_register_rs
and others.
and others.
\version 1.49 2016-01-05
Added patch from Jonathan Perkin with new functions bcm2835_gpio_eds_multi() and bcm2835_gpio_set_eds_multi().
\version 1.50 2016-02-28
Added support for running as non-root, permitting access to GPIO only. Functions
bcm2835_spi_begin() and bcm2835_i2c_begin() will now return 0 if not running as root
(which prevents access to the SPI and I2C peripherals, amongst others).
Testing on Raspbian Jessie.
\author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
\author Mike McCauley (mikem@airspayce.com) DO NOT CONTACT THE AUTHOR DIRECTLY: USE THE LISTS
*/
*/
...
@@ -431,7 +458,7 @@
...
@@ -431,7 +458,7 @@
#include <stdint.h>
#include <stdint.h>
#define BCM2835_VERSION 100
48
/* Version 1.48
*/
#define BCM2835_VERSION 100
50
/* Version 1.50
*/
/* RPi 2 is ARM v7, and has DMB instruction for memory barriers.
/* RPi 2 is ARM v7, and has DMB instruction for memory barriers.
Older RPis are ARM v6 and don't, so a coprocessor instruction must be used instead.
Older RPis are ARM v6 and don't, so a coprocessor instruction must be used instead.
...
@@ -503,7 +530,7 @@ extern uint32_t bcm2835_peripherals_size;
...
@@ -503,7 +530,7 @@ extern uint32_t bcm2835_peripherals_size;
extern
uint32_t
*
bcm2835_peripherals
;
extern
uint32_t
*
bcm2835_peripherals
;
/*! Base of the ST (System Timer) registers.
/*! Base of the ST (System Timer) registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_st
;
extern
volatile
uint32_t
*
bcm2835_st
;
...
@@ -513,32 +540,32 @@ extern volatile uint32_t *bcm2835_st;
...
@@ -513,32 +540,32 @@ extern volatile uint32_t *bcm2835_st;
extern
volatile
uint32_t
*
bcm2835_gpio
;
extern
volatile
uint32_t
*
bcm2835_gpio
;
/*! Base of the PWM registers.
/*! Base of the PWM registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_pwm
;
extern
volatile
uint32_t
*
bcm2835_pwm
;
/*! Base of the CLK registers.
/*! Base of the CLK registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_clk
;
extern
volatile
uint32_t
*
bcm2835_clk
;
/*! Base of the PADS registers.
/*! Base of the PADS registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_pads
;
extern
volatile
uint32_t
*
bcm2835_pads
;
/*! Base of the SPI0 registers.
/*! Base of the SPI0 registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_spi0
;
extern
volatile
uint32_t
*
bcm2835_spi0
;
/*! Base of the BSC0 registers.
/*! Base of the BSC0 registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_bsc0
;
extern
volatile
uint32_t
*
bcm2835_bsc0
;
/*! Base of the BSC1 registers.
/*! Base of the BSC1 registers.
Available after bcm2835_init has been called
Available after bcm2835_init has been called
(as root)
*/
*/
extern
volatile
uint32_t
*
bcm2835_bsc1
;
extern
volatile
uint32_t
*
bcm2835_bsc1
;
...
@@ -552,7 +579,7 @@ typedef enum
...
@@ -552,7 +579,7 @@ typedef enum
BCM2835_REGBASE_PWM
=
3
,
/*!< Base of the PWM registers. */
BCM2835_REGBASE_PWM
=
3
,
/*!< Base of the PWM registers. */
BCM2835_REGBASE_CLK
=
4
,
/*!< Base of the CLK registers. */
BCM2835_REGBASE_CLK
=
4
,
/*!< Base of the CLK registers. */
BCM2835_REGBASE_PADS
=
5
,
/*!< Base of the PADS registers. */
BCM2835_REGBASE_PADS
=
5
,
/*!< Base of the PADS registers. */
BCM2835_REGBASE_SPI0
=
6
,
/*! Base of the SPI0 registers. */
BCM2835_REGBASE_SPI0
=
6
,
/*!
<
Base of the SPI0 registers. */
BCM2835_REGBASE_BSC0
=
7
,
/*!< Base of the BSC0 registers. */
BCM2835_REGBASE_BSC0
=
7
,
/*!< Base of the BSC0 registers. */
BCM2835_REGBASE_BSC1
=
8
/*!< Base of the BSC1 registers. */
BCM2835_REGBASE_BSC1
=
8
/*!< Base of the BSC1 registers. */
}
bcm2835RegisterBase
;
}
bcm2835RegisterBase
;
...
@@ -826,7 +853,7 @@ typedef enum
...
@@ -826,7 +853,7 @@ typedef enum
Figures below give the divider, clock period and clock frequency.
Figures below give the divider, clock period and clock frequency.
Clock divided is based on nominal base clock rate of 250MHz
Clock divided is based on nominal base clock rate of 250MHz
It is reported that (contrary to the documentation) any even divider may used.
It is reported that (contrary to the documentation) any even divider may used.
The frequencies shown for each divider have been confirmed by measurement
The frequencies shown for each divider have been confirmed by measurement
.
*/
*/
typedef
enum
typedef
enum
{
{
...
@@ -1015,12 +1042,16 @@ extern "C" {
...
@@ -1015,12 +1042,16 @@ extern "C" {
@{
@{
*/
*/
/*! Initialise the library by opening /dev/mem and getting pointers to the
/*! Initialise the library by opening /dev/mem (if you are root)
or /dev/gpiomem (if you are not)
and getting pointers to the
internal memory for BCM 2835 device registers. You must call this (successfully)
internal memory for BCM 2835 device registers. You must call this (successfully)
before calling any other
before calling any other
functions in this library (except bcm2835_set_debug).
functions in this library (except bcm2835_set_debug).
If bcm2835_init() fails by returning 0,
If bcm2835_init() fails by returning 0,
calling any other function may result in crashes or other failures.
calling any other function may result in crashes or other failures.
If bcm2835_init() succeeds but you are not running as root, then only gpio operations
are permitted, and calling any other functions may result in crashes or other failures. .
Prints messages to stderr in case of errors.
Prints messages to stderr in case of errors.
\return 1 if successful else 0
\return 1 if successful else 0
*/
*/
...
@@ -1186,6 +1217,13 @@ extern "C" {
...
@@ -1186,6 +1217,13 @@ extern "C" {
*/
*/
extern
uint8_t
bcm2835_gpio_eds
(
uint8_t
pin
);
extern
uint8_t
bcm2835_gpio_eds
(
uint8_t
pin
);
/*! Same as bcm2835_gpio_eds() but checks if any of the pins specified in
the mask have detected a level or edge.
\param[in] mask Mask of pins to check. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
\return Mask of pins HIGH if the event detect status for the given pin is true.
*/
extern
uint32_t
bcm2835_gpio_eds_multi
(
uint32_t
mask
);
/*! Sets the Event Detect Status register for a given pin to 1,
/*! Sets the Event Detect Status register for a given pin to 1,
which has the effect of clearing the flag. Use this afer seeing
which has the effect of clearing the flag. Use this afer seeing
an Event Detect Status on the pin.
an Event Detect Status on the pin.
...
@@ -1193,6 +1231,12 @@ extern "C" {
...
@@ -1193,6 +1231,12 @@ extern "C" {
*/
*/
extern
void
bcm2835_gpio_set_eds
(
uint8_t
pin
);
extern
void
bcm2835_gpio_set_eds
(
uint8_t
pin
);
/*! Same as bcm2835_gpio_set_eds() but clears the flag for any pin which
is set in the mask.
\param[in] mask Mask of pins to clear. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
*/
extern
void
bcm2835_gpio_set_eds_multi
(
uint32_t
mask
);
/*! Enable Rising Edge Detect Enable for the specified pin.
/*! Enable Rising Edge Detect Enable for the specified pin.
When a rising edge is detected, sets the appropriate pin in Event Detect Status.
When a rising edge is detected, sets the appropriate pin in Event Detect Status.
The GPRENn registers use
The GPRENn registers use
...
@@ -1370,10 +1414,11 @@ extern "C" {
...
@@ -1370,10 +1414,11 @@ extern "C" {
Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
Forces RPi SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
to alternate function ALT0, which enables those pins for SPI interface.
to alternate function ALT0, which enables those pins for SPI interface.
You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
their default functions
their default functions
.
\sa bcm2835_spi_end()
\sa bcm2835_spi_end()
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
*/
*/
extern
void
bcm2835_spi_begin
(
void
);
extern
int
bcm2835_spi_begin
(
void
);
/*! End SPI operations.
/*! End SPI operations.
SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
...
@@ -1476,9 +1521,10 @@ extern "C" {
...
@@ -1476,9 +1521,10 @@ extern "C" {
to alternate function ALT0, which enables those pins for I2C interface.
to alternate function ALT0, which enables those pins for I2C interface.
You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to
You should call bcm2835_i2c_end() when all I2C functions are complete to return the pins to
their default functions
their default functions
\return 1 if successful, 0 otherwise (perhaps because you are not running as root)
\sa bcm2835_i2c_end()
\sa bcm2835_i2c_end()
*/
*/
extern
void
bcm2835_i2c_begin
(
void
);
extern
int
bcm2835_i2c_begin
(
void
);
/*! End I2C operations.
/*! End I2C operations.
I2C pins P1-03 (SDA) and P1-05 (SCL)
I2C pins P1-03 (SDA) and P1-05 (SCL)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment