Hello, I am trying to broadcast a data among 2 receivers with a special ACK payload. I transmit and gather ACK with one receiver properly yet m_nrf_esb_mainstate locks in NRF_ESB_STATE_PTX_RX_ACK. As I understand from nrf_esb.c after a certain time if no ack is recieved radio must disable itself am I correct?
I can not start transmitting payloads unless m_nrf_esb_mainstate changed to NRF_ESB_STATE_IDLE.
static void on_radio_disabled_tx() { // Remove the DISABLED -> RXEN shortcut, to make sure the radio stays // disabled after the RX window NRF_RADIO->SHORTS = m_radio_shorts_common; // Make sure the timer is started the next time the radio is ready, // and that it will disable the radio automatically if no packet is // received by the time defined in m_wait_for_ack_timeout_us NRF_ESB_SYS_TIMER->CC[0] = m_wait_for_ack_timeout_us; NRF_ESB_SYS_TIMER->CC[1] = m_config_local.retransmit_delay - 130; NRF_ESB_SYS_TIMER->TASKS_CLEAR = 1; NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0] = 0; NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1] = 0; NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TIMER_START) | (1 << NRF_ESB_PPI_RX_TIMEOUT) | (1 << NRF_ESB_PPI_TIMER_STOP); NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START); NRF_RADIO->EVENTS_END = 0; if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB) { update_rf_payload_format(0); } NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer; on_radio_disabled = on_radio_disabled_tx_wait_for_ack; m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_RX_ACK; }
And this is my code, a bit sloppy but meh,
/********************************************************************* * SEGGER MICROCONTROLLER GmbH & Co. KG * * Solutions for real time microcontroller applications * ********************************************************************** * * * (c) 2014 - 2017 SEGGER Microcontroller GmbH & Co. KG * * * * www.segger.com Support: [email protected] * * * ********************************************************************** -------------------------- END-OF-HEADER ----------------------------- File : main.c Purpose : Generic application start */ #include <stdio.h> #include <stdlib.h> #include "sdk_config.h" #include "nrf_gpio.h" #include "nrf_delay.h" #include "nrf_uart.h" #include "nrf_saadc.c" #include "nrf_drv_pwm.c" #include "radio_config.c" #include "nrf_esb_error_codes.h" #include "nrf_esb.c" #include <math.h> #include <string.h> #define ID 0x01 // ID #define gravity 23.1821 // ADC Reading of g #define acc_offset 127 //0 Acceleration offset #define ldr_limit 80 //Mean of daylight measurement #define PIR_PIN 22 // Input of the HCSR501 PIR Motion Sensor #define SPEAKER_PIN 17 // Sound output (Speakers will be drived by a N-Channel FET #if ID == 0x01 #define x_pos 0 #define y_pos 0 #elif ID == 0x02 #define x_pos 6 #define y_pos 0 #elif ID == 0x03 #define x_pos 12 #define y_pos 0 #else #define x_pos NULL #define y_pos NULL #endif #ifdef x_pos static nrf_esb_payload_t tx_payload=NRF_ESB_CREATE_PAYLOAD(0,ID,x_pos,y_pos,0x31,0x32,0x33,0x34); // (ID,pos_X,pos_y, broadcast order...) #endif static nrf_esb_payload_t rx_payload; nrf_esb_config_t esb_config=NRF_ESB_DEFAULT_CONFIG; uint8_t base_addr_0 = 0xe7; uint8_t addr_prefix = 0xa5; bool tx_flag=true; struct{ int8_t id; double pos_x; double pos_y; int8_t rssi; float distance; }data[150]; double distances[4][4]; // distance[ID][position_x,position_y,RSSI,distance] int8_t order[4]; nrf_esb_evt_t const * p_event; int index=0; static int8_t references[3]={0x01,0x02,0x03}; static nrf_pwm_values_common_t duty_cycle[1]={0}; // Duty cycle value array nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0); // PWM0 is used uint8_t adc_buffer[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //ADC Buffer. ADC somehow transfers the result as mirrored. There is a bitwise mirror script in radio_config.c ! void nrf_esb_event_handler(nrf_esb_evt_t const * p_event); bool arrsrc(int8_t *array,int8_t id){ for(int i=0;i<150;i++){ if(array[i]==id){ return true; break; } else{ return false; break; } } } void clocks_start( void ) { NRF_CLOCK->EVENTS_HFCLKSTARTED = 0; NRF_CLOCK->TASKS_HFCLKSTART = 1; while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0); } int32_t init_esb(char mode){ tx_payload.noack=false; uint32_t err_code=0; err_code = nrf_esb_disable(); nrf_delay_us(150); if(err_code != NRF_SUCCESS) return err_code; esb_config.payload_length=7; esb_config.event_handler=nrf_esb_event_handler; if(mode == 'r') esb_config.mode=NRF_ESB_MODE_PRX; else if (mode == 't') esb_config.mode = NRF_ESB_MODE_PTX; else return NRF_ERROR_INVALID_PARAM; err_code = nrf_esb_init(&esb_config); if(err_code != NRF_SUCCESS) return err_code; err_code = nrf_esb_set_base_address_0(&base_addr_0); if(err_code != NRF_SUCCESS) return err_code; err_code = nrf_esb_set_prefixes(&addr_prefix,1); if(err_code != NRF_SUCCESS) return err_code; if(mode == 'r') err_code = nrf_esb_start_rx(); else if (mode == 't') err_code = nrf_esb_start_tx(); return NRF_SUCCESS; } void init_adc(){ nrf_saadc_channel_config_t adc_channel_conf[8]; nrf_saadc_enable(); nrf_delay_us(100); while(nrf_saadc_enable_check() == 0){ printf("ADC enable failed, trying again..."); nrf_saadc_enable(); nrf_delay_us(100); } nrf_saadc_buffer_init((int16_t *)&adc_buffer,16); nrf_saadc_resolution_set(NRF_SAADC_RESOLUTION_8BIT); nrf_saadc_oversample_set(NRF_SAADC_OVERSAMPLE_DISABLED); for(int i=0;i<4;i++){ adc_channel_conf[i].acq_time=NRF_SAADC_ACQTIME_3US; // tconv<2us adc_channel_conf[i].burst=NRF_SAADC_BURST_DISABLED; adc_channel_conf[i].gain=NRF_SAADC_GAIN1_4; adc_channel_conf[i].mode=NRF_SAADC_MODE_SINGLE_ENDED; adc_channel_conf[i].pin_n=NRF_SAADC_INPUT_DISABLED; adc_channel_conf[i].pin_p=(NRF_SAADC_INPUT_AIN0+i); adc_channel_conf[i].reference=NRF_SAADC_REFERENCE_VDD4; adc_channel_conf[i].resistor_n=NRF_SAADC_RESISTOR_DISABLED; adc_channel_conf[i].resistor_p=NRF_SAADC_RESISTOR_DISABLED; nrf_saadc_channel_init(i,&adc_channel_conf[i]); } nrf_saadc_task_trigger(NRF_SAADC_TASK_START); } void init_pwm(void){ nrf_drv_pwm_config_t pwm_conf=NRF_DRV_PWM_DEFAULT_CONFIG; //Base clock 250khz , counter_top=5 -> freq=50khz nrf_drv_pwm_init(&m_pwm0,&pwm_conf,NULL); nrf_pwm_sequence_t seq_pmw; seq_pmw.values.p_common=&duty_cycle; seq_pmw.repeats=2; seq_pmw.length=1; seq_pmw.end_delay=0; nrf_drv_pwm_simple_playback(&m_pwm0,&seq_pmw,1,NRF_DRV_PWM_FLAG_LOOP); } void main(void) { nrf_gpio_cfg_output(0); nrf_gpio_pin_clear(0); for(int i=0;i<4;i++){ order[i]=0; } uint32_t err_code_main=0; init_adc(); init_pwm(); clocks_start(); if(ID==0x01)err_code_main = init_esb('t'); else err_code_main = init_esb('r'); while(1){ err_code_main = nrf_esb_write_payload(&tx_payload); nrf_saadc_task_trigger(NRF_SAADC_TASK_START); nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE); nrf_saadc_event_clear(NRF_SAADC_EVENT_RESULTDONE); } } void nrf_esb_event_handler(nrf_esb_evt_t const * p_event) { if(p_event->evt_id == NRF_ESB_EVENT_TX_SUCCESS) { tx_flag=false; } else if(p_event->evt_id == NRF_ESB_EVENT_TX_FAILED) { nrf_esb_flush_tx(); } else if(p_event->evt_id == NRF_ESB_EVENT_RX_RECEIVED){ if(nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS){ nrf_esb_stop_rx(); if(!arrsrc(&data->id,rx_payload.data[0])){ data[index].id=rx_payload.data[0]; data[index].pos_x=rx_payload.data[1]; data[index].pos_y=rx_payload.data[2]; data[index].rssi=rx_payload.rssi; data[index].distance= pow(10,(20.0*log10(2.4*pow(10,9))+20.0*log10(4*M_PI/299792458.0)+20.0-data[index].rssi)/(-20.0)); // RSSI to Distance ,in meters index++; } } } }