Commit 2869663f authored by TMRh20's avatar TMRh20

Due & RPi bugfix - #9 - root cause resolved

- Discovered a bug affecting Arduino Due using extended SPI methods, it
seems an extra delay is required before switching to TX mode
- Found the same bug affected the RPi, and removed all delays from
bcm2835 driver, since this bug caused the strange behaviour on RPi
parent ea987810
...@@ -205,10 +205,8 @@ uint8_t RF24::read_payload(void* buf, uint8_t data_len) ...@@ -205,10 +205,8 @@ uint8_t RF24::read_payload(void* buf, uint8_t data_len)
while ( --blank_len ){ while ( --blank_len ){
SPI.transfer(csn_pin,0xFF, SPI_CONTINUE); SPI.transfer(csn_pin,0xFF, SPI_CONTINUE);
delayMicroseconds(10);
} }
SPI.transfer(csn_pin,0xFF); SPI.transfer(csn_pin,0xFF);
delayMicroseconds(10);
}else{ }else{
while ( --data_len ){ while ( --data_len ){
*current++ = SPI.transfer(csn_pin,0xFF, SPI_CONTINUE); *current++ = SPI.transfer(csn_pin,0xFF, SPI_CONTINUE);
...@@ -531,9 +529,14 @@ void RF24::startListening(void) ...@@ -531,9 +529,14 @@ void RF24::startListening(void)
void RF24::stopListening(void) void RF24::stopListening(void)
{ {
ce(LOW); ce(LOW);
#if defined(__arm__)
delayMicroseconds(130);
#endif
flush_tx(); flush_tx();
flush_rx(); flush_rx();
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) ); write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
delayMicroseconds(130); //Found that adding this delay back actually increases response time delayMicroseconds(130); //Found that adding this delay back actually increases response time
} }
......
...@@ -54,7 +54,7 @@ uint8_t RF24::read_register(uint8_t reg) ...@@ -54,7 +54,7 @@ uint8_t RF24::read_register(uint8_t reg)
*ptx++ = ( R_REGISTER | ( REGISTER_MASK & reg ) ); *ptx++ = ( R_REGISTER | ( REGISTER_MASK & reg ) );
*ptx++ = NOP ; // Dummy operation, just for reading *ptx++ = NOP ; // Dummy operation, just for reading
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2); bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
result = *++prx; // result is 2nd byte of receive buffer result = *++prx; // result is 2nd byte of receive buffer
...@@ -73,7 +73,7 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value) ...@@ -73,7 +73,7 @@ uint8_t RF24::write_register(uint8_t reg, uint8_t value)
*ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) ); *ptx++ = ( W_REGISTER | ( REGISTER_MASK & reg ) );
*ptx = value ; *ptx = value ;
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2); bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
status = *prx++; // status is 1st byte of receive buffer status = *prx++; // status is 1st byte of receive buffer
...@@ -129,7 +129,6 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp ...@@ -129,7 +129,6 @@ uint8_t RF24::write_payload(const void* buf, uint8_t len, const uint8_t writeTyp
while ( blank_len-- ) while ( blank_len-- )
*ptx++ = 0; *ptx++ = 0;
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size); bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
status = *prx; // status is 1st byte of receive buffer status = *prx; // status is 1st byte of receive buffer
...@@ -164,11 +163,8 @@ uint8_t RF24::read_payload(void* buf, uint8_t len) ...@@ -164,11 +163,8 @@ uint8_t RF24::read_payload(void* buf, uint8_t len)
// Size has been lost during while, re affect // Size has been lost during while, re affect
size = data_len + blank_len + 1; // Add register value to transmit buffer size = data_len + blank_len + 1; // Add register value to transmit buffer
if(dynamic_payloads_enabled){ bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, size);
}else{
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, size);
}
// 1st byte is status // 1st byte is status
status = *prx++; status = *prx++;
...@@ -534,8 +530,9 @@ void RF24::stopListening(void) ...@@ -534,8 +530,9 @@ void RF24::stopListening(void)
bcm2835_gpio_write(ce_pin, LOW); bcm2835_gpio_write(ce_pin, LOW);
flush_tx(); flush_tx();
flush_rx(); flush_rx();
delayMicroseconds(150);
write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) ); write_register(CONFIG, ( read_register(CONFIG) ) & ~_BV(PRIM_RX) );
delayMicroseconds(130); delayMicroseconds(150);
} }
/****************************************************************************/ /****************************************************************************/
...@@ -736,7 +733,7 @@ uint8_t RF24::getDynamicPayloadSize(void) ...@@ -736,7 +733,7 @@ uint8_t RF24::getDynamicPayloadSize(void)
spi_txbuff[0] = R_RX_PL_WID; spi_txbuff[0] = R_RX_PL_WID;
spi_rxbuff[1] = 0xff; spi_rxbuff[1] = 0xff;
bcm2835_spi_transfernbd( (char *) spi_txbuff, (char *) spi_rxbuff, 2); bcm2835_spi_transfernb( (char *) spi_txbuff, (char *) spi_rxbuff, 2);
if(spi_rxbuff[1] > 32) { flush_rx(); return 0; } if(spi_rxbuff[1] > 32) { flush_rx(); return 0; }
......
...@@ -584,19 +584,9 @@ uint8_t bcm2835_spi_transfer(uint8_t value) ...@@ -584,19 +584,9 @@ uint8_t bcm2835_spi_transfer(uint8_t value)
return ret; return ret;
} }
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 // Writes (and reads) an number of bytes to SPI
void __bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len, uint8_t delay) void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len)
{ {
volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4; volatile uint32_t* paddr = bcm2835_spi0 + BCM2835_SPI0_CS/4;
volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4; volatile uint32_t* fifo = bcm2835_spi0 + BCM2835_SPI0_FIFO/4;
...@@ -623,15 +613,14 @@ void __bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len, uint8_t dela ...@@ -623,15 +613,14 @@ void __bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len, uint8_t dela
TXCnt++; TXCnt++;
} }
//Rx fifo not empty, so get the next received bytes //Rx fifo not empty, so get the next received bytes
while(! (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_DONE) ){}
if(TXCnt == len){ bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA); if(delay){ delayMicroseconds(20);}}
while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len )){ while(((bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_RXD))&&( RXCnt < len )){
rbuf[RXCnt] = bcm2835_peri_read_nb(fifo); rbuf[RXCnt] = bcm2835_peri_read_nb(fifo);
RXCnt++; RXCnt++;
} }
} }
delayMicroseconds(5); while(! (bcm2835_peri_read(paddr) & BCM2835_SPI0_CS_DONE) ){}
if(TXCnt == len){ bcm2835_peri_set_bits(paddr, 0, BCM2835_SPI0_CS_TA);}
} }
......
...@@ -1177,8 +1177,6 @@ extern "C" { ...@@ -1177,8 +1177,6 @@ extern "C" {
/// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received /// \param[in] len Number of bytes in the tbuf buffer, and the number of bytes to send/received
/// \sa bcm2835_spi_transfer() /// \sa bcm2835_spi_transfer()
extern void bcm2835_spi_transfernb(char* tbuf, char* rbuf, uint32_t len); 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 /// Transfers any number of bytes to and from the currently selected SPI slave
/// using bcm2835_spi_transfernb. /// 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