RPi SPI functionality and RPi fix for startWrite
- Enabled use of hardware CS1 pin - Removed custom_cs code for software driven CSN - Modified BCM driver to allow use of hardware SPI pins not in use while SPI is active. - Updated constructor in examples
This commit is contained in:
@@ -37,4 +37,5 @@ Supported Boards:
|
||||
* Mega Types (2560, 1280, etc)
|
||||
* ARM (Arduino Due) via extended SPI methods
|
||||
* ATTiny 24/44/84 25/45/85
|
||||
* Raspberry Pi
|
||||
* See the [documentation](http://tmrh20.github.io/) for more info
|
||||
+85
-72
@@ -4,12 +4,12 @@
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
03/17/2013 : Charles-Henri Hallard (http://hallard.me)
|
||||
Modified to use with Arduipi board http://hallard.me/arduipi
|
||||
Changed to use modified bcm2835 library
|
||||
Changed to use modified bcm2835 library
|
||||
|
||||
TMRh20 2014: Updated to work with optimized RF24 and RF24 Network Arduino libs.
|
||||
*/
|
||||
@@ -53,7 +53,7 @@ uint8_t RF24::read_register(uint8_t reg)
|
||||
|
||||
*ptx++ = ( R_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
*ptx++ = NOP ; // Dummy operation, just for reading
|
||||
|
||||
|
||||
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
|
||||
|
||||
result = *++prx; // result is 2nd byte of receive buffer
|
||||
@@ -71,12 +71,12 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value)
|
||||
|
||||
*ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
*ptx = value ;
|
||||
|
||||
|
||||
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
|
||||
|
||||
|
||||
status = *prx++; // status is 1st byte of receive buffer
|
||||
|
||||
if (debug)
|
||||
if (debug)
|
||||
printf("write_register(%02x,%02x)\r\n",reg,value);
|
||||
|
||||
return status;
|
||||
@@ -90,7 +90,7 @@ uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
|
||||
uint8_t * prx = spi_rxbuff;
|
||||
uint8_t * ptx = spi_txbuff;
|
||||
uint8_t size = len + 1; // Add register value to transmit buffer
|
||||
|
||||
|
||||
*ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
while ( len-- )
|
||||
*ptx++ = *buf++;
|
||||
@@ -98,7 +98,7 @@ uint8_t RF24::write_register(uint8_t reg, const uint8_t* buf, uint8_t len)
|
||||
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
|
||||
|
||||
status = *prx; // status is 1st byte of receive buffer
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -110,15 +110,15 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp
|
||||
uint8_t status;
|
||||
uint8_t * prx = spi_rxbuff;
|
||||
uint8_t * ptx = spi_txbuff;
|
||||
uint8_t size ;
|
||||
|
||||
uint8_t size ;
|
||||
|
||||
const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
|
||||
|
||||
uint8_t data_len = min(len,payload_size);
|
||||
uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
|
||||
|
||||
|
||||
size = data_len + blank_len + 1 ; // Add register value to transmit buffer
|
||||
|
||||
|
||||
if (debug)
|
||||
printf("[Writing %u bytes %u blanks]",data_len,blank_len);
|
||||
|
||||
@@ -126,13 +126,13 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp
|
||||
while ( data_len-- )
|
||||
*ptx++ = *current++;
|
||||
while ( blank_len-- )
|
||||
*ptx++ = 0;
|
||||
*ptx++ = 0;
|
||||
|
||||
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
|
||||
|
||||
status = *prx; // status is 1st byte of receive buffer
|
||||
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -143,30 +143,30 @@ uint8_t RF24::read_payload(void* buf, uint8_t len)
|
||||
uint8_t status;
|
||||
uint8_t * prx = spi_rxbuff;
|
||||
uint8_t * ptx = spi_txbuff;
|
||||
uint8_t size ;
|
||||
|
||||
uint8_t size ;
|
||||
|
||||
uint8_t* current = reinterpret_cast<uint8_t*>(buf);
|
||||
|
||||
uint8_t data_len = min(len,payload_size);
|
||||
uint8_t blank_len = dynamic_payloads_enabled ? 0 : payload_size - data_len;
|
||||
|
||||
|
||||
size = data_len + blank_len + 1; // Add register value to transmit buffer
|
||||
|
||||
|
||||
if (debug)
|
||||
printf("[Reading %u bytes %u blanks]",data_len,blank_len);
|
||||
|
||||
|
||||
*ptx++ = R_RX_PAYLOAD;
|
||||
while(size--)
|
||||
*ptx++ = NOP;
|
||||
|
||||
|
||||
// Size has been lost during while, re affect
|
||||
size = data_len + blank_len + 1; // Add register value to transmit buffer
|
||||
|
||||
|
||||
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
|
||||
|
||||
|
||||
// 1st byte is status
|
||||
status = *prx++;
|
||||
|
||||
|
||||
// Decrement before to skip 1st status byte
|
||||
while ( --size )
|
||||
*current++ = *prx++;
|
||||
@@ -264,7 +264,7 @@ void RF24::print_address_register(const char* name, uint8_t reg, uint8_t qty)
|
||||
/****************************************************************************/
|
||||
|
||||
RF24::RF24(uint8_t _cepin, uint8_t _cspin, uint32_t _spi_speed):
|
||||
ce_pin(_cepin), csn_pin(_cspin), spi_speed(_spi_speed), wide_band(true), p_variant(false),
|
||||
ce_pin(_cepin), csn_pin(_cspin), spi_speed(_spi_speed), wide_band(true), p_variant(false),
|
||||
payload_size(32), dynamic_payloads_enabled(false),
|
||||
pipe0_reading_address(0)
|
||||
{
|
||||
@@ -324,7 +324,7 @@ static const char rf24_pa_dbm_e_str_0[] = "PA_MIN";
|
||||
static const char rf24_pa_dbm_e_str_1[] = "PA_LOW";
|
||||
static const char rf24_pa_dbm_e_str_2[] = "PA_HIGH";
|
||||
static const char rf24_pa_dbm_e_str_3[] = "PA_MAX";
|
||||
static const char * const rf24_pa_dbm_e_str_P[] = {
|
||||
static const char * const rf24_pa_dbm_e_str_P[] = {
|
||||
rf24_pa_dbm_e_str_0,
|
||||
rf24_pa_dbm_e_str_1,
|
||||
rf24_pa_dbm_e_str_2,
|
||||
@@ -335,7 +335,7 @@ static const char rf24_csn_e_str_0[] = "CE0 (PI Hardware Driven)";
|
||||
static const char rf24_csn_e_str_1[] = "CE1 (PI Hardware Driven)";
|
||||
static const char rf24_csn_e_str_2[] = "CE2 (PI Hardware Driven)";
|
||||
static const char rf24_csn_e_str_3[] = "Custom GPIO Software Driven";
|
||||
static const char * const rf24_csn_e_str_P[] = {
|
||||
static const char * const rf24_csn_e_str_P[] = {
|
||||
rf24_csn_e_str_0,
|
||||
rf24_csn_e_str_1,
|
||||
rf24_csn_e_str_2,
|
||||
@@ -352,13 +352,13 @@ void RF24::printDetails(void)
|
||||
printf("CSN Pin \t = %s\n",rf24_csn_e_str_P[csn_pin]);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("CSN Pin \t = Custom GPIO%d%s\n", csn_pin,
|
||||
{
|
||||
printf("CSN Pin \t = Custom GPIO%d%s\n", csn_pin,
|
||||
csn_pin==RPI_V2_GPIO_P1_26 ? " (CE1) Software Driven" : "" );
|
||||
}
|
||||
|
||||
|
||||
printf("CE Pin \t = Custom GPIO%d\n", ce_pin );
|
||||
|
||||
|
||||
// SPI Bus Speed
|
||||
printf("Clock Speed\t = " );
|
||||
switch (spi_speed)
|
||||
@@ -409,32 +409,45 @@ bool RF24::begin(void)
|
||||
{
|
||||
debug = false;
|
||||
//debug = true;
|
||||
// This initialize the SPI bus with
|
||||
// csn pin as chip select (custom or not)
|
||||
|
||||
|
||||
// Init BCM2835 chipset for talking with us
|
||||
if (!bcm2835_init()){
|
||||
return false;
|
||||
}
|
||||
// Initialise the CE pin of NRF24 (chip enable)
|
||||
bcm2835_gpio_fsel(ce_pin, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_write(ce_pin, LOW);
|
||||
|
||||
|
||||
switch(csn_pin){ //Ensure valid hardware CS pin
|
||||
case 0: break;
|
||||
case 1: break;
|
||||
case 8: csn_pin = 0; break;
|
||||
case 7: csn_pin = 1; break;
|
||||
default: csn_pin = 0; break;
|
||||
}
|
||||
|
||||
|
||||
bcm2835_spi_begin();
|
||||
|
||||
// used to drive custom I/O to trigger my logic analyser
|
||||
// bcm2835_gpio_fsel(GPIO_CTRL_PIN , BCM2835_GPIO_FSEL_OUTP);
|
||||
|
||||
// start the SPI library:
|
||||
// Note the NRF24 wants mode 0, MSB first and default to 1 Mbps
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
|
||||
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);
|
||||
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0);
|
||||
|
||||
// Set SPI bus Speed
|
||||
bcm2835_spi_setClockDivider(spi_speed);
|
||||
|
||||
if(csn_pin <= BCM2835_SPI_CS_NONE){
|
||||
bcm2835_spi_chipSelect(csn_pin);
|
||||
}
|
||||
// This initialize the SPI bus with
|
||||
// csn pin as chip select (custom or not)
|
||||
bcm2835_spi_begin(csn_pin);
|
||||
// Choose hardware CSN pin
|
||||
bcm2835_spi_chipSelect(csn_pin);
|
||||
|
||||
|
||||
// Initialise the CE pin of NRF24 (chip enable) after the CSN pin, so that
|
||||
// The input mode is not changed if using one of the hardware CE pins
|
||||
bcm2835_gpio_fsel(ce_pin, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_write(ce_pin, LOW);
|
||||
|
||||
// wait 100ms
|
||||
delay(100);
|
||||
@@ -453,14 +466,14 @@ bool RF24::begin(void)
|
||||
{
|
||||
p_variant = true ;
|
||||
}
|
||||
|
||||
|
||||
// Then set the data rate to the slowest (and most reliable) speed supported by all
|
||||
// hardware.
|
||||
setDataRate( RF24_1MBPS ) ;
|
||||
|
||||
// Initialize CRC and request 2-byte (16bit) CRC
|
||||
setCRCLength( RF24_CRC_16 ) ;
|
||||
|
||||
|
||||
// Reset current status
|
||||
// Notice reset and flush is the last thing we do
|
||||
write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
|
||||
@@ -479,7 +492,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 )
|
||||
// PTX should use only 22uA of power
|
||||
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -501,7 +514,7 @@ void RF24::startListening(void)
|
||||
|
||||
// Go!
|
||||
bcm2835_gpio_write(ce_pin, HIGH);
|
||||
|
||||
|
||||
// wait for the radio to come up (130us actually only needed)
|
||||
//delayMicroseconds(130);
|
||||
}
|
||||
@@ -514,7 +527,7 @@ void RF24::stopListening(void)
|
||||
flush_tx();
|
||||
flush_rx();
|
||||
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -528,7 +541,7 @@ void RF24::powerDown(void)
|
||||
/****************************************************************************/
|
||||
|
||||
void RF24::powerUp(void)
|
||||
{
|
||||
{
|
||||
bool up = read_register(CONFIG) & _BV(PWR_UP);
|
||||
|
||||
if(! up ){
|
||||
@@ -536,7 +549,7 @@ void RF24::powerUp(void)
|
||||
delay(5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
@@ -544,13 +557,13 @@ void RF24::powerUp(void)
|
||||
bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
|
||||
|
||||
// Begin the write
|
||||
startWrite(buf,len, multicast);
|
||||
startFastWrite(buf,len, multicast);
|
||||
|
||||
|
||||
//Wait until complete or failed
|
||||
// If this hangs, it ain't coming back, no sense in timing out
|
||||
while( ! ( get_status() & ( _BV(TX_DS) | _BV(MAX_RT) ))) { }
|
||||
|
||||
|
||||
|
||||
uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
|
||||
bcm2835_gpio_write(ce_pin, LOW);
|
||||
@@ -566,7 +579,7 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
|
||||
|
||||
bool RF24::write( const void* buf, uint8_t len ){
|
||||
return write(buf,len,0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -600,7 +613,7 @@ bool RF24::writeBlocking( const void* buf, uint8_t len, uint32_t timeout )
|
||||
void RF24::reUseTX(){
|
||||
write_register(STATUS,_BV(MAX_RT) ); //Clear max retry flag
|
||||
//spiTrans( REUSE_TX_PL );
|
||||
bcm2835_spi_transfer( REUSE_TX_PL);
|
||||
bcm2835_spi_transfer( REUSE_TX_PL);
|
||||
bcm2835_gpio_write(ce_pin, LOW); //Re-Transfer packet
|
||||
bcm2835_gpio_write(ce_pin, HIGH);
|
||||
}
|
||||
@@ -648,18 +661,18 @@ void RF24::startFastWrite( const void* buf, uint8_t len, const bool multicast){
|
||||
bcm2835_gpio_write(ce_pin, HIGH);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
void RF24::startWrite( const void* buf, uint8_t len, const bool multicast )
|
||||
{
|
||||
|
||||
// Send the payload
|
||||
|
||||
write_payload( buf, len,multicast ? W_TX_PAYLOAD_NO_ACK : W_TX_PAYLOAD ) ;
|
||||
|
||||
bcm2835_gpio_write(ce_pin, HIGH);
|
||||
//bcm2835_gpio_write(ce_pin, LOW);
|
||||
|
||||
delayMicroseconds(10);
|
||||
bcm2835_gpio_write(ce_pin, LOW);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
@@ -736,7 +749,7 @@ bool RF24::available(uint8_t* pipe_num)
|
||||
//Check the FIFO buffer to see if data is waitng to be read
|
||||
|
||||
if (!( read_register(FIFO_STATUS) & _BV(RX_EMPTY) )){
|
||||
|
||||
|
||||
|
||||
// If the caller wants the pipe number, include that
|
||||
if ( pipe_num ){
|
||||
@@ -840,12 +853,12 @@ void RF24::toggle_features(void)
|
||||
|
||||
void RF24::enableDynamicPayloads(void)
|
||||
{
|
||||
|
||||
|
||||
// So enable them and try again
|
||||
toggle_features();
|
||||
write_register(FEATURE,read_register(FEATURE) | _BV(EN_DPL) );
|
||||
|
||||
if (debug)
|
||||
if (debug)
|
||||
printf("FEATURE=%i\r\n",read_register(FEATURE));
|
||||
|
||||
// Enable dynamic payload on all pipes
|
||||
@@ -900,14 +913,14 @@ void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
|
||||
{
|
||||
|
||||
uint8_t * ptx = spi_txbuff;
|
||||
uint8_t size ;
|
||||
|
||||
uint8_t size ;
|
||||
|
||||
const uint8_t* current = reinterpret_cast<const uint8_t*>(buf);
|
||||
|
||||
uint8_t data_len = min(len,payload_size);
|
||||
|
||||
|
||||
size = data_len + 1 ; // Add register value to transmit buffer
|
||||
|
||||
|
||||
if (debug){
|
||||
printf("[Writing %u bytes]",data_len);
|
||||
}
|
||||
@@ -917,9 +930,9 @@ void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
|
||||
}
|
||||
bcm2835_spi_transfern( (char *) spi_txbuff, size);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
bool RF24::isAckPayloadAvailable(void)
|
||||
@@ -1053,7 +1066,7 @@ rf24_datarate_e RF24::getDataRate( void )
|
||||
{
|
||||
rf24_datarate_e result ;
|
||||
uint8_t dr = read_register(RF_SETUP) & (_BV(RF_DR_LOW) | _BV(RF_DR_HIGH));
|
||||
|
||||
|
||||
// switch uses RAM (evil!)
|
||||
// Order matters in our case below
|
||||
if ( dr == _BV(RF_DR_LOW) )
|
||||
@@ -1079,11 +1092,11 @@ rf24_datarate_e RF24::getDataRate( void )
|
||||
void RF24::setCRCLength(rf24_crclength_e length)
|
||||
{
|
||||
uint8_t config = read_register(CONFIG) & ~( _BV(CRCO) | _BV(EN_CRC)) ;
|
||||
|
||||
|
||||
// switch uses RAM (evil!)
|
||||
if ( length == RF24_CRC_DISABLED )
|
||||
{
|
||||
// Do nothing, we turned it off above.
|
||||
// Do nothing, we turned it off above.
|
||||
}
|
||||
else if ( length == RF24_CRC_8 )
|
||||
{
|
||||
|
||||
+93
-145
@@ -59,7 +59,7 @@ static uint8_t debug = 0;
|
||||
static int i2c_byte_wait_us = 0;
|
||||
|
||||
// SPI Custom Chip Select Pin
|
||||
static int spi_custom_cs = 0;
|
||||
//static int spi_custom_cs = 0;
|
||||
|
||||
// Time for millis()
|
||||
static unsigned long long epoch ;
|
||||
@@ -365,7 +365,7 @@ void bcm2835_gpio_set_pad(uint8_t group, uint32_t control)
|
||||
void bcm2835_delay(unsigned int millis)
|
||||
{
|
||||
struct timespec sleeper;
|
||||
|
||||
|
||||
sleeper.tv_sec = (time_t)(millis / 1000);
|
||||
sleeper.tv_nsec = (long)(millis % 1000) * 1000000;
|
||||
nanosleep(&sleeper, NULL);
|
||||
@@ -376,18 +376,18 @@ void bcm2835_delayMicroseconds(uint64_t micros)
|
||||
{
|
||||
struct timespec t1;
|
||||
uint64_t start;
|
||||
|
||||
|
||||
// Calling nanosleep() takes at least 100-200 us, so use it for
|
||||
// long waits and use a busy wait on the System Timer for the rest.
|
||||
start = bcm2835_st_read();
|
||||
|
||||
|
||||
if (micros > 450)
|
||||
{
|
||||
t1.tv_sec = 0;
|
||||
t1.tv_nsec = 1000 * (long)(micros - 200);
|
||||
nanosleep(&t1, NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bcm2835_st_delay(start, micros);
|
||||
}
|
||||
|
||||
@@ -460,91 +460,31 @@ void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud)
|
||||
bcm2835_gpio_pudclk(pin, 0);
|
||||
}
|
||||
|
||||
void bcm2835_spi_begin(uint8_t cs)
|
||||
void bcm2835_spi_begin()
|
||||
{
|
||||
/*
|
||||
|
||||
// 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
|
||||
|
||||
// Enable CE0 by default, will be disabled if bcm2835_chipSelect() is called using another pin
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0
|
||||
|
||||
|
||||
|
||||
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); // MISO
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); // MOSI
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); // CLK
|
||||
|
||||
|
||||
// Set the SPI CS register to the some sensible defaults
|
||||
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
|
||||
bcm2835_peri_write(paddr, 0); // All 0s
|
||||
|
||||
|
||||
// Clear TX and RX fifos
|
||||
bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
|
||||
*/
|
||||
|
||||
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
|
||||
// Set the SPI0 pins to the Alt 0 function to enable SPI0 access on them
|
||||
// except if we need custom Chip Select Pin
|
||||
// printf("bcm2835_spi_begin -> spi_custom_cs = %d \n",cs );
|
||||
|
||||
// Do we need custom chip select control or
|
||||
// drive CE1 manually (because CE1 does not work with hardware)
|
||||
if ( cs > BCM2835_SPI_CS_NONE || cs == BCM2835_SPI_CS1 )
|
||||
{
|
||||
// indicate we will use a custom GPIO port
|
||||
spi_custom_cs = cs ;
|
||||
|
||||
// ok hard CE1 not working, drive it manually
|
||||
if (cs == BCM2835_SPI_CS1 )
|
||||
{
|
||||
// Dirty Hack CE1 in now custom Chip Select GPIO 26
|
||||
// the real CE1 pin
|
||||
spi_custom_cs = RPI_GPIO_P1_26 ;
|
||||
|
||||
bcm2835_gpio_fsel(spi_custom_cs, BCM2835_GPIO_FSEL_OUTP);
|
||||
bcm2835_gpio_write(spi_custom_cs, HIGH);
|
||||
}
|
||||
|
||||
// Mask in we use custom CS (not sure it has a real effect)
|
||||
bcm2835_peri_set_bits(paddr, BCM2835_SPI_CS_NONE, BCM2835_SPI0_CS_CS);
|
||||
}
|
||||
// Ok hardware driving of chip select
|
||||
else
|
||||
{
|
||||
// Just in case
|
||||
spi_custom_cs = 0 ;
|
||||
|
||||
// Mask in the CS bits of CS
|
||||
bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS);
|
||||
}
|
||||
|
||||
// Now we can drive the I/O as asked
|
||||
if (spi_custom_cs == 0)
|
||||
{
|
||||
// Not custom CS, so hardware driven
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1
|
||||
}
|
||||
else
|
||||
{
|
||||
// so set custom CS as output, High level by default
|
||||
bcm2835_gpio_fsel(spi_custom_cs, BCM2835_GPIO_FSEL_OUTP); // Custom GPIO
|
||||
bcm2835_gpio_write(spi_custom_cs, HIGH);
|
||||
}
|
||||
|
||||
// Classic pin, hardware driven
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_ALT0); // MISO
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_ALT0); // MOSI
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_ALT0); // CLK
|
||||
|
||||
// Set the SPI CS register to the some sensible defaults
|
||||
bcm2835_peri_write(paddr, 0); // All 0s
|
||||
|
||||
// Clear TX and RX fifos
|
||||
bcm2835_peri_write_nb(paddr, BCM2835_SPI0_CS_CLEAR);
|
||||
}
|
||||
|
||||
void bcm2835_spi_end(void)
|
||||
{
|
||||
// Set all the SPI0 pins back to input
|
||||
{
|
||||
/* // Set all the SPI0 pins back to input
|
||||
if (spi_custom_cs == 0)
|
||||
{
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); // CE1
|
||||
@@ -557,26 +497,25 @@ void bcm2835_spi_end(void)
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); // MISO
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); // MOSI
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); // CLK
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
// Set all the SPI0 pins back to input
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_INPT); // CE1
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); // CE0
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_21, BCM2835_GPIO_FSEL_INPT); // MISO
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_19, BCM2835_GPIO_FSEL_INPT); // MOSI
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_23, BCM2835_GPIO_FSEL_INPT); // CLK
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
// Drive Custom chip select pin
|
||||
void bcm2835_spi_setChipSelect(uint8_t level)
|
||||
{
|
||||
// Do this only if we are using custom ChipSelect I/O
|
||||
if ( spi_custom_cs > BCM2835_SPI_CS_NONE )
|
||||
bcm2835_gpio_write(spi_custom_cs, level);
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
void bcm2835_spi_setBitOrder(uint8_t order)
|
||||
@@ -606,14 +545,15 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
|
||||
{
|
||||
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
|
||||
volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
|
||||
|
||||
|
||||
// Custom chip select LOW
|
||||
if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
/*if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
bcm2835_spi_setChipSelect(LOW);
|
||||
}
|
||||
}*/
|
||||
|
||||
// This is Polled transfer as per section 10.6.1
|
||||
// BUG ALERT: what happens if we get interupted in this section, and someone else
|
||||
// accesses a different peripheral?
|
||||
// accesses a different peripheral?
|
||||
// Clear TX and RX fifos
|
||||
bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
|
||||
|
||||
@@ -640,9 +580,9 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
|
||||
bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
|
||||
|
||||
// Custom chip select HIGH
|
||||
if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
bcm2835_spi_setChipSelect(HIGH);
|
||||
}
|
||||
//if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
// bcm2835_spi_setChipSelect(HIGH);
|
||||
//}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -656,7 +596,7 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
|
||||
|
||||
// This is Polled transfer as per section 10.6.1
|
||||
// BUG ALERT: what happens if we get interupted in this section, and someone else
|
||||
// accesses a different peripheral?
|
||||
// accesses a different peripheral?
|
||||
|
||||
// Clear TX and RX fifos
|
||||
bcm2835_peri_set_bits(paddr, BCM2835_SPI0_CS_CLEAR, BCM2835_SPI0_CS_CLEAR);
|
||||
@@ -696,9 +636,9 @@ void bcm2835_spi_writenb(char* tbuf, uint32_t len)
|
||||
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
|
||||
volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
|
||||
|
||||
if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
bcm2835_spi_setChipSelect(LOW);
|
||||
}
|
||||
//if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
// bcm2835_spi_setChipSelect(LOW);
|
||||
//}
|
||||
// This is Polled transfer as per section 10.6.1
|
||||
// BUG ALERT: what happens if we get interupted in this section, and someone else
|
||||
// accesses a different peripheral?
|
||||
@@ -715,15 +655,15 @@ void bcm2835_spi_writenb(char* tbuf, uint32_t len)
|
||||
// Maybe wait for TXD
|
||||
while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))
|
||||
;
|
||||
|
||||
|
||||
// Write to FIFO, no barrier
|
||||
bcm2835_peri_write_nb(fifo, tbuf[i]);
|
||||
|
||||
|
||||
// Read from FIFO to prevent stalling
|
||||
while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)
|
||||
(void) bcm2835_peri_read_nb(fifo);
|
||||
}
|
||||
|
||||
|
||||
// Wait for DONE to be set
|
||||
while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)) {
|
||||
while (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD)
|
||||
@@ -732,10 +672,10 @@ void bcm2835_spi_writenb(char* tbuf, uint32_t len)
|
||||
|
||||
// Set TA = 0, and also set the barrier
|
||||
bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
|
||||
|
||||
if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
bcm2835_spi_setChipSelect(HIGH);
|
||||
}
|
||||
|
||||
//if(spi_custom_cs > BCM2835_SPI_CS_NONE){
|
||||
// bcm2835_spi_setChipSelect(HIGH);
|
||||
//}
|
||||
}
|
||||
|
||||
// Writes (and reads) an number of bytes to SPI
|
||||
@@ -748,6 +688,14 @@ void bcm2835_spi_transfern(char* buf, uint32_t len)
|
||||
void bcm2835_spi_chipSelect(uint8_t cs)
|
||||
{
|
||||
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
|
||||
|
||||
if(cs){
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_26, BCM2835_GPIO_FSEL_ALT0); // CE1
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_INPT); // Revert default of CE0 back to input
|
||||
}else{
|
||||
bcm2835_gpio_fsel(RPI_GPIO_P1_24, BCM2835_GPIO_FSEL_ALT0); // CE0
|
||||
}
|
||||
|
||||
// Mask in the CS bits of CS
|
||||
bcm2835_peri_set_bits(paddr, cs, BCM2835_SPI0_CS_CS);
|
||||
}
|
||||
@@ -772,7 +720,7 @@ void bcm2835_i2c_begin(void)
|
||||
// Set the I2C/BSC1 pins to the Alt 0 function to enable I2C access on them
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_03, BCM2835_GPIO_FSEL_ALT0); // SDA
|
||||
bcm2835_gpio_fsel(RPI_V2_GPIO_P1_05, BCM2835_GPIO_FSEL_ALT0); // SCL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Read the clock divider register
|
||||
uint16_t cdiv = bcm2835_peri_read(paddr);
|
||||
@@ -800,7 +748,7 @@ void bcm2835_i2c_setSlaveAddress(uint8_t addr)
|
||||
// Set I2C Device Address
|
||||
#ifdef I2C_V1
|
||||
volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_A/4;
|
||||
#else
|
||||
#else
|
||||
volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_A/4;
|
||||
#endif
|
||||
bcm2835_peri_write(paddr, addr);
|
||||
@@ -815,7 +763,7 @@ void bcm2835_i2c_setClockDivider(uint16_t divider)
|
||||
volatile uint32_t* paddr = bcm2835_bsc0 + BCM2835_BSC_DIV/4;
|
||||
#else
|
||||
volatile uint32_t* paddr = bcm2835_bsc1 + BCM2835_BSC_DIV/4;
|
||||
#endif
|
||||
#endif
|
||||
bcm2835_peri_write(paddr, divider);
|
||||
// Calculate time for transmitting one byte
|
||||
// 1000000 = micros seconds in a second
|
||||
@@ -845,7 +793,7 @@ uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
|
||||
volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
|
||||
volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
|
||||
volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32_t remaining = len;
|
||||
uint32_t i = 0;
|
||||
@@ -864,10 +812,10 @@ uint8_t bcm2835_i2c_write(const char * buf, uint32_t len)
|
||||
i++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
|
||||
// Enable device and start transfer
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
|
||||
|
||||
|
||||
// Transfer is over when BCM2835_BSC_S_DONE
|
||||
while(!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE ))
|
||||
{
|
||||
@@ -916,7 +864,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
|
||||
volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
|
||||
volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
|
||||
volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32_t remaining = len;
|
||||
uint32_t i = 0;
|
||||
@@ -930,7 +878,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
|
||||
bcm2835_peri_write_nb(dlen, len);
|
||||
// Start read
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ);
|
||||
|
||||
|
||||
// wait for transfer to complete
|
||||
while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE))
|
||||
{
|
||||
@@ -943,7 +891,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transfer has finished - grab any remaining stuff in FIFO
|
||||
while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD))
|
||||
{
|
||||
@@ -952,7 +900,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
|
||||
i++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
|
||||
// Received a NACK
|
||||
if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
|
||||
{
|
||||
@@ -979,7 +927,7 @@ uint8_t bcm2835_i2c_read(char* buf, uint32_t len)
|
||||
// Read an number of bytes from I2C sending a repeated start after writing
|
||||
// the required register. Only works if your device supports this mode
|
||||
uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
{
|
||||
{
|
||||
#ifdef I2C_V1
|
||||
volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
|
||||
volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
|
||||
@@ -990,11 +938,11 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
|
||||
volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
|
||||
volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
|
||||
#endif
|
||||
#endif
|
||||
uint32_t remaining = len;
|
||||
uint32_t i = 0;
|
||||
uint8_t reason = BCM2835_I2C_REASON_OK;
|
||||
|
||||
|
||||
// Clear FIFO
|
||||
bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
|
||||
// Clear Status
|
||||
@@ -1005,7 +953,7 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN);
|
||||
bcm2835_peri_write_nb(fifo, regaddr[0]);
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
|
||||
|
||||
|
||||
// poll for transfer has started
|
||||
while ( !( bcm2835_peri_read_nb(status) & BCM2835_BSC_S_TA ) )
|
||||
{
|
||||
@@ -1013,14 +961,14 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
// Send a repeated start with read bit set in address
|
||||
bcm2835_peri_write_nb(dlen, len);
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ );
|
||||
|
||||
// Wait for write to complete and first byte back.
|
||||
|
||||
// Wait for write to complete and first byte back.
|
||||
bcm2835_delayMicroseconds(i2c_byte_wait_us * 3);
|
||||
|
||||
|
||||
// wait for transfer to complete
|
||||
while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE))
|
||||
{
|
||||
@@ -1033,7 +981,7 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transfer has finished - grab any remaining stuff in FIFO
|
||||
while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD))
|
||||
{
|
||||
@@ -1042,7 +990,7 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
i++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
|
||||
// Received a NACK
|
||||
if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
|
||||
{
|
||||
@@ -1066,10 +1014,10 @@ uint8_t bcm2835_i2c_read_register_rs(char* regaddr, char* buf, uint32_t len)
|
||||
return reason;
|
||||
}
|
||||
|
||||
// Sending an arbitrary number of bytes before issuing a repeated start
|
||||
// Sending an arbitrary number of bytes before issuing a repeated start
|
||||
// (with no prior stop) and reading a response. Some devices require this behavior.
|
||||
uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint32_t buf_len)
|
||||
{
|
||||
{
|
||||
#ifdef I2C_V1
|
||||
volatile uint32_t* dlen = bcm2835_bsc0 + BCM2835_BSC_DLEN/4;
|
||||
volatile uint32_t* fifo = bcm2835_bsc0 + BCM2835_BSC_FIFO/4;
|
||||
@@ -1080,12 +1028,12 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
volatile uint32_t* fifo = bcm2835_bsc1 + BCM2835_BSC_FIFO/4;
|
||||
volatile uint32_t* status = bcm2835_bsc1 + BCM2835_BSC_S/4;
|
||||
volatile uint32_t* control = bcm2835_bsc1 + BCM2835_BSC_C/4;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint32_t remaining = cmds_len;
|
||||
uint32_t i = 0;
|
||||
uint8_t reason = BCM2835_I2C_REASON_OK;
|
||||
|
||||
|
||||
// Clear FIFO
|
||||
bcm2835_peri_set_bits(control, BCM2835_BSC_C_CLEAR_1 , BCM2835_BSC_C_CLEAR_1 );
|
||||
|
||||
@@ -1094,7 +1042,7 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
|
||||
// Set Data Length
|
||||
bcm2835_peri_write_nb(dlen, cmds_len);
|
||||
|
||||
|
||||
// pre populate FIFO with max buffer
|
||||
while( remaining && ( i < BCM2835_BSC_FIFO_SIZE ) )
|
||||
{
|
||||
@@ -1103,9 +1051,9 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
remaining--;
|
||||
}
|
||||
|
||||
// Enable device and start transfer
|
||||
// Enable device and start transfer
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST);
|
||||
|
||||
|
||||
// poll for transfer has started (way to do repeated start, from BCM2835 datasheet)
|
||||
while ( !( bcm2835_peri_read_nb(status) & BCM2835_BSC_S_TA ) )
|
||||
{
|
||||
@@ -1113,17 +1061,17 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
if(bcm2835_peri_read(status) & BCM2835_BSC_S_DONE)
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
remaining = buf_len;
|
||||
i = 0;
|
||||
|
||||
// Send a repeated start with read bit set in address
|
||||
bcm2835_peri_write_nb(dlen, buf_len);
|
||||
bcm2835_peri_write_nb(control, BCM2835_BSC_C_I2CEN | BCM2835_BSC_C_ST | BCM2835_BSC_C_READ );
|
||||
|
||||
// Wait for write to complete and first byte back.
|
||||
|
||||
// Wait for write to complete and first byte back.
|
||||
bcm2835_delayMicroseconds(i2c_byte_wait_us * (cmds_len + 1));
|
||||
|
||||
|
||||
// wait for transfer to complete
|
||||
while (!(bcm2835_peri_read_nb(status) & BCM2835_BSC_S_DONE))
|
||||
{
|
||||
@@ -1136,7 +1084,7 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// transfer has finished - grab any remaining stuff in FIFO
|
||||
while (remaining && (bcm2835_peri_read_nb(status) & BCM2835_BSC_S_RXD))
|
||||
{
|
||||
@@ -1145,7 +1093,7 @@ uint8_t bcm2835_i2c_write_read_rs(char* cmds, uint32_t cmds_len, char* buf, uint
|
||||
i++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
|
||||
// Received a NACK
|
||||
if (bcm2835_peri_read(status) & BCM2835_BSC_S_ERR)
|
||||
{
|
||||
@@ -1202,7 +1150,7 @@ void bcm2835_pwm_set_clock(uint32_t divisor)
|
||||
bcm2835_delay(110); // Prevents clock going slow
|
||||
// Wait for the clock to be not busy
|
||||
while ((bcm2835_peri_read(bcm2835_clk + BCM2835_PWMCLK_CNTL) & 0x80) != 0)
|
||||
bcm2835_delay(1);
|
||||
bcm2835_delay(1);
|
||||
// set the clock divider and enable PWM clock
|
||||
bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_DIV, BCM2835_PWM_PASSWRD | (divisor << 12));
|
||||
bcm2835_peri_write(bcm2835_clk + BCM2835_PWMCLK_CNTL, BCM2835_PWM_PASSWRD | 0x11); // Source=osc and enable
|
||||
@@ -1288,7 +1236,7 @@ int bcm2835_init(void)
|
||||
{
|
||||
struct timeval tv ;
|
||||
|
||||
if (debug)
|
||||
if (debug)
|
||||
{
|
||||
bcm2835_pads = (uint32_t*)BCM2835_GPIO_PADS;
|
||||
bcm2835_clk = (uint32_t*)BCM2835_CLOCK_BASE;
|
||||
@@ -1303,13 +1251,13 @@ int bcm2835_init(void)
|
||||
int memfd = -1;
|
||||
int ok = 0;
|
||||
// Open the master /dev/memory device
|
||||
if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
|
||||
if ((memfd = open("/dev/mem", O_RDWR | O_SYNC) ) < 0)
|
||||
{
|
||||
fprintf(stderr, "bcm2835_init: Unable to open /dev/mem: %s\n",
|
||||
strerror(errno)) ;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
|
||||
// GPIO:
|
||||
bcm2835_gpio = (volatile uint32_t *)mapmem("gpio", BCM2835_BLOCK_SIZE, memfd, BCM2835_GPIO_BASE);
|
||||
if (bcm2835_gpio == MAP_FAILED) goto exit;
|
||||
@@ -1321,10 +1269,10 @@ int bcm2835_init(void)
|
||||
// Clock control (needed for PWM)
|
||||
bcm2835_clk = (volatile uint32_t *)mapmem("clk", BCM2835_BLOCK_SIZE, memfd, BCM2835_CLOCK_BASE);
|
||||
if (bcm2835_clk == MAP_FAILED) goto exit;
|
||||
|
||||
|
||||
bcm2835_pads = (volatile uint32_t *)mapmem("pads", BCM2835_BLOCK_SIZE, memfd, BCM2835_GPIO_PADS);
|
||||
if (bcm2835_pads == MAP_FAILED) goto exit;
|
||||
|
||||
|
||||
bcm2835_spi0 = (volatile uint32_t *)mapmem("spi0", BCM2835_BLOCK_SIZE, memfd, BCM2835_SPI0_BASE);
|
||||
if (bcm2835_spi0 == MAP_FAILED) goto exit;
|
||||
|
||||
@@ -1367,10 +1315,10 @@ int bcm2835_close(void)
|
||||
unmapmem((void**) &bcm2835_st, BCM2835_BLOCK_SIZE);
|
||||
unmapmem((void**) &bcm2835_pads, BCM2835_BLOCK_SIZE);
|
||||
return 1; // Success
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef BCM2835_TEST
|
||||
// this is a simple test program that prints out what it will do rather than
|
||||
// this is a simple test program that prints out what it will do rather than
|
||||
// actually doing it
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@@ -1398,13 +1346,13 @@ int main(int argc, char **argv)
|
||||
{
|
||||
// Turn it on
|
||||
bcm2835_gpio_write(RPI_GPIO_P1_11, HIGH);
|
||||
|
||||
|
||||
// wait a bit
|
||||
bcm2835_delay(500);
|
||||
|
||||
|
||||
// turn it off
|
||||
bcm2835_gpio_write(RPI_GPIO_P1_11, LOW);
|
||||
|
||||
|
||||
// wait a bit
|
||||
bcm2835_delay(500);
|
||||
}
|
||||
@@ -1417,7 +1365,7 @@ int main(int argc, char **argv)
|
||||
// Read some data
|
||||
uint8_t value = bcm2835_gpio_lev(RPI_GPIO_P1_15);
|
||||
printf("read from pin 15: %d\n", value);
|
||||
|
||||
|
||||
// wait a bit
|
||||
bcm2835_delay(500);
|
||||
}
|
||||
|
||||
+127
-127
@@ -16,7 +16,7 @@
|
||||
//
|
||||
/// \mainpage C library for Broadcom BCM 2835 as used in Raspberry Pi
|
||||
///
|
||||
/// This is a C library for Raspberry Pi (RPi). It provides access to
|
||||
/// This is a C library for Raspberry Pi (RPi). It provides access to
|
||||
/// GPIO and other IO functions on the Broadcom BCM 2835 chip,
|
||||
/// allowing access to the GPIO pins on the
|
||||
/// 26 pin IDE plug on the RPi board so you can control and interface with various external devices.
|
||||
@@ -25,34 +25,34 @@
|
||||
/// and for accessing the system timers.
|
||||
/// Pin event detection is supported by polling (interrupts are not supported).
|
||||
///
|
||||
/// It is C++ compatible, and installs as a header file and non-shared library on
|
||||
/// any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with
|
||||
/// It is C++ compatible, and installs as a header file and non-shared library on
|
||||
/// any Linux-based distro (but clearly is no use except on Raspberry Pi or another board with
|
||||
/// 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.36.tar.gz
|
||||
/// You can find the latest version at http://www.airspayce.com/mikem/bcm2835
|
||||
///
|
||||
/// Several example programs are provided.
|
||||
///
|
||||
/// Based on data in http://elinux.org/RPi_Low-level_peripherals and
|
||||
/// Based on data in http://elinux.org/RPi_Low-level_peripherals and
|
||||
/// http://www.raspberrypi.org/wp-content/uploads/2012/02/BCM2835-ARM-Peripherals.pdf
|
||||
/// and http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
|
||||
///
|
||||
/// You can also find online help and discussion at http://groups.google.com/group/bcm2835
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Please use that group for all questions and discussions on this topic.
|
||||
/// Do not contact the author directly, unless it is to discuss commercial licensing.
|
||||
///
|
||||
/// Tested on debian6-19-04-2012, 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
|
||||
/// and Occidentalisv01
|
||||
/// 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
|
||||
/// it can cause temporary hangs on 2012-07-15-wheezy-raspbian, 2013-07-26-wheezy-raspbian
|
||||
/// and Occidentalisv01.
|
||||
/// Reason for this is not yet determined, but we suspect that an interrupt handler is
|
||||
/// hitting a hard loop on those OSs.
|
||||
/// If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with
|
||||
/// bcm2835_gpio_clr_len() and friends after use.
|
||||
/// If you must use bcm2835_gpio_len() and friends, make sure you disable the pins with
|
||||
/// bcm2835_gpio_clr_len() and friends after use.
|
||||
///
|
||||
/// \par Installation
|
||||
///
|
||||
@@ -71,10 +71,10 @@
|
||||
///
|
||||
/// \par Physical Addresses
|
||||
///
|
||||
/// The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits()
|
||||
/// The functions bcm2835_peri_read(), bcm2835_peri_write() and bcm2835_peri_set_bits()
|
||||
/// are low level peripheral register access functions. They are designed to use
|
||||
/// physical addresses as described in section 1.2.3 ARM physical addresses
|
||||
/// of the BCM2835 ARM Peripherals manual.
|
||||
/// of the BCM2835 ARM Peripherals manual.
|
||||
/// Physical addresses range from 0x20000000 to 0x20FFFFFF for peripherals. The bus
|
||||
/// addresses for peripherals are set up to map onto the peripheral bus address range starting at
|
||||
/// 0x7E000000. Thus a peripheral advertised in the manual at bus address 0x7Ennnnnn is available at
|
||||
@@ -93,37 +93,37 @@
|
||||
///
|
||||
/// \par Pin Numbering
|
||||
///
|
||||
/// The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying
|
||||
/// The GPIO pin numbering as used by RPi is different to and inconsistent with the underlying
|
||||
/// BCM 2835 chip pin numbering. http://elinux.org/RPi_BCM2835_GPIOs
|
||||
///
|
||||
///
|
||||
/// RPi has a 26 pin IDE header that provides access to some of the GPIO pins on the BCM 2835,
|
||||
/// as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the
|
||||
/// as well as power and ground pins. Not all GPIO pins on the BCM 2835 are available on the
|
||||
/// IDE header.
|
||||
///
|
||||
/// RPi Version 2 also has a P5 connector with 4 GPIO pins, 5V, 3.3V and Gnd.
|
||||
///
|
||||
/// The functions in this library are designed to be passed the BCM 2835 GPIO pin number and _not_
|
||||
/// The functions in this library are designed to be passed the BCM 2835 GPIO pin number and _not_
|
||||
/// the RPi pin number. There are symbolic definitions for each of the available pins
|
||||
/// that you should use for convenience. See \ref RPiGPIOPin.
|
||||
///
|
||||
/// \par SPI Pins
|
||||
///
|
||||
/// The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface,
|
||||
///
|
||||
/// The bcm2835_spi_* functions allow you to control the BCM 2835 SPI0 interface,
|
||||
/// allowing you to send and received data by SPI (Serial Peripheral Interface).
|
||||
/// For more information about SPI, see http://en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus
|
||||
///
|
||||
/// When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their
|
||||
/// default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able
|
||||
/// When bcm2835_spi_begin() is called it changes the bahaviour of the SPI interface pins from their
|
||||
/// default GPIO behaviour in order to support SPI. While SPI is in use, you will not be able
|
||||
/// to control the state of the SPI pins through the usual bcm2835_spi_gpio_write().
|
||||
/// When bcm2835_spi_end() is called, the SPI pins will all revert to inputs, and can then be
|
||||
/// configured and controled with the usual bcm2835_gpio_* calls.
|
||||
///
|
||||
/// The Raspberry Pi GPIO pins used for SPI are:
|
||||
///
|
||||
///
|
||||
/// - P1-19 (MOSI)
|
||||
/// - P1-21 (MISO)
|
||||
/// - P1-23 (CLK)
|
||||
/// - P1-24 (CE0)
|
||||
/// - P1-21 (MISO)
|
||||
/// - P1-23 (CLK)
|
||||
/// - P1-24 (CE0)
|
||||
/// - P1-26 (CE1)
|
||||
///
|
||||
/// \par I2C Pins
|
||||
@@ -139,10 +139,10 @@
|
||||
///
|
||||
/// \par PWM
|
||||
///
|
||||
/// The BCM2835 supports hardware PWM on a limited subset of GPIO pins. This bcm2835 library provides
|
||||
/// The BCM2835 supports hardware PWM on a limited subset of GPIO pins. This bcm2835 library provides
|
||||
/// functions for configuring and controlling PWM output on these pins.
|
||||
///
|
||||
/// The BCM2835 contains 2 independent PWM channels (0 and 1), each of which be connnected to a limited subset of
|
||||
/// The BCM2835 contains 2 independent PWM channels (0 and 1), each of which be connnected to a limited subset of
|
||||
/// GPIO pins. The following GPIO pins may be connected to the following PWM channels (from section 9.5):
|
||||
/// \code
|
||||
/// GPIO PIN RPi pin PWM Channel ALT FUN
|
||||
@@ -161,34 +161,34 @@
|
||||
/// on the IO headers, and therefore this is the only IO pin on the RPi that can be used for PWM.
|
||||
/// Further it must be set to ALT FUN 5 to get PWM output.
|
||||
///
|
||||
/// Both PWM channels are driven by the same PWM clock, whose clock dvider can be varied using
|
||||
/// Both PWM channels are driven by the same PWM clock, whose clock dvider can be varied using
|
||||
/// bcm2835_pwm_set_clock(). Each channel can be separately enabled with bcm2835_pwm_set_mode().
|
||||
/// The average output of the PWM channel is determined by the ratio of DATA/RANGE for that channel.
|
||||
/// Use bcm2835_pwm_set_range() to set the range and bcm2835_pwm_set_data() to set the data in that ratio
|
||||
///
|
||||
/// Each PWM channel can run in either Balanced or Mark-Space mode. In Balanced mode, the hardware
|
||||
/// Each PWM channel can run in either Balanced or Mark-Space mode. In Balanced mode, the hardware
|
||||
/// sends a combination of clock pulses that results in an overall DATA pulses per RANGE pulses.
|
||||
/// In Mark-Space mode, the hardware sets the output HIGH for DATA clock pulses wide, followed by
|
||||
/// LOW for RANGE-DATA clock pulses.
|
||||
/// In Mark-Space mode, the hardware sets the output HIGH for DATA clock pulses wide, followed by
|
||||
/// LOW for RANGE-DATA clock pulses.
|
||||
///
|
||||
/// The PWM clock can be set to control the PWM pulse widths. The PWM clock is derived from
|
||||
/// The PWM clock can be set to control the PWM pulse widths. The PWM clock is derived from
|
||||
/// a 19.2MHz clock. You can set any divider, but some common ones are provided by the BCM2835_PWM_CLOCK_DIVIDER_*
|
||||
/// values of \ref bcm2835PWMClockDivider.
|
||||
///
|
||||
/// For example, say you wanted to drive a DC motor with PWM at about 1kHz,
|
||||
/// and control the speed in 1/1024 increments from
|
||||
/// 0/1024 (stopped) through to 1024/1024 (full on). In that case you might set the
|
||||
///
|
||||
/// For example, say you wanted to drive a DC motor with PWM at about 1kHz,
|
||||
/// and control the speed in 1/1024 increments from
|
||||
/// 0/1024 (stopped) through to 1024/1024 (full on). In that case you might set the
|
||||
/// clock divider to be 16, and the RANGE to 1024. The pulse repetition frequency will be
|
||||
/// 1.2MHz/1024 = 1171.875Hz.
|
||||
///
|
||||
/// \par Real Time performance constraints
|
||||
///
|
||||
/// The bcm2835 is a library for user programs (i.e. they run in 'userland').
|
||||
/// The bcm2835 is a library for user programs (i.e. they run in 'userland').
|
||||
/// Such programs are not part of the kernel and are usually
|
||||
/// subject to paging and swapping by the kernel while it does other things besides running your program.
|
||||
/// This means that you should not expect to get real-time performance or
|
||||
/// real-time timing constraints from such programs. In particular, there is no guarantee that the
|
||||
/// bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested.
|
||||
/// subject to paging and swapping by the kernel while it does other things besides running your program.
|
||||
/// This means that you should not expect to get real-time performance or
|
||||
/// real-time timing constraints from such programs. In particular, there is no guarantee that the
|
||||
/// bcm2835_delay() and bcm2835_delayMicroseconds() will return after exactly the time requested.
|
||||
/// In fact, depending on other activity on the host, IO etc, you might get significantly longer delay times
|
||||
/// than the one you asked for. So please dont expect to get exactly the time delay you request.
|
||||
///
|
||||
@@ -208,9 +208,9 @@
|
||||
/// http://search.cpan.org/~mikem/Device-BCM2835-1.9/lib/Device/BCM2835.pm
|
||||
/// Matthew Baker has kindly made Python bindings available at:
|
||||
/// https://github.com/mubeta06/py-libbcm2835
|
||||
/// Gary Marks has created a Serial Peripheral Interface (SPI) command-line utility
|
||||
/// for Raspberry Pi, based on the bcm2835 library. The
|
||||
/// utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a
|
||||
/// Gary Marks has created a Serial Peripheral Interface (SPI) command-line utility
|
||||
/// for Raspberry Pi, based on the bcm2835 library. The
|
||||
/// utility, spincl, is licensed under Open Source GNU GPLv3 by iP Solutions (http://ipsolutionscorp.com), as a
|
||||
/// free download with source included: http://ipsolutionscorp.com/raspberry-pi-spi-utility/
|
||||
///
|
||||
/// \par Open Source Licensing GPL V2
|
||||
@@ -226,7 +226,7 @@
|
||||
///
|
||||
/// Some of this code has been inspired by Dom and Gert.
|
||||
/// The I2C code has been inspired by Alan Barr.
|
||||
///
|
||||
///
|
||||
/// \par Revision History
|
||||
///
|
||||
/// \version 1.0 Initial release
|
||||
@@ -237,15 +237,15 @@
|
||||
/// \version 1.5 Added bcm2835_close() to deinit the library. Suggested by C?sar Ortiz
|
||||
/// \version 1.6 Document testing on 2012-07-15-wheezy-raspbian and Occidentalisv01
|
||||
/// Functions bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen()
|
||||
/// bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now
|
||||
/// bcm2835_gpio_len(), bcm2835_gpio_aren() and bcm2835_gpio_afen() now
|
||||
/// changes only the pin specified. Other pins that were already previously
|
||||
/// enabled stay enabled.
|
||||
/// Added bcm2835_gpio_clr_ren(), bcm2835_gpio_clr_fen(), bcm2835_gpio_clr_hen()
|
||||
/// bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen()
|
||||
/// bcm2835_gpio_clr_len(), bcm2835_gpio_clr_aren(), bcm2835_gpio_clr_afen()
|
||||
/// to clear the enable for individual pins, suggested by Andreas Sundstrom.
|
||||
/// \version 1.7 Added bcm2835_spi_transfernb to support different buffers for read and write.
|
||||
/// \version 1.8 Improvements to read barrier, as suggested by maddin.
|
||||
/// \version 1.9 Improvements contributed by mikew:
|
||||
/// \version 1.9 Improvements contributed by mikew:
|
||||
/// I noticed that it was mallocing memory for the mmaps on /dev/mem.
|
||||
/// It's not necessary to do that, you can just mmap the file directly,
|
||||
/// so I've removed the mallocs (and frees).
|
||||
@@ -259,40 +259,40 @@
|
||||
/// http://www.scribd.com/doc/101830961/GPIO-Pads-Control2
|
||||
/// Also added a define for the passwrd value that Gert says is needed to
|
||||
/// change pad control settings.
|
||||
/// \version 1.10 Changed the names of the delay functions to bcm2835_delay()
|
||||
/// \version 1.10 Changed the names of the delay functions to bcm2835_delay()
|
||||
/// and bcm2835_delayMicroseconds() to prevent collisions with wiringPi.
|
||||
/// Macros to map delay()-> bcm2835_delay() and
|
||||
/// Macros to map delayMicroseconds()-> bcm2835_delayMicroseconds(), which
|
||||
/// can be disabled by defining BCM2835_NO_DELAY_COMPATIBILITY
|
||||
/// \version 1.11 Fixed incorrect link to download file
|
||||
/// \version 1.12 New GPIO pin definitions for RPi version 2 (which has a different GPIO mapping)
|
||||
/// \version 1.12 New GPIO pin definitions for RPi version 2 (which has a different GPIO mapping)
|
||||
/// \version 1.13 New GPIO pin definitions for RPi version 2 plug P5
|
||||
/// Hardware base pointers are now available (after initialisation) externally as bcm2835_gpio
|
||||
/// bcm2835_pwm bcm2835_clk bcm2835_pads bcm2835_spi0.
|
||||
/// \version 1.14 Now compiles even if CLOCK_MONOTONIC_RAW is not available, uses CLOCK_MONOTONIC instead.
|
||||
/// Fixed errors in documentation of SPI divider frequencies based on 250MHz clock.
|
||||
/// Fixed errors in documentation of SPI divider frequencies based on 250MHz clock.
|
||||
/// Reported by Ben Simpson.
|
||||
/// \version 1.15 Added bcm2835_close() to end of examples as suggested by Mark Wolfe.
|
||||
/// \version 1.16 Added bcm2835_gpio_set_multi, bcm2835_gpio_clr_multi and bcm2835_gpio_write_multi
|
||||
/// to allow a mask of pins to be set all at once. Requested by Sebastian Loncar.
|
||||
/// \version 1.17 Added bcm2835_gpio_write_mask. Requested by Sebastian Loncar.
|
||||
/// \version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseconds:
|
||||
/// now uses the RPi system timer counter, instead of clock_gettime, for improved accuracy.
|
||||
/// \version 1.18 Added bcm2835_i2c_* functions. Changes to bcm2835_delayMicroseconds:
|
||||
/// now uses the RPi system timer counter, instead of clock_gettime, for improved accuracy.
|
||||
/// No need to link with -lrt now. Contributed by Arjan van Vught.
|
||||
/// \version 1.19 Removed inlines added by previous patch since they don't seem to work everywhere.
|
||||
/// \version 1.19 Removed inlines added by previous patch since they don't seem to work everywhere.
|
||||
/// Reported by olly.
|
||||
/// \version 1.20 Patch from Mark Dootson to close /dev/mem after access to the peripherals has been granted.
|
||||
/// \version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns.
|
||||
/// \version 1.21 delayMicroseconds is now not susceptible to 32 bit timer overruns.
|
||||
/// Patch courtesy Jeremy Mortis.
|
||||
/// \version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability to set
|
||||
/// \version 1.22 Fixed incorrect definition of BCM2835_GPFEN0 which broke the ability to set
|
||||
/// falling edge events. Reported by Mark Dootson.
|
||||
/// \version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs.
|
||||
/// \version 1.23 Added bcm2835_i2c_set_baudrate and bcm2835_i2c_read_register_rs.
|
||||
/// Improvements to bcm2835_i2c_read and bcm2835_i2c_write functions
|
||||
/// to fix ocasional reads not completing. Patched by Mark Dootson.
|
||||
/// \version 1.24 Mark Dootson p[atched a problem with his previously submitted code
|
||||
/// under high load from other processes.
|
||||
/// under high load from other processes.
|
||||
/// \version 1.25 Updated author and distribution location details to airspayce.com
|
||||
/// \version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak.
|
||||
/// \version 1.26 Added missing unmapmem for pads in bcm2835_close to prevent a memory leak.
|
||||
/// Reported by Hartmut Henkel.
|
||||
/// \version 1.27 bcm2835_gpio_set_pad() no longer needs BCM2835_PAD_PASSWRD: it is
|
||||
/// now automatically included.
|
||||
@@ -303,11 +303,11 @@
|
||||
/// \version 1.30 10 microsecond delays from bcm2835_spi_transfer and bcm2835_spi_transfern for
|
||||
/// significant performance improvements, Patch by Alan Watson.
|
||||
/// \version 1.31 Fix a GCC warning about dummy variable, patched by Alan Watson. Thanks.
|
||||
/// \version 1.32 Added option I2C_V1 definition to compile for version 1 RPi.
|
||||
/// \version 1.32 Added option I2C_V1 definition to compile for version 1 RPi.
|
||||
/// By default I2C code is generated for the V2 RPi which has SDA1 and SCL1 connected.
|
||||
/// Contributed by Malcolm Wiles based on work by Arvi Govindaraj.
|
||||
/// \version 1.33 Added command line utilities i2c and gpio to examples. Contributed by Shahrooz Shahparnia.
|
||||
/// \version 1.34 Added bcm2835_i2c_write_read_rs() which writes an arbitrary number of bytes,
|
||||
/// \version 1.34 Added bcm2835_i2c_write_read_rs() which writes an arbitrary number of bytes,
|
||||
/// sends a repeat start, and reads from the device. Contributed by Eduardo Steinhorst.
|
||||
/// \version 1.35 Fix build errors when compiled under Qt. Also performance improvements with SPI transfers. Contributed by Udo Klaas.
|
||||
/// \version 1.36 Make automake's test runner detect that we're skipping tests when not root, the second
|
||||
@@ -539,7 +539,7 @@ typedef enum
|
||||
} RPiGPIOPin;
|
||||
|
||||
// Defines for SPI
|
||||
// GPIO register offsets from BCM2835_SPI0_BASE.
|
||||
// GPIO register offsets from BCM2835_SPI0_BASE.
|
||||
// Offsets into the SPI Peripheral block in bytes per 10.5 SPI Register Map
|
||||
#define BCM2835_SPI0_CS 0x0000 ///< SPI Master Control and Status
|
||||
#define BCM2835_SPI0_FIFO 0x0004 ///< SPI Master TX and RX FIFOs
|
||||
@@ -570,8 +570,8 @@ typedef enum
|
||||
#define BCM2835_SPI0_CS_TA 0x00000080 ///< Transfer Active
|
||||
#define BCM2835_SPI0_CS_CSPOL 0x00000040 ///< Chip Select Polarity
|
||||
#define BCM2835_SPI0_CS_CLEAR 0x00000030 ///< Clear FIFO Clear RX and TX
|
||||
#define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 ///< Clear FIFO Clear RX
|
||||
#define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 ///< Clear FIFO Clear TX
|
||||
#define BCM2835_SPI0_CS_CLEAR_RX 0x00000020 ///< Clear FIFO Clear RX
|
||||
#define BCM2835_SPI0_CS_CLEAR_TX 0x00000010 ///< Clear FIFO Clear TX
|
||||
#define BCM2835_SPI0_CS_CPOL 0x00000008 ///< Clock Polarity
|
||||
#define BCM2835_SPI0_CS_CPHA 0x00000004 ///< Clock Phase
|
||||
#define BCM2835_SPI0_CS_CS 0x00000003 ///< Chip Select
|
||||
@@ -597,13 +597,13 @@ typedef enum
|
||||
/// \brief bcm2835SPIChipSelect
|
||||
/// Specify the SPI chip select pin(s)
|
||||
typedef enum
|
||||
{
|
||||
{
|
||||
// Can also use non-standard pins with this lib
|
||||
BCM2835_SPI_CS0 = 0, ///< Chip Select 0
|
||||
BCM2835_SPI_CS1 = 1, ///< Chip Select 1
|
||||
BCM2835_SPI_CS2 = 2, ///< Chip Select 2 (ie pins CS1 and CS2 are asserted)
|
||||
BCM2835_SPI_CS_NONE = 3, ///< No CS, control it yourself
|
||||
|
||||
|
||||
// Only GPIO > 3 can be used (to not interfere with the previous value just above )
|
||||
// Lucky we have plenty of theese pins
|
||||
BCM2835_SPI_CS_GPIO4 = RPI_V2_GPIO_P1_07, /// BCM GPIO 4
|
||||
@@ -617,7 +617,7 @@ typedef enum
|
||||
BCM2835_SPI_CS_GPIO29 = RPI_V2_GPIO_P5_04, /// BCM GPIO 29
|
||||
BCM2835_SPI_CS_GPIO30 = RPI_V2_GPIO_P5_05, /// BCM GPIO 30
|
||||
BCM2835_SPI_CS_GPIO31 = RPI_V2_GPIO_P5_06, /// BCM GPIO 31
|
||||
|
||||
|
||||
} bcm2835SPIChipSelect;
|
||||
|
||||
/// \brief bcm2835SPIClockDivider
|
||||
@@ -812,11 +812,11 @@ extern "C" {
|
||||
/// These functions allow you to intialise and control the bcm2835 library
|
||||
/// @{
|
||||
|
||||
/// Initialise the library by opening /dev/mem and getting pointers to the
|
||||
/// Initialise the library by opening /dev/mem and getting pointers to the
|
||||
/// internal memory for BCM 2835 device registers. You must call this (successfully)
|
||||
/// before calling any other
|
||||
/// functions in this library (except bcm2835_set_debug).
|
||||
/// If bcm2835_init() fails by returning 0,
|
||||
/// before calling any other
|
||||
/// functions in this library (except bcm2835_set_debug).
|
||||
/// If bcm2835_init() fails by returning 0,
|
||||
/// calling any other function may result in crashes or other failures.
|
||||
/// Prints messages to stderr in case of errors.
|
||||
/// \return 1 if successful else 0
|
||||
@@ -838,12 +838,12 @@ extern "C" {
|
||||
|
||||
/// \defgroup lowlevel Low level register access
|
||||
/// These functions provide low level register access, and should not generally
|
||||
/// need to be used
|
||||
///
|
||||
/// need to be used
|
||||
///
|
||||
/// @{
|
||||
|
||||
/// Reads 32 bit value from a peripheral address
|
||||
/// The read is done twice, and is therefore always safe in terms of
|
||||
/// The read is done twice, and is therefore always safe in terms of
|
||||
/// manual section 1.3 Peripheral access precautions for correct memory ordering
|
||||
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
|
||||
/// \return the value read from the 32 bit register
|
||||
@@ -861,7 +861,7 @@ extern "C" {
|
||||
|
||||
|
||||
/// Writes 32 bit value from a peripheral address
|
||||
/// The write is done twice, and is therefore always safe in terms of
|
||||
/// The write is done twice, and is therefore always safe in terms of
|
||||
/// manual section 1.3 Peripheral access precautions for correct memory ordering
|
||||
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
|
||||
/// \param[in] value The 32 bit value to write
|
||||
@@ -877,11 +877,11 @@ extern "C" {
|
||||
extern void bcm2835_peri_write_nb(volatile uint32_t* paddr, uint32_t value);
|
||||
|
||||
/// Alters a number of bits in a 32 peripheral regsiter.
|
||||
/// It reads the current valu and then alters the bits deines as 1 in mask,
|
||||
/// according to the bit value in value.
|
||||
/// It reads the current valu and then alters the bits deines as 1 in mask,
|
||||
/// according to the bit value in value.
|
||||
/// All other bits that are 0 in the mask are unaffected.
|
||||
/// Use this to alter a subset of the bits in a register.
|
||||
/// The write is done twice, and is therefore always safe in terms of
|
||||
/// The write is done twice, and is therefore always safe in terms of
|
||||
/// manual section 1.3 Peripheral access precautions for correct memory ordering
|
||||
/// \param[in] paddr Physical address to read from. See BCM2835_GPIO_BASE etc.
|
||||
/// \param[in] value The 32 bit value to write, masked in by mask.
|
||||
@@ -891,7 +891,7 @@ extern "C" {
|
||||
/// @} // end of lowlevel
|
||||
|
||||
/// \defgroup gpio GPIO register access
|
||||
/// These functions allow you to control the GPIO interface. You can set the
|
||||
/// These functions allow you to control the GPIO interface. You can set the
|
||||
/// function of each GPIO pin, read the input state and set the output state.
|
||||
/// @{
|
||||
|
||||
@@ -901,31 +901,31 @@ extern "C" {
|
||||
/// \param[in] mode Mode to set the pin to, one of BCM2835_GPIO_FSEL_* from \ref bcm2835FunctionSelect
|
||||
extern void bcm2835_gpio_fsel(uint8_t pin, uint8_t mode);
|
||||
|
||||
/// Sets the specified pin output to
|
||||
/// Sets the specified pin output to
|
||||
/// HIGH.
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
/// \sa bcm2835_gpio_write()
|
||||
extern void bcm2835_gpio_set(uint8_t pin);
|
||||
|
||||
/// Sets the specified pin output to
|
||||
/// Sets the specified pin output to
|
||||
/// LOW.
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
/// \sa bcm2835_gpio_write()
|
||||
extern void bcm2835_gpio_clr(uint8_t pin);
|
||||
|
||||
/// Sets any of the first 32 GPIO output pins specified in the mask to
|
||||
/// Sets any of the first 32 GPIO output pins specified in the mask to
|
||||
/// HIGH.
|
||||
/// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
|
||||
/// \sa bcm2835_gpio_write_multi()
|
||||
extern void bcm2835_gpio_set_multi(uint32_t mask);
|
||||
|
||||
/// Sets any of the first 32 GPIO output pins specified in the mask to
|
||||
/// Sets any of the first 32 GPIO output pins specified in the mask to
|
||||
/// LOW.
|
||||
/// \param[in] mask Mask of pins to affect. Use eg: (1 << RPI_GPIO_P1_03) | (1 << RPI_GPIO_P1_05)
|
||||
/// \sa bcm2835_gpio_write_multi()
|
||||
extern void bcm2835_gpio_clr_multi(uint32_t mask);
|
||||
|
||||
/// Reads the current level on the specified
|
||||
/// Reads the current level on the specified
|
||||
/// pin and returns either HIGH or LOW. Works whether or not the pin
|
||||
/// is an input or an output.
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
@@ -934,14 +934,14 @@ extern "C" {
|
||||
|
||||
/// Event Detect Status.
|
||||
/// Tests whether the specified pin has detected a level or edge
|
||||
/// as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(),
|
||||
/// as requested by bcm2835_gpio_ren(), bcm2835_gpio_fen(), bcm2835_gpio_hen(),
|
||||
/// bcm2835_gpio_len(), bcm2835_gpio_aren(), bcm2835_gpio_afen().
|
||||
/// Clear the flag for a given pin by calling bcm2835_gpio_set_eds(pin);
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
/// \return HIGH if the event detect status for the given pin is true.
|
||||
extern uint8_t bcm2835_gpio_eds(uint8_t pin);
|
||||
|
||||
/// 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
|
||||
/// an Event Detect Status on the pin.
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
@@ -1022,8 +1022,8 @@ extern "C" {
|
||||
|
||||
/// Clocks the Pull-up/down value set earlier by bcm2835_gpio_pud() into the pin.
|
||||
/// \param[in] pin GPIO number, or one of RPI_GPIO_P1_* from \ref RPiGPIOPin.
|
||||
/// \param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin.
|
||||
/// LOW to remove the clock.
|
||||
/// \param[in] on HIGH to clock the value from bcm2835_gpio_pud() into the pin.
|
||||
/// LOW to remove the clock.
|
||||
/// \sa bcm2835_gpio_set_pud()
|
||||
extern void bcm2835_gpio_pudclk(uint8_t pin, uint8_t on);
|
||||
|
||||
@@ -1034,7 +1034,7 @@ extern "C" {
|
||||
|
||||
/// Sets the Pad Control for the given GPIO group.
|
||||
/// \param[in] group The GPIO pad group number, one of BCM2835_PAD_GROUP_GPIO_*
|
||||
/// \param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup. Note
|
||||
/// \param[in] control Mask of bits from BCM2835_PAD_* from \ref bcm2835PadGroup. Note
|
||||
/// that it is not necessary to include BCM2835_PAD_PASSWRD in the mask as this
|
||||
/// is automatically included.
|
||||
extern void bcm2835_gpio_set_pad(uint8_t group, uint32_t control);
|
||||
@@ -1042,9 +1042,9 @@ extern "C" {
|
||||
/// Delays for the specified number of milliseconds.
|
||||
/// Uses nanosleep(), and therefore does not use CPU until the time is up.
|
||||
/// However, you are at the mercy of nanosleep(). From the manual for nanosleep():
|
||||
/// If the interval specified in req is not an exact multiple of the granularity
|
||||
/// If the interval specified in req is not an exact multiple of the granularity
|
||||
/// underlying clock (see time(7)), then the interval will be
|
||||
/// rounded up to the next multiple. Furthermore, after the sleep completes,
|
||||
/// rounded up to the next multiple. Furthermore, after the sleep completes,
|
||||
/// there may still be a delay before the CPU becomes free to once
|
||||
/// again execute the calling thread.
|
||||
/// \param[in] millis Delay in milliseconds
|
||||
@@ -1053,9 +1053,9 @@ extern "C" {
|
||||
/// Delays for the specified number of microseconds.
|
||||
/// Uses a combination of nanosleep() and a busy wait loop on the BCM2835 system timers,
|
||||
/// However, you are at the mercy of nanosleep(). From the manual for nanosleep():
|
||||
/// If the interval specified in req is not an exact multiple of the granularity
|
||||
/// If the interval specified in req is not an exact multiple of the granularity
|
||||
/// underlying clock (see time(7)), then the interval will be
|
||||
/// rounded up to the next multiple. Furthermore, after the sleep completes,
|
||||
/// rounded up to the next multiple. Furthermore, after the sleep completes,
|
||||
/// there may still be a delay before the CPU becomes free to once
|
||||
/// again execute the calling thread.
|
||||
/// For times less than about 450 microseconds, uses a busy wait on the System Timer.
|
||||
@@ -1063,7 +1063,7 @@ extern "C" {
|
||||
/// result in a delay of about 80 microseconds. Your mileage may vary.
|
||||
/// \param[in] micros Delay in microseconds
|
||||
extern void bcm2835_delayMicroseconds (uint64_t micros);
|
||||
|
||||
|
||||
/// Indicate the number of milliseconds since startup of PI
|
||||
/// This function is like the Arduino millis function
|
||||
/// \return Number of milliseconds
|
||||
@@ -1090,24 +1090,24 @@ extern "C" {
|
||||
/// \param[in] pud The desired Pull-up/down mode. One of BCM2835_GPIO_PUD_* from bcm2835PUDControl
|
||||
extern void bcm2835_gpio_set_pud(uint8_t pin, uint8_t pud);
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
|
||||
/// \defgroup spi SPI access
|
||||
/// These functions let you use SPI0 (Serial Peripheral Interface) to
|
||||
/// These functions let you use SPI0 (Serial Peripheral Interface) to
|
||||
/// interface with an external SPI device.
|
||||
/// @{
|
||||
|
||||
/// Start SPI operations.
|
||||
/// 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.
|
||||
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
|
||||
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
|
||||
/// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
|
||||
/// or one of One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
|
||||
/// by default PI hardware driven using CE0
|
||||
/// You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
|
||||
/// by default PI hardware driven using CE0
|
||||
/// You should call bcm2835_spi_end() when all SPI funcitons are complete to return the pins to
|
||||
/// their default functions
|
||||
/// \sa bcm2835_spi_end()
|
||||
extern void bcm2835_spi_begin(uint8_t cs);
|
||||
extern void bcm2835_spi_begin();
|
||||
|
||||
/// End SPI operations.
|
||||
/// SPI0 pins P1-19 (MOSI), P1-21 (MISO), P1-23 (CLK), P1-24 (CE0) and P1-26 (CE1)
|
||||
@@ -1115,64 +1115,64 @@ extern "C" {
|
||||
extern void bcm2835_spi_end(void);
|
||||
|
||||
/// Sets the SPI custom Chip Select pin to correct level
|
||||
/// Defaults to
|
||||
/// \param[in] level The desired level, LOW or HIGH,
|
||||
/// Defaults to
|
||||
/// \param[in] level The desired level, LOW or HIGH,
|
||||
extern void bcm2835_spi_setChipSelect(uint8_t level);
|
||||
|
||||
|
||||
/// Sets the SPI bit order
|
||||
/// NOTE: has no effect. Not supported by SPI0.
|
||||
/// Defaults to
|
||||
/// \param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*,
|
||||
/// Defaults to
|
||||
/// \param[in] order The desired bit order, one of BCM2835_SPI_BIT_ORDER_*,
|
||||
/// see \ref bcm2835SPIBitOrder
|
||||
extern void bcm2835_spi_setBitOrder(uint8_t order);
|
||||
|
||||
/// Sets the SPI clock divider and therefore the
|
||||
/// SPI clock speed.
|
||||
/// \param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK_DIVIDER_*,
|
||||
/// Sets the SPI clock divider and therefore the
|
||||
/// SPI clock speed.
|
||||
/// \param[in] divider The desired SPI clock divider, one of BCM2835_SPI_CLOCK_DIVIDER_*,
|
||||
/// see \ref bcm2835SPIClockDivider
|
||||
extern void bcm2835_spi_setClockDivider(uint16_t divider);
|
||||
|
||||
/// Sets the SPI data mode
|
||||
/// Sets the clock polariy and phase
|
||||
/// \param[in] mode The desired data mode, one of BCM2835_SPI_MODE*,
|
||||
/// \param[in] mode The desired data mode, one of BCM2835_SPI_MODE*,
|
||||
/// see \ref bcm2835SPIMode
|
||||
extern void bcm2835_spi_setDataMode(uint8_t mode);
|
||||
|
||||
/// Sets the chip select pin(s)
|
||||
/// When an bcm2835_spi_transfer() is made, the selected pin(s) will be asserted during the
|
||||
/// transfer.
|
||||
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
|
||||
/// \param[in] cs Specifies the CS pins(s) that are used to activate the desired slave.
|
||||
/// One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
|
||||
/// or one of One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
|
||||
/// or one of One of BCM2835_SPI_CS*, see \ref bcm2835SPIChipSelect
|
||||
extern void bcm2835_spi_chipSelect(uint8_t cs);
|
||||
|
||||
/// Sets the chip select pin polarity for a given pin
|
||||
/// When an bcm2835_spi_transfer() occurs, the currently selected chip select pin(s)
|
||||
/// will be asserted to the
|
||||
/// value given by active. When transfers are not happening, the chip select pin(s)
|
||||
/// When an bcm2835_spi_transfer() occurs, the currently selected chip select pin(s)
|
||||
/// will be asserted to the
|
||||
/// value given by active. When transfers are not happening, the chip select pin(s)
|
||||
/// return to the complement (inactive) value.
|
||||
/// \param[in] cs The chip select pin to affect
|
||||
/// \param[in] active Whether the chip select pin is to be active HIGH
|
||||
extern void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active);
|
||||
|
||||
/// Transfers one byte to and from the currently selected SPI slave.
|
||||
/// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
||||
/// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
||||
/// during the transfer.
|
||||
/// Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO.
|
||||
/// Clocks the 8 bit value out on MOSI, and simultaneously clocks in data from MISO.
|
||||
/// Returns the read data byte from the slave.
|
||||
/// Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
|
||||
/// \param[in] value The 8 bit data byte to write to MOSI
|
||||
/// \return The 8 bit byte simultaneously read from MISO
|
||||
/// \sa bcm2835_spi_transfern()
|
||||
extern uint8_t bcm2835_spi_transfer(uint8_t value);
|
||||
|
||||
|
||||
/// Transfers any number of bytes to and from the currently selected SPI slave.
|
||||
/// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
||||
/// Asserts the currently selected CS pins (as previously set by bcm2835_spi_chipSelect)
|
||||
/// during the transfer.
|
||||
/// Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO.
|
||||
/// Clocks the len 8 bit bytes out on MOSI, and simultaneously clocks in data from MISO.
|
||||
/// The data read read from the slave is placed into rbuf. rbuf must be at least len bytes long
|
||||
/// Uses polled transfer as per section 10.6.1 of the BCM 2835 ARM Peripherls manual
|
||||
/// \param[in] tbuf Buffer of bytes to send.
|
||||
/// \param[in] tbuf Buffer of bytes to send.
|
||||
/// \param[out] rbuf Received bytes will by put in this buffer
|
||||
/// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
|
||||
/// \sa bcm2835_spi_transfer()
|
||||
@@ -1284,7 +1284,7 @@ extern "C" {
|
||||
/// \param[in] micros Delay in microseconds
|
||||
extern void bcm2835_st_delay(uint64_t offset_micros, uint64_t micros);
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
|
||||
/// \defgroup pwm Pulse Width Modulation
|
||||
/// Allows control of 2 independent PWM channels. A limited subset of GPIO pins
|
||||
@@ -1293,12 +1293,12 @@ extern "C" {
|
||||
/// documentation on the Main Page.
|
||||
/// @{
|
||||
|
||||
/// Sets the PWM clock divisor,
|
||||
/// Sets the PWM clock divisor,
|
||||
/// to control the basic PWM pulse widths.
|
||||
/// \param[in] divisor Divides the basic 19.2MHz PWM clock. You can use one of the common
|
||||
/// values BCM2835_PWM_CLOCK_DIVIDER_* in \ref bcm2835PWMClockDivider
|
||||
extern void bcm2835_pwm_set_clock(uint32_t divisor);
|
||||
|
||||
|
||||
/// Sets the mode of the given PWM channel,
|
||||
/// allowing you to control the PWM mode and enable/disable that channel
|
||||
/// \param[in] channel The PWM channel. 0 or 1.
|
||||
@@ -1311,15 +1311,15 @@ extern "C" {
|
||||
/// \param[in] channel The PWM channel. 0 or 1.
|
||||
/// \param[in] range The maximum value permitted for DATA.
|
||||
extern void bcm2835_pwm_set_range(uint8_t channel, uint32_t range);
|
||||
|
||||
/// Sets the PWM pulse ratio to emit to DATA/RANGE,
|
||||
|
||||
/// Sets the PWM pulse ratio to emit to DATA/RANGE,
|
||||
/// where RANGE is set by bcm2835_pwm_set_range().
|
||||
/// \param[in] channel The PWM channel. 0 or 1.
|
||||
/// \param[in] data Controls the PWM output ratio as a fraction of the range.
|
||||
/// \param[in] data Controls the PWM output ratio as a fraction of the range.
|
||||
/// Can vary from 0 to RANGE.
|
||||
extern void bcm2835_pwm_set_data(uint8_t channel, uint32_t data);
|
||||
|
||||
/// @}
|
||||
/// @}
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -1345,9 +1345,9 @@ extern "C" {
|
||||
/// Shows how to use PWM to control GPIO pins
|
||||
|
||||
/// @example i2c.c
|
||||
/// Command line utility for executing i2c commands with the
|
||||
/// Command line utility for executing i2c commands with the
|
||||
/// Broadcom bcm2835. Contributed by Shahrooz Shahparnia.
|
||||
|
||||
/// example gpio.c
|
||||
/// Command line utility for executing gpio commands with the
|
||||
/// Command line utility for executing gpio commands with the
|
||||
/// Broadcom bcm2835. Contributed by Shahrooz Shahparnia.
|
||||
|
||||
@@ -32,15 +32,14 @@ using namespace std;
|
||||
|
||||
// CE Pin, CSN Pin, SPI Speed
|
||||
|
||||
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_1MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
|
||||
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -27,15 +27,14 @@ using namespace std;
|
||||
|
||||
// CE Pin, CSN Pin, SPI Speed
|
||||
|
||||
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_1MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
|
||||
|
||||
|
||||
// Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example using Dynamic Payloads
|
||||
* Example using Dynamic Payloads
|
||||
*
|
||||
* This is an example of how to use payloads of a varying (dynamic) size.
|
||||
* This is an example of how to use payloads of a varying (dynamic) size.
|
||||
*/
|
||||
|
||||
#include <cstdlib>
|
||||
@@ -22,14 +22,14 @@ using namespace std;
|
||||
|
||||
// CE Pin, CSN Pin, SPI Speed
|
||||
|
||||
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_1MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
|
||||
|
||||
|
||||
// Radio pipe addresses for the 2 nodes to communicate.
|
||||
@@ -47,7 +47,7 @@ char receive_payload[max_payload_size+1]; // +1 to allow room for a terminating
|
||||
|
||||
int main(int argc, char** argv){
|
||||
|
||||
|
||||
|
||||
// Print preamble:
|
||||
printf("RF24/examples/pingpair_dyn/\n");
|
||||
|
||||
@@ -65,7 +65,7 @@ int main(int argc, char** argv){
|
||||
char myChar = {0};
|
||||
cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit) \n>";
|
||||
getline(cin,input);
|
||||
|
||||
|
||||
if(input.length() == 1) {
|
||||
myChar = input[0];
|
||||
if(myChar == '0'){
|
||||
@@ -129,7 +129,7 @@ if (role == role_ping_out)
|
||||
// Spew it
|
||||
printf("Got response size=%i value=%s\n\r",len,receive_payload);
|
||||
}
|
||||
|
||||
|
||||
// Update size for next time.
|
||||
next_payload_size += payload_size_increments_by;
|
||||
if ( next_payload_size > max_payload_size )
|
||||
|
||||
@@ -7,7 +7,7 @@ TMRh20 2014
|
||||
*/
|
||||
|
||||
/** General Data Transfer Rate Test
|
||||
* This example demonstrates basic data transfer functionality with the
|
||||
* This example demonstrates basic data transfer functionality with the
|
||||
updated library. This example will display the transfer rates acheived using
|
||||
the slower form of high-speed transfer using blocking-writes.
|
||||
*/
|
||||
@@ -26,14 +26,14 @@ using namespace std;
|
||||
|
||||
// CE Pin, CSN Pin, SPI Speed
|
||||
|
||||
// Setup for GPIO 22 CE and GPIO 25 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_18, BCM2835_SPI_SPEED_1MHZ);
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 1Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_1MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ);
|
||||
|
||||
// Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_8MHZ);
|
||||
// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 8Mhz
|
||||
RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ);
|
||||
|
||||
|
||||
|
||||
@@ -42,16 +42,16 @@ const uint64_t addresses[2] = { 0xABCDABCD71LL, 0x544d52687CLL };
|
||||
|
||||
bool role_ping_out = 1, role_pong_back = 0;
|
||||
bool role = 0;
|
||||
uint8_t data[32];
|
||||
unsigned long startTime, stopTime, counter, rxTimer=0;
|
||||
uint8_t data[32];
|
||||
unsigned long startTime, stopTime, counter, rxTimer=0;
|
||||
|
||||
int main(int argc, char** argv){
|
||||
|
||||
|
||||
|
||||
// Print preamble:
|
||||
|
||||
printf("RF24/examples/Transfer/\n");
|
||||
|
||||
|
||||
radio.begin(); // Setup and configure rf radio
|
||||
radio.setChannel(1);
|
||||
radio.setPALevel(RF24_PA_MAX);
|
||||
@@ -67,7 +67,7 @@ int main(int argc, char** argv){
|
||||
char myChar = {0};
|
||||
cout << "Choose a role: Enter 0 for receiver, 1 for transmitter (CTRL+C to exit)\n>";
|
||||
getline(cin,input);
|
||||
|
||||
|
||||
if(input.length() == 1) {
|
||||
myChar = input[0];
|
||||
if(myChar == '0'){
|
||||
@@ -86,8 +86,8 @@ int main(int argc, char** argv){
|
||||
radio.openReadingPipe(1,addresses[0]);
|
||||
radio.startListening();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for(int i=0; i<32; i++){
|
||||
data[i] = rand() % 255; //Load the buffer with random data
|
||||
}
|
||||
@@ -105,7 +105,7 @@ int main(int argc, char** argv){
|
||||
|
||||
for(int i=0; i<cycles; i++){ //Loop through a number of cycles
|
||||
data[0] = i; //Change the first byte of the payload for identification
|
||||
if(!radio.writeFast(&data,32)){ //Write to the FIFO buffers
|
||||
if(!radio.writeFast(&data,32)){ //Write to the FIFO buffers
|
||||
counter++; //Keep count of failed payloads
|
||||
}
|
||||
}
|
||||
@@ -115,16 +115,16 @@ int main(int argc, char** argv){
|
||||
|
||||
float numBytes = cycles*32;
|
||||
float rate = numBytes / (stopTime - startTime);
|
||||
|
||||
|
||||
printf("Transfer complete at %.2f KB/s \n\r",rate);
|
||||
printf("%lu of %lu Packets Failed to Send\n\r",counter,cycles);
|
||||
counter = 0;
|
||||
counter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(role == role_pong_back){
|
||||
while(radio.available()){
|
||||
while(radio.available()){
|
||||
radio.read(&data,32);
|
||||
counter++;
|
||||
}
|
||||
|
||||
+17
-8
@@ -75,24 +75,33 @@ Connection Info
|
||||
|
||||
Using pin 15/GPIO 22 for CE, pin 24/GPIO8 (CE0) for CSN
|
||||
|
||||
Can use either RPi CE0 or CE1 pins for radio CSN.
|
||||
Choose any RPi output pin for radio CE pin.
|
||||
|
||||
**Constructor:**
|
||||
```
|
||||
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
|
||||
or
|
||||
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS1, BCM2835_SPI_SPEED_8MHZ);
|
||||
```
|
||||
|
||||
**Pins:**
|
||||
|
||||
|NRF24L01 | RPI | P1 Connector |
|
||||
|----- |----------- | -------------|
|
||||
|VCC: | rpi-3v3 | (17) |
|
||||
|GND: | rpi-gnd | (25) |
|
||||
|CE: | rpi-gpio22 | (15) |
|
||||
|CSN: | rpi-gpio8 | (24) |
|
||||
|SCK: | rpi-sckl | (23) |
|
||||
|MOSI: | rpi-mosi | (19) |
|
||||
|MISO: | rpi-miso | (21) |
|
||||
|-----|-----------|-------------|
|
||||
| VCC | rpi-3v3 | (17) |
|
||||
| GND | rpi-gnd | (25) |
|
||||
| CE | rpi-gpio22 | (15) |
|
||||
| CSN | rpi-gpio8 | (24) |
|
||||
| SCK | rpi-sckl | (23) |
|
||||
| MOSI | rpi-mosi | (19) |
|
||||
| MISO | rpi-miso | (21) |
|
||||
|
||||
|
||||
See http://www.airspayce.com/mikem/bcm2835/index.html for BCM2835 class documentation.
|
||||
Note: The BCM library has been customized slightly to allow use of hardware CE pins not
|
||||
in use for SPI, and to include a millis() function.
|
||||
|
||||
****************
|
||||
|
||||
|
||||
|
||||
+17
-8
@@ -75,24 +75,33 @@ Connection Info
|
||||
|
||||
Using pin 15/GPIO 22 for CE, pin 24/GPIO8 (CE0) for CSN
|
||||
|
||||
Can use either RPi CE0 or CE1 pins for radio CSN.
|
||||
Choose any RPi output pin for radio CE pin.
|
||||
|
||||
**Constructor:**
|
||||
```
|
||||
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS0, BCM2835_SPI_SPEED_8MHZ);
|
||||
or
|
||||
RF24 radio(RPI_V2_GPIO_P1_15,BCM2835_SPI_CS1, BCM2835_SPI_SPEED_8MHZ);
|
||||
```
|
||||
|
||||
**Pins:**
|
||||
|
||||
|NRF24L01 | RPI | P1 Connector |
|
||||
|----- |----------- | -------------|
|
||||
|VCC: | rpi-3v3 | (17) |
|
||||
|GND: | rpi-gnd | (25) |
|
||||
|CE: | rpi-gpio22 | (15) |
|
||||
|CSN: | rpi-gpio8 | (24) |
|
||||
|SCK: | rpi-sckl | (23) |
|
||||
|MOSI: | rpi-mosi | (19) |
|
||||
|MISO: | rpi-miso | (21) |
|
||||
|-----|-----------|-------------|
|
||||
| VCC | rpi-3v3 | (17) |
|
||||
| GND | rpi-gnd | (25) |
|
||||
| CE | rpi-gpio22 | (15) |
|
||||
| CSN | rpi-gpio8 | (24) |
|
||||
| SCK | rpi-sckl | (23) |
|
||||
| MOSI | rpi-mosi | (19) |
|
||||
| MISO | rpi-miso | (21) |
|
||||
|
||||
|
||||
See http://www.airspayce.com/mikem/bcm2835/index.html for BCM2835 class documentation.
|
||||
Note: The BCM library has been customized slightly to allow use of hardware CE pins not
|
||||
in use for SPI, and to include a millis() function.
|
||||
|
||||
****************
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user