/* 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 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)<_SETUP_RETR,(delay&0xf)<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<_CONFIG,(1<_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()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<_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<_STATUS,(1<_STATUS.value & (1<spi_cmd(FLUSH_TX); write_register_bits(&p_spi2_regs->_STATUS,(1<_STATUS.value & (1<spi_cmd(FLUSH_TX); write_register_bits(&p_spi2_regs->_STATUS,(1<_STATUS.value & (1<_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<_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<_STATUS,0xE);//ПЕРЕДЕЛАТЬ!!! сброс битов прерываний //if(p_spi2_regs->_FIFO_STATUS.value & (1<_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<_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<_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<spi_cmd(FLUSH_TX); //p_spi2_regs->PTX_transmit_pipe(0); //write_register_bits(&p_spi2_regs->_STATUS,(1<_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<get_pipe_buf(rx_pipe)); if(p_spi2_regs->_STATUS.value & (1<_STATUS,(1<_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<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<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<_CONFIG,(1<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'; }