Commit 5ec5b06b authored by TMRh20's avatar TMRh20

Performance tweaks to address #9

- added delays to stop/start listening on RPi
- removed buffer flushes on start/stop listening for RPi
- added modified transfernbd function to BCM library - one has no
delays, also removed one delay period from both by waiting for RX data
- modified transfernb function to stop sending if RX fifo is full
- added delay to stoplistening for arduino etc. (actually seems to
improve performance)
- tests on-par with Arduino performance
parent b8312b53
......@@ -533,7 +533,7 @@ void RF24::stopListening(void)
flush_tx();
flush_rx();
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
delayMicroseconds(130); //Found that adding this delay back actually increases response time
}
/****************************************************************************/
......@@ -972,6 +972,7 @@ void RF24::enableAckPayload(void)
//
write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));
dynamic_payloads_enabled = true;
}
/****************************************************************************/
......
......@@ -32,7 +32,6 @@ uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
*ptx++ = NOP ; // Dummy operation, just for reading
}
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
//bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) buf, size);
status = *prx++; // status is 1st byte of receive buffer
......@@ -48,13 +47,14 @@ uint8_t RF24::read_register(uint8_t reg, uint8_t* buf, uint8_t len)
uint8_t RF24::read_register(uint8_t reg)
{
uint8_t result;
uint8_t * prx = spi_rxbuff;
uint8_t * ptx = spi_txbuff;
*ptx++ = ( R_REGISTER | ( REGISTER_MASK & reg ) );
*ptx++ = NOP ; // Dummy operation, just for reading
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
result = *++prx; // result is 2nd byte of receive buffer
......@@ -66,13 +66,14 @@ uint8_t RF24::read_register(uint8_t reg)
uint8_t RF24::write_register(uint8_t reg, uint8_t value)
{
uint8_t status;
uint8_t * prx = spi_rxbuff;
uint8_t * ptx = spi_txbuff;
*ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) );
*ptx = value ;
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
status = *prx++; // status is 1st byte of receive buffer
......@@ -162,7 +163,7 @@ uint8_t RF24::read_payload(void* buf, uint8_t len)
// 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);
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, size);
// 1st byte is status
status = *prx++;
......@@ -512,14 +513,14 @@ void RF24::startListening(void)
write_register(RX_ADDR_P0, pipe0_reading_address,addr_width);
}
// Flush buffers
flush_rx();
flush_tx();
//flush_rx();
//flush_tx();
// Go!
bcm2835_gpio_write(ce_pin, HIGH);
// wait for the radio to come up (130us actually only needed)
//delayMicroseconds(130);
delayMicroseconds(130);
}
/****************************************************************************/
......@@ -527,10 +528,10 @@ void RF24::startListening(void)
void RF24::stopListening(void)
{
bcm2835_gpio_write(ce_pin, LOW);
flush_tx();
flush_rx();
//flush_tx();
//flush_rx();
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
delayMicroseconds(130);
}
/****************************************************************************/
......@@ -567,9 +568,9 @@ bool RF24::write( const void* buf, uint8_t len, const bool multicast ){
// 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);
uint8_t status = write_register(STATUS,_BV(RX_DR) | _BV(TX_DS) | _BV(MAX_RT) );
//Max retries exceeded
if( status & _BV(MAX_RT)){
......@@ -731,7 +732,7 @@ uint8_t RF24::getDynamicPayloadSize(void)
spi_txbuff[0] = R_RX_PL_WID;
spi_rxbuff[1] = 0xff;
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
if(spi_rxbuff[1] > 32) { flush_rx(); return 0; }
......@@ -750,7 +751,6 @@ bool RF24::available(void)
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) )){
......@@ -946,7 +946,7 @@ void RF24::enableAckPayload(void)
//
// Enable dynamic payload on pipes 0 & 1
//
dynamic_payloads_enabled = true;
write_register(DYNPD,read_register(DYNPD) | _BV(DPL_P1) | _BV(DPL_P0));
}
......@@ -985,7 +985,7 @@ void RF24::writeAckPayload(uint8_t pipe, const void* buf, uint8_t len)
while ( data_len-- ){
*ptx++ = *current++;
}
bcm2835_spi_transfern( (char *) spi_txbuff, size);
bcm2835_spi_transfernb( (char *) spi_txbuff,(char *)spi_rxbuff, size);
}
......
......@@ -562,17 +562,15 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
// Maybe wait for TXD
while (!(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD)){
delayMicroseconds(10);
}
}
// Write to FIFO, no barrier
bcm2835_peri_write_nb(fifo, value);
// Wait for DONE to be set
while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)){
delayMicroseconds(10);
}
}
// Read any byte that was sent back by the slave while we sere sending to it
uint32_t ret = bcm2835_peri_read_nb(fifo);
......@@ -586,8 +584,19 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
return ret;
}
// Writes (and reads) an number of bytes to SPI
void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
{
__bcm2835_spi_transfernb(tbuf,rbuf,len,0);
}
void bcm2835_spi_transfernbd(char* tbuf, char* rbuf, uint32_t len)
{
__bcm2835_spi_transfernb(tbuf,rbuf,len,1);
}
// Writes (and reads) an number of bytes to SPI
void __bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len, uint8_t delay)
{
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
......@@ -608,28 +617,36 @@ void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
while((TXCnt < len)||(RXCnt < len))
{
// TX fifo not full, so add some more bytes
while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD))&&(TXCnt < len ))
while( (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_TXD ) && (TXCnt < len ) && !(bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXR) )
{
delayMicroseconds(10);
bcm2835_peri_write_nb(fifo, tbuf[TXCnt]);
TXCnt++;
}
//Rx fifo not empty, so get the next received bytes
while(! (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD) ){}
while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len ))
{
delayMicroseconds(10);
rbuf[RXCnt] = bcm2835_peri_read_nb(fifo);
RXCnt++;
}
if(delay){ delayMicroseconds(10); }
}
// Wait for DONE to be set
while (!(bcm2835_peri_read_nb(paddr) & BCM2835_SPI0_CS_DONE)){
delayMicroseconds(10);
}
// Set TA = 0, and also set the barrier
bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);
if(delay){delayMicroseconds(10);}
}
// Writes an number of bytes to SPI
void bcm2835_spi_writenb(char* tbuf, uint32_t len)
{
......
......@@ -1177,6 +1177,8 @@ extern "C" {
/// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
/// \sa bcm2835_spi_transfer()
extern void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len);
extern void bcm2835_spi_transfernbd(char* tbuf, char* rbuf, uint32_t len);
extern void __bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len,uint8_t delay);
/// Transfers any number of bytes to and from the currently selected SPI slave
/// using bcm2835_spi_transfernb.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment