This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Infrared receive driver can not use,How to fix it ?

I write an infrared receive driver on example ble_app_uart with softDevice 6, but it not work after I use softDevice 8.How to fix it ? Is there an offical infrared receive driver ? Thank you!

I use HS388D as infrared receiver, below wave is the output by infrared receiver

image description

image description

the first one is 9000us the second is 4543us, so infrared receiver driver store these value to an array 9000 4543 ... ...

below is code:

    #define MIN_RECEIVE_BUFF_LENGTH 20    


#define RECEIVE_TIME_INTERVAL     APP_TIMER_TICKS(1, 0)



static irparams_t irparams;
volatile int receiveflag=0;

static app_timer_id_t m_receive_timer_id; 
static uint8_t receive_timer_flag=0;

void receive_para_init(){
  irparams.rawlen=0;
	irparams.rcvstate=STATE_IDLE;
	irparams.timer=0;
	irparams.receive_begin=0;
	receiveflag=0;
}


void receive_timer1_init(){
	uint32_t crystal_is_running = 0;
	
		sd_clock_hfclk_request();
	 
    while(!crystal_is_running)
    {
        sd_clock_hfclk_is_running(&crystal_is_running);
    } 
        // Clear TIMER1
    NRF_TIMER1->TASKS_CLEAR = 1; 
    NRF_TIMER1->MODE        = TIMER_MODE_MODE_Timer;
    NRF_TIMER1->PRESCALER   = 6;  // one ticket is 4us
    NRF_TIMER1->BITMODE     = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;

    NRF_TIMER1->TASKS_START = 1; // Start clocks
}


void receive_gpiote_init(){
	    nrf_gpio_cfg_sense_input(INFRAD_RECEIVE_PIN, GPIO_PIN_CNF_PULL_Pullup, NRF_GPIO_PIN_SENSE_LOW);

    NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos);
	
	  NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN3_Enabled << GPIOTE_INTENSET_IN3_Pos);
	
	

    nrf_gpiote_event_config(0, INFRAD_RECEIVE_PIN, NRF_GPIOTE_POLARITY_HITOLO);
    
    nrf_gpiote_event_config(1, INFRAD_RECEIVE_PIN, NRF_GPIOTE_POLARITY_LOTOHI);
	
    sd_nvic_SetPriority(GPIOTE_IRQn, 3);
    sd_nvic_EnableIRQ(GPIOTE_IRQn);
}


void GPIOTE_IRQHandler(void)
{
    static uint32_t prev_cc1 = 0;
    int64_t curr_wave;
    uint32_t active_time;

	  if( irparams.receive_begin==0)
		{
	
			irparams.receive_begin=1; 
			irparams.rawlen=0;
			nrf_gpio_pin_toggle(LED_DEBUG_RECEIVE);
		}	

		if(irparams.rawlen>296)
			irparams.rawlen=0;
		if(NRF_GPIOTE->EVENTS_IN[0]==1){
			  irparams.rawbuf[irparams.rawlen]=NRF_TIMER1->CC[0];
	  	  irparams.rawlen++;
				NRF_GPIOTE->EVENTS_IN[0] = 0; 
		}
		if(NRF_GPIOTE->EVENTS_IN[1]==1){
				irparams.rawbuf[irparams.rawlen]=NRF_TIMER1->CC[1];		
    		irparams.rawlen++;
		    NRF_GPIOTE->EVENTS_IN[1] = 0; 
		}
		
			
}

void receive_ppi_init(){
		receive_ppi_enable_channel(0,&(NRF_GPIOTE->EVENTS_IN[0]),&(NRF_TIMER1->TASKS_CAPTURE[0]));
		receive_ppi_enable_channel(1,&(NRF_GPIOTE->EVENTS_IN[1]),&(NRF_TIMER1->TASKS_CAPTURE[1]));
}

void receive_enable(void){
   receive_para_init();  
	 receive_gpiote_init();
	 receive_ppi_init();
	 receive_timer1_init();
	 

	if(receive_timer_flag){
		receive_timerStop();
	}
	receive_timerStart();
	printf("receive enable done\r\n");
	
}



static void receive_ppi_enable_channel(uint32_t ch_num, volatile uint32_t *event_ptr, volatile uint32_t *task_ptr)
{
   uint32_t err_code;
   uint32_t error;
       err_code =  sd_ppi_channel_assign(ch_num, event_ptr, task_ptr);
	 if( err_code != NRF_SUCCESS ){
					error = err_code;//erreur
				}
      err_code =  sd_ppi_channel_enable_set(1 << ch_num);
				if( err_code != NRF_SUCCESS ){
					error = err_code;//erreur
				}
}



int receive_decode(decode_results *results){
  int resVal=0;

	printf("Time Array buffer:\r\n");
	char str[64];
	for(int i=0;i<irparams.rawlen;i++){
		  if(i&&(i%8)==0){
				printf("\r\n");
		}	
		snprintf(str,sizeof(str),"%d",irparams.rawbuf[i]);	
		printf("%s",str);
		printf("\r\n");
  	
	}
	printf("\r\n");
	calculate_time();
	
  results->rawbuf=irparams.rawbuf;
	results->rawlen=irparams.rawlen;
	

			resVal=1;

		//init for next time
  	receive_para_init();
		receive_timer1_init();
		NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos);
		return resVal;
}

void calculate_time(){
  for(int i=0;i<irparams.rawlen-1;i++){
	 irparams.rawbuf[i]=((irparams.rawbuf[i+1]-irparams.rawbuf[i])+65535)%65535;	
		irparams.rawbuf[i]<<=2;
	}
		char str[64];

	printf("Time real buffer:\r\n");
	for(int i=0;i<irparams.rawlen-1;i++){
		  if(i&&(i%8)==0){
				printf("\r\n");
		}	
		snprintf(str,sizeof(str),"%d",irparams.rawbuf[i]);
		printf("%s",str);
		printf("\n\r");
  	
	}
	printf("\n\r");
	
}


int receive_done(){

    return receiveflag;
}

int receive_halt(){
 NRF_TIMER1->TASKS_SHUTDOWN=1;
	NRF_TIMER2->TASKS_SHUTDOWN=1;
	NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Disabled << GPIOTE_INTENSET_IN1_Pos);
}

int receive_continue(){

 NRF_TIMER1->TASKS_START=1;
	NRF_TIMER2->TASKS_START=1;
	NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Enabled << GPIOTE_INTENSET_IN1_Pos);
}



static void receive_timerHandle(void * pcontext){
	  
   if(irparams.receive_begin==1)		
	 {
		 irparams.timer++;
	 }
	 if(irparams.timer){
	  //now irparams.timer is the gap time
		if(irparams.timer>GAP_TIME){
		  irparams.rcvstate=STATE_STOP;
			irparams.receive_begin=0;
			irparams.timer=0;

			if(irparams.rawlen>MIN_RECEIVE_BUFF_LENGTH)
			{
				//data is good
				receiveflag=1;
				NRF_TIMER1->TASKS_SHUTDOWN=1;
			  NRF_GPIOTE->INTENSET = (GPIOTE_INTENSET_IN1_Disabled << GPIOTE_INTENSET_IN1_Pos);
			}		
      else{
			  //
				receiveflag=0;
			}			

		}
	 }
}

void receive_timerInit(void){
      uint32_t err_code;

    err_code = app_timer_create(&m_receive_timer_id,
                                APP_TIMER_MODE_REPEATED,
                                receive_timerHandle);
    APP_ERROR_CHECK(err_code);
	receive_timer_flag=0;
}

void receive_timerStart(void){
  uint32_t err_code;
	 if(receive_timer_flag==0){
			err_code = app_timer_start(m_receive_timer_id, RECEIVE_TIME_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
	 receive_timer_flag=1;
		 }
}

void receive_timerStop(void){
  uint32_t err_code;
	if(receive_timer_flag==1){
	  	    err_code = app_timer_stop(m_receive_timer_id);
    APP_ERROR_CHECK(err_code);
	receive_timer_flag=0;
	}

}
Related