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 readRegister(uint8_t reg, uint8_t * value, uint8_t len){ csnLow(); SSPSend(®, 1); SSPReceive((uint8_t *)value, len); csnHi(); }
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::init() // Initializes pins to communicate with the MiRF module // Should be called in the early initializing phase at startup. { GPIO_InitTypeDef PORT; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC,ENABLE); // TODO: 根据情况更改 // Configure CE pin as output with Push-Pull PORT.GPIO_Speed = GPIO_Speed_50MHz; PORT.GPIO_Pin = nRF24_CE_PIN; PORT.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(nRF24_CE_PORT,&PORT); // Configure CS pin as output with Push-Pull PORT.GPIO_Pin = nRF24_CS_PIN; PORT.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(nRF24_CS_PORT,&PORT); // pinMode(cePin,OUTPUT); // pinMode(csnPin,OUTPUT); ceLow(); csnHi(); // Initialize spi module spi->begin(); }
void Nrf24l::flushRx(){ //清除RX FIFO 寄存器,应用于接收模式下。 //在传输应答信号过程中不应执行此指令。也就是说,若传输应答 //信号过程中执行此指令的话将使得应答信号不能被完整的传输。 csnLow(); spi->transfer( FLUSH_RX ); 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::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::init() // Initializes pins to communicate with the MiRF module // Should be called in the early initializing phase at startup. { pinMode(cePin, OUTPUT); pinMode(csnPin, OUTPUT); ceLow(); csnHi(); // Initialize spi module spi->begin(); }
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(); }
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()); }
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(); }
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::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(); }
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 }
void Nrf24l::flushRx(){ csnLow(); spi->transfer( FLUSH_RX ); csnHi(); }
void Nrf24l::send_end() { csnHi(); // Pull up chip select ceHi(); // Start transmission }
void flushRx(){ uint8_t result = FLUSH_RX; csnLow(); SSPSend(&result, 1); csnHi(); }