/*
 25.10.2020 ad0x0
 */
#include "RF24.h"
#include "../spi/ad0x0_spi2.h"
#include "../admisc/ad0x0_timman.h"
#include "../usart/ad0x0_usart.h"
#include "../spi/ad0x0_spi_ext.h"
#include <string.h>

rf24_spi_regs_t *p_spi2_regs;
static pipe_data_t pipes_spi2[6];//пока для для rx и для tx одинаковые ПЕРЕДЕЛАТЬ!!!!!!!!!!!
static pipe_data_t pipe_musor;
static uint8_t ad0x0_enable_irq=0;
static uint32_t last_tx_irq_tick=0;
static uint16_t tx_in_frame=0,rx_in_frame=0,frame_max_ms=250;
static uint32_t frame_start_tick=0;
static int16_t ad0x0_rssi=100;//,ad0x0_rssi_max_count=1000;

static uint32_t get_frame_ms(uint32_t _tick_start){
	uint32_t t=(HAL_GetTick()<_tick_start)
		?((uint64_t)HAL_GetTick()+UINT32_MAX-_tick_start)
		:(HAL_GetTick()-_tick_start);
	return t;
}

static packet_data_t *get_pipe_packet_buf(uint8_t _pipe_index){
	return &pipes_spi2[_pipe_index].packet;
}
static packet_data_ack_t *get_pipe_ack_buf(uint8_t _pipe_index){
	return &pipes_spi2[_pipe_index].packet_ack;
}

static pipe_data_t *get_pipe_buf(uint8_t _pipe_index){
	return pipes_spi2 + _pipe_index;
}

static uint8_t scan_data[130];// 128 + в конце \n\0
static uint8_t scan_cur_ch;

//rf24_regs_t r_regs;

void rf24_spi2_powerUp(void)
{
	p_spi2_regs->set_ce(1);
	write_register_bits(&p_spi2_regs->_CONFIG, (1 << PWR_UP),0xff);
}

void rf24_spi2_powerDown(void)
{
	write_register_bits(&p_spi2_regs->_CONFIG, 0x0,~(1 << PWR_UP));
	p_spi2_regs->set_ce(0);
}

void rf24_spi2_enableRXPipe(uint8_t _pipe_index,uint8_t _payload_size,bool _enable_AutoAck,bool _enable_DYN_PL){
	if(_pipe_index>5)ad0x0_err();
	//pipes_spi2[_pipe_index].bytes_count_packet=_payload_size;
	write_register_bits(&p_spi2_regs->_EN_RXADDR,(1<<_pipe_index),~(1<<_pipe_index));
	switch(_pipe_index){
		case 0: write_register(&p_spi2_regs->_RX_PW_P0,_payload_size);break;
		case 1: write_register(&p_spi2_regs->_RX_PW_P1,_payload_size);break;
		case 2: write_register(&p_spi2_regs->_RX_PW_P2,_payload_size);break;
		case 3: write_register(&p_spi2_regs->_RX_PW_P3,_payload_size);break;
		case 4: write_register(&p_spi2_regs->_RX_PW_P4,_payload_size);break;
		case 5: write_register(&p_spi2_regs->_RX_PW_P5,_payload_size);break;
		default: ad0x0_err();
	}
	write_register_bits(&p_spi2_regs->_DYNPD, (1<<_pipe_index),~(1<<_pipe_index));//Enable dynamic payload length data pipe 0.
	write_register_bits(&p_spi2_regs->_EN_AA, (1<<_pipe_index),~(1<<_pipe_index));//
}

void rf24_spi2_setRateAndPA(rf24_datarate_e speed,rf24_pa_dbm_e _power)
{
	/*[RF_DR_LOW,RF_DR_HIGH]
	‘00’ – 1Mbps
	‘01’ – 2Mbps
	‘10’ – 250kbps
	Set RF output power in TX mode
	'00' –  -18dBm
	'01' –  -12dBm
	'10' –    -6dBm
	'11' –     0dBm*/
	uint8_t PA_and_Rate_clr_masr=~((1 << RF_DR_LOW) | (1 << RF_DR_HIGH) | 0x3);
	if(_power>3)ad0x0_err();
	if(speed==RF24_250KBPS)write_register_bits(&p_spi2_regs->_RF_SETUP, (1 << RF_DR_LOW)|_power,PA_and_Rate_clr_masr);else
	if(speed==RF24_2MBPS)write_register_bits(&p_spi2_regs->_RF_SETUP, (1 << RF_DR_HIGH)|_power,PA_and_Rate_clr_masr);else
	if(speed==RF24_1MBPS)write_register_bits(&p_spi2_regs->_RF_SETUP, _power,PA_and_Rate_clr_masr);else ad0x0_err();
}

/*‘0000’ – Wait 250µS
‘0001’ – Wait 500µS 
‘0010’ – Wait 750µS 
……..
‘1111’ – Wait 4000µS
Auto Retransmit Count
‘0000’ –Re-Transmit disabled
‘0001’ – Up to 1 Re-Transmit on fail of AA
……
‘1111’ – Up to 15 Re-Transmit on fail of AA*/
void rf24_spi2_setRetransmission(uint8_t delay, uint8_t count)
{
//	write_register(SETUP_RETR, (delay&0xf)<<ARD | (count&0xf)<<ARC);
	//write_register(&ad0x0_SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC);
	write_register(&p_spi2_regs->_SETUP_RETR,(delay&0xf)<<ARD | (count&0xf)<<ARC);
}

enum{
	xSCAN_INIT,
	xSCAN_NEXT
};
static void	cb_scan_channels(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t){
ad0x0_spi_ext_t *p_ext=(ad0x0_spi_ext_t*)p_spi_ext_t;	
static void (*p_cb_func_return)(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t);
static uint8_t sf_id_return;
	switch(_sf_id){
		case xSCAN_INIT:
			scan_cur_ch=0;
			sf_id_return=(uint8_t)p_ext->user_data0;
			p_cb_func_return=(p_ext_func_t)p_ext->user_pointer1;
			p_spi2_regs->powerUp();
			p_spi2_regs->set_ce(1);
			p_spi2_regs->ad0x0_spi_push(ADQS_DELAY_MS,2);
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xSCAN_NEXT,cb_scan_channels);
		break;
		case xSCAN_NEXT:
			scan_data[scan_cur_ch]=p_spi2_regs->_RPD.value ? '1' : '0';
			scan_cur_ch++;
			//write_register(&r_spi_regs._CONFIG,(1<<PWR_UP)|(1<<PRIM_RX));
			//PTX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!	
			//write_register(&p_spi2_regs->_CONFIG,(1<<PWR_UP));//PTX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			write_register(&p_spi2_regs->_RF_CH,scan_cur_ch);
			p_spi2_regs->ad0x0_spi_push(ADQS_DELAY_MS,1);
			read_register(&p_spi2_regs->_RPD);
	
			if(scan_cur_ch>=127){
				scan_cur_ch=0;
				p_spi2_regs->powerDown();
				p_spi2_regs->set_ce(0);
				if(ad0x0_usart_isReady())ad0x0_usart_txstr(scan_data);
				p_spi2_regs->ad0x0_spi_push_ext_setfunc(sf_id_return,p_cb_func_return);
			}else{				
				p_spi2_regs->ad0x0_spi_push_ext_setfunc(xSCAN_NEXT,cb_scan_channels);
			}	
		break;
		default:
			ad0x0_err();
		}
}

void	rf24_spi2_scan_channels(uint8_t _sf_id,void (*_p_cb_func)(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t)){
	//rf24_set_ce(1);
	p_spi2_regs->set_ce(1);
	scan_cur_ch=0;
	//p_spi2_regs->ad0x0_spi_push_ext_setfunc(0,cb_scan_channels);
	uint8_t h_ext;
	ad0x0_spi_ext_t *p_spi_ext_t=NULL;
	p_spi2_regs->ad0x0_spi_get_ext_async2(&h_ext,(void**)&p_spi_ext_t);//получить ячейку, ассоциированную с командой в очереди

	p_spi_ext_t->sf_id=xSCAN_INIT;
	p_spi_ext_t->user_data0=(uint32_t)_sf_id;
	p_spi_ext_t->user_pointer1=_p_cb_func;
	p_spi_ext_t->_p_post_cb_func = cb_scan_channels;

	p_spi2_regs->ad0x0_spi_push(ADQS_USE_EXT,h_ext);
}

/*_payload_size получается чтением из спи: read_register(&r_spi2_regs._R_RX_PL_WID);
_ack_payload_size - определяет PRX*/
static void	PRX_readPayload_transmitAck(uint8_t _pipe_index,uint8_t _payload_size, uint8_t _ack_payload_size){
	pipes_spi2[_pipe_index].bytes_count_packet=_payload_size;
	pipes_spi2[_pipe_index].spi_cmd=R_RX_PAYLOAD;
	p_spi2_regs->ad0x0_spi_push_txrx_dma_ext((uint8_t*)&pipes_spi2[_pipe_index].spi_cmd,(uint8_t*)&pipes_spi2[_pipe_index].spi_cmd,pipes_spi2[_pipe_index].bytes_count_packet+1);
				//делать до прерывания!!!! ПЕРЕДЕЛАТЬ!!!!!!
	pipes_spi2[_pipe_index].bytes_count_ack=_ack_payload_size;
	pipes_spi2[_pipe_index].packet_ack.id=pipes_spi2[_pipe_index].packet.id;
	pipes_spi2[_pipe_index].spi_cmd_ack=W_ACK_PAYLOAD | _pipe_index;
	p_spi2_regs->ad0x0_spi_push_txrx_dma_ext((uint8_t*)&pipes_spi2[_pipe_index].spi_cmd_ack,(uint8_t*)&pipe_musor.spi_cmd_ack,_ack_payload_size+1);
	rx_in_frame++;
}

static void PTX_transmit_pipe(uint8_t _pipe_index){
	pipes_spi2[_pipe_index].spi_cmd=W_TX_PAYLOAD;
	p_spi2_regs->ad0x0_spi_push_txrx_dma_ext((uint8_t*)&pipes_spi2[_pipe_index].spi_cmd,(uint8_t*)&pipe_musor.spi_cmd,sizeof(packet_data_t)+1);
	pipes_spi2[_pipe_index].packet.id++;
	tx_in_frame++;
}

static void PTX_read_Ack(uint8_t _pipe_index,uint8_t _ack_payload_size){
	if(_pipe_index>5)ad0x0_err();//дадада, всю херню отслеживаем, 
	pipes_spi2[_pipe_index].bytes_count_ack=_ack_payload_size;
	pipes_spi2[_pipe_index].spi_cmd_ack=R_RX_PAYLOAD;
	p_spi2_regs->ad0x0_spi_push_txrx_dma_ext((uint8_t*)&pipes_spi2[_pipe_index].spi_cmd_ack,(uint8_t*)&pipes_spi2[_pipe_index].spi_cmd_ack,
		pipes_spi2[_pipe_index].bytes_count_ack+1);
	rx_in_frame++;
}

static uint32_t get_last_tx_irq_ms(void){
	uint32_t t=(HAL_GetTick()<last_tx_irq_tick)
		?((uint64_t)HAL_GetTick()+UINT32_MAX-last_tx_irq_tick)
		:(HAL_GetTick()-last_tx_irq_tick);	
	return t;
}

static void init_pipes(void){
	if(sizeof(packet_data_t)!=32)ad0x0_err();
	for(uint8_t i=0;i<6;i++){
		pipes_spi2[i].bytes_count_packet=sizeof(packet_data_t);		
		memset((void*)&pipes_spi2[i].packet,0,sizeof(packet_data_t));
		pipes_spi2[i].bytes_count_ack=sizeof(packet_data_ack_t);
		memset((void*)&pipes_spi2[i].packet_ack,0,sizeof(packet_data_ack_t));
	}
}

void	rf24_spi2_set_ce(uint8_t _isHigh){
	extern void	rf24_set_ce(rf24_spi_regs_t *p, uint8_t _isHigh);
	rf24_set_ce(p_spi2_regs, _isHigh);
}

void	rf24_spi2_cmd(uint8_t _cmd){
	extern void spi_cmd(rf24_spi_regs_t *p, uint8_t _val);
	spi_cmd(p_spi2_regs, _cmd);
}

enum{
	xNRF24_PTX,
	xNRF24_PRX,
	xNRF24_RESET,
	xNRF24_ENABLE_PIPES,
	xNRF24_FEATURE,
	xNRF24_END,
	xNRF24_SCAN,
	xNRF24_PWR_UP_AND_CE
};

static void	rf24_init_cb(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t){
static bool isPRX=false;
	switch(_sf_id){
		case xNRF24_PRX:
			isPRX=true;
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_RESET,rf24_init_cb);
		break;
		case xNRF24_PTX:
			isPRX=false;
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_RESET,rf24_init_cb);
		break;
		case xNRF24_RESET:
			p_spi2_regs->powerDown();
			p_spi2_regs->set_ce(0);
			p_spi2_regs->ad0x0_spi_push(ADQS_DELAY_MS,2);
			write_register(&p_spi2_regs->_CONFIG, 0x0C); // Reset NRF_CONFIG and enable 16-bit CRC.			
			//In 250kbps mode (even when the payload is not in ACK) the ARD must be 500µS or more	
			write_register(&p_spi2_regs->_FEATURE, (1<<EN_DPL)|(1<<EN_ACK_PAY)|(1<<EN_DYN_ACK));		
		/*эта скотина при отладке оставляет флаги прерываний, если их не очистить, 
		то новые прерывания не вызовутся*/
			write_register(&p_spi2_regs->_STATUS, 0x7E);
			p_spi2_regs->setRetransmission(15,0);//нет повторным попыткам
			p_spi2_regs->setRateAndPA(RF24_250KBPS,RF24_PA_MIN);
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_FEATURE,rf24_init_cb);
		break;
		case xNRF24_FEATURE:
			__asm("nop");
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_SCAN,rf24_init_cb);
		break;	
		case xNRF24_SCAN:
			rf24_spi2_scan_channels(xNRF24_ENABLE_PIPES,rf24_init_cb);
			
		break;
		case xNRF24_ENABLE_PIPES:
			__asm("nop");
		p_spi2_regs->enableRXPipe(0x0,sizeof(packet_data_ack_t),true,true);	
		p_spi2_regs->enableRXPipe(0x1,sizeof(packet_data_ack_t),true,true);
			p_spi2_regs->spi_cmd(FLUSH_TX);
			p_spi2_regs->spi_cmd(FLUSH_RX);
			write_register(&p_spi2_regs->_STATUS, 0x7E);
			read_register5(&p_spi2_regs->_RX_ADDR_P0);
			read_register5(&p_spi2_regs->_RX_ADDR_P1);
			read_register5(&p_spi2_regs->_TX_ADDR);
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_PWR_UP_AND_CE,rf24_init_cb);
		break;	
		case xNRF24_PWR_UP_AND_CE:
			//uint8_t cfg = read_register(NRF_CONFIG);
	// if not powered up then power up and wait for the radio to initialize
			write_register(&p_spi2_regs->_RF_CH,0x40);//канал 64	
			
			p_spi2_regs->powerUp();
			p_spi2_regs->set_ce(1);
			p_spi2_regs->ad0x0_spi_push(ADQS_DELAY_MS,2);
			//rf24_start_tx();
			//rf24_start_rx();
			if(isPRX)p_spi2_regs->PRX_start(0,8);else p_spi2_regs->PTX_start(0);
			//write_register(&p_spi2_regs->_STATUS, 0x7E);
		read_register(&p_spi2_regs->_FIFO_STATUS);
		read_register(&p_spi2_regs->_STATUS);
		break;
		
		default:
			ad0x0_err();
	}
}

//------------------------------------------------
enum{
	xNRF24_IRQ_RX,
	xNRF24_IRQ_RX_READ_OK
};

void	rf24_spi2_irq_rx(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t){
//3723080032124353354B4E00
	static uint8_t rx_pipe=0xFF;
	switch(_sf_id){
		case xNRF24_IRQ_RX:
			if(p_spi2_regs->_STATUS.value & (1<<TX_DS)){//ad0x0_err();//на этом этапе ниче не отправляем
				//это в ответочку на W_ACK_PAYLOAD приходит, сбрасывам флажок				
				tx_in_frame++;
				write_register_bits(&p_spi2_regs->_STATUS,(1<<TX_DS),0xFF);
			}
			if(p_spi2_regs->_STATUS.value & (1<<MAX_RT)){//ad0x0_err();//на этом этапе ниче не отправляем
				p_spi2_regs->spi_cmd(FLUSH_TX);
				write_register_bits(&p_spi2_regs->_STATUS,(1<<MAX_RT),0xFF);
			}
			if(p_spi2_regs->_STATUS.value & (1<<TX_FULL)){//ad0x0_err();//на этом этапе ниче не отправляем
				p_spi2_regs->spi_cmd(FLUSH_TX);
				write_register_bits(&p_spi2_regs->_STATUS,(1<<TX_FULL),0xFF);
			}
		//
		if(p_spi2_regs->_STATUS.value & (1<<RX_DR)){			
			rx_pipe=(p_spi2_regs->_STATUS.value>>1) & 0x5;//RX_P_NO 3:1, 						
			if(rx_pipe>5)ad0x0_err();//дадада, всю херню отслеживаем, 
			if(rx_pipe<=5){
				p_spi2_regs->PRX_readPayload_transmitAck(rx_pipe,p_spi2_regs->_R_RX_PL_WID.value,sizeof(packet_data_ack_t));				
			}			
			//write_register_bits(&p_spi2_regs->_STATUS,(1<<RX_DR),0xFF);
//			read_register(&p_spi2_regs->_CONFIG);
//			read_register(&p_spi2_regs->_OBSERVE_TX);
			read_register(&p_spi2_regs->_FIFO_STATUS);
			read_register(&p_spi2_regs->_STATUS);
			p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_RX_READ_OK,rf24_spi2_irq_rx);
			//write_register_bits(&p_spi2_regs->_CONFIG,(1<<PRIM_RX),0xFF);
		}//else ad0x0_err();
		break;
		case xNRF24_IRQ_RX_READ_OK:
			//write_register(&p_spi2_regs->_STATUS,0xE);//ПЕРЕДЕЛАТЬ!!! сброс битов прерываний
			//if(p_spi2_regs->_FIFO_STATUS.value & (1<<RX_EMPTY)){
			if( (p_spi2_regs->_STATUS.value & 0xE)==0xE){
				onRF24DataReady(p_spi2_regs->get_pipe_buf(rx_pipe));
				if(ad0x0_usart_isReady())ad0x0_usart_txbuf(p_spi2_regs->get_pipe_packet_buf(rx_pipe),p_spi2_regs->_R_RX_PL_WID.value);//прям в ком порт
				write_register_bits(&p_spi2_regs->_STATUS,(1<<RX_DR),0xFF);
			}else{
				read_register(&p_spi2_regs->_R_RX_PL_WID);
				p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_RX,rf24_spi2_irq_rx);
			}
			/*if(rx_in_frame>=ad0x0_rssi_max_count){
				ad0x0_rssi=tx_in_frame;
				tx_in_frame=rx_in_frame=0;
			}	*/
			//if(ad0x0_usart_isReady())ad0x0_usart_txbuf(&pipes_spi2[rx_pipe].packet,pipes_spi2[rx_pipe].bytes_count_packet);//прям в ком порт
			
		break;
		default:
			ad0x0_err();
	}
}
//------------------------------------------------
enum{
	xNRF24_IRQ_TX,
	xNRF24_IRQ_TX_OK
};

static void	rf24_irq_tx_cb(uint8_t _sf_id,ad0x0_spi_desc_s *pdspi,void *p_spi_ext_t){
//2E0703002C135737334D4E00
	static uint8_t rx_pipe=0xFF;
	switch(_sf_id){
case xNRF24_IRQ_TX:
/*как я понял, передать на отправку пакет нужно максимально быстро*/
	if(p_spi2_regs->_FIFO_STATUS.value & (1<<4/*TX_EMPTY*/)){
		if(p_spi2_regs->_FIFO_STATUS.value & (1<<5/*TX_FULL*/)){
			__ASM("nop");
		}else{			
			p_spi2_regs->PTX_transmit_pipe(0);
		}
		//write_register_bits(&p_spi2_regs->_STATUS,(1<<TX_DS),0xFF);
	}
	//RX_DR==1 для PTX означает что прикатил ACK от PRX
	if(!(p_spi2_regs->_FIFO_STATUS.value & (1<<0/*RX_EMPTY*/))){
			rx_pipe=(p_spi2_regs->_STATUS.value>>1) & 0x5;//RX_P_NO 3:1, 						
			p_spi2_regs->PTX_read_Ack(rx_pipe,p_spi2_regs->_R_RX_PL_WID.value);
	}	
	if(p_spi2_regs->_OBSERVE_TX.value){
		__ASM("nop");
	}
	if(p_spi2_regs->_STATUS.value & (1<<MAX_RT)){
		//p_spi2_regs->spi_cmd(FLUSH_TX);
		//p_spi2_regs->PTX_transmit_pipe(0);
		//write_register_bits(&p_spi2_regs->_STATUS,(1<<MAX_RT),0xFF);
	}	
	//read_register(&p_spi2_regs->_OBSERVE_TX);
	read_register(&p_spi2_regs->_FIFO_STATUS);
	read_register(&p_spi2_regs->_STATUS);

	p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_TX_OK,rf24_irq_tx_cb);
break;
case xNRF24_IRQ_TX_OK:
	if( (p_spi2_regs->_STATUS.value & 0xE)==0xE){		
		write_register_bits(&p_spi2_regs->_STATUS,(1<<RX_DR)|(1<<TX_DS)|(1<<MAX_RT),0xFF);
		if(rx_pipe<6)onRF24DataReady(p_spi2_regs->get_pipe_buf(rx_pipe));
		if(p_spi2_regs->_STATUS.value & (1<<TX_DS)){
//			write_register_bits(&p_spi2_regs->_STATUS,(1<<TX_DS),0xFF);
		}
	}else{
		read_register(&p_spi2_regs->_R_RX_PL_WID);
		read_register(&p_spi2_regs->_FIFO_STATUS);
		read_register(&p_spi2_regs->_STATUS);
		p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_RX,rf24_irq_tx_cb);
	}
	/*if(tx_in_frame>=ad0x0_rssi_max_count){
				ad0x0_rssi=rx_in_frame;
				tx_in_frame=rx_in_frame=0;
	}	*/
break;
default:
			ad0x0_err();
	}
}
//------------------------------------------------

void ad0x0_rf24_spi2_irq(void){
	if(!ad0x0_enable_irq){
		return;
	}
	read_register(&p_spi2_regs->_STATUS);//!!!не убирать нахрен это отсюда
	read_register(&p_spi2_regs->_FIFO_STATUS);
	read_register(&p_spi2_regs->_R_RX_PL_WID);
	if(p_spi2_regs->_CONFIG.value & (1<<PRIM_RX)){		
		p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_RX,rf24_spi2_irq_rx);
	}else{
		last_tx_irq_tick=HAL_GetTick();
		p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_IRQ_TX,rf24_irq_tx_cb);
	}
}

uint8_t spi2_wakeup(){
	
	if(get_frame_ms(frame_start_tick)>frame_max_ms){
		if(p_spi2_regs->_CONFIG.value & (1<<PRIM_RX)){		
			ad0x0_rssi=rx_in_frame;
		}else{
			uint32_t t=get_last_tx_irq_ms();
			if(t>50){
				p_spi2_regs->PTX_transmit_pipe(0);
				last_tx_irq_tick=HAL_GetTick();
				//ad0x0_rf24_spi2_irq();
			}			
			ad0x0_rssi=tx_in_frame;
		}
		//ad0x0_rssi=tx_in_frame;
		tx_in_frame=rx_in_frame=0;
		frame_start_tick=HAL_GetTick();
	}
	return 0;
}

static void PTX_start(uint8_t _pipe_index){
	ad0x0_enable_irq=1;
	write_register_bits(&p_spi2_regs->_CONFIG,0x0,~(1<<PRIM_RX));
	PTX_transmit_pipe(_pipe_index);
	ad0x0_timman_add(10,spi2_wakeup);
}

static void PRX_start(uint8_t _pipe_index,uint8_t _ack_payload_size){
	ad0x0_enable_irq=1;
	write_register_bits(&p_spi2_regs->_CONFIG,(1<<PRIM_RX),0xFF);
	p_spi2_regs->enableRXPipe(_pipe_index,_ack_payload_size,true,true);
	ad0x0_timman_add(10,spi2_wakeup);
}

static void PTX_init(void){
	p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_PTX,rf24_init_cb);
}

static void PRX_init(void){
	p_spi2_regs->ad0x0_spi_push_ext_setfunc(xNRF24_PRX,rf24_init_cb);
}

static uint8_t    get_rssi(void){
	return ad0x0_rssi;
}

void rf24_init_spi2_regs(rf24_spi_regs_t *p,GPIO_TypeDef *rf24_CE_GPIO_Port, uint16_t rf24_CE_Pin){
	if(sizeof(packet_data_t)!=32)ad0x0_err();
	extern void rf24_init_spi_regs(rf24_spi_regs_t *p);
	rf24_init_spi_regs(p);
	p_spi2_regs=p;
	p->CE_GPIO_Port=rf24_CE_GPIO_Port;
	p->CE_Pin=rf24_CE_Pin;
	p->ad0x0_spi_get_ext_async2=ad0x0_spi2_get_ext_async2;
	p->ad0x0_spi_push=ad0x0_spi2_push;
	p->ad0x0_spi_push_ext_setfunc=ad0x0_spi2_push_ext_setfunc;
	p->ad0x0_spi_push_txrx_dma_ext=ad0x0_spi2_push_txrx_dma_ext;
	p->ad0x0_spi_push_tx_pbuf_dma_ext=ad0x0_spi2_push_tx_pbuf_dma_ext;
	p->ad0x0_spi_push_tx_pbuf_ext=ad0x0_spi2_push_tx_pbuf_ext;
	p->powerUp=rf24_spi2_powerUp;
	p->powerDown=rf24_spi2_powerDown;
	p->set_ce=rf24_spi2_set_ce;
	p->enableRXPipe=rf24_spi2_enableRXPipe;
	p->setRateAndPA=rf24_spi2_setRateAndPA;
	p->setRetransmission=rf24_spi2_setRetransmission;
	p->spi_cmd=rf24_spi2_cmd;
	p->PRX_readPayload_transmitAck=PRX_readPayload_transmitAck;
	p->get_pipe_packet_buf=get_pipe_packet_buf;
	p->get_pipe_ack_buf=get_pipe_ack_buf;
	p->get_pipe_buf=get_pipe_buf;
	p->PTX_transmit_pipe=PTX_transmit_pipe;
	p->PRX_start=PRX_start;
	p->PTX_start=PTX_start;
	p->init_pipes=init_pipes;
	p->PTX_read_Ack=PTX_read_Ack;
	p->PRX_init=PRX_init;
	p->PTX_init=PTX_init;
	p->get_rssi=get_rssi;
	//init_pipes();
	memset((void*)scan_data,0,sizeof(scan_data));	
	scan_data[128]='\n';
}

