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
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;
}
}