void Nrf24l::send_head() // Sends a data package to the default address. Be sure to send the correct // amount of bytes as configured as payload on the receiver. { uint8_t status; status = getStatus(); while (PTX) { status = getStatus(); //TX_DS 5 0 R/W 数据发送完成中断。当数据发送完成后产生中 //断。如果工作在自动应答模式下,只有当接收到应答信号后此位置一。 //写‘1’清除中断。 //MAX_RT 4 0 R/W 达到最多次重发中断。 //写‘1’清除中断。 //如果MAX_RT 中断产生则必须清除后系统才 //能进行通讯。 if((status & ((1 << TX_DS) | (1 << MAX_RT)))){ PTX = 0; break; } } // Wait until last paket is send ceLow(); powerUpTx(); // Set to transmitter mode , Power up csnLow(); // Pull down chip select spi->transfer( FLUSH_TX ); // Write cmd to flush tx fifo csnHi(); // Pull up chip select csnLow(); // Pull down chip select //W_RX_PAYLOAD 1010 0000 写TX 有效数据:1-32 字节。写操作从字节0 开始。 //应用于发射模式下 spi->transfer( W_TX_PAYLOAD ); // Write cmd to write payload }
void Nrf24l::send(uint8_t * value) // Sends a data package to the default address. Be sure to send the correct // amount of bytes as configured as payload on the receiver. { uint8_t status; status = getStatus(); while (PTX) { status = getStatus(); if((status & ((1 << TX_DS) | (1 << MAX_RT)))){ PTX = 0; break; } } // Wait until last paket is send ceLow(); powerUpTx(); // Set to transmitter mode , Power up csnLow(); // Pull down chip select spi->transfer( FLUSH_TX ); // Write cmd to flush tx fifo csnHi(); // Pull up chip select csnLow(); // Pull down chip select spi->transfer( W_TX_PAYLOAD ); // Write cmd to write payload transmitSync(value,payload); // Write payload csnHi(); // Pull up chip select ceHi(); // Start transmission }
extern void Nrf24l::getData(uint8_t * data) // Reads payload bytes into data array //读RX 有效数据:1-32 字节。读操作全部从字节0 开始。当读RX //有效数据完成后,FIFO 寄存器中有效数据被清除。 //应用于接收模式下。 { csnLow(); // Pull down chip select spi->transfer( R_RX_PAYLOAD ); // Send cmd to read rx payload transferSync(data,data,payload); // Read payload csnHi(); // Pull up chip select // NVI: per product spec, p 67, note c: // "The RX_DR IRQ is asserted by a new packet arrival event. The procedure // for handling this interrupt should be: 1) read payload through SPI, // 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more // payloads available in RX FIFO, 4) if there are more data in RX FIFO, // repeat from step 1)." // So if we're going to clear RX_DR here, we need to check the RX FIFO // in the dataReady() function // NVI:每个产品的规格,第67页,注三: //“的RX_DR IRQ是断言一个新的数据包到达事件的过程 //处理这个中断应该是:1)通过SPI读取有效负载, //2)明确RX_DR IRQ,3)读FIFO_STATUS,以检查是否有更多的 //在RX FIFO中可用的有效载荷,4)如果在RX FIFO更多的数据, //重复从步骤1开始)。“ //所以,如果我们要在这里清除RX_DR,我们需要检查RX FIFO //在dataReady()函数 configRegister(STATUS,(1<<RX_DR)); // Reset status register }
void Radio::reUseTX() { // Clear max retry flag. write_register(STATUS, _BV(MAX_RT)); csnLow(); HalfDuplexSPI::byte(REUSE_TX_PL); csnHigh(); }
byte nRF24L01p::payLoadWidth(){ csnLow(); SPI.transfer(R_RX_PL_WID); byte _width=SPI.transfer(0x00); csnHigh(); return _width; }
byte nRF24L01p::readReg(byte _reg){ csnLow(); _status=SPI.transfer(_reg & REGISTERS); byte _byteRead=SPI.transfer(0x00); csnHigh(); return _byteRead; }
void readRegister(uint8_t reg, uint8_t * value, uint8_t len){ csnLow(); SSPSend(®, 1); SSPReceive((uint8_t *)value, len); csnHi(); }
void Nrf24l::readRegister(uint8_t reg, uint8_t * value, uint8_t len) // Reads an array of bytes from the given start position in the MiRF registers. { csnLow(); spi->transfer(R_REGISTER | (REGISTER_MASK & reg)); transferSync(value,value,len); csnHi(); }
void Nrf24l::writeRegister(uint8_t reg, uint8_t * value, uint8_t len) // Writes an array of bytes into inte the MiRF registers. { csnLow(); spi->transfer(W_REGISTER | (REGISTER_MASK & reg)); transmitSync(value,len); csnHi(); }
void Nrf24l::configRegister(uint8_t reg, uint8_t value) // Clocks only one byte into the given MiRF register { csnLow(); spi->transfer(W_REGISTER | (REGISTER_MASK & reg)); spi->transfer(value); csnHi(); }
void Nrf24l::flushRx(){ //清除RX FIFO 寄存器,应用于接收模式下。 //在传输应答信号过程中不应执行此指令。也就是说,若传输应答 //信号过程中执行此指令的话将使得应答信号不能被完整的传输。 csnLow(); spi->transfer( FLUSH_RX ); csnHi(); }
void nRF24L01p::writeReg(byte _reg, char* _data, byte _numBytes){ csnLow(); _status=SPI.transfer(W_REGISTER | (_reg & REGISTERS)); for(byte it=0; it<_numBytes; it++){ SPI.transfer(_data[it]); } csnHigh(); }
uint8_t Radio::get_status(void) { csnLow(); uint8_t status = HalfDuplexSPI::byte(NOP); csnHigh(); return status; }
uint8_t Radio::flush_tx(void) { csnLow(); uint8_t status = HalfDuplexSPI::byte(FLUSH_TX); csnHigh(); return status; }
uint8_t Radio::write_register(uint8_t reg, uint8_t value) { csnLow(); uint8_t status = HalfDuplexSPI::byte(W_REGISTER | (REGISTER_MASK & reg)); HalfDuplexSPI::byte(value); csnHigh(); return status; }
uint8_t Radio::read_register(uint8_t reg) { csnLow(); HalfDuplexSPI::byte(R_REGISTER | (REGISTER_MASK & reg)); uint8_t result = HalfDuplexSPI::byte(0xff); csnHigh(); return result; }
uint8_t Radio::write_register(uint8_t reg, const uint8_t *buf, uint8_t len) { csnLow(); uint8_t status = HalfDuplexSPI::byte(W_REGISTER | (REGISTER_MASK & reg)); while (len--) { HalfDuplexSPI::byte(*buf++); } csnHigh(); return status; }
void writeRegister(uint8_t reg, uint8_t * value, uint8_t len){ uint8_t* rx = (uint8_t*)malloc(sizeof(uint8_t)*(len+1)); rx[0] = W_REGISTER | (REGISTER_MASK & reg); uint8_t a; for(a = 1; a < len+1; a++){ rx[a] = value[a-1]; } csnLow(); free(rx); SSPSend(rx, len+1); csnHi(); }
uint8_t Radio::read_register(uint8_t reg, uint8_t *buf, uint8_t len) { csnLow(); uint8_t status = HalfDuplexSPI::byte(R_REGISTER | (REGISTER_MASK & reg)); while (len--) { *buf++ = HalfDuplexSPI::byte(0xff); } csnHigh(); return status; }
void send_rf(uint8_t * value) // Sends a data package to the default address. Be sure to send the correct // amount of bytes as configured as payload on the receiver. { uint8_t status; status = getStatus(); while (PTX) { status = getStatus(); if((status & ((1 << TX_DS) | (1 << MAX_RT)))){ PTX = 0; break; } } // Wait until last paket is send ceLow(); powerUpTx(); // Set to transmitter mode , Power up csnLow(); uint8_t result = FLUSH_TX; SSPSend(&result, 1); csnHi(); uint8_t* rx = (uint8_t*)malloc(sizeof(uint8_t)*(payload+1)); rx[0] = W_TX_PAYLOAD; uint8_t a; for(a = 1; a < payload+1; a++){ rx[a] = value[a-1]; } csnLow(); SSPSend(rx, payload+1); free(rx); csnHi(); ceHi(); // Start transmission while(isSending()); }
boolean nRF24L01p::send(boolean _modeSend){ if(_prim_tx==false){ _txIndex=32; return false; } if(_prim_rx==true){ ceLow(); primPTX(); } csnLow(); if(_modeSend==false || (_prim_rx && _prim_tx)){ SPI.transfer(W_TX_PAYLOAD); }else{ SPI.transfer(W_TX_PAYLOAD_NOACK); } for(int i=0;i<_txIndex;i++){ SPI.transfer(_txPayLoad[i]); } csnHigh(); cePulse(); unsigned long tmC1=micros(); while(1){ if(bitRead(getStatus(),5)){ //writeReg(STATUS,_status|(1<<6)); writeReg(STATUS,_status|(1<<5)); writeReg(STATUS,_status|(1<<4)); break; } if(bitRead(getStatus(),4)){ writeReg(STATUS,_status|(1<<4)); cePulse(); } unsigned long tmC2=micros(); if(tmC2-tmC1>100L){ //was 250000L - lowered to make the timeout wait much shorter //Serial.println("send(SLOW) returned false"); //Serial.println("connection lost "); return false; } } _txIndex=0; if(_prim_rx==true){ primPRX(); ceHigh(); } return true; }
extern void Nrf24l::getData(uint8_t * data) // Reads payload bytes into data array { csnLow(); // Pull down chip select spi->transfer( R_RX_PAYLOAD ); // Send cmd to read rx payload transferSync(data,data,payload); // Read payload csnHi(); // Pull up chip select // NVI: per product spec, p 67, note c: // "The RX_DR IRQ is asserted by a new packet arrival event. The procedure // for handling this interrupt should be: 1) read payload through SPI, // 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more // payloads available in RX FIFO, 4) if there are more data in RX FIFO, // repeat from step 1)." // So if we're going to clear RX_DR here, we need to check the RX FIFO // in the dataReady() function configRegister(STATUS,(1<<RX_DR)); // Reset status register }
void Nrf24l::configRegister(uint8_t reg, uint8_t value) // Clocks only one byte into the given MiRF register { csnLow(); // (REGISTER_MASK & reg) // 寄存器地址只有5位, // 通过 REGISTER_MASK(0x1F = 11111) 把输入的超过5位的地址给过滤成0 // 防止干扰到8-6位的操作寄存器指令 // W_REGISTER // 写寄存器命令 W_REGISTER = 0x20 = 00100000 // W_REGISTER 001A AAAA 写配置寄存器。AAAAA 指出写操作的寄存器地址 // 只有在掉电模式和待机模式下可操作。 spi->transfer(W_REGISTER | (REGISTER_MASK & reg)); spi->transfer(value); csnHi(); }
void Nrf24l::nrfSpiWrite(uint8_t reg, uint8_t *data, boolean readData, uint8_t len) { csnLow(); spi->transfer(reg); if (data) { uint8_t i; for(i = 0; i < len; ++i) { uint8_t readValue = spi->transfer(data[i]); if (readData) { data[i] = readValue; } } } csnHi(); }
boolean nRF24L01p::read(){ if(_prim_rx==false){ _rxIndex=32; return false; } _rxIndex=0; for(int it=0;it<32;it++){ _rxPayLoad[it]=0; } byte _plw=payLoadWidth(); csnLow(); SPI.transfer(R_RX_PAYLOAD); for(int it=0;it<_plw;it++){ _rxPayLoad[it]=SPI.transfer(0x00); } csnHigh(); writeReg(STATUS,1<<6); return true; }
void getData(uint8_t * data) // Reads payload bytes into data array { csnLow(); //SSPSend(R_RX_PAYLOAD,1); //for(a = 0; a < payload; a++){ readRegister(R_RX_PAYLOAD,data,payload); //} csnHi(); // NVI: per product spec, p 67, note c: // "The RX_DR IRQ is asserted by a new packet arrival event. The procedure // for handling this interrupt should be: 1) read payload through SPI, // 2) clear RX_DR IRQ, 3) read FIFO_STATUS to check if there are more // payloads available in RX FIFO, 4) if there are more data in RX FIFO, // repeat from step 1)." // So if we're going to clear RX_DR here, we need to check the RX FIFO // in the dataReady() function uint8_t result = (1<<RX_DR); writeRegister(STATUS, &result, 1); // Reset status register }
uint8_t Radio::write_payload(const void *buf, uint8_t data_len, const uint8_t writeType) { const uint8_t *current = reinterpret_cast<const uint8_t *>(buf); data_len = data_len < PAYLOAD_SIZE ? data_len : PAYLOAD_SIZE; uint8_t blank_len = PAYLOAD_SIZE - data_len; csnLow(); uint8_t status = HalfDuplexSPI::byte(writeType); while (data_len--) { HalfDuplexSPI::byte(*current++); } while (blank_len--) { HalfDuplexSPI::byte(0); } csnHigh(); return status; }
uint8_t Radio::read_payload(void *buf, uint8_t data_len) { uint8_t *current = reinterpret_cast<uint8_t *>(buf); data_len = data_len > PAYLOAD_SIZE ? PAYLOAD_SIZE : data_len; uint8_t blank_len = PAYLOAD_SIZE - data_len; csnLow(); uint8_t status = HalfDuplexSPI::byte(R_RX_PAYLOAD); while (data_len--) { *current++ = HalfDuplexSPI::byte(0xFF); } while (blank_len--) { HalfDuplexSPI::byte(0xff); } csnHigh(); return status; }
void nRF24L01p::writeReg(byte _reg, byte _data){ csnLow(); _status=SPI.transfer(W_REGISTER | (_reg & REGISTERS)); SPI.transfer(_data); csnHigh(); }
void nRF24L01p::flushTX(){ csnLow(); SPI.transfer(FLUSH_TX); csnHigh(); }