/* use only after Packet_Received(); function can clear interrupt in worst case scenario if packet is received, function will fill RX_Buffer with received data */ void Receive_Packet(void *Buffer){ uint8_t Length, Status, FIFO_Status; uint8_t Loop_Counter; Status=SPI_Read_Register(STATUS); // read register STATUS's value if( (Status&RX_DR)!=0 ){ // if receive data ready (RX_DR) interrupt Loop_Counter=0; do{ Length=SPI_Read_Register(R_RX_PL_WID); SPI_Read_Buffer(R_RX_PAYLOAD,Buffer,Length);// read receive payload from RX_FIFO buffer FIFO_Status=SPI_Read_Register(FIFO_STATUS); Loop_Counter++;//emptied one FIFO, exit loop after FIFO_Size cycles to prevent freezing }while( ((FIFO_Status&FIFO_STATUS_RX_EMPTY)==0) && (Loop_Counter<FIFO_Size) ); //while not empty and not stuck } SPI_Write_Register(STATUS,RX_DR);// clear RX_DR interrupt flag }
/* Command: ACTIVATE This write command followed by data 0x73 activates the following features: • R_RX_PL_WID • W_ACK_PAYLOAD • W_TX_PAYLOAD_NOACK A new ACTIVATE command with the same data deactivates them again. This is executable in power down or stand by modes only. The R_RX_PL_WID, W_ACK_PAYLOAD, and W_TX_PAYLOAD_NOACK features registers are initially in a deactivated state; a write has no effect, a read only results in zeros on MISO. To activate these registers, use the ACTIVATE command followed by data 0x73. Then they can be accessed as any other register. Use the same command and data to deactivate the registers again. summary: Check if activated, if not activated; activate Run before putting device in rx-mode */ void Activate_Feature_registers(){ uint8_t Feature; uint8_t Data=ACTIVATE_Features; Feature=SPI_Read_Register(FEATURE); if(Feature==0){ //not activated yet SPI_Write_Buffer(ACTIVATE,&Data,1); } }
//switches module to TX-mode void Select_TX_Mode(){ uint8_t Config; SPI_Write_Command(FLUSH_TX); //flush TX Chip_Disable(); //without this, the module won't switch modes properly Config=SPI_Read_Register(CONFIG); //keep CONFIG's value if( (Config&PRIM_RX)!=0 ){ //switch if in RX-mode SPI_Write_Register(CONFIG, Config&(~PRIM_RX)); //clear PRIM_RX in CONFIG's value and write it back back } Chip_Enable(); //without this, the module won't switch modes properly }
__interrupt void IRQHandler_PortD_nRF(void) { IRQ_Printf("(IRQ)"); BYTE status = SPI_Read_Register(STATUS); IRQ_PrintStatus(status); #if(Enable_RX_IRQ == 1) if(( status & (bit_RX_DR) ) != 0)//Rx IRQ was triggered { BYTE fifo_Status; do { SPI_Read_Buf(RD_RX_PLOAD,RxData,RX_DataSize); ProcessUserData_inIRQ(); nRF_ClearStatus( bit_RX_DR ); fifo_Status = SPI_Read_Register(FIFO_STATUS); IRQ_Printf(" FifoStatus: "); IRQ_PrintfHex(fifo_Status); IRQ_Printf("\n\r"); }while((fifo_Status & 0x01) == 0 ); } #endif #if(Enable_TX_IRQ == 1) if( ( status & (bit_TX_DS ) ) != 0 ) { nRF_ClearStatus(bit_TX_DS); } #endif #if(Enable_RT_IRQ == 1) if( ( status & (bit_MAX_RT) ) != 0 )//check other IRQs { nRF_ClearStatus(bit_MAX_RT); } #endif }
//switches module to RX-mode, use after Send_Packet to receive data void Select_RX_Mode(){ uint8_t Value; SPI_Write_Command(FLUSH_RX); //flush RX Value=SPI_Read_STATUS(); SPI_Write_Register(STATUS,Value); //clear RX_DR or TX_DS or MAX_RT interrupt flag Chip_Disable(); //without this, the module won't switch modes properly Value=SPI_Read_Register(CONFIG); //keep CONFIG's value if( (Value&PRIM_RX)==0 ){ //switch if NOT in RX-mode SPI_Write_Register(CONFIG, Value|PRIM_RX); //set PRIM_RX in CONFIG's value and write it back back } Chip_Enable(); //without this, the module won't switch modes properly }
//send any data type not greater than Payload_Length, returns true on success bool Send_Packet(const void *Buffer, uint8_t Length){ uint8_t FIFO_Status; uint8_t Payload[Payload_Length]; if(Length>Payload_Length){ return false; } memcpy(Payload, Buffer, Length); //void * memcpy ( void * destination, const void * source, size_t num ) returns destination Select_TX_Mode(); Chip_Disable(); //prevent device from sending packet after 1 byte FIFO_Status=SPI_Read_Register(FIFO_STATUS); //read register FIFO_STATUS's value if( (FIFO_Status&FIFO_STATUS_TX_FULL)==0 ){ //if not full, send data (write buff) SPI_Write_Buffer(W_TX_PAYLOAD, Payload, Payload_Length); //writes data to buffer } else{ return false; } Chip_Enable(); //done with updating payload return true; }
/* returns true if carrier detected, result is volatile wait at least 150us before polling again */ bool Carrier_Detected(){ return (SPI_Read_Register(CD) & CD_CD) != 0; }