diff --git a/README.md b/README.md index 054d80d..d0f2c0e 100644 --- a/README.md +++ b/README.md @@ -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 \ No newline at end of file diff --git a/RPi/RF24/RF24.cpp b/RPi/RF24/RF24.cpp index 303fde0..c45afaf 100644 --- a/RPi/RF24/RF24.cpp +++ b/RPi/RF24/RF24.cpp @@ -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(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(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(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 ) { diff --git a/RPi/RF24/bcm2835.c b/RPi/RF24/bcm2835.c index 1c76a13..5c5e0c4 100644 --- a/RPi/RF24/bcm2835.c +++ b/RPi/RF24/bcm2835.c @@ -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); } diff --git a/RPi/RF24/bcm2835.h b/RPi/RF24/bcm2835.h index ab47838..f550fcb 100644 --- a/RPi/RF24/bcm2835.h +++ b/RPi/RF24/bcm2835.h @@ -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. diff --git a/RPi/RF24/examples/gettingstarted.cpp b/RPi/RF24/examples/gettingstarted.cpp index d4aeaa3..5539c4d 100644 --- a/RPi/RF24/examples/gettingstarted.cpp +++ b/RPi/RF24/examples/gettingstarted.cpp @@ -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); diff --git a/RPi/RF24/examples/gettingstarted_call_response.cpp b/RPi/RF24/examples/gettingstarted_call_response.cpp index 4444191..19a16cc 100644 --- a/RPi/RF24/examples/gettingstarted_call_response.cpp +++ b/RPi/RF24/examples/gettingstarted_call_response.cpp @@ -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. diff --git a/RPi/RF24/examples/pingpair_dyn.cpp b/RPi/RF24/examples/pingpair_dyn.cpp index b7e4d70..09f94e6 100644 --- a/RPi/RF24/examples/pingpair_dyn.cpp +++ b/RPi/RF24/examples/pingpair_dyn.cpp @@ -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 @@ -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 ) diff --git a/RPi/RF24/examples/transfer.cpp b/RPi/RF24/examples/transfer.cpp index c4e4ecb..9d55470 100644 --- a/RPi/RF24/examples/transfer.cpp +++ b/RPi/RF24/examples/transfer.cpp @@ -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