void send_packet() { u32 temp; for(u8 ch=0;ch<8;ch++) { temp=((s32)Channels[ch] * 0x1f1 / CHAN_MAX_VALUE + 0x5d9)<<3; packet[2*ch]=temp>>8; packet[2*ch+1]=temp; } for(u8 i=0; i<ADDRESS_LENGTH; i++) packet[16+i]=packet[23-i]; NRF24L01_WriteReg(NRF24L01_07_STATUS, 0x70); // Clear data ready, data sent, and retransmit NRF24L01_FlushTx(); NRF24L01_WritePayload(packet, PACKET_SIZE); // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power // settings change - we have plenty of time until next // packet. if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } }
static void send_search_packet() { uint8_t buf[1]; buf[0] = 0xff; // clear packet status bits and TX FIFO NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); if (rf_channel++ > 125) { rf_channel = 0; switch(data_rate) { case NRF24L01_BR_250K: data_rate = NRF24L01_BR_1M; break; case NRF24L01_BR_1M: data_rate = NRF24L01_BR_2M; break; case NRF24L01_BR_2M: data_rate = NRF24L01_BR_250K; break; } } set_rate_channel(data_rate, rf_channel); NRF24L01_WritePayload(buf, sizeof(buf)); ++packet_counter; }
u8 XN297_WritePayload(u8* msg, int len) { u8 packet[32]; u8 res; if (is_xn297) { res = NRF24L01_WritePayload(msg, len); } else { int last = 0; if (xn297_addr_len < 4) { // If address length (which is defined by receive address length) // is less than 4 the TX address can't fit the preamble, so the last // byte goes here packet[last++] = 0x55; } for (int i = 0; i < xn297_addr_len; ++i) { packet[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i]; } for (int i = 0; i < len; ++i) { // bit-reverse bytes in packet u8 b_out = bit_reverse(msg[i]); packet[last++] = b_out ^ xn297_scramble[xn297_addr_len+i]; } if (xn297_crc) { int offset = xn297_addr_len < 4 ? 1 : 0; u16 crc = initial; for (int i = offset; i < last; ++i) { crc = crc16_update(crc, packet[i]); } crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len]; packet[last++] = crc >> 8; packet[last++] = crc & 0xff; } res = NRF24L01_WritePayload(packet, last); } return res; }
uint8_t XN297_WritePayload(uint8_t *data, int len, const uint8_t *rxAddr) { uint8_t packet[NRF24L01_MAX_PAYLOAD_SIZE]; uint16_t crc = 0xb5d2; for (int ii = 0; ii < RX_TX_ADDR_LEN; ++ii) { packet[ii] = rxAddr[RX_TX_ADDR_LEN - 1 - ii]; crc = crc16_ccitt(crc, packet[ii]); } for (int ii = 0; ii < len; ++ii) { const uint8_t bOut = bitReverse(data[ii]); packet[ii + RX_TX_ADDR_LEN] = bOut ^ xn297_data_scramble[ii]; crc = crc16_ccitt(crc, packet[ii + RX_TX_ADDR_LEN]); } crc ^= xn297_crc_xorout[len]; packet[RX_TX_ADDR_LEN + len] = crc >> 8; packet[RX_TX_ADDR_LEN + len + 1] = crc & 0xff; return NRF24L01_WritePayload(packet, RX_TX_ADDR_LEN + len + 2); }
// Helper for sending a packet // Assumes packet data has been put in tx_packet // and tx_payload_len has been set correctly static void send_packet() { // clear packet status bits and Tx/Rx FIFOs NRF24L01_WriteReg(NRF24L01_07_STATUS, (BV(NRF24L01_07_TX_DS) | BV(NRF24L01_07_MAX_RT))); NRF24L01_FlushTx(); NRF24L01_FlushRx(); // Transmit the payload NRF24L01_WritePayload(tx_packet, tx_payload_len); ++packet_counter; // Check and adjust transmission power. We do this after // transmission to not bother with timeout after power // settings change - we have plenty of time until next // packet. if (tx_power != Model.tx_power) { //Keep transmit power updated tx_power = Model.tx_power; NRF24L01_SetPower(tx_power); } }
uint8_t XN297_WritePayload(uint8_t* msg, int len) { uint8_t buf[32]; uint8_t res; int last = 0; if (xn297_addr_len < 4) { // If address length (which is defined by receive address length) // is less than 4 the TX address can't fit the preamble, so the last // byte goes here buf[last++] = 0x55; } int i; for (i = 0; i < xn297_addr_len; ++i) { buf[last++] = xn297_tx_addr[xn297_addr_len-i-1] ^ xn297_scramble[i]; } for (i = 0; i < len; ++i) { // bit-reverse bytes in packet uint8_t b_out = bit_reverse(msg[i]); buf[last++] = b_out ^ xn297_scramble[xn297_addr_len+i]; } if (xn297_crc) { int offset = xn297_addr_len < 4 ? 1 : 0; uint16_t crc = initial; int i; for (i = offset; i < last; ++i) { crc = crc16_update(crc, buf[i]); } crc ^= xn297_crc_xorout[xn297_addr_len - 3 + len]; buf[last++] = crc >> 8; buf[last++] = crc & 0xff; } res = NRF24L01_WritePayload(buf, last); return res; }
u16 ASSAN_callback() { switch (state) { // Bind case BIND0: //Config RX @1M NRF24L01_WriteReg(NRF24L01_05_RF_CH, RF_BIND_CHANNEL); NRF24L01_SetBitrate(NRF24L01_BR_1M); // 1Mbps NRF24L01_SetTxRxMode(RX_EN); state = BIND1; /* FALLTHROUGH */ case BIND1: //Wait for receiver to send the frames if( NRF24L01_ReadReg(NRF24L01_07_STATUS) & BV(NRF24L01_07_RX_DR)) { //Something has been received NRF24L01_ReadPayload(packet, PACKET_SIZE); if(packet[19]==0x13) { //Last frame received state = BIND2 | WAIT; //Switch to TX NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); //Prepare bind packet memset(packet,0x05,PACKET_SIZE-5); packet[15]=0x99; for(u8 i=0;i<4;i++) packet[16+i]=packet[23-i]; packet_count=0; return 10000; } } return 1000; case BIND2|WAIT: if(++packet_count == 27) // Wait 270ms in total... { packet_count = 0; state &= ~WAIT; } return 10000; case BIND2: // Send 20 packets packet_count++; if(packet_count==20) packet[15]=0x13; // different value for last packet NRF24L01_WritePayload(packet, PACKET_SIZE); if(packet_count==20) { state = DATA0 | WAIT; packet_count = 0; } return 22520; case DATA0|WAIT: if(++packet_count == 217) state &= ~WAIT; return 10000; // Normal operation case DATA0: // Bind Done PROTOCOL_SetBindState(0); NRF24L01_SetBitrate(NRF24L01_BR_250K); // 250Kbps NRF24L01_SetTxRxMode(TXRX_OFF); NRF24L01_SetTxRxMode(TX_EN); /* FALLTHROUGH */ case DATA1: case DATA4: // Change ID and RF channel NRF24L01_WriteRegisterMulti(NRF24L01_10_TX_ADDR, packet+20+4*hopping_frequency_no, ADDRESS_LENGTH); NRF24L01_WriteReg(NRF24L01_05_RF_CH, hopping_frequency[hopping_frequency_no]); hopping_frequency_no^=0x01; state=DATA2; return 2000; case DATA2: case DATA3: send_packet(); state++; // DATA 3 or 4 return 5000; } return 0; }
int main() { uint8 data; uint8 payload; char OutputString[8]; uint8 status; CyGlobalIntEnable; SPI_Start(); UART_Start(); UART_UartPutString("\n"); UART_UartPutString("Writing registers... \n"); // reflect TX_DS and MAX_RT interrupts as IRQ active low, enable 2-byte CRC, power-up, TX mode NRF24L01_WriteReg(NRF24L01_00_CONFIG, 0x4E); //01001110 // enable auto acknowledgement pipe 0 NRF24L01_WriteReg(NRF24L01_01_EN_AA, 0x01); //00000001 // 5 byte address width NRF24L01_WriteReg(NRF24L01_03_SETUP_AW, 0x03); //00000011 // 1 byte of payload on pipe 0 NRF24L01_WriteReg(NRF24L01_11_RX_PW_P0, 0x01); //00000001 UART_UartPutString("Reading registers... \n"); sprintf(OutputString, "Config: %x \n", NRF24L01_ReadReg(NRF24L01_00_CONFIG)); UART_UartPutString(OutputString); sprintf(OutputString, "EN_AA: %x \n", NRF24L01_ReadReg(NRF24L01_01_EN_AA)); UART_UartPutString(OutputString); sprintf(OutputString, "Setup_AW: %x \n", NRF24L01_ReadReg(NRF24L01_03_SETUP_AW)); UART_UartPutString(OutputString); sprintf(OutputString, "RX_PW_P0: %x \n", NRF24L01_ReadReg(NRF24L01_11_RX_PW_P0)); UART_UartPutString(OutputString); UART_UartPutString("\n"); for(;;) { //reading input LED_Write(!SW_Read()); payload = !SW_Read(); //sending data into TX FIFO NRF24L01_WritePayload(&payload, 1); //transmitting data CE_Write(1); CyDelayUs(10); CE_Write(0); //waiting for interrupt while (IRQ_Read()) ; //checking interrupt type (0x2E = TX_DS, RX FIFO empty) data = NRF24L01_ReadReg(NRF24L01_07_STATUS); sprintf(OutputString, "%x: ", data); UART_UartPutString(OutputString); // TX_DS = 0x20 MAX_RT = 0x10 if ((data & 0x20) || (data & 0x10)){ if ((data & 0x20)) UART_UartPutString("Data sent!\n"); if (data & 0x10) UART_UartPutString("Max RT achieved!\n"); } else { UART_UartPutString("Wrong interrupt?\n"); } //clearing status register NRF24L01_WriteReg(NRF24L01_07_STATUS, (1 << NRF24L01_07_RX_DR) | (1 << NRF24L01_07_TX_DS) | (1 << NRF24L01_07_MAX_RT)); //delay for debugging purposes CyDelay(750); } }