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

Why is the GPS operation always blocked

One of my projects needs to use NB and GPS functions at the same time. When testing, I found that even though NB network is not transmitting data, after I start GPS, I often receive messages that the operation is blocked. Why is that?  

This is my code:

static void set_gps_enable(const bool enable)
{
	u8_t tmpbuf[128] = {0};
	
	if(enable == gps_control_is_enabled())
	{
		return;
	}

	if(enable)
	{
		at_cmd_write("AT+CFUN?", tmpbuf, sizeof(tmpbuf), NULL);
		LOG_INF("modem status:%s", tmpbuf);
		if(strcmp(tmpbuf, "+CFUN: 1") != 0)
		{
			if(at_cmd_write("AT+CFUN=1", NULL, 0, NULL) != 0)
			{
				LOG_INF("Can't turn on modem!");
				EnterIdleScreen();
				return;
			}
		}
		
		LOG_INF("Starting GPS");
		gps_control_start(K_NO_WAIT);
		gps_is_on = true;
		gps_start_time = k_uptime_get();
	}
	else
	{
		LOG_INF("Stopping GPS");
		gps_control_stop(K_NO_WAIT);
		gps_is_on = false;
		gps_fix_time = 0;
		gps_local_time = 0;
	}
}

static void gps_handler(struct device *dev, struct gps_event *evt)
{
	u8_t tmpbuf[128] = {0};
	
	switch (evt->type)
	{
	case GPS_EVT_SEARCH_STARTED:
		LOG_INF("GPS_EVT_SEARCH_STARTED\n");
		gps_control_set_active(true);
		break;
		
	case GPS_EVT_SEARCH_STOPPED:
		LOG_INF("GPS_EVT_SEARCH_STOPPED\n");
		gps_control_set_active(false);
		break;
		
	case GPS_EVT_SEARCH_TIMEOUT:
		LOG_INF("GPS_EVT_SEARCH_TIMEOUT\n");
		gps_control_set_active(false);
		break;
		
	case GPS_EVT_PVT:
		/* Don't spam logs */
		LOG_INF("GPS_EVT_PVT");
		
		if(test_gps_flag)
		{
			u8_t i,tracked;
			u8_t strbuf[256] = {0};

			memset(gps_test_info, 0x00, sizeof(gps_test_info));
			
			for(i=0;i<GPS_PVT_MAX_SV_COUNT;i++)
			{
				u8_t buf[128] = {0};
				
				if((evt->pvt.sv[i].sv > 0) && (evt->pvt.sv[i].sv < 32))
				{
					tracked++;
			
					sprintf(buf, "%02d|%02d;", evt->pvt.sv[i].sv, evt->pvt.sv[i].cn0/10);
					strcat(strbuf, buf);
				}
			}

			sprintf(gps_test_info, "%d,", tracked);
			strcat(gps_test_info, strbuf);
			gps_test_update_flag = true;
			
			//LOG_INF("%s\n",gps_test_info);
			//UpdataTestGPSInfo();
			//TestGPSShowInfor();
		}
		else
		{
			sprintf(tmpbuf, "Longitude:%f, Latitude:%f, Altitude:%f, Speed:%f, Heading:%f", 
								evt->pvt.longitude, 
								evt->pvt.latitude,
								evt->pvt.altitude,
								evt->pvt.speed,
								evt->pvt.heading);
			LOG_INF("%s",tmpbuf);
			
			LOG_INF("Date:       %02u-%02u-%02u", evt->pvt.datetime.year,
						       					  evt->pvt.datetime.month,
						       					  evt->pvt.datetime.day);
			LOG_INF("Time (UTC): %02u:%02u:%02u\n", evt->pvt.datetime.hour,
						       					  evt->pvt.datetime.minute,
						      					  evt->pvt.datetime.seconds);
		}
		break;
	
	case GPS_EVT_PVT_FIX:
		LOG_INF("GPS_EVT_PVT_FIX");

		if(test_gps_flag)
		{
			u8_t i,tracked;
			u8_t strbuf[256] = {0};

			memset(gps_test_info, 0x00, sizeof(gps_test_info));
			
			for(i=0;i<GPS_PVT_MAX_SV_COUNT;i++)
			{
				u8_t buf[256] = {0};
				
				if((evt->pvt.sv[i].sv > 0) && (evt->pvt.sv[i].sv < 32))
				{
					tracked++;
			
					sprintf(buf, "%02d|%02d;", evt->pvt.sv[i].sv, evt->pvt.sv[i].cn0/10);
					strcat(strbuf, buf);
				}
			}

			sprintf(gps_test_info, "%d,", tracked);
			strcat(gps_test_info, strbuf);
			strcat(gps_test_info, "\n");
			sprintf(strbuf, "Longitude:%f, Latitude:%f\n", evt->pvt.longitude, evt->pvt.latitude);
			strcat(gps_test_info, strbuf);
			sprintf(strbuf, "fix time:%d", gps_local_time/1000);
			strcat(gps_test_info, strbuf);
			gps_test_update_flag = true;
			
			//LOG_INF("%s\n",gps_test_info);
			//UpdataTestGPSInfo();
			//TestGPSShowInfor();
		}		
		else
		{
			sprintf(tmpbuf, "Longitude:%f, Latitude:%f", evt->pvt.longitude, evt->pvt.latitude);
			LOG_INF("%s\n",tmpbuf);
		
			memcpy(&gps_pvt_data, &(evt->pvt), sizeof(evt->pvt));
		}
		break;
		
	case GPS_EVT_NMEA:
		/* Don't spam logs */
		LOG_INF("GPS_EVT_NMEA\n");
		break;
		
	case GPS_EVT_NMEA_FIX:
		LOG_INF("GPS_EVT_NMEA_FIX");

		if(gps_fix_time == 0)
		{
			gps_fix_time = k_uptime_get();
			gps_local_time = gps_fix_time-gps_start_time;
		}
		
		if(!test_gps_flag)
		{
			LOG_INF("Position fix with NMEA data, fix time:%d", gps_local_time);
			LOG_INF("NMEA:%s\n", evt->nmea.buf);
		
			APP_Ask_GPS_off();

			if(k_timer_remaining_get(&app_wait_gps_timer) > 0)
				k_timer_stop(&app_wait_gps_timer);

			k_timer_start(&app_send_gps_timer, K_MSEC(1000), NULL);
		}
		break;
		
	case GPS_EVT_OPERATION_BLOCKED:
		LOG_INF("GPS_EVT_OPERATION_BLOCKED\n");
		break;
		
	case GPS_EVT_OPERATION_UNBLOCKED:
		LOG_INF("GPS_EVT_OPERATION_UNBLOCKED\n");
		break;
		
	case GPS_EVT_AGPS_DATA_NEEDED:
		LOG_INF("GPS_EVT_AGPS_DATA_NEEDED\n");
		k_work_submit_to_queue(app_work_q,
				       &send_agps_request_work);
		break;
		
	case GPS_EVT_ERROR:
		LOG_INF("GPS_EVT_ERROR\n");
		break;
		
	default:
		break;
	}
}

void GPS_init(struct k_work_q *work_q)
{
	app_work_q = work_q;

	k_work_init(&send_agps_request_work, send_agps_request);

	gps_control_init(app_work_q, gps_handler);
}

Parents
  • Hello,

    my apologies for the late reply. I was on vacation for the last couple of weeks.

    duxinglang said:
    Is there any other way to keep the network connection and enable the GPS function properly?  

    Yes. The GPS socket can be used while the LTE socket is released which happens after it has entered RRC idle. For this, your network provider has to support PSM and you have to configure your device requesting PSM to the network accordingly.

    Regards,

    Markus

Reply
  • Hello,

    my apologies for the late reply. I was on vacation for the last couple of weeks.

    duxinglang said:
    Is there any other way to keep the network connection and enable the GPS function properly?  

    Yes. The GPS socket can be used while the LTE socket is released which happens after it has entered RRC idle. For this, your network provider has to support PSM and you have to configure your device requesting PSM to the network accordingly.

    Regards,

    Markus

Children
No Data
Related