#include #include #include #include #include #include "nrf24l01.h" #include "nrf24l01_definitions.h" #include "uart_debug.h" /* TODO * - Build a state machine that tracks the mode the NRF is set to * - Configuration of NRF24L01 and startup * - Send and Receive functions * - Interrupt handling for Send and Receive */ void Print_Register_Contents(uint8_t address); /* Startup and initial configuration of the NRF24L01 */ void Initialize_NRF24L01(void) { CONFIG_REGISTER configRegisterContents = {.byte = 0x0}; /* Configure the AVR pins for the nrf24l01 */ /* Set up the NRF24L01 */ NRF_CE_DDR |= (1 << NRF_CE_PIN); NRF_CSN_DDR |= (1 << NRF_CSN_PIN); NRF_CSN_PORT |= (1 << NRF_CSN_PIN); /* Ensure that the CE pin is set to 0*/ NRF_CE_PORT &= ~(1 << NRF_CE_PIN); /* Wait more than 10.3 ms to make sure the nrf24l01 is running */ _delay_ms(11); /* Write the PWR_UP bit of the CONFIG register (EN_CRC is also set) */ configRegisterContents.bits.EN_CRC = 0x1; configRegisterContents.bits.PWR_UP = 0x1; Write_NRF_Register(CONFIG_ADDRESS, configRegisterContents.byte); /* Wait more than 1.5 ms for the change to take effect */ _delay_ms(2); /* The NRF24L01 is now in the mode Standby-I */ } void Configure_Transmission(void) { FEATURE_REGISTER featureRegisterContents = {.byte = 0x0}; DYNPD_REGISTER dyndpRegisterContents = {.byte = 0x0}; /* * - Length of CRC (CRCO in CONFIG) * - Enable auto acknowledgment (EN_AA) * -> Register already set correctly after reset * - Enable data pipes (EN_RXADDR)? * -> Two pipes are already enabled on reset * - Set up address width (SETUP_AW) * -> 3 bytes * - Automatic Retransmission (SETUP_RETR) * -> ARD = 0b0000 * -> 3 retransmits -> ARC = 0b0011 * -> Register already set correctly after reset * - RF Channel (RF_CH) * -> RF_CH = 0b1010000 * - RF Setup (RF_SETUP) * -> first use reset values, can be fine tuned later * - Enable dynamic payload length (DYNPD) -> command activate + 0x73, then set bits in FEATURE? */ /* Set the address width to 3 bytes */ //Write_NRF_Register(0x03, 0x1); /* Set the frequency to 1450 MHz */ Write_NRF_Register(RF_CH_ADDRESS, 0x32); /* Enable dynamic payload length */ Send_Activate_Command(); featureRegisterContents.bits.EN_DPL = 1; // enable dynamic payload length Write_NRF_Register(FEATURE_ADDRESS, featureRegisterContents.byte); /* set dynamic payload length for all data pipes */ dyndpRegisterContents.bits.DPL_P0 = 1; dyndpRegisterContents.bits.DPL_P1 = 1; dyndpRegisterContents.bits.DPL_P2 = 1; dyndpRegisterContents.bits.DPL_P3 = 1; dyndpRegisterContents.bits.DPL_P4 = 1; dyndpRegisterContents.bits.DPL_P5 = 1; Write_NRF_Register(DYNPD_ADDRESS, dyndpRegisterContents.byte); /* Set the TX address */ Set_TX_Address(0x123456); Set_RX_P0_Address(0x123456); // TODO: set addresses for all data pipes } void Send_Test_Message(void) { uint8_t buffer[4] = {0xDE, 0xAD, 0xBE, 0xEF}; bool transmissionFinished = false; uint8_t statusContent = 0; uint8_t registerContent[5]; STATUS_REGISTER statusRegisterContents = {.byte = 0x0}; uint8_t lengthRead; char debugString[50] = ""; uint32_t timeout = 0; /* TODO: * - if needed: PRIM_RX = 0 * - Set CE = 1 for more than 10 us * - Wait until the transmission is finished * - Read number of retries for debug purposes * - Check if the FIFO is empty -> if not, flush it * - reset the interupts of the STATUS */ Write_Message_To_TX_FIFO(4, buffer); /* Set CE = 1 for more than 10 us */ NRF_CE_PORT |= (1 << NRF_CE_PIN); _delay_us(15); NRF_CE_PORT &= ~(1 << NRF_CE_PIN); do { _delay_ms(1); lengthRead = Read_NRF_Register(STATUS_ADDRESS, &(statusRegisterContents.byte)); /* TODO: use funtion to read status register -> no overflow possible, only one NOP transfer needed, not two */ if (lengthRead > 1) { sprintf(debugString, "%s\r\n", "Read error"); Print_Debug_String(debugString); } if (statusRegisterContent.bits.TX_DS == true) { transmissionFinished = true; sprintf(debugString, "%s\r\n", "TX fin"); Print_Debug_String(debugString); } if (statusRegisterContent.bits.MAX_RT == true) { transmissionFinished = true; sprintf(debugString, "%s\r\n", "max ret"); Print_Debug_String(debugString); } timeout ++; } while ((transmissionFinished == false) && (timeout < 0xFF)); if (timeout >= 0xFF) { sprintf(debugString, "%s\r\n", "timeout"); Print_Debug_String(debugString); } /* Reset the interrupts */ lengthRead = Read_NRF_Register(STATUS_ADDRESS, statusRegisterContents); /* TODO: use status register read function */ statusContent = registerContent[0] & 0x0F; statusRegisterContents.bits.RX_DR = false; statusRegisterContents.bits.TX_DS = false; statusRegisterContents.bits.MAX_RT = false; Write_NRF_Register(STATUS_ADDRESS, statusContent); // TODO: flush FIFO if an error occured } void Print_Register_Contents(uint8_t address) { uint8_t registerContent[5]; uint8_t lengthRead; char debugString[50] = ""; char registerContentString[30]; lengthRead = Read_NRF_Register(address, registerContent); registerContentString[0] = '\0'; for (uint8_t i = 0; i < lengthRead; i++) { sprintf(registerContentString, "%s0x%x ", registerContentString, registerContent[i]); } sprintf(debugString, "%s\r\n", registerContentString); Print_Debug_String(debugString); } /* Send a message: * - Set PRIM_RX = 0 and add one message to the TX-FIFO * - Set CE=1 for more than 10 us * - The NRF takes 130 us to enter the TX Mode * - An Interrupt is generated once the * - */ /* Set the NRF to RX Mode */ /* Disable the RX Mode */ uint8_t Read_NRF_Status_Register(void) { NRF_CSN_PORT &= ~(1 << NRF_CSN_PIN); // Start the transmission SPDR = 0XFF; while(!(SPSR & (1<